Commit dc55e307 authored by Michal Kazior's avatar Michal Kazior Committed by Kalle Valo

ath10k: improve channel switching

In some cases during heavy tx vdev stop-start
would timeout on vdev synchronization causing
traffic to stall for a few seconds.

Instead of stop-starting use a dedicated vdev
restart command and down vdevs explicitly before
doing so.

This gets rid of the synchronization
warnings/timeouts and makes channel switching
smoother during traffic.
Signed-off-by: default avatarMichal Kazior <michal.kazior@tieto.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 76f5329a
...@@ -796,7 +796,7 @@ static void ath10k_recalc_radar_detection(struct ath10k *ar) ...@@ -796,7 +796,7 @@ static void ath10k_recalc_radar_detection(struct ath10k *ar)
} }
} }
static int ath10k_vdev_start(struct ath10k_vif *arvif) static int ath10k_vdev_start_restart(struct ath10k_vif *arvif, bool restart)
{ {
struct ath10k *ar = arvif->ar; struct ath10k *ar = arvif->ar;
struct cfg80211_chan_def *chandef = &ar->chandef; struct cfg80211_chan_def *chandef = &ar->chandef;
...@@ -838,7 +838,11 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) ...@@ -838,7 +838,11 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
arg.vdev_id, arg.channel.freq, arg.vdev_id, arg.channel.freq,
ath10k_wmi_phymode_str(arg.channel.mode)); ath10k_wmi_phymode_str(arg.channel.mode));
ret = ath10k_wmi_vdev_start(ar, &arg); if (restart)
ret = ath10k_wmi_vdev_restart(ar, &arg);
else
ret = ath10k_wmi_vdev_start(ar, &arg);
if (ret) { if (ret) {
ath10k_warn("failed to start WMI vdev %i: %d\n", ath10k_warn("failed to start WMI vdev %i: %d\n",
arg.vdev_id, ret); arg.vdev_id, ret);
...@@ -858,6 +862,16 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif) ...@@ -858,6 +862,16 @@ static int ath10k_vdev_start(struct ath10k_vif *arvif)
return ret; return ret;
} }
static int ath10k_vdev_start(struct ath10k_vif *arvif)
{
return ath10k_vdev_start_restart(arvif, false);
}
static int ath10k_vdev_restart(struct ath10k_vif *arvif)
{
return ath10k_vdev_start_restart(arvif, true);
}
static int ath10k_vdev_stop(struct ath10k_vif *arvif) static int ath10k_vdev_stop(struct ath10k_vif *arvif)
{ {
struct ath10k *ar = arvif->ar; struct ath10k *ar = arvif->ar;
...@@ -2582,18 +2596,21 @@ static void ath10k_config_chan(struct ath10k *ar) ...@@ -2582,18 +2596,21 @@ static void ath10k_config_chan(struct ath10k *ar)
if (!arvif->is_started) if (!arvif->is_started)
continue; continue;
if (!arvif->is_up)
continue;
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
continue; continue;
ret = ath10k_vdev_stop(arvif); ret = ath10k_wmi_vdev_down(ar, arvif->vdev_id);
if (ret) { if (ret) {
ath10k_warn("failed to stop vdev %d: %d\n", ath10k_warn("failed to down vdev %d: %d\n",
arvif->vdev_id, ret); arvif->vdev_id, ret);
continue; continue;
} }
} }
/* all vdevs are now stopped - now attempt to restart them */ /* all vdevs are downed now - attempt to restart and re-up them */
list_for_each_entry(arvif, &ar->arvifs, list) { list_for_each_entry(arvif, &ar->arvifs, list) {
if (!arvif->is_started) if (!arvif->is_started)
...@@ -2602,9 +2619,9 @@ static void ath10k_config_chan(struct ath10k *ar) ...@@ -2602,9 +2619,9 @@ static void ath10k_config_chan(struct ath10k *ar)
if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR) if (arvif->vdev_type == WMI_VDEV_TYPE_MONITOR)
continue; continue;
ret = ath10k_vdev_start(arvif); ret = ath10k_vdev_restart(arvif);
if (ret) { if (ret) {
ath10k_warn("failed to start vdev %d: %d\n", ath10k_warn("failed to restart vdev %d: %d\n",
arvif->vdev_id, ret); arvif->vdev_id, ret);
continue; continue;
} }
......
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