ath10k: fix per-vif queue locking
Whenever any vdev was supposed to be paused all Tx
queues were stopped (except offchannel) instead of
only these associated with the given vdev.
This caused subtle issues with
multi-channel/multi-vif scenarios, e.g.
authentication of station vif could sometimes fail
depending on fw tx pause request timing.
Fixes: b4aa539dd8
("ath10k: implement tx pause wmi event")
Signed-off-by: Michal Kazior <michal.kazior@tieto.com>
Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
@@ -3034,38 +3034,16 @@ static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
|
||||
|
||||
lockdep_assert_held(&ar->htt.tx_lock);
|
||||
|
||||
switch (pause_id) {
|
||||
case WMI_TLV_TX_PAUSE_ID_MCC:
|
||||
case WMI_TLV_TX_PAUSE_ID_P2P_CLI_NOA:
|
||||
case WMI_TLV_TX_PAUSE_ID_P2P_GO_PS:
|
||||
case WMI_TLV_TX_PAUSE_ID_AP_PS:
|
||||
case WMI_TLV_TX_PAUSE_ID_IBSS_PS:
|
||||
switch (action) {
|
||||
case WMI_TLV_TX_PAUSE_ACTION_STOP:
|
||||
ath10k_mac_vif_tx_lock(arvif, pause_id);
|
||||
break;
|
||||
case WMI_TLV_TX_PAUSE_ACTION_WAKE:
|
||||
ath10k_mac_vif_tx_unlock(arvif, pause_id);
|
||||
break;
|
||||
default:
|
||||
ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
|
||||
action, arvif->vdev_id);
|
||||
break;
|
||||
}
|
||||
switch (action) {
|
||||
case WMI_TLV_TX_PAUSE_ACTION_STOP:
|
||||
ath10k_mac_vif_tx_lock(arvif, pause_id);
|
||||
break;
|
||||
case WMI_TLV_TX_PAUSE_ACTION_WAKE:
|
||||
ath10k_mac_vif_tx_unlock(arvif, pause_id);
|
||||
break;
|
||||
case WMI_TLV_TX_PAUSE_ID_AP_PEER_PS:
|
||||
case WMI_TLV_TX_PAUSE_ID_AP_PEER_UAPSD:
|
||||
case WMI_TLV_TX_PAUSE_ID_STA_ADD_BA:
|
||||
case WMI_TLV_TX_PAUSE_ID_HOST:
|
||||
default:
|
||||
/* FIXME: Some pause_ids aren't vdev specific. Instead they
|
||||
* target peer_id and tid. Implementing these could improve
|
||||
* traffic scheduling fairness across multiple connected
|
||||
* stations in AP/IBSS modes.
|
||||
*/
|
||||
ath10k_dbg(ar, ATH10K_DBG_MAC,
|
||||
"mac ignoring unsupported tx pause vdev %i id %d\n",
|
||||
arvif->vdev_id, pause_id);
|
||||
ath10k_warn(ar, "received unknown tx pause action %d on vdev %i, ignoring\n",
|
||||
action, arvif->vdev_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -3082,12 +3060,15 @@ static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
|
||||
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
||||
struct ath10k_mac_tx_pause *arg = data;
|
||||
|
||||
if (arvif->vdev_id != arg->vdev_id)
|
||||
return;
|
||||
|
||||
ath10k_mac_vif_handle_tx_pause(arvif, arg->pause_id, arg->action);
|
||||
}
|
||||
|
||||
void ath10k_mac_handle_tx_pause(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_tlv_tx_pause_id pause_id,
|
||||
enum wmi_tlv_tx_pause_action action)
|
||||
void ath10k_mac_handle_tx_pause_vdev(struct ath10k *ar, u32 vdev_id,
|
||||
enum wmi_tlv_tx_pause_id pause_id,
|
||||
enum wmi_tlv_tx_pause_action action)
|
||||
{
|
||||
struct ath10k_mac_tx_pause arg = {
|
||||
.vdev_id = vdev_id,
|
||||
|
Reference in New Issue
Block a user