1: a645b4bd44b2 < -: ------------ wifi: nl80211: Define Seamless Mobility Domain (SMD) device capability  2: 457790d60e69 < -: ------------ wifi: nl80211: Add kernel interfaces for Seamless Mobility Domain setup  3: 42cd5cda9e25 < -: ------------ wifi: cfg80211/mac80211: Configure AP with SMD capabilities  4: 3f836cc85d0c < -: ------------ wifi: cfg80211/mac80211: Parse SMD parameters in STA addition/modification  5: ad7b3a2d544f < -: ------------ wifi: nl80211/cfg80211: Indicate STA creation via SMD BSS Transition  -: ------------ > 1: cdd41c8fc9c8 wifi: nl80211: define Seamless Mobility Domain (SMD) device capability  -: ------------ > 2: 3df988a34e75 wifi: nl80211/cfg80211: define interfaces for SMD setup and STA update  -: ------------ > 3: fde33a5067d0 wifi: nl80211: add SMD BSS Transition sub-state STA flags  -: ------------ > 4: aa57cee0218e wifi: cfg80211: define layouts for SMD BSS Transition context  -: ------------ > 5: 51ec4d3a07e6 wifi: nl80211: define interfaces for SMD BSS Transition context transfer  -: ------------ > 6: 20a93b51eeab wifi: ieee80211: define APIs for UHR Link Reconfiguration frame checks  -: ------------ > 7: 3d03de0689db wifi: ieee80211: define API to check if frame is class 3  -: ------------ > 8: e0b779b7d0ab wifi: nl80211/cfg80211: pack SMD dynamic context along with frame 13: ac70af58367d ! 9: 91dce91761a9 wifi: nl80211/cfg80211: Add support for SMD context programming @@ Metadata Author: Pooventhiran G   ## Commit message ## - wifi: nl80211/cfg80211: Add support for SMD context programming + wifi: nl80211/cfg80211: add support for SMD context programming  On the target AP MLD to which the STA will be transitioning, the dynamic context collected and sent by the current AP MLD needs to be programmed @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,   +static int  +nl80211_parse_smd_ctx_ba_params(struct nlattr *tb, -+ struct ieee80211_smd_ctx_ba *ba_tids, -+ unsigned long *valid_ctx_bmap) ++ struct ieee80211_smd_ctx_ba *ba_tids)  +{  + struct nlattr *ba_tb[NL80211_SMD_CTX_BA_ATTR_MAX + 1];  + struct ieee80211_smd_ctx_ba *ba; @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  + int n_tids = 0;  + int rem, tid;  + -+ if (!tb) -+ return 0; -+  + nla_for_each_nested(ba_attr, tb, rem) {  + tid = nla_type(ba_attr) - 1;  + if (tid < 0 || tid >= IEEE80211_SMD_CTX_NUM_TIDS) @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  + ba->ext_buffer_size =  + nla_get_u16(ba_tb[NL80211_SMD_CTX_BA_ATTR_EXT_BUFF_SIZE]);  + ++ if (ba_tb[NL80211_SMD_CTX_BA_ATTR_WINSTARTO]) ++ ba->winstarto = ++ nla_get_u16(ba_tb[NL80211_SMD_CTX_BA_ATTR_WINSTARTO]); ++  + n_tids++;  + }  +  + if (!n_tids)  + return -EINVAL;  + -+ set_bit(IEEE80211_SMD_CTX_VALID_BA_PARAMS, valid_ctx_bmap); -+  + return 0;  +}  + @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  + struct nlattr *tb[NL80211_SMD_CTX_ATTR_MAX + 1];  + struct ieee80211_smd_ctx *ctx;  + struct nlattr *bmap_attr; -+ size_t drv_ctx_size = 0;  +  + st_info->type = nla_get_u8(info->attrs[NL80211_ATTR_SMD_CTX_TYPE]);  + @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  + return -EINVAL;  + }  + -+ if (tb[NL80211_SMD_CTX_ATTR_DRV_DATA]) -+ drv_ctx_size = nla_len(tb[NL80211_SMD_CTX_ATTR_DRV_DATA]); -+ -+ ctx = kzalloc(sizeof(*ctx) + drv_ctx_size, GFP_KERNEL); ++ ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);  + if (!ctx)  + return -ENOMEM;  + @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  +  + bmap_attr = dl_tb[NL80211_SMD_CTX_DL_ATTR_VALID_TID_BITMAP];  + if (bmap_attr) -+ bitmap_write(ctx->dl.valid_tid_bmap, -+ nla_get_u8(bmap_attr), -+ 0, IEEE80211_SMD_CTX_NUM_TIDS); ++ ctx->dl.valid_tid_bmap = nla_get_u8(bmap_attr);  +  + if (dl_tb[NL80211_SMD_CTX_DL_ATTR_SN]) {  + struct nlattr *sn_attr; @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  + goto err_free_ctx;  + }  + -+ set_bit(IEEE80211_SMD_CTX_VALID_DL_SN, -+ ctx->valid_ctx_bmap); ++ ctx->dl_sn_valid = 1;  + }  +  + if (dl_tb[NL80211_SMD_CTX_DL_ATTR_PN]) { @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  +  + ctx->pn_len =  + nla_len(dl_tb[NL80211_SMD_CTX_DL_ATTR_PN]); ++ if (ctx->pn_len > IEEE80211_SMD_CTX_MAX_PN_LEN) { ++ GENL_SET_ERR_MSG(info, "invalid DL PN length"); ++ goto err_free_ctx; ++ }  +  + memcpy(ctx->dl.pn, pn_data, ctx->pn_len); -+ set_bit(IEEE80211_SMD_CTX_VALID_PN, -+ ctx->valid_ctx_bmap); ++ ctx->pn_valid = 1;  + }  +  + ba_attr = dl_tb[NL80211_SMD_CTX_DL_ATTR_BA_PARAMS]; -+ if (ba_attr && -+ nl80211_parse_smd_ctx_ba_params(ba_attr, ctx->dl.ba, -+ ctx->valid_ctx_bmap)) { -+ GENL_SET_ERR_MSG(info, -+ "failed to parse DL BlockAck params"); -+ goto err_free_ctx; ++ if (ba_attr) { ++ if (nl80211_parse_smd_ctx_ba_params(ba_attr, ++ ctx->dl.ba)) { ++ GENL_SET_ERR_MSG(info, ++ "failed to parse DL BlockAck params"); ++ goto err_free_ctx; ++ } ++ ++ ctx->ba_params_valid = 1; ++ } ++ ++ if (dl_tb[NL80211_SMD_CTX_DL_ATTR_MGMT_SN]) { ++ ctx->dl.mgmt_sn = ++ nla_get_u16(dl_tb[NL80211_SMD_CTX_DL_ATTR_MGMT_SN]); ++ ctx->mgmt_tid_valid = 1; ++ ctx->dl_sn_valid = 1;  + }  + }  + @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  +  + bmap_attr = ul_tb[NL80211_SMD_CTX_UL_ATTR_VALID_TID_BITMAP];  + if (bmap_attr) -+ bitmap_write(ctx->ul.valid_tid_bmap, -+ nla_get_u8(bmap_attr), -+ 0, IEEE80211_SMD_CTX_NUM_TIDS); ++ ctx->ul.valid_tid_bmap = nla_get_u8(bmap_attr);  +  + if (ul_tb[NL80211_SMD_CTX_UL_ATTR_SN]) {  + struct nlattr *sn_attr; @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  + goto err_free_ctx;  + }  + -+ set_bit(IEEE80211_SMD_CTX_VALID_UL_SN, -+ ctx->valid_ctx_bmap); ++ ctx->ul_sn_valid = 1;  + }  +  + if (ul_tb[NL80211_SMD_CTX_UL_ATTR_PN]) { @@ net/wireless/nl80211.c: static int nl80211_put_smd_ctx(struct sk_buff *msg,  + goto err_free_ctx;  + }  + -+ set_bit(IEEE80211_SMD_CTX_VALID_PN, -+ ctx->valid_ctx_bmap); ++ ctx->pn_valid = 1;  + }  +  + ba_attr = ul_tb[NL80211_SMD_CTX_UL_ATTR_BA_PARAMS]; -+ if (ba_attr && -+ nl80211_parse_smd_ctx_ba_params(ba_attr, ctx->ul.ba, -+ ctx->valid_ctx_bmap)) { -+ GENL_SET_ERR_MSG(info, -+ "failed to parse UL BlockAck params"); -+ goto err_free_ctx; ++ if (ba_attr) { ++ if (nl80211_parse_smd_ctx_ba_params(ba_attr, ++ ctx->ul.ba)) { ++ GENL_SET_ERR_MSG(info, ++ "failed to parse UL BlockAck params"); ++ goto err_free_ctx; ++ } ++ ++ ctx->ba_params_valid = 1; ++ } ++ ++ if (ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_SN]) { ++ ctx->ul.mgmt_sn = ++ nla_get_u16(ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_SN]); ++ ctx->mgmt_tid_valid = 1; ++ ctx->ul_sn_valid = 1;  + } -+ }  + -+ /* Driver data */ -+ if (tb[NL80211_SMD_CTX_ATTR_DRV_DATA]) { -+ ctx->drv_ctx_size = drv_ctx_size; -+ memcpy(ctx->drv_ctx, -+ nla_data(tb[NL80211_SMD_CTX_ATTR_DRV_DATA]), -+ drv_ctx_size); ++ if (ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_PN]) { ++ u8 pn_len = nla_len(ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_PN]); ++ ++ if (pn_len > IEEE80211_SMD_CTX_MAX_PN_LEN || ++ (ctx->pn_len && pn_len != ctx->pn_len)) { ++ GENL_SET_ERR_MSG(info, "invalid UL mgmt PN length"); ++ goto err_free_ctx; ++ } ++ memcpy(ctx->ul.mgmt_pn, ++ nla_data(ul_tb[NL80211_SMD_CTX_UL_ATTR_MGMT_PN]), ++ pn_len); ++ ctx->mgmt_tid_valid = 1; ++ ctx->pn_valid = 1; ++ }  + }  +  + return 0; @@ net/wireless/nl80211.c: static int nl80211_set_sar_specs(struct sk_buff *skb, st ((__sel) == (value)) ? NL80211_IFL_SEL_##name : int __missing_selector(void);  @@ net/wireless/nl80211.c: static const struct genl_small_ops nl80211_small_ops[] = { - .flags = GENL_ADMIN_PERM, - .internal_flags = IFLAGS(NL80211_FLAG_NEED_WDEV_UP), + .internal_flags = IFLAGS(NL80211_FLAG_NEED_NETDEV_UP | + NL80211_FLAG_NO_WIPHY_MTX), },  + {  + .cmd = NL80211_CMD_SET_SMD_CTX, @@ net/wireless/trace.h: TRACE_EVENT(cfg80211_nan_channel_evac,  + WDEV_ENTRY  + MAC_ENTRY(sta_addr)  + __field(u8, st_type) -+ __field(unsigned int, num_tids) -+ __dynamic_array(unsigned long, tx_tid_bitmap, -+ BITS_TO_LONGS(IEEE80211_SMD_CTX_NUM_TIDS)) -+ __dynamic_array(unsigned long, rx_tid_bitmap, -+ BITS_TO_LONGS(IEEE80211_SMD_CTX_NUM_TIDS)) ++ __field(u8, dl_tid_bitmap) ++ __field(u8, ul_tid_bitmap)  + ),  +  + TP_fast_assign(  + struct ieee80211_smd_ctx *ctx = st_info->ctx; -+ unsigned long sz;  +  + WIPHY_ASSIGN;  + WDEV_ASSIGN;  + MAC_ASSIGN(sta_addr, addr);  + __entry->st_type = st_info->type; -+ -+ __entry->num_tids = IEEE80211_SMD_CTX_NUM_TIDS; -+ sz = BITS_TO_LONGS(__entry->num_tids) * sizeof(unsigned long); -+ -+ memcpy(__get_dynamic_array(tx_tid_bitmap), -+ ctx->dl.valid_tid_bmap, sz); -+ memcpy(__get_dynamic_array(rx_tid_bitmap), -+ ctx->ul.valid_tid_bmap, sz); ++ __entry->dl_tid_bitmap = ctx->dl.valid_tid_bmap; ++ __entry->ul_tid_bitmap = ctx->ul.valid_tid_bmap;  + ),  +  + TP_printk(WIPHY_PR_FMT ", " WDEV_PR_FMT -+ ", sta=%pM, ST type=%u DL TIDs: %*pb, UL TIDs: %*pb", ++ ", sta=%pM, ST type=%u DL TIDs: 0x%x, UL TIDs: 0x%x",  + WIPHY_PR_ARG, WDEV_PR_ARG, __entry->sta_addr,  + __entry->st_type, -+ __entry->num_tids, -+ (unsigned long *)__get_dynamic_array(tx_tid_bitmap), -+ __entry->num_tids, -+ (unsigned long *)__get_dynamic_array(rx_tid_bitmap)) ++ __entry->dl_tid_bitmap, __entry->ul_tid_bitmap ++ )  +);  + #endif /* !__RDEV_OPS_TRACE || TRACE_HEADER_MULTI_READ */ 15: c48102db71f3 ! 10: 6d619b777c2d wifi: nl80211/cfg80211: Add support for querying SMD context for target AP MLD @@ Metadata Author: Pooventhiran G   ## Commit message ## - wifi: nl80211/cfg80211: Add support for querying SMD context for target AP MLD + wifi: nl80211/cfg80211: add support for querying SMD context for target AP MLD  During SMD BSS Transition, the non-AP MLD that has been prepared with a target AP MLD may send the ST Execution frame directly to the target AP @@ include/net/cfg80211.h: struct cfg80211_smd_transition_info {  + * struct cfg80211_smd_get_ctx_pending - pending async GET_SMD_CTX request  + * @list: linkage on wireless_dev::smd_get_ctx_pending_list  + * @sta_addr: non-AP MLD address for which context was requested ++ * @dev_tracker: tracker object for the netdev referenced  + */  +struct cfg80211_smd_get_ctx_pending {  + struct list_head list;  + u8 sta_addr[ETH_ALEN]; ++ netdevice_tracker dev_tracker;  +};  + /** @@ include/net/cfg80211.h: struct wireless_dev { u32 radio_mask; };  -@@ include/net/cfg80211.h: void cfg80211_incumbent_signal_notify(struct wiphy *wiphy, - u32 signal_interference_bitmap, - gfp_t gfp); +@@ include/net/cfg80211.h: struct ieee80211_smd_ctx { + } ul; + };   +/**  + * cfg80211_free_pending_smd_ctx_req - Free remaining entries in the @@ net/wireless/core.c: void wiphy_rfkill_set_hw_state_reason(struct wiphy *wiphy,  + list) {  + if (!addr || ether_addr_equal(pending->sta_addr, addr)) {  + list_del(&pending->list); ++ netdev_put(wdev->netdev, &pending->dev_tracker);  + kfree(pending); -+ dev_put(wdev->netdev);  + }  + }  + spin_unlock_bh(&wdev->smd_get_ctx_lock); @@ net/wireless/mlme.c: void cfg80211_mlo_reconf_add_done(struct net_device *dev,  +  + nl80211_notify_get_smd_ctx_done(wdev, sta_addr, st_info);  + -+ dev_put(wdev->netdev); ++ netdev_put(wdev->netdev, &pending->dev_tracker);  + kfree(pending);  +}  +EXPORT_SYMBOL(cfg80211_get_smd_ctx_done);  ## net/wireless/nl80211.c ## -@@ net/wireless/nl80211.c: static size_t _nl80211_smd_ctx_nl_ba_param_size(u8 n_tids) +@@ net/wireless/nl80211.c: static size_t _nl80211_smd_ctx_nl_ba_param_size(u8 n_tids, bool dl) return n; }  @@ net/wireless/nl80211.c: static int nl80211_set_smd_ctx(struct sk_buff *skb, stru  + * race. Upon success, the reference is released while reporting back  + * the context or in the list removal and drain path.  + */ -+ dev_hold(wdev->netdev); ++ netdev_hold(wdev->netdev, &pending->dev_tracker, GFP_KERNEL);  +  + spin_lock_bh(&wdev->smd_get_ctx_lock);  + list_add_tail(&pending->list, &wdev->smd_get_ctx_pending_list); @@ net/wireless/nl80211.c: static int nl80211_set_smd_ctx(struct sk_buff *skb, stru  + pending = __cfg80211_get_smd_sta_pending_ctx(wdev, addr);  + if (pending) {  + list_del(&pending->list); ++ netdev_put(wdev->netdev, &pending->dev_tracker);  + kfree(pending); -+ dev_put(wdev->netdev);  + }  + spin_unlock_bh(&wdev->smd_get_ctx_lock);  + return err; @@ net/wireless/rdev-ops.h: static inline int rdev_set_smd_ctx(struct cfg80211_regi  ## net/wireless/trace.h ##  @@ net/wireless/trace.h: TRACE_EVENT(rdev_set_smd_ctx, - (unsigned long *)__get_dynamic_array(rx_tid_bitmap)) + ) );   +TRACE_EVENT(rdev_get_smd_ctx,  -: ------------ > 11: 6036cdd97b4f wifi: nl80211/cfg80211: define API to notify SMD Drain completion  -: ------------ > 12: ae5cfe315173 wifi: mac80211: set SMD parameters for AP setup and STA update  6: b6a345fb53db ! 13: b839d6390f4a wifi: nl80211/mac80211: Add SMD BSS Transition sub-state STA flags @@ Metadata Author: Pooventhiran G   ## Commit message ## - wifi: nl80211/mac80211: Add SMD BSS Transition sub-state STA flags + wifi: mac80211: apply SMD BSS Transition STA sub-states  - IEEE P802.11bn/D2.0, Aug 2026, subclause 11.3.1, defines three new MLD - state sub-states (4a, 4b, 4c) that apply when a non-AP MLD and its - associated SMD-ME are in state 4 and an SMD BSS Transition is - in progress. - - Add the corresponding nl80211 STA flags and internal STA flags to track - the SMD BSS Transition sub-states (4a, 4b, or 4c) in mac80211: - - NL80211_STA_FLAG_SMD_PREP_TARGET (WLAN_STA_SMD_PREP_TARGET): - State 4a: non-AP MLD is prepared with target AP MLD - - NL80211_STA_FLAG_SMD_EXEC_CURRENT (WLAN_STA_SMD_EXEC_CURRENT): - State 4b: ST execution active on current AP MLD - - NL80211_STA_FLAG_SMD_DL_DRAIN (WLAN_STA_SMD_DL_DRAIN): - State 4c: DL draining period + During SMD BSS Transition, the non-AP STA MLD roaming from the current + AP MLD to the target AP MLD switches its new SMD sub-states. Capture + these state transitions to track the station roaming.  These are transient sub-states of WLAN_STA_AUTHORIZED with the SMD-ME. The station remains authenticated, associated, and RSNA-established @@ Commit message  Signed-off-by: Pooventhiran G   - ## include/uapi/linux/nl80211.h ## -@@ include/uapi/linux/nl80211.h: enum nl80211_iftype { - * previously added station into associated state - * @NL80211_STA_FLAG_SPP_AMSDU: station supports SPP A-MSDUs - * @NL80211_STA_FLAG_SMD: station has negotiated SMD. -+ * @NL80211_STA_FLAG_SMD_PREP_TARGET: station is prepared at SMD target AP MLD -+ * (State 4a). -+ * @NL80211_STA_FLAG_SMD_EXEC_CURRENT: current AP MLD is executing SMD BSS -+ * Transition (State 4b). -+ * @NL80211_STA_FLAG_SMD_DL_DRAIN: current AP MLD is in DL draining period -+ * (State 4c). - * @NL80211_STA_FLAG_MAX: highest station flag number currently defined - * @__NL80211_STA_FLAG_AFTER_LAST: internal use - */ -@@ include/uapi/linux/nl80211.h: enum nl80211_sta_flags { - NL80211_STA_FLAG_ASSOCIATED, - NL80211_STA_FLAG_SPP_AMSDU, - NL80211_STA_FLAG_SMD, -+ NL80211_STA_FLAG_SMD_PREP_TARGET, -+ NL80211_STA_FLAG_SMD_EXEC_CURRENT, -+ NL80211_STA_FLAG_SMD_DL_DRAIN, -  - /* keep last */ - __NL80211_STA_FLAG_AFTER_LAST, - ## net/mac80211/cfg.c ##  @@ net/mac80211/cfg.c: static int sta_link_apply_parameters(struct ieee80211_local *local, return 0; @@ net/mac80211/sta_info.h: enum ieee80211_sta_info_flags {  NUM_WLAN_STA_FLAGS, }; - - ## net/wireless/nl80211.c ## -@@ net/wireless/nl80211.c: static const struct nla_policy sta_flags_policy[NL80211_STA_FLAG_MAX + 1] = { - [NL80211_STA_FLAG_AUTHENTICATED] = { .type = NLA_FLAG }, - [NL80211_STA_FLAG_TDLS_PEER] = { .type = NLA_FLAG }, - [NL80211_STA_FLAG_SMD] = { .type = NLA_FLAG }, -+ [NL80211_STA_FLAG_SMD_PREP_TARGET] = { .type = NLA_FLAG }, -+ [NL80211_STA_FLAG_SMD_EXEC_CURRENT] = { .type = NLA_FLAG }, -+ [NL80211_STA_FLAG_SMD_DL_DRAIN] = { .type = NLA_FLAG }, - }; -  - static int parse_station_flags(struct genl_info *info, -@@ net/wireless/nl80211.c: static int parse_station_flags(struct genl_info *info, - switch (iftype) { - case NL80211_IFTYPE_AP: - case NL80211_IFTYPE_AP_VLAN: -- params->sta_flags_mask = BIT(NL80211_STA_FLAG_SMD); -+ params->sta_flags_mask = -+ BIT(NL80211_STA_FLAG_SMD) | -+ BIT(NL80211_STA_FLAG_SMD_PREP_TARGET) | -+ BIT(NL80211_STA_FLAG_SMD_EXEC_CURRENT) | -+ BIT(NL80211_STA_FLAG_SMD_DL_DRAIN); - fallthrough; - case NL80211_IFTYPE_P2P_GO: - params->sta_flags_mask |= BIT(NL80211_STA_FLAG_AUTHORIZED) | -@@ net/wireless/nl80211.c: int cfg80211_check_station_change(struct wiphy *wiphy, - return -EINVAL; -  - /* When you run into this, adjust the code below for the new flag */ -- BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 9); -+ BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 12); -  - switch (statype) { - case CFG80211_STA_MESH_PEER_KERNEL: -@@ net/wireless/nl80211.c: int cfg80211_check_station_change(struct wiphy *wiphy, - BIT(NL80211_STA_FLAG_WME) | - BIT(NL80211_STA_FLAG_MFP) | - BIT(NL80211_STA_FLAG_SPP_AMSDU) | -- BIT(NL80211_STA_FLAG_SMD))) -+ BIT(NL80211_STA_FLAG_SMD) | -+ BIT(NL80211_STA_FLAG_SMD_PREP_TARGET) | -+ BIT(NL80211_STA_FLAG_SMD_EXEC_CURRENT) | -+ BIT(NL80211_STA_FLAG_SMD_DL_DRAIN))) - return -EINVAL; -  - /* but authenticated/associated only if driver handles it */ -@@ net/wireless/nl80211.c: static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) - return -EINVAL; -  - /* When you run into this, adjust the code below for the new flag */ -- BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 9); -+ BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 12); -  - switch (wdev->iftype) { - case NL80211_IFTYPE_AP:  7: b75b9bf05bca ! 14: 493acdcde955 wifi: mac80211: Add driver_op for SMD substate changes @@ Metadata Author: Pooventhiran G   ## Commit message ## - wifi: mac80211: Add driver_op for SMD substate changes + wifi: mac80211: add driver_op for SMD substate changes  During SMD BSS Transition, a non-AP MLD moves through sub-states 4a, 4b, and 4c that impose different frame-filtering rules on the AP MLD. @@ net/mac80211/cfg.c: static int ieee80211_add_station(struct wiphy *wiphy, struct   ## net/mac80211/driver-ops.c ## -@@ net/mac80211/driver-ops.c: int drv_change_sta_links(struct ieee80211_local *local, +@@ net/mac80211/driver-ops.c: int drv_link_sta_statistics(struct ieee80211_local *local,  return 0; }  -: ------------ > 15: 1351cb3f0c6d wifi: mac80211: filter uplink and downlink frames based on SMD states  8: f66d1129e71d ! 16: 67a7933f8897 wifi: mac80211: Send BlockAck policy in AMPDU action @@ Metadata Author: Pooventhiran G   ## Commit message ## - wifi: mac80211: Send BlockAck policy in AMPDU action + wifi: mac80211: send BlockAck policy in AMPDU action  While sending AMPDU action hints to drivers, mac80211 does not include the BlockAck policy extracted from ADDBA frames. Drivers may require the  9: 60c58e616ed0 < -: ------------ wifi: mac80211: Define layouts for SMD BSS Transition context 10: 14c15b3c39f1 < -: ------------ wifi: nl80211: Define attributes to pack SMD BSS Transition context 11: 07dd3bd1e229 < -: ------------ wifi: cfg80211/mac80211: Handle UHR Link Reconfiguration frame 12: fe44e1d4d066 < -: ------------ wifi: nl80211: Pack SMD dynamic context along with frame  -: ------------ > 17: 4b4b81a4f9e4 wifi: mac80211: pass rx_data directly from ieee80211_rx_list()  -: ------------ > 18: 1f1ec66eaf77 wifi: mac80211: handle UHR Link Reconfiguration frame 14: 1cba72a0fdfc ! 19: 96682e263f53 wifi: mac80211: Add mac80211 support to handle NL80211_CMD_SET_SMD_CTX @@ Metadata Author: Pooventhiran G   ## Commit message ## - wifi: mac80211: Add mac80211 support to handle NL80211_CMD_SET_SMD_CTX + wifi: mac80211: add mac80211 support to handle NL80211_CMD_SET_SMD_CTX  cfg80211 supports NL80211_CMD_SET_SMD_CTX on the target AP MLD for userspace to program the station's dynamic context on the TX and RX @@ include/net/mac80211.h: struct ieee80211_ops { /**  ## net/mac80211/cfg.c ## -@@ net/mac80211/cfg.c: ieee80211_set_peer_nan_sched(struct wiphy *wiphy, - return ieee80211_nan_set_peer_sched(sdata, sched); +@@ net/mac80211/cfg.c: ieee80211_set_nan_non_evac_channels(struct wiphy *wiphy, + return ieee80211_nan_set_non_evac_channels(sdata, channels); }   +static int ieee80211_set_smd_ctx(struct wiphy *wiphy, struct wireless_dev *wdev, @@ net/mac80211/cfg.c: ieee80211_set_peer_nan_sched(struct wiphy *wiphy,  + sta = sta_info_get_bss(sdata, addr);  + if (!sta)  + return -ENOENT; -+ if (!sta->sta.smd_params.smd_sta) ++ if (!sta->sta.smd_params.smd_sta || ++ sta->smd_state != IEEE80211_STA_SMD_PREP) ++ return -EINVAL; ++ ++ if (!wiphy_dereference(wiphy, sta->ptk[sta->ptk_idx]))  + return -EINVAL;  +  + return drv_set_smd_ctx(local, sdata, &sta->sta, st_info); @@ net/mac80211/cfg.c: ieee80211_set_peer_nan_sched(struct wiphy *wiphy, .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface,  @@ net/mac80211/cfg.c: const struct cfg80211_ops mac80211_config_ops = { - .set_epcs = ieee80211_set_epcs, .nan_set_local_sched = ieee80211_set_local_nan_sched, .nan_set_peer_sched = ieee80211_set_peer_nan_sched, + .nan_set_non_evac_channels = ieee80211_set_nan_non_evac_channels,  + .set_smd_ctx = ieee80211_set_smd_ctx, };  @@ net/mac80211/trace.h: TRACE_EVENT(drv_sta_smd_state,  + VIF_ENTRY  + STA_ENTRY  + __field(u8, st_type) -+ __field(unsigned int, num_tids) -+ __dynamic_array(unsigned long, dl_tid_bitmap, -+ BITS_TO_LONGS(IEEE80211_SMD_CTX_NUM_TIDS)) -+ __dynamic_array(unsigned long, ul_tid_bitmap, -+ BITS_TO_LONGS(IEEE80211_SMD_CTX_NUM_TIDS)) ++ __field(u8, dl_tid_bitmap) ++ __field(u8, ul_tid_bitmap)  + ),  +  + TP_fast_assign(  + struct ieee80211_smd_ctx *ctx = st_info->ctx; -+ unsigned long sz;  +  + LOCAL_ASSIGN;  + VIF_ASSIGN;  + STA_ASSIGN;  + __entry->st_type = st_info->type; -+ -+ __entry->num_tids = IEEE80211_SMD_CTX_NUM_TIDS; -+ sz = BITS_TO_LONGS(__entry->num_tids) * sizeof(unsigned long); -+ -+ memcpy(__get_dynamic_array(dl_tid_bitmap), -+ ctx->dl.valid_tid_bmap, sz); -+ memcpy(__get_dynamic_array(ul_tid_bitmap), -+ ctx->ul.valid_tid_bmap, sz); ++ __entry->dl_tid_bitmap = ctx->dl.valid_tid_bmap; ++ __entry->ul_tid_bitmap = ctx->ul.valid_tid_bmap;  + ),  +  + TP_printk(LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT -+ ", ST type=%u DL TIDs: %*pb, UL TIDs: %*pb", ++ ", ST type=%u DL TIDs: 0x%x, UL TIDs: 0x%x",  + LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG,  + __entry->st_type, -+ __entry->num_tids, -+ (unsigned long *)__get_dynamic_array(dl_tid_bitmap), -+ __entry->num_tids, -+ (unsigned long *)__get_dynamic_array(ul_tid_bitmap) ++ __entry->dl_tid_bitmap, __entry->ul_tid_bitmap  + )  +);  + 16: 74167bb33aa7 ! 20: 802ba7c3980f wifi: mac80211: Add mac80211 support to handle NL80211_CMD_GET_SMD_CTX @@ Metadata Author: Pooventhiran G   ## Commit message ## - wifi: mac80211: Add mac80211 support to handle NL80211_CMD_GET_SMD_CTX + wifi: mac80211: add mac80211 support to handle NL80211_CMD_GET_SMD_CTX  cfg80211 supports NL80211_CMD_GET_SMD_CTX from userspace on the current AP MLD to collect the station's context on the target AP MLD's behalf; @@ net/mac80211/cfg.c: static int ieee80211_set_smd_ctx(struct wiphy *wiphy, struct .add_virtual_intf = ieee80211_add_iface, .del_virtual_intf = ieee80211_del_iface,  @@ net/mac80211/cfg.c: const struct cfg80211_ops mac80211_config_ops = { - .nan_set_local_sched = ieee80211_set_local_nan_sched, .nan_set_peer_sched = ieee80211_set_peer_nan_sched, + .nan_set_non_evac_channels = ieee80211_set_nan_non_evac_channels, .set_smd_ctx = ieee80211_set_smd_ctx,  + .get_smd_ctx = ieee80211_get_smd_ctx, };  -: ------------ > 21: 8244862521a9 wifi: mac80211: define API to invoke SMD Drain Completion event