wifi: ath11k: mac: fix struct ieee80211_sband_iftype_data handling
authorKalle Valo <quic_kvalo@quicinc.com>
Wed, 27 Sep 2023 14:27:08 +0000 (17:27 +0300)
committerKalle Valo <quic_kvalo@quicinc.com>
Thu, 28 Sep 2023 15:15:36 +0000 (18:15 +0300)
Commit e8c1841278a7 ("wifi: cfg80211: annotate iftype_data pointer with
sparse") added sparse checks for struct ieee80211_sband_iftype_data handling
which immediately found an issue in ath11k:

drivers/net/wireless/ath/ath11k/mac.c:7952:22: warning: incorrect type in argument 1 (different address spaces)
drivers/net/wireless/ath/ath11k/mac.c:7952:22:    expected struct ieee80211_sta_he_cap const *he_cap
drivers/net/wireless/ath/ath11k/mac.c:7952:22:    got struct ieee80211_sta_he_cap const [noderef] __iftype_data *

The problem here is that we are accessing sband->iftype_data directly even
though we should use for_each_sband_iftype_data() or similar. Fortunately
there's ieee80211_get_he_iftype_cap_vif() which is just what we need here so
use it to get HE capabilities.

Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.23

Reported-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Kalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20230927142708.2897504-2-kvalo@kernel.org
drivers/net/wireless/ath/ath11k/mac.c

index 9ce3b575d9cc0481014064ad6a9b977de0edab64..276fbc78018e96e811d24d5ccaa4d9ebcd3e4f0c 100644 (file)
@@ -7910,12 +7910,14 @@ ath11k_mac_get_tx_mcs_map(const struct ieee80211_sta_he_cap *he_cap)
 
 static bool
 ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
+                                      struct ath11k_vif *arvif,
                                       enum nl80211_band band,
                                       const struct cfg80211_bitrate_mask *mask,
                                       int *nss)
 {
        struct ieee80211_supported_band *sband = &ar->mac.sbands[band];
        u16 vht_mcs_map = le16_to_cpu(sband->vht_cap.vht_mcs.tx_mcs_map);
+       const struct ieee80211_sta_he_cap *he_cap;
        u16 he_mcs_map = 0;
        u8 ht_nss_mask = 0;
        u8 vht_nss_mask = 0;
@@ -7946,7 +7948,11 @@ ath11k_mac_bitrate_mask_get_single_nss(struct ath11k *ar,
                        return false;
        }
 
-       he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(&sband->iftype_data->he_cap));
+       he_cap = ieee80211_get_he_iftype_cap_vif(sband, arvif->vif);
+       if (!he_cap)
+               return false;
+
+       he_mcs_map = le16_to_cpu(ath11k_mac_get_tx_mcs_map(he_cap));
 
        for (i = 0; i < ARRAY_SIZE(mask->control[band].he_mcs); i++) {
                if (mask->control[band].he_mcs[i] == 0)
@@ -8362,7 +8368,7 @@ ath11k_mac_op_set_bitrate_mask(struct ieee80211_hw *hw,
                ieee80211_iterate_stations_atomic(ar->hw,
                                                  ath11k_mac_disable_peer_fixed_rate,
                                                  arvif);
-       } else if (ath11k_mac_bitrate_mask_get_single_nss(ar, band, mask,
+       } else if (ath11k_mac_bitrate_mask_get_single_nss(ar, arvif, band, mask,
                                                          &single_nss)) {
                rate = WMI_FIXED_RATE_NONE;
                nss = single_nss;