From 3a74003841f04a5daac160e26c51d81c1dd99fd7 Mon Sep 17 00:00:00 2001
From: Anilkumar Kolli <akolli@codeaurora.org>
Date: Mon, 25 Jan 2021 19:54:00 +0530
Subject: ath11k: Fix rate in monior mode radiotap header

Packet Rate info is not part of msdu in mon_dst_ring,
rate is updated from monitor status ring.

Signed-off-by: Anilkumar Kolli <akolli@codeaurora.org>
---
 drivers/net/wireless/ath/ath11k/dp_rx.c  | 20 ++++++++++++++++----
 drivers/net/wireless/ath/ath11k/hal_rx.c |  1 +
 2 files changed, 17 insertions(+), 4 deletions(-)

--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
@@ -5704,31 +5704,42 @@ ath11k_dp_rx_update_radiotap_he_mu(struc
 	rtap_buf[rtap_len] = rx_status->he_RU[3];
 }
 
-static void ath11k_update_radiotap(struct hal_rx_mon_ppdu_info *ppduinfo,
-				    struct sk_buff *mon_skb,
-				    struct ieee80211_rx_status *rxs)
+static void ath11k_update_radiotap(struct ath11k *ar,
+				   struct hal_rx_mon_ppdu_info *ppduinfo,
+				   struct sk_buff *mon_skb,
+				   struct ieee80211_rx_status *rxs)
 {
+	struct ieee80211_supported_band *sband;
 	u8 *ptr = NULL;
 
+	rxs->flag |= RX_FLAG_MACTIME_START;
+	rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
+	rxs->nss = ppduinfo->nss + 1;
+
 	if (ppduinfo->he_mu_flags) {
 		rxs->flag |= RX_FLAG_RADIOTAP_HE_MU;
 		rxs->encoding = RX_ENC_HE;
 		ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he_mu));
 		ath11k_dp_rx_update_radiotap_he_mu(ppduinfo, ptr);
-	}
-	if (ppduinfo->he_flags) {
+	} else if (ppduinfo->he_flags) {
 		rxs->flag |= RX_FLAG_RADIOTAP_HE;
 		rxs->encoding = RX_ENC_HE;
 		ptr = skb_push(mon_skb, sizeof(struct ieee80211_radiotap_he));
 		ath11k_dp_rx_update_radiotap_he(ppduinfo, ptr);
+		rxs->rate_idx = ppduinfo->rate;
+	} else if (ppduinfo->vht_flags) {
+		rxs->encoding = RX_ENC_VHT;
+		rxs->rate_idx = ppduinfo->rate;
+	} else if (ppduinfo->ht_flags) {
+		rxs->encoding = RX_ENC_HT;
+		rxs->rate_idx = ppduinfo->rate;
+	} else {
+		rxs->encoding = RX_ENC_LEGACY;
+		sband = &ar->mac.sbands[rxs->band];
+		rxs->rate_idx = ath11k_mac_hw_rate_to_idx(sband, ppduinfo->rate,
+							  ppduinfo->cck_flag);
 	}
 
-	rxs->flag |= RX_FLAG_MACTIME_START;
-	rxs->signal = ppduinfo->rssi_comb + ATH11K_DEFAULT_NOISE_FLOOR;
-
-	if (ppduinfo->nss)
-		rxs->nss = ppduinfo->nss;
-
 	rxs->mactime = ppduinfo->tsft;
 }
 
@@ -5763,7 +5774,7 @@ static int ath11k_dp_rx_mon_deliver(stru
 			rxs->flag |= RX_FLAG_ALLOW_SAME_PN;
 		}
 		rxs->flag |= RX_FLAG_ONLY_MONITOR;
-		ath11k_update_radiotap(ppduinfo, mon_skb, rxs);
+		ath11k_update_radiotap(ar, ppduinfo, mon_skb, rxs);
 		ath11k_dp_rx_deliver_msdu(ar, napi, mon_skb, rxs);
 		mon_skb = skb_next;
 	} while (mon_skb);
--- a/drivers/net/wireless/ath/ath11k/hal_rx.c
+++ b/drivers/net/wireless/ath/ath11k/hal_rx.c
@@ -1032,7 +1032,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
 					       info1);
 		ppdu_info->ldpc = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_FEC_CODING, info1);
 		ppdu_info->gi = FIELD_GET(HAL_RX_HT_SIG_INFO_INFO1_GI, info1);
-		ppdu_info->nss = (ppdu_info->mcs >> 3) + 1;
+		ppdu_info->nss = (ppdu_info->mcs >> 3);
 		ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
 		break;
 	}
@@ -1064,6 +1064,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
 			rate = HAL_RX_LEGACY_RATE_INVALID;
 		}
 		ppdu_info->rate = rate;
+		ppdu_info->cck_flag = 1;
 		ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
 		break;
 	}
@@ -1137,7 +1138,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
 		if (ppdu_info->is_stbc && nsts > 0)
 			nsts = ((nsts + 1) >> 1) - 1;
 
-		ppdu_info->nss = (nsts & VHT_SIG_SU_NSS_MASK) + 1;
+		ppdu_info->nss = (nsts & VHT_SIG_SU_NSS_MASK);
 		ppdu_info->bw = FIELD_GET(HAL_RX_VHT_SIG_A_INFO_INFO0_BW,
 					  info0);
 		ppdu_info->beamformed = info1 &
@@ -1160,7 +1161,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
 	case HAL_PHYRX_HE_SIG_A_SU: {
 		struct hal_rx_he_sig_a_su_info *he_sig_a =
 			(struct hal_rx_he_sig_a_su_info *)tlv_data;
-		u32 nsts, cp_ltf, dcm, value;
+		u32 cp_ltf, dcm, value;
 		ppdu_info->he_flags = 1;
 
 		info0 = __le32_to_cpu(he_sig_a->info0);
@@ -1280,7 +1281,6 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
 		/* data6 */
 		value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);
 		value++;
-		ppdu_info->nss = value;
 		ppdu_info->he_data6 = value;
 		value = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO1_DOPPLER_IND, info1);
 		value = value << HE_DOPPLER_SHIFT;
@@ -1303,9 +1303,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
 		dcm = info0 & HAL_RX_HE_SIG_A_SU_INFO_INFO0_DCM;
 		cp_ltf = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_CP_LTF_SIZE,
 				   info0);
-		nsts = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);
-
-		ppdu_info->nss = nsts + 1;
+		ppdu_info->nss = FIELD_GET(HAL_RX_HE_SIG_A_SU_INFO_INFO0_NSTS, info0);
 		ppdu_info->dcm = dcm;
 		ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_SU;
 		break;
@@ -1482,7 +1480,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
 
 		ppdu_info->nss =
 			FIELD_GET(HAL_RX_HE_SIG_B2_MU_INFO_INFO0_STA_NSTS,
-				  info0) + 1;
+				  info0);
 		break;
 	}
 	case HAL_PHYRX_HE_SIG_B2_OFDMA: {
@@ -1520,7 +1518,7 @@ ath11k_hal_rx_parse_mon_status_tlv(struc
 
 		ppdu_info->nss =
 			FIELD_GET(HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_NSTS,
-				  info0) + 1;
+				  info0);
 		ppdu_info->beamformed =
 			info0 & HAL_RX_HE_SIG_B2_OFDMA_INFO_INFO0_STA_TXBF;
 		ppdu_info->reception_type = HAL_RX_RECEPTION_TYPE_MU_OFDMA;
