From: Zong-Zhe Yang The RTW89_QUIRK_DISABLE_2GHZ only blocked registering NL80211_BAND_2GHZ in wiphy->bands, but didn't handle other SW logic. Other SW flow still determined things based on chip->support_bands, and caused inconsistent behavior. Introduce supported_bands bitmap which is set by intersection of quirks and chip->support_bands when initializing core. Besides, initialize quirks when allocating HW. Fixes: 355626a2c232 ("wifi: rtw89: 8852cu: add quirk to disable 2.4 GHz band") Signed-off-by: Zong-Zhe Yang Signed-off-by: Ping-Ke Shih --- drivers/net/wireless/realtek/rtw89/core.c | 37 ++++++++++++++-------- drivers/net/wireless/realtek/rtw89/core.h | 1 + drivers/net/wireless/realtek/rtw89/debug.c | 5 +-- drivers/net/wireless/realtek/rtw89/fw.c | 30 ++++++------------ drivers/net/wireless/realtek/rtw89/mac.c | 3 +- drivers/net/wireless/realtek/rtw89/regd.c | 3 +- drivers/net/wireless/realtek/rtw89/wow.c | 5 +-- 7 files changed, 37 insertions(+), 47 deletions(-) diff --git a/drivers/net/wireless/realtek/rtw89/core.c b/drivers/net/wireless/realtek/rtw89/core.c index b7df97e7d622..4467ca25f1b0 100644 --- a/drivers/net/wireless/realtek/rtw89/core.c +++ b/drivers/net/wireless/realtek/rtw89/core.c @@ -2584,7 +2584,7 @@ static void rtw89_core_cancel_6ghz_probe_tx(struct rtw89_dev *rtwdev, if (rx_status->band != NL80211_BAND_6GHZ) return; - if (unlikely(!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ)))) { + if (unlikely(!test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands))) { rtw89_debug(rtwdev, RTW89_DBG_UNEXP, "invalid rx on unsupported 6 GHz\n"); return; } @@ -6427,13 +6427,9 @@ static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev) { struct ieee80211_hw *hw = rtwdev->hw; struct ieee80211_supported_band *sband; - u8 support_bands = rtwdev->chip->support_bands; int ret; - if (test_bit(RTW89_QUIRK_DISABLE_2GHZ, rtwdev->quirks)) - support_bands &= ~BIT(NL80211_BAND_2GHZ); - - if (support_bands & BIT(NL80211_BAND_2GHZ)) { + if (test_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands)) { sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_2ghz); if (!sband) return -ENOMEM; @@ -6444,7 +6440,7 @@ static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev) hw->wiphy->bands[NL80211_BAND_2GHZ] = sband; } - if (support_bands & BIT(NL80211_BAND_5GHZ)) { + if (test_bit(NL80211_BAND_5GHZ, rtwdev->supported_bands)) { sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_5ghz); if (!sband) return -ENOMEM; @@ -6456,7 +6452,7 @@ static int rtw89_core_set_supported_band(struct rtw89_dev *rtwdev) hw->wiphy->bands[NL80211_BAND_5GHZ] = sband; } - if (support_bands & BIT(NL80211_BAND_6GHZ)) { + if (test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands)) { sband = rtw89_core_sband_dup(rtwdev, &rtw89_sband_6ghz); if (!sband) return -ENOMEM; @@ -6970,6 +6966,22 @@ void rtw89_sta_unset_link(struct rtw89_sta *rtwsta, unsigned int link_id) list_del(&link->dlink_schd); } +static void rtw89_core_init_supported_bands(struct rtw89_dev *rtwdev) +{ + const struct rtw89_chip_info *chip = rtwdev->chip; + enum nl80211_band band; + + for (band = 0; band < NUM_NL80211_BANDS; band++) { + if (!(chip->support_bands & BIT(band))) + continue; + + set_bit(band, rtwdev->supported_bands); + } + + if (test_bit(RTW89_QUIRK_DISABLE_2GHZ, rtwdev->quirks)) + clear_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands); +} + int rtw89_core_init(struct rtw89_dev *rtwdev) { const struct rtw89_mac_gen_def *mac = rtwdev->chip->mac_def; @@ -6978,18 +6990,14 @@ int rtw89_core_init(struct rtw89_dev *rtwdev) rtwdev->io = rtw89_fw_cmd_ofld_alloc_and_get_io_ops(rtwdev); - bitmap_or(rtwdev->quirks, rtwdev->quirks, &rtwdev->chip->default_quirks, - NUM_OF_RTW89_QUIRKS); + rtw89_core_init_supported_bands(rtwdev); INIT_LIST_HEAD(&rtwdev->ba_list); INIT_LIST_HEAD(&rtwdev->forbid_ba_list); INIT_LIST_HEAD(&rtwdev->rtwvifs_list); INIT_LIST_HEAD(&rtwdev->early_h2c_list); - for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { - if (!(rtwdev->chip->support_bands & BIT(band))) - continue; + for_each_set_bit(band, rtwdev->supported_bands, NUM_NL80211_BANDS) INIT_LIST_HEAD(&rtwdev->scan_info.pkt_list[band]); - } INIT_LIST_HEAD(&rtwdev->scan_info.chan_list); INIT_LIST_HEAD(&rtwdev->tx_waits); INIT_LIST_HEAD(&rtwdev->fw.dup_data_list); @@ -7722,6 +7730,7 @@ struct rtw89_dev *rtw89_alloc_ieee80211_hw(struct device *device, rtwdev->fw.fw_format = fw_format; rtwdev->support_mlo = support_mlo; + bitmap_copy(rtwdev->quirks, &chip->default_quirks, NUM_OF_RTW89_QUIRKS); bitmap_or(rtwdev->quirks, rtwdev->quirks, dev_id_quirks, NUM_OF_RTW89_QUIRKS); diff --git a/drivers/net/wireless/realtek/rtw89/core.h b/drivers/net/wireless/realtek/rtw89/core.h index afec4e166b78..2a691daf7dab 100644 --- a/drivers/net/wireless/realtek/rtw89/core.h +++ b/drivers/net/wireless/realtek/rtw89/core.h @@ -7753,6 +7753,7 @@ struct rtw89_dev { struct rtw89_ser ser; + DECLARE_BITMAP(supported_bands, NUM_NL80211_BANDS); DECLARE_BITMAP(hw_port, RTW89_PORT_NUM); DECLARE_BITMAP(mac_id_map, RTW89_MAX_MAC_ID_NUM); DECLARE_BITMAP(flags, NUM_OF_RTW89_FLAGS); diff --git a/drivers/net/wireless/realtek/rtw89/debug.c b/drivers/net/wireless/realtek/rtw89/debug.c index 3ebe4aa04e2b..9d680360a89b 100644 --- a/drivers/net/wireless/realtek/rtw89/debug.c +++ b/drivers/net/wireless/realtek/rtw89/debug.c @@ -4747,12 +4747,9 @@ static ssize_t rtw89_debug_priv_stations_get(struct rtw89_dev *rtwdev, (int)sizeof(rtwdev->pkt_offload), rtwdev->pkt_offload); - for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { - if (!(rtwdev->chip->support_bands & BIT(idx))) - continue; + for_each_set_bit(idx, rtwdev->supported_bands, NUM_NL80211_BANDS) p += rtw89_dump_pkt_offload(p, end - p, &rtwdev->scan_info.pkt_list[idx], "\t\t[SCAN %u]: ", idx); - } rtw89_debugfs_iter_data_setup(&iter_data, p, end - p); ieee80211_iterate_active_interfaces_atomic(rtwdev->hw, diff --git a/drivers/net/wireless/realtek/rtw89/fw.c b/drivers/net/wireless/realtek/rtw89/fw.c index e965aca66fdc..72882fe14d77 100644 --- a/drivers/net/wireless/realtek/rtw89/fw.c +++ b/drivers/net/wireless/realtek/rtw89/fw.c @@ -1328,7 +1328,6 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev, const union rtw89_fw_element_arg arg) { struct rtw89_fw_elm_info *elm_info = &rtwdev->fw.elm_info; - const struct rtw89_chip_info *chip = rtwdev->chip; const struct rtw89_fw_element_hdr *elm_dup; struct rtw89_hal *hal = &rtwdev->hal; u16 aid = le16_to_cpu(elm->aid); @@ -1341,11 +1340,11 @@ int rtw89_build_txpwr_trk_tbl_from_elm(struct rtw89_dev *rtwdev, if (aid && aid != hal->aid) return 1; - if (chip->support_bands & BIT(NL80211_BAND_6GHZ)) + if (test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands)) needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_6GHZ; - if (chip->support_bands & BIT(NL80211_BAND_5GHZ)) + if (test_bit(NL80211_BAND_5GHZ, rtwdev->supported_bands)) needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_5GHZ; - if (chip->support_bands & BIT(NL80211_BAND_2GHZ)) + if (test_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands)) needed_bitmap |= RTW89_DEFAULT_NEEDED_FW_TXPWR_TRK_2GHZ; bitmap = le32_to_cpu(elm->u.txpwr_trk.bitmap); @@ -9920,10 +9919,7 @@ static void rtw89_hw_scan_release_pkt_list(struct rtw89_dev *rtwdev) struct rtw89_pktofld_info *info, *tmp; u8 idx, wildcard_pkt_id; - for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { - if (!(rtwdev->chip->support_bands & BIT(idx))) - continue; - + for_each_set_bit(idx, rtwdev->supported_bands, NUM_NL80211_BANDS) { wildcard_pkt_id = scan_info->wildcard_pkt_id[idx]; if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE) rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id); @@ -9987,10 +9983,7 @@ static int rtw89_append_probe_req_ie(struct rtw89_dev *rtwdev, int ret = 0; u8 band; - for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { - if (!(rtwdev->chip->support_bands & BIT(band))) - continue; - + for_each_set_bit(band, rtwdev->supported_bands, NUM_NL80211_BANDS) { new = skb_copy(skb, GFP_KERNEL); if (!new) { ret = -ENOMEM; @@ -10039,10 +10032,7 @@ int rtw89_hw_scan_append_wildcard_probe_req(struct rtw89_dev *rtwdev, int ret; u8 id; - for (band = NL80211_BAND_2GHZ; band < NUM_NL80211_BANDS; band++) { - if (!(rtwdev->chip->support_bands & BIT(band))) - continue; - + for_each_set_bit(band, rtwdev->supported_bands, NUM_NL80211_BANDS) { if (wowlan) { nd_config = rtw_wow->nd_config; @@ -13090,17 +13080,15 @@ void rtw89_fw_load_tx_shape_lmt_ru(struct rtw89_tx_shape_lmt_ru_data *data) static bool rtw89_fw_has_da_txpwr_table(struct rtw89_dev *rtwdev, const struct rtw89_rfe_parms *parms) { - const struct rtw89_chip_info *chip = rtwdev->chip; - - if (chip->support_bands & BIT(NL80211_BAND_2GHZ) && + if (test_bit(NL80211_BAND_2GHZ, rtwdev->supported_bands) && !(parms->rule_da_2ghz.lmt && parms->rule_da_2ghz.lmt_ru)) return false; - if (chip->support_bands & BIT(NL80211_BAND_5GHZ) && + if (test_bit(NL80211_BAND_5GHZ, rtwdev->supported_bands) && !(parms->rule_da_5ghz.lmt && parms->rule_da_5ghz.lmt_ru)) return false; - if (chip->support_bands & BIT(NL80211_BAND_6GHZ) && + if (test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands) && !(parms->rule_da_6ghz.lmt && parms->rule_da_6ghz.lmt_ru)) return false; diff --git a/drivers/net/wireless/realtek/rtw89/mac.c b/drivers/net/wireless/realtek/rtw89/mac.c index 41796bff08ed..11b6c6510050 100644 --- a/drivers/net/wireless/realtek/rtw89/mac.c +++ b/drivers/net/wireless/realtek/rtw89/mac.c @@ -5319,8 +5319,7 @@ rtw89_mac_c2h_scanofld_rsp(struct rtw89_dev *rtwdev, struct sk_buff *skb, actual_period = le32_get_bits(c2h->w2, RTW89_C2H_SCANOFLD_W2_PERIOD); mac_idx = le32_get_bits(c2h->w5, RTW89_C2H_SCANOFLD_W5_MAC_IDX); - - if (!(rtwdev->chip->support_bands & BIT(NL80211_BAND_6GHZ))) + if (!test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands)) band = chan > 14 ? RTW89_BAND_5G : RTW89_BAND_2G; if (rtwdev->chip->chip_gen == RTW89_CHIP_BE) { diff --git a/drivers/net/wireless/realtek/rtw89/regd.c b/drivers/net/wireless/realtek/rtw89/regd.c index f75ce808254c..017e6a2b4b0d 100644 --- a/drivers/net/wireless/realtek/rtw89/regd.c +++ b/drivers/net/wireless/realtek/rtw89/regd.c @@ -587,8 +587,7 @@ static void rtw89_regd_setup_policy_6ghz_vlp(struct rtw89_dev *rtwdev) static void rtw89_regd_setup_6ghz(struct rtw89_dev *rtwdev, struct wiphy *wiphy) { - const struct rtw89_chip_info *chip = rtwdev->chip; - bool chip_support_6ghz = chip->support_bands & BIT(NL80211_BAND_6GHZ); + bool chip_support_6ghz = test_bit(NL80211_BAND_6GHZ, rtwdev->supported_bands); bool skip_acpi_dsm = rtwdev->hci.type == RTW89_HCI_TYPE_USB; bool regd_allow_6ghz = chip_support_6ghz; struct ieee80211_supported_band *sband; diff --git a/drivers/net/wireless/realtek/rtw89/wow.c b/drivers/net/wireless/realtek/rtw89/wow.c index 928faf71c239..91fbb6d28069 100644 --- a/drivers/net/wireless/realtek/rtw89/wow.c +++ b/drivers/net/wireless/realtek/rtw89/wow.c @@ -1470,10 +1470,7 @@ static void rtw89_fw_release_pno_pkt_list(struct rtw89_dev *rtwdev, struct rtw89_pktofld_info *info, *tmp; u8 idx, wildcard_pkt_id; - for (idx = NL80211_BAND_2GHZ; idx < NUM_NL80211_BANDS; idx++) { - if (!(rtwdev->chip->support_bands & BIT(idx))) - continue; - + for_each_set_bit(idx, rtwdev->supported_bands, NUM_NL80211_BANDS) { wildcard_pkt_id = scan_info->wildcard_pkt_id[idx]; if (wildcard_pkt_id != RTW89_SCANOFLD_PKT_NONE) rtw89_fw_h2c_del_pkt_offload(rtwdev, wildcard_pkt_id); -- 2.53.0