wifi: mac80211: work around Cisco AP 9115 VHT MPDU length
[platform/kernel/linux-starfive.git] / net / mac80211 / vht.c
index c1250aa..b3a5c3e 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Portions of this file
  * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
- * Copyright (C) 2018 - 2022 Intel Corporation
+ * Copyright (C) 2018 - 2023 Intel Corporation
  */
 
 #include <linux/ieee80211.h>
@@ -116,12 +116,14 @@ void
 ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
                                    struct ieee80211_supported_band *sband,
                                    const struct ieee80211_vht_cap *vht_cap_ie,
+                                   const struct ieee80211_vht_cap *vht_cap_ie2,
                                    struct link_sta_info *link_sta)
 {
        struct ieee80211_sta_vht_cap *vht_cap = &link_sta->pub->vht_cap;
        struct ieee80211_sta_vht_cap own_cap;
        u32 cap_info, i;
        bool have_80mhz;
+       u32 mpdu_len;
 
        memset(vht_cap, 0, sizeof(*vht_cap));
 
@@ -318,10 +320,20 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
        link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta);
 
        /*
+        * Work around the Cisco 9115 FW 17.3 bug by taking the min of
+        * both reported MPDU lengths.
+        */
+       mpdu_len = vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK;
+       if (vht_cap_ie2)
+               mpdu_len = min_t(u32, mpdu_len,
+                                le32_get_bits(vht_cap_ie2->vht_cap_info,
+                                              IEEE80211_VHT_CAP_MAX_MPDU_MASK));
+
+       /*
         * FIXME - should the amsdu len be per link? store per link
         * and maintain a minimum?
         */
-       switch (vht_cap->cap & IEEE80211_VHT_CAP_MAX_MPDU_MASK) {
+       switch (mpdu_len) {
        case IEEE80211_VHT_CAP_MAX_MPDU_LENGTH_11454:
                link_sta->pub->agg.max_amsdu_len = IEEE80211_MAX_MPDU_LEN_VHT_11454;
                break;