Commit 9713e3de authored by Michal Kazior's avatar Michal Kazior Committed by Kalle Valo

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: default avatarMichal Kazior <michal.kazior@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 7be6d1b7
......@@ -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? */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment