diff options
-rw-r--r-- | include/net/mac80211.h | 13 | ||||
-rw-r--r-- | net/mac80211/tx.c | 25 |
2 files changed, 38 insertions, 0 deletions
diff --git a/include/net/mac80211.h b/include/net/mac80211.h index d2279b2d61aa..52f36c43f35f 100644 --- a/include/net/mac80211.h +++ b/include/net/mac80211.h @@ -4450,6 +4450,19 @@ static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw, u8 ieee80211_csa_update_counter(struct ieee80211_vif *vif); /** + * ieee80211_csa_set_counter - request mac80211 to set csa counter + * @vif: &struct ieee80211_vif pointer from the add_interface callback. + * @counter: the new value for the counter + * + * The csa counter can be changed by the device, this API should be + * used by the device driver to update csa counter in mac80211. + * + * It should never be used together with ieee80211_csa_update_counter(), + * as it will cause a race condition around the counter value. + */ +void ieee80211_csa_set_counter(struct ieee80211_vif *vif, u8 counter); + +/** * ieee80211_csa_finish - notify mac80211 about channel switch * @vif: &struct ieee80211_vif pointer from the add_interface callback. * diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 535de3161a78..062e125a324c 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4084,6 +4084,31 @@ unlock: } EXPORT_SYMBOL(ieee80211_csa_update_counter); +void ieee80211_csa_set_counter(struct ieee80211_vif *vif, u8 counter) +{ + struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); + struct beacon_data *beacon = NULL; + + rcu_read_lock(); + + if (sdata->vif.type == NL80211_IFTYPE_AP) + beacon = rcu_dereference(sdata->u.ap.beacon); + else if (sdata->vif.type == NL80211_IFTYPE_ADHOC) + beacon = rcu_dereference(sdata->u.ibss.presp); + else if (ieee80211_vif_is_mesh(&sdata->vif)) + beacon = rcu_dereference(sdata->u.mesh.beacon); + + if (!beacon) + goto unlock; + + if (counter < beacon->csa_current_counter) + beacon->csa_current_counter = counter; + +unlock: + rcu_read_unlock(); +} +EXPORT_SYMBOL(ieee80211_csa_set_counter); + bool ieee80211_csa_is_complete(struct ieee80211_vif *vif) { struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |