diff options
Diffstat (limited to 'drivers/net/wireless/realtek/rtw88/main.c')
-rw-r--r-- | drivers/net/wireless/realtek/rtw88/main.c | 91 |
1 files changed, 70 insertions, 21 deletions
diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c index ae61415e1665..2845d2838f7b 100644 --- a/drivers/net/wireless/realtek/rtw88/main.c +++ b/drivers/net/wireless/realtek/rtw88/main.c @@ -706,8 +706,8 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) if (sta->vht_cap.cap & IEEE80211_VHT_CAP_SHORT_GI_80) is_support_sgi = true; } else if (sta->ht_cap.ht_supported) { - ra_mask |= (sta->ht_cap.mcs.rx_mask[NL80211_BAND_5GHZ] << 20) | - (sta->ht_cap.mcs.rx_mask[NL80211_BAND_2GHZ] << 12); + ra_mask |= (sta->ht_cap.mcs.rx_mask[1] << 20) | + (sta->ht_cap.mcs.rx_mask[0] << 12); if (sta->ht_cap.cap & IEEE80211_HT_CAP_RX_STBC) stbc_en = HT_STBC_EN; if (sta->ht_cap.cap & IEEE80211_HT_CAP_LDPC_CODING) @@ -717,6 +717,9 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) is_support_sgi = true; } + if (efuse->hw_cap.nss == 1) + ra_mask &= RA_MASK_VHT_RATES_1SS | RA_MASK_HT_RATES_1SS; + if (hal->current_band_type == RTW_BAND_5G) { ra_mask |= (u64)sta->supp_rates[NL80211_BAND_5GHZ] << 4; if (sta->vht_cap.vht_supported) { @@ -750,11 +753,6 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) wireless_set = 0; } - if (efuse->hw_cap.nss == 1) { - ra_mask &= RA_MASK_VHT_RATES_1SS; - ra_mask &= RA_MASK_HT_RATES_1SS; - } - switch (sta->bandwidth) { case IEEE80211_STA_RX_BW_80: bw_mode = RTW_CHANNEL_WIDTH_80; @@ -793,6 +791,26 @@ void rtw_update_sta_info(struct rtw_dev *rtwdev, struct rtw_sta_info *si) rtw_fw_send_ra_info(rtwdev, si); } +static int rtw_wait_firmware_completion(struct rtw_dev *rtwdev) +{ + struct rtw_chip_info *chip = rtwdev->chip; + struct rtw_fw_state *fw; + + fw = &rtwdev->fw; + wait_for_completion(&fw->completion); + if (!fw->firmware) + return -EINVAL; + + if (chip->wow_fw_name) { + fw = &rtwdev->wow_fw; + wait_for_completion(&fw->completion); + if (!fw->firmware) + return -EINVAL; + } + + return 0; +} + static int rtw_power_on(struct rtw_dev *rtwdev) { struct rtw_chip_info *chip = rtwdev->chip; @@ -813,11 +831,10 @@ static int rtw_power_on(struct rtw_dev *rtwdev) goto err; } - wait_for_completion(&fw->completion); - if (!fw->firmware) { - ret = -EINVAL; - rtw_err(rtwdev, "failed to load firmware\n"); - goto err; + ret = rtw_wait_firmware_completion(rtwdev); + if (ret) { + rtw_err(rtwdev, "failed to wait firmware completion\n"); + goto err_off; } ret = rtw_download_firmware(rtwdev, fw); @@ -881,7 +898,7 @@ int rtw_core_start(struct rtw_dev *rtwdev) static void rtw_power_off(struct rtw_dev *rtwdev) { - rtwdev->hci.ops->stop(rtwdev); + rtw_hci_stop(rtwdev); rtw_mac_power_off(rtwdev); } @@ -1020,8 +1037,8 @@ static void rtw_unset_supported_band(struct ieee80211_hw *hw, static void rtw_load_firmware_cb(const struct firmware *firmware, void *context) { - struct rtw_dev *rtwdev = context; - struct rtw_fw_state *fw = &rtwdev->fw; + struct rtw_fw_state *fw = context; + struct rtw_dev *rtwdev = fw->rtwdev; const struct rtw_fw_hdr *fw_hdr; if (!firmware || !firmware->data) { @@ -1043,17 +1060,35 @@ static void rtw_load_firmware_cb(const struct firmware *firmware, void *context) fw->version, fw->sub_version, fw->sub_index, fw->h2c_version); } -static int rtw_load_firmware(struct rtw_dev *rtwdev, const char *fw_name) +static int rtw_load_firmware(struct rtw_dev *rtwdev, enum rtw_fw_type type) { - struct rtw_fw_state *fw = &rtwdev->fw; + const char *fw_name; + struct rtw_fw_state *fw; int ret; + switch (type) { + case RTW_WOWLAN_FW: + fw = &rtwdev->wow_fw; + fw_name = rtwdev->chip->wow_fw_name; + break; + + case RTW_NORMAL_FW: + fw = &rtwdev->fw; + fw_name = rtwdev->chip->fw_name; + break; + + default: + rtw_warn(rtwdev, "unsupported firmware type\n"); + return -ENOENT; + } + + fw->rtwdev = rtwdev; init_completion(&fw->completion); ret = request_firmware_nowait(THIS_MODULE, true, fw_name, rtwdev->dev, - GFP_KERNEL, rtwdev, rtw_load_firmware_cb); + GFP_KERNEL, fw, rtw_load_firmware_cb); if (ret) { - rtw_err(rtwdev, "async firmware request failed\n"); + rtw_err(rtwdev, "failed to async firmware request\n"); return ret; } @@ -1341,7 +1376,6 @@ int rtw_core_init(struct rtw_dev *rtwdev) skb_queue_head_init(&rtwdev->coex.queue); skb_queue_head_init(&rtwdev->tx_report.queue); - spin_lock_init(&rtwdev->dm_lock); spin_lock_init(&rtwdev->rf_lock); spin_lock_init(&rtwdev->h2c.lock); spin_lock_init(&rtwdev->txq_lock); @@ -1372,12 +1406,19 @@ int rtw_core_init(struct rtw_dev *rtwdev) BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | BIT_AB | BIT_AM | BIT_APM; - ret = rtw_load_firmware(rtwdev, rtwdev->chip->fw_name); + ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW); if (ret) { rtw_warn(rtwdev, "no firmware loaded\n"); return ret; } + if (chip->wow_fw_name) { + ret = rtw_load_firmware(rtwdev, RTW_WOWLAN_FW); + if (ret) { + rtw_warn(rtwdev, "no wow firmware loaded\n"); + return ret; + } + } return 0; } EXPORT_SYMBOL(rtw_core_init); @@ -1385,12 +1426,16 @@ EXPORT_SYMBOL(rtw_core_init); void rtw_core_deinit(struct rtw_dev *rtwdev) { struct rtw_fw_state *fw = &rtwdev->fw; + struct rtw_fw_state *wow_fw = &rtwdev->wow_fw; struct rtw_rsvd_page *rsvd_pkt, *tmp; unsigned long flags; if (fw->firmware) release_firmware(fw->firmware); + if (wow_fw->firmware) + release_firmware(wow_fw->firmware); + tasklet_kill(&rtwdev->tx_tasklet); spin_lock_irqsave(&rtwdev->tx_report.q_lock, flags); skb_queue_purge(&rtwdev->tx_report.queue); @@ -1445,6 +1490,10 @@ int rtw_register_hw(struct rtw_dev *rtwdev, struct ieee80211_hw *hw) wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CAN_REPLACE_PTK0); +#ifdef CONFIG_PM + hw->wiphy->wowlan = rtwdev->chip->wowlan_stub; + hw->wiphy->max_sched_scan_ssids = rtwdev->chip->max_sched_scan_ssids; +#endif rtw_set_supported_band(hw, rtwdev->chip); SET_IEEE80211_PERM_ADDR(hw, rtwdev->efuse.addr); |