]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
wifi: ath12k: change the status update in the monitor Rx
authorP Praneesh <quic_ppranees@quicinc.com>
Mon, 24 Mar 2025 06:25:13 +0000 (11:55 +0530)
committerJeff Johnson <jeff.johnson@oss.qualcomm.com>
Thu, 27 Mar 2025 22:55:41 +0000 (15:55 -0700)
Currently, in the monitor Rx path, status is filled from the RX TLV header
present in the MSDU data. This logic is inherited from ath11k. However, in
the ath12k 802.11be hardware, the Rx TLV header is not present in the MSDU
data. This information is reported under various TLV tags. Therefore, avoid
the existing status filling by accumulating the needed information in the
PPDU information structure and fill the status.

Tested-on: QCN9274 hw2.0 PCI WLAN.WBE.1.3.1-00173-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: P Praneesh <quic_ppranees@quicinc.com>
Tested-by: Nicolas Escande <nico.escande@gmail.com>
Reviewed-by: Vasanthakumar Thiagarajan <vasanthakumar.thiagarajan@oss.qualcomm.com>
Signed-off-by: Karthikeyan Periyasamy <quic_periyasa@quicinc.com>
Link: https://patch.msgid.link/20250324062518.2752822-6-quic_periyasa@quicinc.com
Signed-off-by: Jeff Johnson <jeff.johnson@oss.qualcomm.com>
drivers/net/wireless/ath/ath12k/core.h
drivers/net/wireless/ath/ath12k/dp_mon.c
drivers/net/wireless/ath/ath12k/hal_rx.h

index 2a1ad27e331cb7cdb91d980e6eb2bda2554fd5e7..3f9475db5e6862187175d45536f4319707567ed0 100644 (file)
@@ -536,9 +536,19 @@ struct ath12k_sta {
        enum ieee80211_sta_state state;
 };
 
-#define ATH12K_MIN_5GHZ_FREQ 4150
-#define ATH12K_MIN_6GHZ_FREQ 5925
-#define ATH12K_MAX_6GHZ_FREQ 7115
+#define ATH12K_HALF_20MHZ_BW   10
+#define ATH12K_2GHZ_MIN_CENTER 2412
+#define ATH12K_2GHZ_MAX_CENTER 2484
+#define ATH12K_5GHZ_MIN_CENTER 4900
+#define ATH12K_5GHZ_MAX_CENTER 5920
+#define ATH12K_6GHZ_MIN_CENTER 5935
+#define ATH12K_6GHZ_MAX_CENTER 7115
+#define ATH12K_MIN_2GHZ_FREQ   (ATH12K_2GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW - 1)
+#define ATH12K_MAX_2GHZ_FREQ   (ATH12K_2GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW + 1)
+#define ATH12K_MIN_5GHZ_FREQ   (ATH12K_5GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW)
+#define ATH12K_MAX_5GHZ_FREQ   (ATH12K_5GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW)
+#define ATH12K_MIN_6GHZ_FREQ   (ATH12K_6GHZ_MIN_CENTER - ATH12K_HALF_20MHZ_BW)
+#define ATH12K_MAX_6GHZ_FREQ   (ATH12K_6GHZ_MAX_CENTER + ATH12K_HALF_20MHZ_BW)
 #define ATH12K_NUM_CHANS 101
 #define ATH12K_MAX_5GHZ_CHAN 173
 
index c613f8408c848d98c6f53fccc4fe66ab80b1394e..bb227c7e27484e40fbdea1ef22a3cc28b860d2ef 100644 (file)
@@ -1700,18 +1700,128 @@ static void ath12k_dp_mon_rx_msdus_set_payload(struct ath12k *ar,
        skb_pull(head_msdu, rx_pkt_offset + l2_hdr_offset);
 }
 
+static void
+ath12k_dp_mon_fill_rx_stats_info(struct ath12k *ar,
+                                struct hal_rx_mon_ppdu_info *ppdu_info,
+                                struct ieee80211_rx_status *rx_status)
+{
+       u32 center_freq = ppdu_info->freq;
+
+       rx_status->freq = center_freq;
+       rx_status->bw = ath12k_mac_bw_to_mac80211_bw(ppdu_info->bw);
+       rx_status->nss = ppdu_info->nss;
+       rx_status->rate_idx = 0;
+       rx_status->encoding = RX_ENC_LEGACY;
+       rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
+
+       if (center_freq >= ATH12K_MIN_6GHZ_FREQ &&
+           center_freq <= ATH12K_MAX_6GHZ_FREQ) {
+               rx_status->band = NL80211_BAND_6GHZ;
+       } else if (center_freq >= ATH12K_MIN_2GHZ_FREQ &&
+                  center_freq <= ATH12K_MAX_2GHZ_FREQ) {
+               rx_status->band = NL80211_BAND_2GHZ;
+       } else if (center_freq >= ATH12K_MIN_5GHZ_FREQ &&
+                  center_freq <= ATH12K_MAX_5GHZ_FREQ) {
+               rx_status->band = NL80211_BAND_5GHZ;
+       } else {
+               rx_status->band = NUM_NL80211_BANDS;
+       }
+}
+
+static void
+ath12k_dp_mon_fill_rx_rate(struct ath12k *ar,
+                          struct hal_rx_mon_ppdu_info *ppdu_info,
+                          struct ieee80211_rx_status *rx_status)
+{
+       struct ieee80211_supported_band *sband;
+       enum rx_msdu_start_pkt_type pkt_type;
+       u8 rate_mcs, nss, sgi;
+       bool is_cck;
+
+       pkt_type = ppdu_info->preamble_type;
+       rate_mcs = ppdu_info->rate;
+       nss = ppdu_info->nss;
+       sgi = ppdu_info->gi;
+
+       switch (pkt_type) {
+       case RX_MSDU_START_PKT_TYPE_11A:
+       case RX_MSDU_START_PKT_TYPE_11B:
+               is_cck = (pkt_type == RX_MSDU_START_PKT_TYPE_11B);
+               if (rx_status->band < NUM_NL80211_BANDS) {
+                       sband = &ar->mac.sbands[rx_status->band];
+                       rx_status->rate_idx = ath12k_mac_hw_rate_to_idx(sband, rate_mcs,
+                                                                       is_cck);
+               }
+               break;
+       case RX_MSDU_START_PKT_TYPE_11N:
+               rx_status->encoding = RX_ENC_HT;
+               if (rate_mcs > ATH12K_HT_MCS_MAX) {
+                       ath12k_warn(ar->ab,
+                                   "Received with invalid mcs in HT mode %d\n",
+                                    rate_mcs);
+                       break;
+               }
+               rx_status->rate_idx = rate_mcs + (8 * (nss - 1));
+               if (sgi)
+                       rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
+               break;
+       case RX_MSDU_START_PKT_TYPE_11AC:
+               rx_status->encoding = RX_ENC_VHT;
+               rx_status->rate_idx = rate_mcs;
+               if (rate_mcs > ATH12K_VHT_MCS_MAX) {
+                       ath12k_warn(ar->ab,
+                                   "Received with invalid mcs in VHT mode %d\n",
+                                    rate_mcs);
+                       break;
+               }
+               if (sgi)
+                       rx_status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
+               break;
+       case RX_MSDU_START_PKT_TYPE_11AX:
+               rx_status->rate_idx = rate_mcs;
+               if (rate_mcs > ATH12K_HE_MCS_MAX) {
+                       ath12k_warn(ar->ab,
+                                   "Received with invalid mcs in HE mode %d\n",
+                                   rate_mcs);
+                       break;
+               }
+               rx_status->encoding = RX_ENC_HE;
+               rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
+               break;
+       case RX_MSDU_START_PKT_TYPE_11BE:
+               rx_status->rate_idx = rate_mcs;
+               if (rate_mcs > ATH12K_EHT_MCS_MAX) {
+                       ath12k_warn(ar->ab,
+                                   "Received with invalid mcs in EHT mode %d\n",
+                                   rate_mcs);
+                       break;
+               }
+               rx_status->encoding = RX_ENC_EHT;
+               rx_status->he_gi = ath12k_he_gi_to_nl80211_he_gi(sgi);
+               break;
+       default:
+               ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
+                          "monitor receives invalid preamble type %d",
+                           pkt_type);
+               break;
+       }
+}
+
 static struct sk_buff *
 ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
                            struct dp_mon_mpdu *mon_mpdu,
+                           struct hal_rx_mon_ppdu_info *ppdu_info,
                            struct ieee80211_rx_status *rxs)
 {
        struct ath12k_base *ab = ar->ab;
        struct sk_buff *msdu, *mpdu_buf, *prev_buf, *head_frag_list;
        struct sk_buff *head_msdu, *tail_msdu;
-       struct hal_rx_desc *rx_desc, *tail_rx_desc;
+       struct hal_rx_desc *rx_desc;
        u8 *hdr_desc, *dest, decap_format = mon_mpdu->decap_format;
        struct ieee80211_hdr_3addr *wh;
+       struct ieee80211_channel *channel;
        u32 frag_list_sum_len = 0;
+       u8 channel_num = ppdu_info->chan_num;
 
        mpdu_buf = NULL;
        head_msdu = mon_mpdu->head;
@@ -1720,9 +1830,29 @@ ath12k_dp_mon_rx_merg_msdus(struct ath12k *ar,
        if (!head_msdu)
                goto err_merge_fail;
 
-       tail_rx_desc = (struct hal_rx_desc *)tail_msdu->data;
+       ath12k_dp_mon_fill_rx_stats_info(ar, ppdu_info, rxs);
+
+       if (unlikely(rxs->band == NUM_NL80211_BANDS ||
+                    !ath12k_ar_to_hw(ar)->wiphy->bands[rxs->band])) {
+               ath12k_dbg(ar->ab, ATH12K_DBG_DATA,
+                          "sband is NULL for status band %d channel_num %d center_freq %d pdev_id %d\n",
+                          rxs->band, channel_num, ppdu_info->freq, ar->pdev_idx);
+
+               spin_lock_bh(&ar->data_lock);
+               channel = ar->rx_channel;
+               if (channel) {
+                       rxs->band = channel->band;
+                       channel_num =
+                               ieee80211_frequency_to_channel(channel->center_freq);
+               }
+               spin_unlock_bh(&ar->data_lock);
+       }
+
+       if (rxs->band < NUM_NL80211_BANDS)
+               rxs->freq = ieee80211_channel_to_frequency(channel_num,
+                                                          rxs->band);
 
-       ath12k_dp_rx_h_ppdu(ar, tail_rx_desc, rxs);
+       ath12k_dp_mon_fill_rx_rate(ar, ppdu_info, rxs);
 
        if (decap_format == DP_RX_DECAP_TYPE_RAW) {
                ath12k_dp_mon_rx_msdus_set_payload(ar, head_msdu, tail_msdu);
@@ -2040,7 +2170,7 @@ static int ath12k_dp_mon_rx_deliver(struct ath12k *ar,
        struct ieee80211_rx_status *rxs = &dp->rx_status;
        u8 decap = DP_RX_DECAP_TYPE_RAW;
 
-       mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mon_mpdu, rxs);
+       mon_skb = ath12k_dp_mon_rx_merg_msdus(ar, mon_mpdu, ppduinfo, rxs);
        if (!mon_skb)
                goto mon_deliver_fail;
 
index 6f10e4222ba6e6d6c1ea78788b57f7bfbdb7ebea..c753eb2a03ad24f809eac79652fc9af65937abaf 100644 (file)
@@ -509,7 +509,10 @@ struct hal_rx_mpdu_start {
 
 struct hal_rx_msdu_end {
        __le32 info0;
-       __le32 rsvd0[18];
+       __le32 rsvd0[9];
+       __le16 info00;
+       __le16 info01;
+       __le32 rsvd00[8];
        __le32 info1;
        __le32 rsvd1[10];
        __le32 info2;