ath10k: implement tx pause wmi event
qca6174 wmi-tlv firmware defines a new wmi event for host tx pausing (i.e. stop/wake tx queues). Map these events to ath10k/mac80211 tx queue control. This is important for multi-channel throughput performance. Signed-off-by: Michal Kazior <michal.kazior@tieto.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:

committed by
Kalle Valo

parent
96d828d45e
commit
b4aa539dd8
@@ -28,6 +28,7 @@
|
||||
#include "txrx.h"
|
||||
#include "testmode.h"
|
||||
#include "wmi.h"
|
||||
#include "wmi-tlv.h"
|
||||
#include "wmi-ops.h"
|
||||
#include "wow.h"
|
||||
|
||||
@@ -2919,6 +2920,83 @@ void ath10k_mac_vif_tx_unlock(struct ath10k_vif *arvif, int reason)
|
||||
ieee80211_wake_queue(ar->hw, arvif->vdev_id);
|
||||
}
|
||||
|
||||
static void ath10k_mac_vif_handle_tx_pause(struct ath10k_vif *arvif,
|
||||
enum wmi_tlv_tx_pause_id pause_id,
|
||||
enum wmi_tlv_tx_pause_action action)
|
||||
{
|
||||
struct ath10k *ar = arvif->ar;
|
||||
|
||||
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;
|
||||
}
|
||||
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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
struct ath10k_mac_tx_pause {
|
||||
u32 vdev_id;
|
||||
enum wmi_tlv_tx_pause_id pause_id;
|
||||
enum wmi_tlv_tx_pause_action action;
|
||||
};
|
||||
|
||||
static void ath10k_mac_handle_tx_pause_iter(void *data, u8 *mac,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
struct ath10k_vif *arvif = ath10k_vif_to_arvif(vif);
|
||||
struct ath10k_mac_tx_pause *arg = data;
|
||||
|
||||
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)
|
||||
{
|
||||
struct ath10k_mac_tx_pause arg = {
|
||||
.vdev_id = vdev_id,
|
||||
.pause_id = pause_id,
|
||||
.action = action,
|
||||
};
|
||||
|
||||
spin_lock_bh(&ar->htt.tx_lock);
|
||||
ieee80211_iterate_active_interfaces_atomic(ar->hw,
|
||||
IEEE80211_IFACE_ITER_RESUME_ALL,
|
||||
ath10k_mac_handle_tx_pause_iter,
|
||||
&arg);
|
||||
spin_unlock_bh(&ar->htt.tx_lock);
|
||||
}
|
||||
|
||||
static u8 ath10k_tx_h_get_tid(struct ieee80211_hdr *hdr)
|
||||
{
|
||||
if (ieee80211_is_mgmt(hdr->frame_control))
|
||||
@@ -4174,6 +4252,14 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ath10k_mac_vif_tx_unlock_all(struct ath10k_vif *arvif)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < BITS_PER_LONG; i++)
|
||||
ath10k_mac_vif_tx_unlock(arvif, i);
|
||||
}
|
||||
|
||||
static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
||||
struct ieee80211_vif *vif)
|
||||
{
|
||||
@@ -4240,6 +4326,10 @@ static void ath10k_remove_interface(struct ieee80211_hw *hw,
|
||||
ath10k_warn(ar, "failed to recalc monitor: %d\n", ret);
|
||||
}
|
||||
|
||||
spin_lock_bh(&ar->htt.tx_lock);
|
||||
ath10k_mac_vif_tx_unlock_all(arvif);
|
||||
spin_unlock_bh(&ar->htt.tx_lock);
|
||||
|
||||
mutex_unlock(&ar->conf_mutex);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user