mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-10 22:22:51 -04:00
wifi: ath12k: Fix TX status reporting to mac80211 when offload is enabled
Currently, the ath12k driver supports only the native Wi-Fi frame format. In this mode, the ieee80211_tx_status() function works correctly to report transmission status to mac80211, as it retrieves station information using sta_info_get_by_addrs(). However, this method is not applicable for Ethernet-converted packets, since sta_info_get_by_addrs() cannot extract station information from such formats. Retrieve station information using ath12k_peer_find_by_id() to support all frame formats, including native Wi-Fi, raw, and Ethernet. Report transmission status using ieee80211_tx_status_ext(), and include rate information as part of the datapath TX status report. Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.4.1-00217-QCAHKSWPL_SILICONZ-1 Tested-on: WCN7850 hw2.0 PCI WLAN.HMT.1.0.c5-00481-QCAHMTSWPL_V1.0_V2.0_SILICONZ-3 Signed-off-by: Nithyanantham Paramasivam <nithyanantham.paramasivam@oss.qualcomm.com> Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com> Link: https://patch.msgid.link/20250718025513.32982-3-nithyanantham.paramasivam@oss.qualcomm.com [changed instances of { 0 } to {}] Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
This commit is contained in:
committed by
Jeff Johnson
parent
192c8e9a13
commit
981050b918
@@ -568,7 +568,8 @@ static void
|
||||
ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
|
||||
struct ath12k_tx_desc_params *desc_params,
|
||||
struct dp_tx_ring *tx_ring,
|
||||
struct ath12k_dp_htt_wbm_tx_status *ts)
|
||||
struct ath12k_dp_htt_wbm_tx_status *ts,
|
||||
u16 peer_id)
|
||||
{
|
||||
struct ieee80211_tx_info *info;
|
||||
struct ath12k_link_vif *arvif;
|
||||
@@ -578,6 +579,8 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
|
||||
struct ath12k *ar;
|
||||
struct sk_buff *msdu = desc_params->skb;
|
||||
s32 noise_floor;
|
||||
struct ieee80211_tx_status status = {};
|
||||
struct ath12k_peer *peer;
|
||||
|
||||
skb_cb = ATH12K_SKB_CB(msdu);
|
||||
info = IEEE80211_SKB_CB(msdu);
|
||||
@@ -629,8 +632,25 @@ ath12k_dp_tx_htt_tx_complete_buf(struct ath12k_base *ab,
|
||||
info->flags |= IEEE80211_TX_STAT_NOACK_TRANSMITTED;
|
||||
}
|
||||
}
|
||||
rcu_read_lock();
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath12k_peer_find_by_id(ab, peer_id);
|
||||
if (!peer || !peer->sta) {
|
||||
ath12k_dbg(ab, ATH12K_DBG_DATA,
|
||||
"dp_tx: failed to find the peer with peer_id %d\n", peer_id);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
|
||||
goto exit;
|
||||
} else {
|
||||
status.sta = peer->sta;
|
||||
}
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
ieee80211_tx_status_skb(ath12k_ar_to_hw(ar), msdu);
|
||||
status.info = info;
|
||||
status.skb = msdu;
|
||||
ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status);
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -641,6 +661,7 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc,
|
||||
struct htt_tx_wbm_completion *status_desc;
|
||||
struct ath12k_dp_htt_wbm_tx_status ts = {0};
|
||||
enum hal_wbm_htt_tx_comp_status wbm_status;
|
||||
u16 peer_id;
|
||||
|
||||
status_desc = desc;
|
||||
|
||||
@@ -653,7 +674,11 @@ ath12k_dp_tx_process_htt_tx_complete(struct ath12k_base *ab, void *desc,
|
||||
ts.acked = (wbm_status == HAL_WBM_REL_HTT_TX_COMP_STATUS_OK);
|
||||
ts.ack_rssi = le32_get_bits(status_desc->info2,
|
||||
HTT_TX_WBM_COMP_INFO2_ACK_RSSI);
|
||||
ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts);
|
||||
|
||||
peer_id = le32_get_bits(((struct hal_wbm_completion_ring_tx *)desc)->
|
||||
info3, HAL_WBM_COMPL_TX_INFO3_PEER_ID);
|
||||
|
||||
ath12k_dp_tx_htt_tx_complete_buf(ab, desc_params, tx_ring, &ts, peer_id);
|
||||
break;
|
||||
case HAL_WBM_REL_HTT_TX_COMP_STATUS_DROP:
|
||||
case HAL_WBM_REL_HTT_TX_COMP_STATUS_TTL:
|
||||
@@ -805,6 +830,12 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
|
||||
struct ath12k_vif *ahvif;
|
||||
struct sk_buff *msdu = desc_params->skb;
|
||||
s32 noise_floor;
|
||||
struct ieee80211_tx_status status = {};
|
||||
struct ieee80211_rate_status status_rate = {};
|
||||
struct ath12k_peer *peer;
|
||||
struct ath12k_link_sta *arsta;
|
||||
struct ath12k_sta *ahsta;
|
||||
struct rate_info rate;
|
||||
|
||||
if (WARN_ON_ONCE(ts->buf_rel_source != HAL_WBM_REL_SRC_MODULE_TQM)) {
|
||||
/* Must not happen */
|
||||
@@ -896,7 +927,32 @@ static void ath12k_dp_tx_complete_msdu(struct ath12k *ar,
|
||||
|
||||
ath12k_dp_tx_update_txcompl(ar, ts);
|
||||
|
||||
ieee80211_tx_status_skb(ath12k_ar_to_hw(ar), msdu);
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath12k_peer_find_by_id(ab, ts->peer_id);
|
||||
if (!peer || !peer->sta) {
|
||||
ath12k_err(ab,
|
||||
"dp_tx: failed to find the peer with peer_id %d\n",
|
||||
ts->peer_id);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
ieee80211_free_txskb(ath12k_ar_to_hw(ar), msdu);
|
||||
goto exit;
|
||||
}
|
||||
ahsta = ath12k_sta_to_ahsta(peer->sta);
|
||||
arsta = &ahsta->deflink;
|
||||
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
status.sta = peer->sta;
|
||||
status.info = info;
|
||||
status.skb = msdu;
|
||||
rate = arsta->last_txrate;
|
||||
|
||||
status_rate.rate_idx = rate;
|
||||
status_rate.try_count = 1;
|
||||
|
||||
status.rates = &status_rate;
|
||||
status.n_rates = 1;
|
||||
ieee80211_tx_status_ext(ath12k_ar_to_hw(ar), &status);
|
||||
|
||||
exit:
|
||||
rcu_read_unlock();
|
||||
|
||||
Reference in New Issue
Block a user