mac80211: add BSS color change support
Subsystems (2)
v7 cover mac80211: add BSS color change support
This series adds support for BSS color collission detection and change.
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
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 | 25 ++-- net/wireless/nl80211.c | 157 +++++++++++++++++++++++ net/wireless/rdev-ops.h | 13 ++ net/wireless/trace.h | 46 +++++++ 10 files changed, 631 insertions(+), 21 deletions(-)
Signature · 1 line
2.31.1
PATCH v7 1/2 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); };/*
@@ -8216,4 +8242,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
PATCH v7 2/2 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 | 25 ++-- 5 files changed, 280 insertions(+), 21 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 +15 -10
@@ -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 ; +u16 *bcn_offsets, *resp_offsets;struct probe_resp *resp; -u8 *beacon_data;size_t beacon_data_len;int i; -u8 count = beacon->cntdwn_current_counter;switch (sdata->vif.type) {case NL80211_IFTYPE_AP :
@@ -4799,21 +4799,25 @@ 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; + resp_offsets = resp->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; + resp->data[resp_offsets[i]] = count; }rcu_read_unlock (); }
@@ -5023,6 +5027,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