@@ -307,6 +307,11 @@ static inline u16 ieee80211_sn_sub(u16 sn1, u16 sn2)
#define IEEE80211_TRIGGER_TYPE_BQRP 0x6
#define IEEE80211_TRIGGER_TYPE_NFRP 0x7
+/* max color index */
+#define IEEE80211_BSS_COLOR_MAX 63
+/* ageout time for OBSS BSS color */
+#define IEEE80211_BSS_COLOR_AGEOUT_TIME 10
+
struct ieee80211_hdr {
__le16 frame_control;
__le16 duration_id;
@@ -750,6 +750,7 @@ struct ieee80211_bss_conf {
bool color_change_active;
u8 color_change_color;
u64 used_color_bitmap;
+ unsigned long color_last_seen[IEEE80211_BSS_COLOR_MAX + 1];
bool vht_su_beamformer;
bool vht_su_beamformee;
@@ -4759,6 +4759,35 @@ ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,
return err;
}
+void ieee80211_color_aging_work(struct work_struct *work)
+{
+ struct ieee80211_sub_if_data *sdata =
+ container_of(work, struct ieee80211_sub_if_data,
+ deflink.color_aging_work.work);
+ struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
+ int i;
+
+ sdata_lock(sdata);
+
+ if (!ieee80211_sdata_running(sdata))
+ goto unlock;
+
+ for (i = 1; i < IEEE80211_BSS_COLOR_MAX + 1; i++) {
+ /* ageout if not seen for a period */
+ if ((bss_conf->used_color_bitmap & BIT_ULL(i)) &&
+ time_before(bss_conf->color_last_seen[i],
+ jiffies - IEEE80211_BSS_COLOR_AGEOUT_TIME * HZ)) {
+ bss_conf->used_color_bitmap &= ~BIT_ULL(i);
+ }
+ }
+
+ ieee80211_queue_delayed_work(&sdata->local->hw,
+ &sdata->deflink.color_aging_work, HZ);
+
+unlock:
+ sdata_unlock(sdata);
+}
+
static int
ieee80211_set_radar_background(struct wiphy *wiphy,
struct cfg80211_chan_def *chandef)
@@ -974,6 +974,7 @@ struct ieee80211_link_data {
struct work_struct color_change_finalize_work;
struct delayed_work color_collision_detect_work;
+ struct delayed_work color_aging_work;
u64 color_bitmap;
/* context reservation -- protected with chanctx_mtx */
@@ -1931,6 +1932,7 @@ int ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
/* color change handling */
void ieee80211_color_change_finalize_work(struct work_struct *work);
void ieee80211_color_collision_detection_work(struct work_struct *work);
+void ieee80211_color_aging_work(struct work_struct *work);
/* interface handling */
#define MAC80211_SUPPORTED_FEATURES_TX (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
@@ -541,6 +541,7 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata, bool going_do
cancel_work_sync(&sdata->deflink.color_change_finalize_work);
cancel_delayed_work_sync(&sdata->deflink.dfs_cac_timer_work);
+ cancel_delayed_work_sync(&sdata->deflink.color_aging_work);
if (sdata->wdev.cac_started) {
chandef = sdata->vif.bss_conf.chandef;
@@ -1430,6 +1431,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up)
set_bit(SDATA_STATE_RUNNING, &sdata->state);
+ if (sdata->vif.type == NL80211_IFTYPE_AP)
+ ieee80211_queue_delayed_work(&sdata->local->hw,
+ &sdata->deflink.color_aging_work,
+ HZ);
+
return 0;
err_del_interface:
drv_remove_interface(local, sdata);
@@ -41,6 +41,7 @@ void ieee80211_link_init(struct ieee80211_sub_if_data *sdata,
ieee80211_color_change_finalize_work);
INIT_DELAYED_WORK(&link->color_collision_detect_work,
ieee80211_color_collision_detection_work);
+ INIT_DELAYED_WORK(&link->color_aging_work, ieee80211_color_aging_work);
INIT_LIST_HEAD(&link->assigned_chanctx_list);
INIT_LIST_HEAD(&link->reserved_chanctx_list);
INIT_DELAYED_WORK(&link->dfs_cac_timer_work,
@@ -3265,6 +3265,7 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
color = le32_get_bits(he_oper->he_oper_params,
IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
bss_conf->used_color_bitmap |= BIT_ULL(color);
+ bss_conf->color_last_seen[color] = jiffies;
if (color == bss_conf->he_bss_color.color)
ieee80211_obss_color_collision_notify(&rx->sdata->vif,
Add a periodic work runs once every second to check BSS color. OBSS BSS Color will be aged out if not seen for 10 seconds. Signed-off-by: Yi-Chia Hsieh <yi-chia.hsieh@mediatek.com> --- include/linux/ieee80211.h | 5 +++++ include/net/mac80211.h | 1 + net/mac80211/cfg.c | 29 +++++++++++++++++++++++++++++ net/mac80211/ieee80211_i.h | 2 ++ net/mac80211/iface.c | 6 ++++++ net/mac80211/link.c | 1 + net/mac80211/rx.c | 1 + 7 files changed, 45 insertions(+)