wcn36xx: Fix TX data path
This patch contains the following fixes: - Use correct queue for submitting QoS packet. The queue id to use is a one-to-one mapping with the TID. - Don't encrypt a frame with IEEE80211_TX_INTFL_DONT_ENCRYPT flag. - Use the 'special queue' for null packets, preventing the firmware to submit it as AMPDU. Signed-off-by: Loic Poulain <loic.poulain@linaro.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/1595586052-16081-5-git-send-email-loic.poulain@linaro.org
This commit is contained in:
@@ -267,9 +267,11 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
|
|||||||
bool bcast)
|
bool bcast)
|
||||||
{
|
{
|
||||||
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
|
||||||
|
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
|
||||||
struct ieee80211_vif *vif = NULL;
|
struct ieee80211_vif *vif = NULL;
|
||||||
struct wcn36xx_vif *__vif_priv = NULL;
|
struct wcn36xx_vif *__vif_priv = NULL;
|
||||||
bool is_data_qos;
|
bool is_data_qos = ieee80211_is_data_qos(hdr->frame_control);
|
||||||
|
u16 tid = 0;
|
||||||
|
|
||||||
bd->bd_rate = WCN36XX_BD_RATE_DATA;
|
bd->bd_rate = WCN36XX_BD_RATE_DATA;
|
||||||
|
|
||||||
@@ -298,24 +300,33 @@ static void wcn36xx_set_tx_data(struct wcn36xx_tx_bd *bd,
|
|||||||
bd->dpu_sign = __vif_priv->self_ucast_dpu_sign;
|
bd->dpu_sign = __vif_priv->self_ucast_dpu_sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ieee80211_is_any_nullfunc(hdr->frame_control) ||
|
if (is_data_qos) {
|
||||||
|
tid = ieee80211_get_tid(hdr);
|
||||||
|
/* TID->QID is one-to-one mapping */
|
||||||
|
bd->queue_id = tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT ||
|
||||||
(sta_priv && !sta_priv->is_data_encrypted)) {
|
(sta_priv && !sta_priv->is_data_encrypted)) {
|
||||||
bd->dpu_ne = 1;
|
bd->dpu_ne = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ieee80211_is_any_nullfunc(hdr->frame_control)) {
|
||||||
|
/* Don't use a regular queue for null packet (no ampdu) */
|
||||||
|
bd->queue_id = WCN36XX_TX_U_WQ_ID;
|
||||||
|
}
|
||||||
|
|
||||||
if (bcast) {
|
if (bcast) {
|
||||||
bd->ub = 1;
|
bd->ub = 1;
|
||||||
bd->ack_policy = 1;
|
bd->ack_policy = 1;
|
||||||
}
|
}
|
||||||
*vif_priv = __vif_priv;
|
*vif_priv = __vif_priv;
|
||||||
|
|
||||||
is_data_qos = ieee80211_is_data_qos(hdr->frame_control);
|
|
||||||
|
|
||||||
wcn36xx_set_tx_pdu(bd,
|
wcn36xx_set_tx_pdu(bd,
|
||||||
is_data_qos ?
|
is_data_qos ?
|
||||||
sizeof(struct ieee80211_qos_hdr) :
|
sizeof(struct ieee80211_qos_hdr) :
|
||||||
sizeof(struct ieee80211_hdr_3addr),
|
sizeof(struct ieee80211_hdr_3addr),
|
||||||
skb->len, sta_priv ? sta_priv->tid : 0);
|
skb->len, tid);
|
||||||
|
|
||||||
if (sta_priv && is_data_qos)
|
if (sta_priv && is_data_qos)
|
||||||
wcn36xx_tx_start_ampdu(wcn, sta_priv, skb);
|
wcn36xx_tx_start_ampdu(wcn, sta_priv, skb);
|
||||||
|
Reference in New Issue
Block a user