mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 14:44:10 +08:00
wifi: mac80211: handle color change per link
In order to support color change with MLO, handle the link ID now passed from cfg80211, adjust the code to do everything per link and call the notifications to cfg80211 correctly. Signed-off-by: Aditya Kumar Singh <quic_adisi@quicinc.com> Link: https://msgid.link/20240422053412.2024075-4-quic_adisi@quicinc.com Link: https://msgid.link/20240422053412.2024075-5-quic_adisi@quicinc.com Link: https://msgid.link/20240422053412.2024075-6-quic_adisi@quicinc.com Link: https://msgid.link/20240422053412.2024075-7-quic_adisi@quicinc.com [squash, move API call updates to this patch] Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
91d2b6ee13
commit
414e736c3d
@ -1659,7 +1659,7 @@ void ath11k_mac_bcn_tx_event(struct ath11k_vif *arvif)
|
||||
if (vif->bss_conf.color_change_active &&
|
||||
ieee80211_beacon_cntdwn_is_complete(vif, 0)) {
|
||||
arvif->bcca_zero_sent = true;
|
||||
ieee80211_color_change_finish(vif);
|
||||
ieee80211_color_change_finish(vif, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -4064,7 +4064,8 @@ ath11k_wmi_obss_color_collision_event(struct ath11k_base *ab, struct sk_buff *sk
|
||||
|
||||
switch (ev->evt_type) {
|
||||
case WMI_BSS_COLOR_COLLISION_DETECTION:
|
||||
ieee80211_obss_color_collision_notify(arvif->vif, ev->obss_color_bitmap);
|
||||
ieee80211_obss_color_collision_notify(arvif->vif, ev->obss_color_bitmap,
|
||||
0);
|
||||
ath11k_dbg(ab, ATH11K_DBG_WMI,
|
||||
"OBSS color collision detected vdev:%d, event:%d, bitmap:%08llx\n",
|
||||
ev->vdev_id, ev->evt_type, ev->obss_color_bitmap);
|
||||
|
@ -331,7 +331,7 @@ mt7915_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
||||
if (!vif->bss_conf.color_change_active || vif->type == NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
ieee80211_color_change_finish(vif);
|
||||
ieee80211_color_change_finish(vif, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -418,7 +418,7 @@ mt7996_mcu_cca_finish(void *priv, u8 *mac, struct ieee80211_vif *vif)
|
||||
if (!vif->bss_conf.color_change_active || vif->type == NL80211_IFTYPE_STATION)
|
||||
return;
|
||||
|
||||
ieee80211_color_change_finish(vif);
|
||||
ieee80211_color_change_finish(vif, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -5615,12 +5615,13 @@ 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.
|
||||
* @link_id: valid link_id during MLO or 0 for non-MLO
|
||||
*
|
||||
* 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);
|
||||
void ieee80211_color_change_finish(struct ieee80211_vif *vif, u8 link_id);
|
||||
|
||||
/**
|
||||
* ieee80211_proberesp_get - retrieve a Probe Response template
|
||||
@ -7533,6 +7534,7 @@ ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
|
||||
/**
|
||||
* ieee80211_obss_color_collision_notify - notify userland about a BSS color
|
||||
* collision.
|
||||
* @link_id: valid link_id during MLO or 0 for non-MLO
|
||||
*
|
||||
* @vif: &struct ieee80211_vif pointer from the add_interface callback.
|
||||
* @color_bitmap: a 64 bit bitmap representing the colors that the local BSS is
|
||||
@ -7540,7 +7542,7 @@ ieee80211_get_unsol_bcast_probe_resp_tmpl(struct ieee80211_hw *hw,
|
||||
*/
|
||||
void
|
||||
ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
u64 color_bitmap);
|
||||
u64 color_bitmap, u8 link_id);
|
||||
|
||||
/**
|
||||
* ieee80211_is_tx_data - check if frame is a data frame
|
||||
|
@ -3918,13 +3918,13 @@ static int ieee80211_set_csa_beacon(struct ieee80211_link_data *link_data,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ieee80211_color_change_abort(struct ieee80211_sub_if_data *sdata)
|
||||
static void ieee80211_color_change_abort(struct ieee80211_link_data *link)
|
||||
{
|
||||
sdata->vif.bss_conf.color_change_active = false;
|
||||
link->conf->color_change_active = false;
|
||||
|
||||
ieee80211_free_next_beacon(&sdata->deflink);
|
||||
ieee80211_free_next_beacon(link);
|
||||
|
||||
cfg80211_color_change_aborted_notify(sdata->dev, 0);
|
||||
cfg80211_color_change_aborted_notify(link->sdata->dev, link->link_id);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -4008,7 +4008,7 @@ __ieee80211_channel_switch(struct wiphy *wiphy, struct net_device *dev,
|
||||
|
||||
/* if there is a color change in progress, abort it */
|
||||
if (link_conf->color_change_active)
|
||||
ieee80211_color_change_abort(sdata);
|
||||
ieee80211_color_change_abort(link_data);
|
||||
|
||||
err = ieee80211_set_csa_beacon(link_data, params, &changed);
|
||||
if (err) {
|
||||
@ -4666,20 +4666,22 @@ static int ieee80211_set_sar_specs(struct wiphy *wiphy,
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_set_after_color_change_beacon(struct ieee80211_link_data *link,
|
||||
u64 *changed)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP: {
|
||||
int ret;
|
||||
|
||||
if (!sdata->deflink.u.ap.next_beacon)
|
||||
if (!link->u.ap.next_beacon)
|
||||
return -EINVAL;
|
||||
|
||||
ret = ieee80211_assign_beacon(sdata, &sdata->deflink,
|
||||
sdata->deflink.u.ap.next_beacon,
|
||||
ret = ieee80211_assign_beacon(sdata, link,
|
||||
link->u.ap.next_beacon,
|
||||
NULL, NULL, changed);
|
||||
ieee80211_free_next_beacon(&sdata->deflink);
|
||||
ieee80211_free_next_beacon(link);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -4695,18 +4697,19 @@ ieee80211_set_after_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
static int
|
||||
ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_set_color_change_beacon(struct ieee80211_link_data *link,
|
||||
struct cfg80211_color_change_settings *params,
|
||||
u64 *changed)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
struct ieee80211_color_change_settings color_change = {};
|
||||
int err;
|
||||
|
||||
switch (sdata->vif.type) {
|
||||
case NL80211_IFTYPE_AP:
|
||||
sdata->deflink.u.ap.next_beacon =
|
||||
link->u.ap.next_beacon =
|
||||
cfg80211_beacon_dup(¶ms->beacon_next);
|
||||
if (!sdata->deflink.u.ap.next_beacon)
|
||||
if (!link->u.ap.next_beacon)
|
||||
return -ENOMEM;
|
||||
|
||||
if (params->count <= 1)
|
||||
@ -4718,11 +4721,11 @@ ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
params->counter_offset_presp;
|
||||
color_change.count = params->count;
|
||||
|
||||
err = ieee80211_assign_beacon(sdata, &sdata->deflink,
|
||||
err = ieee80211_assign_beacon(sdata, link,
|
||||
¶ms->beacon_color_change,
|
||||
NULL, &color_change, changed);
|
||||
if (err < 0) {
|
||||
ieee80211_free_next_beacon(&sdata->deflink);
|
||||
ieee80211_free_next_beacon(link);
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
@ -4734,16 +4737,18 @@ ieee80211_set_color_change_beacon(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
|
||||
static void
|
||||
ieee80211_color_change_bss_config_notify(struct ieee80211_sub_if_data *sdata,
|
||||
ieee80211_color_change_bss_config_notify(struct ieee80211_link_data *link,
|
||||
u8 color, int enable, u64 changed)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
lockdep_assert_wiphy(sdata->local->hw.wiphy);
|
||||
|
||||
sdata->vif.bss_conf.he_bss_color.color = color;
|
||||
sdata->vif.bss_conf.he_bss_color.enabled = enable;
|
||||
link->conf->he_bss_color.color = color;
|
||||
link->conf->he_bss_color.enabled = enable;
|
||||
changed |= BSS_CHANGED_HE_BSS_COLOR;
|
||||
|
||||
ieee80211_link_info_change_notify(sdata, &sdata->deflink, changed);
|
||||
ieee80211_link_info_change_notify(sdata, link, changed);
|
||||
|
||||
if (!sdata->vif.bss_conf.nontransmitted && sdata->vif.mbssid_tx_vif) {
|
||||
struct ieee80211_sub_if_data *child;
|
||||
@ -4760,26 +4765,27 @@ ieee80211_color_change_bss_config_notify(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
}
|
||||
|
||||
static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata)
|
||||
static int ieee80211_color_change_finalize(struct ieee80211_link_data *link)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
u64 changed = 0;
|
||||
int err;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
sdata->vif.bss_conf.color_change_active = false;
|
||||
link->conf->color_change_active = false;
|
||||
|
||||
err = ieee80211_set_after_color_change_beacon(sdata, &changed);
|
||||
err = ieee80211_set_after_color_change_beacon(link, &changed);
|
||||
if (err) {
|
||||
cfg80211_color_change_aborted_notify(sdata->dev, 0);
|
||||
cfg80211_color_change_aborted_notify(sdata->dev, link->link_id);
|
||||
return err;
|
||||
}
|
||||
|
||||
ieee80211_color_change_bss_config_notify(sdata,
|
||||
sdata->vif.bss_conf.color_change_color,
|
||||
ieee80211_color_change_bss_config_notify(link,
|
||||
link->conf->color_change_color,
|
||||
1, changed);
|
||||
cfg80211_color_change_notify(sdata->dev, 0);
|
||||
cfg80211_color_change_notify(sdata->dev, link->link_id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -4787,21 +4793,23 @@ static int ieee80211_color_change_finalize(struct ieee80211_sub_if_data *sdata)
|
||||
void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
|
||||
struct wiphy_work *work)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata =
|
||||
container_of(work, struct ieee80211_sub_if_data,
|
||||
deflink.color_change_finalize_work);
|
||||
struct ieee80211_link_data *link =
|
||||
container_of(work, struct ieee80211_link_data,
|
||||
color_change_finalize_work);
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
struct ieee80211_bss_conf *link_conf = link->conf;
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
/* AP might have been stopped while waiting for the lock. */
|
||||
if (!sdata->vif.bss_conf.color_change_active)
|
||||
if (!link_conf->color_change_active)
|
||||
return;
|
||||
|
||||
if (!ieee80211_sdata_running(sdata))
|
||||
return;
|
||||
|
||||
ieee80211_color_change_finalize(sdata);
|
||||
ieee80211_color_change_finalize(link);
|
||||
}
|
||||
|
||||
void ieee80211_color_collision_detection_work(struct work_struct *work)
|
||||
@ -4812,30 +4820,60 @@ void ieee80211_color_collision_detection_work(struct work_struct *work)
|
||||
color_collision_detect_work);
|
||||
struct ieee80211_sub_if_data *sdata = link->sdata;
|
||||
|
||||
cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap, 0);
|
||||
cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap,
|
||||
link->link_id);
|
||||
}
|
||||
|
||||
void ieee80211_color_change_finish(struct ieee80211_vif *vif)
|
||||
void ieee80211_color_change_finish(struct ieee80211_vif *vif, u8 link_id)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
struct ieee80211_link_data *link;
|
||||
|
||||
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
||||
return;
|
||||
|
||||
rcu_read_lock();
|
||||
|
||||
link = rcu_dereference(sdata->link[link_id]);
|
||||
if (WARN_ON(!link)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
wiphy_work_queue(sdata->local->hw.wiphy,
|
||||
&sdata->deflink.color_change_finalize_work);
|
||||
&link->color_change_finalize_work);
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211_color_change_finish);
|
||||
|
||||
void
|
||||
ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
u64 color_bitmap)
|
||||
u64 color_bitmap, u8 link_id)
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
|
||||
struct ieee80211_link_data *link = &sdata->deflink;
|
||||
struct ieee80211_link_data *link;
|
||||
|
||||
if (sdata->vif.bss_conf.color_change_active || sdata->vif.bss_conf.csa_active)
|
||||
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
||||
return;
|
||||
|
||||
if (delayed_work_pending(&link->color_collision_detect_work))
|
||||
rcu_read_lock();
|
||||
|
||||
link = rcu_dereference(sdata->link[link_id]);
|
||||
if (WARN_ON(!link)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (link->conf->color_change_active || link->conf->csa_active) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
if (delayed_work_pending(&link->color_collision_detect_work)) {
|
||||
rcu_read_unlock();
|
||||
return;
|
||||
}
|
||||
|
||||
link->color_bitmap = color_bitmap;
|
||||
/* queue the color collision detection event every 500 ms in order to
|
||||
@ -4844,6 +4882,8 @@ ieee80211_obss_color_collision_notify(struct ieee80211_vif *vif,
|
||||
ieee80211_queue_delayed_work(&sdata->local->hw,
|
||||
&link->color_collision_detect_work,
|
||||
msecs_to_jiffies(500));
|
||||
|
||||
rcu_read_unlock();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ieee80211_obss_color_collision_notify);
|
||||
|
||||
@ -4853,36 +4893,48 @@ ieee80211_color_change(struct wiphy *wiphy, struct net_device *dev,
|
||||
{
|
||||
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
struct ieee80211_bss_conf *link_conf;
|
||||
struct ieee80211_link_data *link;
|
||||
u8 link_id = params->link_id;
|
||||
u64 changed = 0;
|
||||
int err;
|
||||
|
||||
lockdep_assert_wiphy(local->hw.wiphy);
|
||||
|
||||
if (sdata->vif.bss_conf.nontransmitted)
|
||||
if (WARN_ON(link_id >= IEEE80211_MLD_MAX_NUM_LINKS))
|
||||
return -EINVAL;
|
||||
|
||||
link = wiphy_dereference(wiphy, sdata->link[link_id]);
|
||||
if (!link)
|
||||
return -ENOLINK;
|
||||
|
||||
link_conf = link->conf;
|
||||
|
||||
if (link_conf->nontransmitted)
|
||||
return -EINVAL;
|
||||
|
||||
/* don't allow another color change if one is already active or if csa
|
||||
* is active
|
||||
*/
|
||||
if (sdata->vif.bss_conf.color_change_active || sdata->vif.bss_conf.csa_active) {
|
||||
if (link_conf->color_change_active || link_conf->csa_active) {
|
||||
err = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
err = ieee80211_set_color_change_beacon(sdata, params, &changed);
|
||||
err = ieee80211_set_color_change_beacon(link, params, &changed);
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
sdata->vif.bss_conf.color_change_active = true;
|
||||
sdata->vif.bss_conf.color_change_color = params->color;
|
||||
link_conf->color_change_active = true;
|
||||
link_conf->color_change_color = params->color;
|
||||
|
||||
cfg80211_color_change_started_notify(sdata->dev, params->count, 0);
|
||||
cfg80211_color_change_started_notify(sdata->dev, params->count, link_id);
|
||||
|
||||
if (changed)
|
||||
ieee80211_color_change_bss_config_notify(sdata, 0, 0, changed);
|
||||
ieee80211_color_change_bss_config_notify(link, 0, 0, changed);
|
||||
else
|
||||
/* if the beacon didn't change, we can finalize immediately */
|
||||
ieee80211_color_change_finalize(sdata);
|
||||
ieee80211_color_change_finalize(link);
|
||||
|
||||
out:
|
||||
|
||||
|
@ -3368,7 +3368,7 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
|
||||
if (ieee80211_hw_check(&rx->local->hw, DETECTS_COLOR_COLLISION))
|
||||
return;
|
||||
|
||||
if (rx->sdata->vif.bss_conf.csa_active)
|
||||
if (rx->link->conf->csa_active)
|
||||
return;
|
||||
|
||||
baselen = mgmt->u.beacon.variable - rx->skb->data;
|
||||
@ -3380,7 +3380,7 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
|
||||
rx->skb->len - baselen);
|
||||
if (ie && ie->datalen >= sizeof(struct ieee80211_he_operation) &&
|
||||
ie->datalen >= ieee80211_he_oper_size(ie->data + 1)) {
|
||||
struct ieee80211_bss_conf *bss_conf = &rx->sdata->vif.bss_conf;
|
||||
struct ieee80211_bss_conf *bss_conf = rx->link->conf;
|
||||
const struct ieee80211_he_operation *he_oper;
|
||||
u8 color;
|
||||
|
||||
@ -3393,7 +3393,8 @@ ieee80211_rx_check_bss_color_collision(struct ieee80211_rx_data *rx)
|
||||
IEEE80211_HE_OPERATION_BSS_COLOR_MASK);
|
||||
if (color == bss_conf->he_bss_color.color)
|
||||
ieee80211_obss_color_collision_notify(&rx->sdata->vif,
|
||||
BIT_ULL(color));
|
||||
BIT_ULL(color),
|
||||
bss_conf->link_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user