]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211: handle station association response with S1G
authorLachlan Hodges <lachlan.hodges@morsemicro.com>
Tue, 17 Jun 2025 08:06:08 +0000 (18:06 +1000)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 24 Jun 2025 13:19:28 +0000 (15:19 +0200)
Add support for updating the stations S1G capabilities when
an S1G association occurs.

Signed-off-by: Lachlan Hodges <lachlan.hodges@morsemicro.com>
Link: https://patch.msgid.link/20250617080610.756048-3-lachlan.hodges@morsemicro.com
[remove unused S1G_CAP3_MAX_MPDU_LEN_3895/_7791]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
include/net/mac80211.h
net/mac80211/ieee80211_i.h
net/mac80211/mlme.c
net/mac80211/s1g.c

index a0de0da4d79bb9c1a269fcce0e3df5ab18803cc7..dcd5969bb559ba8cd21d6ac9bcf8cf9aa709a871 100644 (file)
@@ -2428,6 +2428,7 @@ struct ieee80211_sta_aggregates {
  * @he_cap: HE capabilities of this STA
  * @he_6ghz_capa: on 6 GHz, holds the HE 6 GHz band capabilities
  * @eht_cap: EHT capabilities of this STA
+ * @s1g_cap: S1G capabilities of this STA
  * @agg: per-link data for multi-link aggregation
  * @bandwidth: current bandwidth the station can receive with
  * @rx_nss: in HT/VHT, the maximum number of spatial streams the
@@ -2450,6 +2451,7 @@ struct ieee80211_link_sta {
        struct ieee80211_sta_he_cap he_cap;
        struct ieee80211_he_6ghz_capa he_6ghz_capa;
        struct ieee80211_sta_eht_cap eht_cap;
+       struct ieee80211_sta_s1g_cap s1g_cap;
 
        struct ieee80211_sta_aggregates agg;
 
index f59a5b38e6f2c223668450c810184fa596a0a6aa..4ef7b3656aca80872e95d114b90ee5abccff5bfa 100644 (file)
@@ -2270,6 +2270,9 @@ void ieee80211_s1g_rx_twt_action(struct ieee80211_sub_if_data *sdata,
                                 struct sk_buff *skb);
 void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
                                     struct sk_buff *skb);
+void ieee80211_s1g_cap_to_sta_s1g_cap(struct ieee80211_sub_if_data *sdata,
+                                     const struct ieee80211_s1g_cap *s1g_cap_ie,
+                                     struct link_sta_info *link_sta);
 
 /* Spectrum management */
 void ieee80211_process_measurement_req(struct ieee80211_sub_if_data *sdata,
index d526f2fe9fe50874939dc49fffa04f622b53072d..6001c8897d7cbd3a175bc677679965ce18b6d099 100644 (file)
@@ -5399,6 +5399,12 @@ static bool ieee80211_assoc_config_link(struct ieee80211_link_data *link,
                bss_conf->epcs_support = false;
        }
 
+       if (elems->s1g_oper &&
+           link->u.mgd.conn.mode == IEEE80211_CONN_MODE_S1G &&
+           elems->s1g_capab)
+               ieee80211_s1g_cap_to_sta_s1g_cap(sdata, elems->s1g_capab,
+                                                link_sta);
+
        bss_conf->twt_broadcast =
                ieee80211_twt_bcast_support(sdata, bss_conf, sband, link_sta);
 
index d4ed0c0a335ca95c397fcf63e010c5a82c416067..1f68df6e80670ae98a30d0a24c5bb676821a2cf0 100644 (file)
@@ -194,3 +194,29 @@ void ieee80211_s1g_status_twt_action(struct ieee80211_sub_if_data *sdata,
                break;
        }
 }
+
+void ieee80211_s1g_cap_to_sta_s1g_cap(struct ieee80211_sub_if_data *sdata,
+                                     const struct ieee80211_s1g_cap *s1g_cap_ie,
+                                     struct link_sta_info *link_sta)
+{
+       struct ieee80211_sta_s1g_cap *s1g_cap = &link_sta->pub->s1g_cap;
+
+       memset(s1g_cap, 0, sizeof(*s1g_cap));
+
+       memcpy(s1g_cap->cap, s1g_cap_ie->capab_info, sizeof(s1g_cap->cap));
+       memcpy(s1g_cap->nss_mcs, s1g_cap_ie->supp_mcs_nss,
+              sizeof(s1g_cap->nss_mcs));
+
+       s1g_cap->s1g = true;
+
+       /* Maximum MPDU length is 1 bit for S1G */
+       if (s1g_cap->cap[3] & S1G_CAP3_MAX_MPDU_LEN) {
+               link_sta->pub->agg.max_amsdu_len =
+                       IEEE80211_MAX_MPDU_LEN_VHT_7991;
+       } else {
+               link_sta->pub->agg.max_amsdu_len =
+                       IEEE80211_MAX_MPDU_LEN_VHT_3895;
+       }
+
+       ieee80211_sta_recalc_aggregates(&link_sta->sta->sta);
+}