]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: mac80211: don't consider the sband when processing capabilities
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>
Fri, 20 Mar 2026 12:15:32 +0000 (14:15 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 24 Mar 2026 15:32:16 +0000 (16:32 +0100)
In NAN, we have one set of (HT, VHT, HE) capabilities for all bands,
which means that we will need to process those capabilities without a
given sband.

To prepare for that, remove the sband argument from
ieee80211_ht_cap_ie_to_sta_ht_cap and ieee80211_he_cap_ie_to_sta_he_cap
and pass our own capabilities instead.

For ieee80211_vht_cap_ie_to_sta_vht_cap, make the sband argument
optional, since it is also used to check if there is at least one channel
that supports 80 MHz.
(Note that this check doesn't make much sense, but this can be handled in
 a different patch.)

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260320141504.e42ef1f0eabb.If994d6346f00219437e22043e7bf2395b827b34a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/mac80211/he.c
net/mac80211/ht.c
net/mac80211/ibss.c
net/mac80211/ieee80211_i.h
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/vht.c

index ee64ac8e0f61d1f5251eeb65ca83242af098aef3..9aa4ae0621be5d4a6bd6869d4938b179c878f6a0 100644 (file)
@@ -2140,12 +2140,13 @@ static int sta_link_apply_parameters(struct ieee80211_local *local,
                return -EINVAL;
 
        if (params->ht_capa)
-               ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+               ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, &sband->ht_cap,
                                                  params->ht_capa, link_sta);
 
        /* VHT can override some HT caps such as the A-MSDU max length */
        if (params->vht_capa)
                ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
+                                                   &sband->vht_cap,
                                                    params->vht_capa, NULL,
                                                    link_sta);
 
index f7b05e59374c7eef8ff8038a6e95bd452e09a5d2..93e0342cff4fab5df3ff547c5d7a8d3e43c9453e 100644 (file)
@@ -108,14 +108,13 @@ static void ieee80211_he_mcs_intersection(__le16 *he_own_rx, __le16 *he_peer_rx,
 }
 
 void
-ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
-                                 struct ieee80211_supported_band *sband,
-                                 const u8 *he_cap_ie, u8 he_cap_len,
-                                 const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
-                                 struct link_sta_info *link_sta)
+_ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
+                                  const struct ieee80211_sta_he_cap *own_he_cap_ptr,
+                                  const u8 *he_cap_ie, u8 he_cap_len,
+                                  const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
+                                  struct link_sta_info *link_sta)
 {
        struct ieee80211_sta_he_cap *he_cap = &link_sta->pub->he_cap;
-       const struct ieee80211_sta_he_cap *own_he_cap_ptr;
        struct ieee80211_sta_he_cap own_he_cap;
        struct ieee80211_he_cap_elem *he_cap_ie_elem = (void *)he_cap_ie;
        u8 he_ppe_size;
@@ -125,12 +124,7 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
 
        memset(he_cap, 0, sizeof(*he_cap));
 
-       if (!he_cap_ie)
-               return;
-
-       own_he_cap_ptr =
-               ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
-       if (!own_he_cap_ptr)
+       if (!he_cap_ie || !own_he_cap_ptr || !own_he_cap_ptr->has_he)
                return;
 
        own_he_cap = *own_he_cap_ptr;
@@ -164,7 +158,7 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
        link_sta->cur_max_bandwidth = ieee80211_sta_cap_rx_bw(link_sta);
        link_sta->pub->bandwidth = ieee80211_sta_cur_vht_bw(link_sta);
 
-       if (sband->band == NL80211_BAND_6GHZ && he_6ghz_capa)
+       if (he_6ghz_capa)
                ieee80211_update_from_he_6ghz_capa(he_6ghz_capa, link_sta);
 
        ieee80211_he_mcs_intersection(&own_he_cap.he_mcs_nss_supp.rx_mcs_80,
@@ -207,6 +201,23 @@ ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
        }
 }
 
+void
+ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
+                                 struct ieee80211_supported_band *sband,
+                                 const u8 *he_cap_ie, u8 he_cap_len,
+                                 const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
+                                 struct link_sta_info *link_sta)
+{
+       const struct ieee80211_sta_he_cap *own_he_cap =
+               ieee80211_get_he_iftype_cap_vif(sband, &sdata->vif);
+
+       _ieee80211_he_cap_ie_to_sta_he_cap(sdata, own_he_cap, he_cap_ie,
+                                          he_cap_len,
+                                          (sband->band == NL80211_BAND_6GHZ) ?
+                                               he_6ghz_capa : NULL,
+                                          link_sta);
+}
+
 void
 ieee80211_he_op_ie_to_bss_conf(struct ieee80211_vif *vif,
                        const struct ieee80211_he_operation *he_op_ie)
index 33f1e1b235e95a44711c6b4f9d774c50675a8174..410e2354f33aa609812f35eac33f57403c38d846 100644 (file)
@@ -136,7 +136,7 @@ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
 
 
 bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
-                                      struct ieee80211_supported_band *sband,
+                                      const struct ieee80211_sta_ht_cap *own_cap_ptr,
                                       const struct ieee80211_ht_cap *ht_cap_ie,
                                       struct link_sta_info *link_sta)
 {
@@ -151,12 +151,12 @@ bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
 
        memset(&ht_cap, 0, sizeof(ht_cap));
 
-       if (!ht_cap_ie || !sband->ht_cap.ht_supported)
+       if (!ht_cap_ie || !own_cap_ptr->ht_supported)
                goto apply;
 
        ht_cap.ht_supported = true;
 
-       own_cap = sband->ht_cap;
+       own_cap = *own_cap_ptr;
 
        /*
         * If user has specified capability over-rides, take care
index 0298272c37ec4f444a802ad959b450af6379ebed..1e1ab25d9d8ded71cfc85962a385daa5dd5a9a08 100644 (file)
@@ -1014,7 +1014,8 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
                ieee80211_chandef_ht_oper(elems->ht_operation, &chandef);
 
                memcpy(&htcap_ie, elems->ht_cap_elem, sizeof(htcap_ie));
-               rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+               rates_updated |= ieee80211_ht_cap_ie_to_sta_ht_cap(sdata,
+                                                                  &sband->ht_cap,
                                                                   &htcap_ie,
                                                                   &sta->deflink);
 
@@ -1033,6 +1034,7 @@ static void ieee80211_update_sta_info(struct ieee80211_sub_if_data *sdata,
                                                   &chandef);
                        memcpy(&cap_ie, elems->vht_cap_elem, sizeof(cap_ie));
                        ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
+                                                           &sband->vht_cap,
                                                            &cap_ie, NULL,
                                                            &sta->deflink);
                        if (memcmp(&cap, &sta->sta.deflink.vht_cap, sizeof(cap)))
index fe53812eca95c6ba1cbd7ec6d65898d4891f71c1..bacb49ad281738a54d79e844c3710efdc2c2ebc0 100644 (file)
@@ -2188,7 +2188,7 @@ void ieee80211_aggr_check(struct ieee80211_sub_if_data *sdata,
 void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata,
                                     struct ieee80211_sta_ht_cap *ht_cap);
 bool ieee80211_ht_cap_ie_to_sta_ht_cap(struct ieee80211_sub_if_data *sdata,
-                                      struct ieee80211_supported_band *sband,
+                                      const struct ieee80211_sta_ht_cap *own_cap,
                                       const struct ieee80211_ht_cap *ht_cap_ie,
                                       struct link_sta_info *link_sta);
 void ieee80211_send_delba(struct ieee80211_sub_if_data *sdata,
@@ -2273,6 +2273,7 @@ void ieee80211_ht_handle_chanwidth_notif(struct ieee80211_local *local,
 void
 ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
                                    struct ieee80211_supported_band *sband,
+                                   const struct ieee80211_sta_vht_cap *own_vht_cap,
                                    const struct ieee80211_vht_cap *vht_cap_ie,
                                    const struct ieee80211_vht_cap *vht_cap_ie2,
                                    struct link_sta_info *link_sta);
@@ -2313,6 +2314,12 @@ ieee80211_sta_rx_bw_to_chan_width(struct link_sta_info *sta);
 
 /* HE */
 void
+_ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
+                                  const struct ieee80211_sta_he_cap *own_he_cap,
+                                  const u8 *he_cap_ie, u8 he_cap_len,
+                                  const struct ieee80211_he_6ghz_capa *he_6ghz_capa,
+                                  struct link_sta_info *link_sta);
+void
 ieee80211_he_cap_ie_to_sta_he_cap(struct ieee80211_sub_if_data *sdata,
                                  struct ieee80211_supported_band *sband,
                                  const u8 *he_cap_ie, u8 he_cap_len,
index 7d823a55636fb10a302e2f250b40c615c7e96ead..803106fc313489eb9fa06eca78f3d3dc376f33da 100644 (file)
@@ -450,12 +450,13 @@ static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
                changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
        sta->sta.deflink.supp_rates[sband->band] = rates;
 
-       if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+       if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, &sband->ht_cap,
                                              elems->ht_cap_elem,
                                              &sta->deflink))
                changed |= IEEE80211_RC_BW_CHANGED;
 
        ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
+                                           &sband->vht_cap,
                                            elems->vht_cap_elem, NULL,
                                            &sta->deflink);
 
index 0cd8d07bf668987027727c1fa6557c7afaa7dfef..173a60360a45487cd8aaebb4b95b1270212d3fb9 100644 (file)
@@ -5586,7 +5586,7 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
 
        /* Set up internal HT/VHT capabilities */
        if (elems->ht_cap_elem && link->u.mgd.conn.mode >= IEEE80211_CONN_MODE_HT)
-               ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
+               ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, &sband->ht_cap,
                                                  elems->ht_cap_elem,
                                                  link_sta);
 
@@ -5622,6 +5622,7 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
                }
 
                ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
+                                                   &sband->vht_cap,
                                                    elems->vht_cap_elem,
                                                    bss_vht_cap, link_sta);
                rcu_read_unlock();
index 80120f9f17b6398545a66b5e20f5c8a6519ac7b5..a6570781740adadd703f94e6142169c9cc8d4026 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Portions of this file
  * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
- * Copyright (C) 2018-2026 Intel Corporation
+ * Copyright (C) 2018 - 2026 Intel Corporation
  */
 
 #include <linux/ieee80211.h>
@@ -115,6 +115,7 @@ void ieee80211_apply_vhtcap_overrides(struct ieee80211_sub_if_data *sdata,
 void
 ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
                                    struct ieee80211_supported_band *sband,
+                                   const struct ieee80211_sta_vht_cap *own_vht_cap,
                                    const struct ieee80211_vht_cap *vht_cap_ie,
                                    const struct ieee80211_vht_cap *vht_cap_ie2,
                                    struct link_sta_info *link_sta)
@@ -122,7 +123,6 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
        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));
@@ -130,22 +130,25 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
        if (!link_sta->pub->ht_cap.ht_supported)
                return;
 
-       if (!vht_cap_ie || !sband->vht_cap.vht_supported)
+       if (!vht_cap_ie || !own_vht_cap->vht_supported)
                return;
 
-       /* Allow VHT if at least one channel on the sband supports 80 MHz */
-       have_80mhz = false;
-       for (i = 0; i < sband->n_channels; i++) {
-               if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
-                                               IEEE80211_CHAN_NO_80MHZ))
-                       continue;
+       if (sband) {
+               /* Allow VHT if at least one channel on the sband supports 80 MHz */
+               bool have_80mhz = false;
 
-               have_80mhz = true;
-               break;
-       }
+               for (i = 0; i < sband->n_channels; i++) {
+                       if (sband->channels[i].flags & (IEEE80211_CHAN_DISABLED |
+                                                       IEEE80211_CHAN_NO_80MHZ))
+                               continue;
 
-       if (!have_80mhz)
-               return;
+                       have_80mhz = true;
+                       break;
+               }
+
+               if (!have_80mhz)
+                       return;
+       }
 
        /*
         * A VHT STA must support 40 MHz, but if we verify that here
@@ -156,7 +159,7 @@ ieee80211_vht_cap_ie_to_sta_vht_cap(struct ieee80211_sub_if_data *sdata,
 
        vht_cap->vht_supported = true;
 
-       own_cap = sband->vht_cap;
+       own_cap = *own_vht_cap;
        /*
         * If user has specified capability overrides, take care
         * of that if the station we're setting up is the AP that