mac80211: add BSS color change support
Subsystems (4)
Lorenzo Bianconi
maintainerv9 cover mac80211: add BSS color change support
This series adds support for BSS color collission detection and change.
Changes since v8:
- fix a possible NULL pointer dereference in ieee80211_set_beacon_cntdwn()
Changes since v7:
- always notify the driver about bss change in
ieee80211_color_change_finalize()
- add mt7915 bss color support
Changes since v6:
- rebase on top of mac80211-next
- fix check_patch issues
- alloc nlattr tb array dynamically in nl80211_color_change
- move NL80211_ATTR_CNTDWN_OFFS_BEACON and NL80211_ATTR_CNTDWN_OFFS_PRESP in NL80211_ATTR_COLOR_CHANGE_ELEMS as nested attributes
- remove unused definitions
- remove mbss series dependency
- remove ath11k code
John Crispin (2):
nl80211: add support for BSS coloring
mac80211: add support for BSS color change
Lorenzo Bianconi (1):
mt76: mt7915: introduce bss coloring support
.../net/wireless/mediatek/mt76/mt7915/init.c | 1 + .../net/wireless/mediatek/mt76/mt7915/main.c | 26 ++ .../net/wireless/mediatek/mt76/mt7915/mcu.c | 84 +++++-- .../net/wireless/mediatek/mt76/mt7915/mcu.h | 21 +- .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 + include/net/cfg80211.h | 92 +++++++ include/net/mac80211.h | 29 +++ include/uapi/linux/nl80211.h | 43 ++++ net/mac80211/cfg.c | 234 +++++++++++++++++- net/mac80211/ieee80211_i.h | 11 + net/mac80211/iface.c | 2 + net/mac80211/tx.c | 29 ++- net/wireless/nl80211.c | 157 ++++++++++++ net/wireless/rdev-ops.h | 13 + net/wireless/trace.h | 46 ++++ 15 files changed, 739 insertions(+), 51 deletions(-)
Signature · 1 line
2.31.1
Lorenzo Bianconi
maintainerPATCH v9 1/3 nl80211: add support for BSS coloring
From: John Crispin <[email protected]>
This patch adds support for BSS color collisions to the wireless subsystem. Add the required functionality to nl80211 that will notify about color collisions, triggering the color change and notifying when it is completed.
--- include/net/cfg80211.h | 92 ++++++++++++++++++++ include/uapi/linux/nl80211.h | 43 ++++++++++ net/wireless/nl80211.c | 157 +++++++++++++++++++++++++++++++++++ net/wireless/rdev-ops.h | 13 +++ net/wireless/trace.h | 46 ++++++++++ 5 files changed, 351 insertions(+)
include/net/cfg80211.h +92 -0
@@ -1252,6 +1252,27 @@ struct cfg80211_csa_settings {u8 count; }; +/** +* struct cfg80211_color_change_settings - color change settings +* +* Used for bss color change +* +* @beacon_color_change: beacon data while performing the color countdown +* @counter_offsets_beacon: offsets of the counters within the beacon (tail) +* @counter_offsets_presp: offsets of the counters within the probe response +* @beacon_next: beacon data to be used after the color change +* @count: number of beacons until the color change +* @color: the color used after the change +*/ +struct cfg80211_color_change_settings { +struct cfg80211_beacon_data beacon_color_change; +u16 counter_offset_beacon; +u16 counter_offset_presp; +struct cfg80211_beacon_data beacon_next; +u8 count; +u8 color; +}; +/** * struct iface_combination_params - input parameters for interface combinations *
@@ -3995,6 +4016,8 @@ struct mgmt_frame_regs {* given TIDs. This callback may sleep. * * @set_sar_specs: Update the SAR (TX power) settings. +* +* @color_change: Initiate a color change. */ struct cfg80211_ops {int (*suspend)(struct wiphy *wiphy,struct cfg80211_wowlan *wow);
@@ -4322,6 +4345,9 @@ struct cfg80211_ops { const u8 *peer, u8 tids);int (*set_sar_specs)(struct wiphy *wiphy,struct cfg80211_sar_specs *sar); +int (*color_change)(struct wiphy *wiphy, +struct net_device *dev, +struct cfg80211_color_change_settings *params); };/*
@@ -8218,4 +8244,70 @@ void cfg80211_update_owe_info_event(struct net_device *netdev,*/ void cfg80211_bss_flush (struct wiphy *wiphy); +/** +* cfg80211_bss_color_notify - notify about bss color event +* @dev: network device +* @gfp: allocation flags +* @cmd: the actual event we want to notify +* @count: the number of TBTTs until the color change happens +* @color_bitmap: representations of the colors that the local BSS is aware of +*/ +int cfg80211_bss_color_notify (struct net_device *dev,gfp_t gfp, +enum nl80211_commands cmd,u8 count, +u64 color_bitmap); + +/** +* cfg80211_obss_color_collision_notify - notify about bss color collision +* @dev: network device +* @color_bitmap: representations of the colors that the local BSS is aware of +*/ +static inline int cfg80211_obss_color_collision_notify (struct net_device *dev, +u64 color_bitmap) +{ +return cfg80211_bss_color_notify (dev,GFP_KERNEL , +NL80211_CMD_OBSS_COLOR_COLLISION , +0 , color_bitmap); +} + +/** +* cfg80211_color_change_started_notify - notify color change start +* @dev: the device on which the color is switched +* @count: the number of TBTTs until the color change happens +* +* Inform the userspace about the color change that has started. +*/ +static inline int cfg80211_color_change_started_notify (struct net_device *dev, +u8 count) +{ +return cfg80211_bss_color_notify (dev,GFP_KERNEL , +NL80211_CMD_COLOR_CHANGE_STARTED , + count,0 ); +} + +/** +* cfg80211_color_change_aborted_notify - notify color change abort +* @dev: the device on which the color is switched +* +* Inform the userspace about the color change that has aborted. +*/ +static inline int cfg80211_color_change_aborted_notify (struct net_device *dev) +{ +return cfg80211_bss_color_notify (dev,GFP_KERNEL , +NL80211_CMD_COLOR_CHANGE_ABORTED , +0 ,0 ); +} + +/** +* cfg80211_color_change_notify - notify color change completion +* @dev: the device on which the color was switched +* +* Inform the userspace about the color change that has completed. +*/ +static inline int cfg80211_color_change_notify (struct net_device *dev) +{ +return cfg80211_bss_color_notify (dev,GFP_KERNEL , +NL80211_CMD_COLOR_CHANGE_COMPLETED , +0 ,0 ); +} +#endif /* __NET_CFG80211_H */
include/uapi/linux/nl80211.h +43 -0
79 lines not on this page · raw message
net/wireless/nl80211.c +157 -0
181 lines not on this page · raw message
net/wireless/rdev-ops.h +13 -0
@@ -1368,4 +1368,17 @@ static inline int rdev_set_sar_specs(struct cfg80211_registered_device *rdev, return ret; } +static inline int rdev_color_change (struct cfg80211_registered_device *rdev, +struct net_device *dev, +struct cfg80211_color_change_settings *params) +{ +int ret; + +trace_rdev_color_change (&rdev->wiphy, dev, params); + ret = rdev->ops->color_change (&rdev->wiphy, dev, params); +trace_rdev_return_int (&rdev->wiphy, ret); + +return ret; +} +#endif /* __CFG80211_RDEV_OPS */
net/wireless/trace.h +46 -0
52 lines not on this page · raw message
Signature · 1 line
2.31.1
Lorenzo Bianconi
maintainerPATCH v9 2/3 mac80211: add support for BSS color change
In reply to Lorenzo BianconiFrom: John Crispin <[email protected]>
The color change announcement is very similar to how CSA works where we have an IE that includes a counter. When the counter hits 0, the new color is applied via an updated beacon.
This patch makes the CSA counter functionality reusable, rather than implementing it again. This also allows for future reuse incase support for other counter IEs gets added.
--- include/net/mac80211.h | 29 +++++ net/mac80211/cfg.c | 234 +++++++++++++++++++++++++++++++++++-- net/mac80211/ieee80211_i.h | 11 ++ net/mac80211/iface.c | 2 + net/mac80211/tx.c | 29 +++-- 5 files changed, 283 insertions(+), 22 deletions(-)
include/net/mac80211.h +29 -0
@@ -1711,6 +1711,10 @@ enum ieee80211_offload_flags {* protected by fq->lock. * @offload_flags: 802.3 -> 802.11 enapsulation offload flags, see * &enum ieee80211_offload_flags. +* @color_change_active: marks whether a color change is ongoing. Internally it is +* write-protected by sdata_lock and local->mtx so holding either is fine +* for read access. +* @color_change_color: the bss color that will be used after the change. */ struct ieee80211_vif {enum nl80211_iftype type;
@@ -1739,6 +1743,9 @@ struct ieee80211_vif {bool txqs_stopped[IEEE80211_NUM_ACS ]; +bool color_change_active; +u8 color_change_color; +/* must be last */ u8 drv_priv[]__aligned(sizeof(void *)) ; };
@@ -5007,6 +5014,16 @@ void ieee80211_csa_finish(struct ieee80211_vif *vif);*/ bool ieee80211_beacon_cntdwn_is_complete (struct ieee80211_vif *vif); +/** +* ieee80211_color_change_finish - notify mac80211 about color change +* @vif: &struct ieee80211_vif pointer from the add_interface callback. +* +* After a color change announcement was scheduled and the counter in this +* announcement hits 1, this function must be called by the driver to +* notify mac80211 that the color can be changed +*/ +void ieee80211_color_change_finish (struct ieee80211_vif *vif); +/** * ieee80211_proberesp_get - retrieve a Probe Response template * @hw: pointer obtained from ieee80211_alloc_hw().
@@ -6771,6 +6788,18 @@ struct sk_buff * ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw, struct ieee80211_vif *vif); +/** +* ieeee80211_obss_color_collision_notify - notify userland about a BSS color +* collision. +* +* @vif: &struct ieee80211_vif pointer from the add_interface callback. +* @color_bitmap: a 64 bit bitmap representing the colors that the local BSS is +* aware of. +*/ +void +ieeee80211_obss_color_collision_notify (struct ieee80211_vif *vif, +u64 color_bitmap); +/** * ieee80211_is_tx_data - check if frame is a data frame *
net/mac80211/cfg.c +223 -11
318 lines not on this page · raw message
net/mac80211/ieee80211_i.h +11 -0
@@ -244,6 +244,12 @@ struct ieee80211_csa_settings {u8 count; }; +struct ieee80211_color_change_settings { +u16 counter_offset_beacon; +u16 counter_offset_presp; +u8 count; +}; +struct beacon_data {u8 *head, *tail;int head_len, tail_len;
@@ -923,6 +929,8 @@ struct ieee80211_sub_if_data {bool csa_block_tx;/* write-protected by sdata_lock and local->mtx */ struct cfg80211_chan_def csa_chandef; +struct work_struct color_change_finalize_work; +struct list_head assigned_chanctx_list;/* protected by chanctx_mtx */ struct list_head reserved_chanctx_list;/* protected by chanctx_mtx */
@@ -1887,6 +1895,9 @@ void ieee80211_csa_finalize_work(struct work_struct *work);int ieee80211_channel_switch (struct wiphy *wiphy,struct net_device *dev,struct cfg80211_csa_settings *params); +/* color change handling */ +void ieee80211_color_change_finalize_work (struct work_struct *work); +/* interface handling */ #define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \ NETIF_F_HW_CSUM | NETIF_F_SG | \
net/mac80211/iface.c +2 -0
@@ -462,6 +462,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_dosdata_unlock (sdata);cancel_work_sync (&sdata->csa_finalize_work); +cancel_work_sync (&sdata->color_change_finalize_work);cancel_delayed_work_sync (&sdata->dfs_cac_timer_work);
@@ -1531,6 +1532,7 @@ static void ieee80211_setup_sdata(struct ieee80211_sub_if_data *sdata,INIT_WORK (&sdata->work, ieee80211_iface_work);INIT_WORK (&sdata->recalc_smps, ieee80211_recalc_smps_work);INIT_WORK (&sdata->csa_finalize_work, ieee80211_csa_finalize_work); +INIT_WORK (&sdata->color_change_finalize_work, ieee80211_color_change_finalize_work);INIT_LIST_HEAD (&sdata->assigned_chanctx_list);INIT_LIST_HEAD (&sdata->reserved_chanctx_list);
net/mac80211/tx.c +18 -11
@@ -4775,11 +4775,11 @@ static int ieee80211_beacon_add_tim(struct ieee80211_sub_if_data *sdata,static void ieee80211_set_beacon_cntdwn (struct ieee80211_sub_if_data *sdata,struct beacon_data *beacon) { +u8 *beacon_data, count, max_count =1 ;struct probe_resp *resp; -u8 *beacon_data;size_t beacon_data_len; +u16 *bcn_offsets;int i; -u8 count = beacon->cntdwn_current_counter;switch (sdata->vif.type) {case NL80211_IFTYPE_AP :
@@ -4799,21 +4799,27 @@ static void ieee80211_set_beacon_cntdwn(struct ieee80211_sub_if_data *sdata, }rcu_read_lock (); -for (i =0 ; i <IEEE80211_MAX_CNTDWN_COUNTERS_NUM ; ++i) { - resp =rcu_dereference (sdata->u.ap.probe_resp); + resp =rcu_dereference (sdata->u.ap.probe_resp); + + bcn_offsets = beacon->cntdwn_counter_offsets; + count = beacon->cntdwn_current_counter; +if (sdata->vif.csa_active) + max_count =IEEE80211_MAX_CNTDWN_COUNTERS_NUM ; -if (beacon->cntdwn_counter_offsets[i]) { -if (WARN_ON_ONCE (beacon->cntdwn_counter_offsets[i] >= - beacon_data_len)) { +for (i =0 ; i < max_count; ++i) { +if (bcn_offsets[i]) { +if (WARN_ON_ONCE (bcn_offsets[i] >= beacon_data_len)) {rcu_read_unlock ();return ; } - - beacon_data[beacon->cntdwn_counter_offsets[i]] = count; + beacon_data[bcn_offsets[i]] = count; } -if (sdata->vif.type ==NL80211_IFTYPE_AP && resp) - resp->data[resp->cntdwn_counter_offsets[i]] = count; +if (sdata->vif.type ==NL80211_IFTYPE_AP && resp) { +u16 *resp_offsets = resp->cntdwn_counter_offsets; + + resp->data[resp_offsets[i]] = count; + } }rcu_read_unlock (); }
@@ -5023,6 +5029,7 @@ __ieee80211_beacon_get(struct ieee80211_hw *hw,if (offs) { offs->tim_offset = beacon->head_len; offs->tim_length = skb->len - beacon->head_len; + offs->cntdwn_counter_offs[0 ] = beacon->cntdwn_counter_offsets[0 ];/* for AP the csa offsets are from tail */ csa_off_base = skb->len;
Signature · 1 line
2.31.1
Lorenzo Bianconi
maintainerPATCH v9 3/3 mt76: mt7915: introduce bss coloring support
In reply to Lorenzo BianconiIntroduce mcu APIs to configure bss coloring and to report bss coloring collisions. Add support to report coloring countdown in beacon sent by the device.
--- .../net/wireless/mediatek/mt76/mt7915/init.c | 1 + .../net/wireless/mediatek/mt76/mt7915/main.c | 26 ++++++ .../net/wireless/mediatek/mt76/mt7915/mcu.c | 84 ++++++++++++++----- .../net/wireless/mediatek/mt76/mt7915/mcu.h | 21 ++--- .../wireless/mediatek/mt76/mt7915/mt7915.h | 2 + 5 files changed, 105 insertions(+), 29 deletions(-)
drivers/net/wireless/mediatek/mt76/mt7915/init.c +1 -0
@@ -232,6 +232,7 @@ mt7915_init_wiphy(struct ieee80211_hw *hw) wiphy->reg_notifier = mt7915_regd_notifier; wiphy->flags |=WIPHY_FLAG_HAS_CHANNEL_SWITCH ; +wiphy_ext_feature_set (wiphy,NL80211_EXT_FEATURE_BSS_COLOR );wiphy_ext_feature_set (wiphy,NL80211_EXT_FEATURE_VHT_IBSS );ieee80211_hw_set (hw,HAS_RATE_CONTROL );
drivers/net/wireless/mediatek/mt76/mt7915/main.c +26 -0
@@ -538,6 +538,29 @@ static void mt7915_configure_filter(struct ieee80211_hw *hw,mutex_unlock (&dev->mt76.mutex); } +static void +mt7915_update_bss_color (struct ieee80211_hw *hw, +struct ieee80211_vif *vif, +struct cfg80211_he_bss_color *bss_color) +{ +struct mt7915_dev *dev =mt7915_hw_dev (hw); + +switch (vif->type) { +case NL80211_IFTYPE_AP : { +struct mt7915_vif *mvif = (struct mt7915_vif *)vif->drv_priv; + +if (mvif->omac_idx >HW_BSSID_MAX ) +return ; + fallthrough; + } +case NL80211_IFTYPE_STATION : +mt7915_mcu_update_bss_color (dev, vif, bss_color); +break ; +default : +break ; + } +} + static void mt7915_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info,
@@ -586,6 +609,9 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,if (changed &BSS_CHANGED_HE_OBSS_PD )mt7915_mcu_add_obss_spr (dev, vif, info->he_obss_pd.enable); +if (changed &BSS_CHANGED_HE_BSS_COLOR ) +mt7915_update_bss_color (hw, vif, &info->he_bss_color); +if (changed & (BSS_CHANGED_BEACON |BSS_CHANGED_BEACON_ENABLED ))mt7915_mcu_add_beacon (hw, vif, info->enable_beacon);
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +65 -19
128 lines not on this page · raw message
drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +11 -10
@@ -43,6 +43,7 @@ enum {MCU_EXT_EVENT_ASSERT_DUMP =0x23 ,MCU_EXT_EVENT_RDD_REPORT =0x3a ,MCU_EXT_EVENT_CSA_NOTIFY =0x4f , +MCU_EXT_EVENT_BCC_NOTIFY =0x75 , MCU_EXT_EVENT_RATE_REPORT = 0x87, };
@@ -545,6 +546,14 @@ struct bss_info_hw_amsdu {u8 rsv; } __packed; +struct bss_info_color { +__le16 tag; +__le16 len; +u8 disable; +u8 color; +u8 rsv[2 ]; +} __packed; +struct bss_info_he {__le16 tag;__le16 len;
@@ -563,14 +572,7 @@ struct bss_info_bcn {__le16 sub_ntlv; } __packed__aligned(4) ; -struct bss_info_bcn_csa { -__le16 tag; -__le16 len; -u8 cnt; -u8 rsv[3 ]; -} __packed__aligned(4) ; - -struct bss_info_bcn_bcc { +struct bss_info_bcn_cntdwn {__le16 tag;__le16 len;u8 cnt;
@@ -1156,8 +1158,7 @@ enum { sizeof(struct bss_info_ext_bss))#define MT7915_BEACON_UPDATE_SIZE (sizeof(struct sta_req_hdr) + \ - sizeof(struct bss_info_bcn_csa) + \ - sizeof(struct bss_info_bcn_bcc) + \ + sizeof(struct bss_info_bcn_cntdwn) + \ sizeof(struct bss_info_bcn_mbss) + \ sizeof(struct bss_info_bcn_cont))
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +2 -0
@@ -327,6 +327,8 @@ int mt7915_mcu_add_rx_ba(struct mt7915_dev *dev,int mt7915_mcu_add_key (struct mt7915_dev *dev,struct ieee80211_vif *vif,struct mt7915_sta *msta,struct ieee80211_key_conf *key,enum set_key_cmd cmd); +int mt7915_mcu_update_bss_color (struct mt7915_dev *dev,struct ieee80211_vif *vif, +struct cfg80211_he_bss_color *he_bss_color);int mt7915_mcu_add_beacon (struct ieee80211_hw *hw,struct ieee80211_vif *vif,int enable); int mt7915_mcu_add_obss_spr(struct mt7915_dev *dev, struct ieee80211_vif *vif,
Signature · 1 line
2.31.1