ath10k: handle IEEE80211_CHANCTX_CHANGE_WIDTH properly
Vdevs associated with a given chanctx should be restarted if the bandwidth changes. Otherwise traffic may cease. This is known to fix STA CSA with bandwidths wider than 20MHz. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
7be6d1b762
commit
9713e3de80
@ -6408,12 +6408,52 @@ ath10k_mac_op_remove_chanctx(struct ieee80211_hw *hw,
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
struct ath10k_mac_change_chanctx_arg {
|
||||
struct ieee80211_chanctx_conf *ctx;
|
||||
struct ieee80211_vif_chanctx_switch *vifs;
|
||||
int n_vifs;
|
||||
int next_vif;
|
||||
};
|
||||
|
||||
static void
|
||||
ath10k_mac_change_chanctx_cnt_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath10k_mac_change_chanctx_arg *arg = data;
|
||||
|
||||
if (rcu_access_pointer(vif->chanctx_conf) != arg->ctx)
|
||||
return;
|
||||
|
||||
arg->n_vifs++;
|
||||
}
|
||||
|
||||
static void
|
||||
ath10k_mac_change_chanctx_fill_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath10k_mac_change_chanctx_arg *arg = data;
|
||||
struct ieee80211_chanctx_conf *ctx;
|
||||
|
||||
ctx = rcu_access_pointer(vif->chanctx_conf);
|
||||
if (ctx != arg->ctx)
|
||||
return;
|
||||
|
||||
if (WARN_ON(arg->next_vif == arg->n_vifs))
|
||||
return;
|
||||
|
||||
arg->vifs[arg->next_vif].vif = vif;
|
||||
arg->vifs[arg->next_vif].old_ctx = ctx;
|
||||
arg->vifs[arg->next_vif].new_ctx = ctx;
|
||||
arg->next_vif++;
|
||||
}
|
||||
|
||||
static void
|
||||
ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
|
||||
struct ieee80211_chanctx_conf *ctx,
|
||||
u32 changed)
|
||||
{
|
||||
struct ath10k *ar = hw->priv;
|
||||
struct ath10k_mac_change_chanctx_arg arg = { .ctx = ctx };
|
||||
|
||||
mutex_lock(&ar->conf_mutex);
|
||||
|
||||
@ -6427,6 +6467,30 @@ ath10k_mac_op_change_chanctx(struct ieee80211_hw *hw,
|
||||
if (WARN_ON(changed & IEEE80211_CHANCTX_CHANGE_CHANNEL))
|
||||
goto unlock;
|
||||
|
||||
if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
|
||||
ieee80211_iterate_active_interfaces_atomic(
|
||||
hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
ath10k_mac_change_chanctx_cnt_iter,
|
||||
&arg);
|
||||
if (arg.n_vifs == 0)
|
||||
goto radar;
|
||||
|
||||
arg.vifs = kcalloc(arg.n_vifs, sizeof(arg.vifs[0]),
|
||||
GFP_KERNEL);
|
||||
if (!arg.vifs)
|
||||
goto radar;
|
||||
|
||||
ieee80211_iterate_active_interfaces_atomic(
|
||||
hw,
|
||||
IEEE80211_IFACE_ITER_NORMAL,
|
||||
ath10k_mac_change_chanctx_fill_iter,
|
||||
&arg);
|
||||
ath10k_mac_update_vif_chan(ar, arg.vifs, arg.n_vifs);
|
||||
kfree(arg.vifs);
|
||||
}
|
||||
|
||||
radar:
|
||||
ath10k_recalc_radar_detection(ar);
|
||||
|
||||
/* FIXME: How to configure Rx chains properly? */
|
||||
|
Loading…
Reference in New Issue
Block a user