Commit 6257c702 authored by Pradeep Kumar Chitrapu's avatar Pradeep Kumar Chitrapu Committed by Kalle Valo
Browse files

wifi: ath11k: fix tx status reporting in encap offload mode



ieee80211_tx_status() treats packets in 802.11 frame format and
tries to extract sta address from packet header. When tx encap
offload is enabled, this becomes invalid operation. Hence, switch
to using ieee80211_tx_status_ext() after filling in station
address for handling both 802.11 and 802.3 frames.

Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1

Signed-off-by: default avatarPradeep Kumar Chitrapu <quic_pradeepc@quicinc.com>
Signed-off-by: default avatarKalle Valo <quic_kvalo@quicinc.com>
Link: https://lore.kernel.org/r/20230403195738.25367-2-quic_pradeepc@quicinc.com
parent 20487cc3
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -303,12 +303,16 @@ struct ath11k_dp {

#define HTT_TX_WBM_COMP_STATUS_OFFSET 8

#define HTT_INVALID_PEER_ID	0xffff

/* HTT tx completion is overlaid in wbm_release_ring */
#define HTT_TX_WBM_COMP_INFO0_STATUS		GENMASK(12, 9)
#define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON	GENMASK(16, 13)
#define HTT_TX_WBM_COMP_INFO0_REINJECT_REASON	GENMASK(16, 13)

#define HTT_TX_WBM_COMP_INFO1_ACK_RSSI		GENMASK(31, 24)
#define HTT_TX_WBM_COMP_INFO2_SW_PEER_ID	GENMASK(15, 0)
#define HTT_TX_WBM_COMP_INFO2_VALID		BIT(21)

struct htt_tx_wbm_completion {
	u32 info0;
+32 −1
Original line number Diff line number Diff line
@@ -316,10 +316,12 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab,
				 struct dp_tx_ring *tx_ring,
				 struct ath11k_dp_htt_wbm_tx_status *ts)
{
	struct ieee80211_tx_status status = { 0 };
	struct sk_buff *msdu;
	struct ieee80211_tx_info *info;
	struct ath11k_skb_cb *skb_cb;
	struct ath11k *ar;
	struct ath11k_peer *peer;

	spin_lock(&tx_ring->tx_idr_lock);
	msdu = idr_remove(&tx_ring->txbuf_idr, ts->msdu_id);
@@ -341,6 +343,11 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab,

	dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, DMA_TO_DEVICE);

	if (!skb_cb->vif) {
		dev_kfree_skb_any(msdu);
		return;
	}

	memset(&info->status, 0, sizeof(info->status));

	if (ts->acked) {
@@ -355,7 +362,23 @@ ath11k_dp_tx_htt_tx_complete_buf(struct ath11k_base *ab,
		}
	}

	ieee80211_tx_status(ar->hw, msdu);
	spin_lock_bh(&ab->base_lock);
	peer = ath11k_peer_find_by_id(ab, ts->peer_id);
	if (!peer || !peer->sta) {
		ath11k_dbg(ab, ATH11K_DBG_DATA,
			   "dp_tx: failed to find the peer with peer_id %d\n",
			    ts->peer_id);
		spin_unlock_bh(&ab->base_lock);
		dev_kfree_skb_any(msdu);
		return;
	}
	spin_unlock_bh(&ab->base_lock);

	status.sta = peer->sta;
	status.info = info;
	status.skb = msdu;

	ieee80211_tx_status_ext(ar->hw, &status);
}

static void
@@ -379,7 +402,15 @@ ath11k_dp_tx_process_htt_tx_complete(struct ath11k_base *ab,
		ts.msdu_id = msdu_id;
		ts.ack_rssi = FIELD_GET(HTT_TX_WBM_COMP_INFO1_ACK_RSSI,
					status_desc->info1);

		if (FIELD_GET(HTT_TX_WBM_COMP_INFO2_VALID, status_desc->info2))
			ts.peer_id = FIELD_GET(HTT_TX_WBM_COMP_INFO2_SW_PEER_ID,
					       status_desc->info2);
		else
			ts.peer_id = HTT_INVALID_PEER_ID;

		ath11k_dp_tx_htt_tx_complete_buf(ab, tx_ring, &ts);

		break;
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_REINJ:
	case HAL_WBM_REL_HTT_TX_COMP_STATUS_INSPECT:
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ struct ath11k_dp_htt_wbm_tx_status {
	u32 msdu_id;
	bool acked;
	int ack_rssi;
	u16 peer_id;
};

void ath11k_dp_tx_update_txcompl(struct ath11k *ar, struct hal_tx_status *ts);