Răsfoiți Sursa

qcacmn: Add 6GHz Monitor Mode Support

Add monitor mode support to capture packets over 6GHz frequencies by
getting capture frequency from pdev.

Change freq type to qdf_freq_t.

Change-Id: I7b6edc43e254dc98a3c2939c369874bec9d16ddd
CRs-Fixed: 2568970
Saket Jha 5 ani în urmă
părinte
comite
540da9a56c

+ 22 - 3
dp/inc/cdp_txrx_mon.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2016-2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -150,8 +150,9 @@ static inline QDF_STATUS cdp_reset_monitor_mode
 	return soc->ops->mon_ops->txrx_reset_monitor_mode(pdev);
 }
 
-static inline void cdp_record_monitor_chan_num
-(ol_txrx_soc_handle soc, struct cdp_pdev *pdev, int chan_num)
+static inline void
+cdp_record_monitor_chan_num(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
+			    int chan_num)
 {
 	if (!soc || !soc->ops) {
 		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
@@ -167,6 +168,24 @@ static inline void cdp_record_monitor_chan_num
 	soc->ops->mon_ops->txrx_monitor_record_channel(pdev, chan_num);
 }
 
+static inline void
+cdp_record_monitor_chan_freq(ol_txrx_soc_handle soc, struct cdp_pdev *pdev,
+			     qdf_freq_t chan_freq)
+{
+	if (!soc || !soc->ops) {
+		QDF_TRACE(QDF_MODULE_ID_CDP, QDF_TRACE_LEVEL_DEBUG,
+			  "%s: Invalid Instance", __func__);
+		QDF_BUG(0);
+		return;
+	}
+
+	if (!soc->ops->mon_ops ||
+	    !soc->ops->mon_ops->txrx_monitor_record_frequency)
+		return;
+
+	soc->ops->mon_ops->txrx_monitor_record_frequency(pdev, chan_freq);
+}
+
 /**
  * cdp_deliver_tx_mgmt() - Deliver mgmt frame for tx capture
  * @soc: Datapath SOC handle

+ 4 - 1
dp/inc/cdp_txrx_ops.h

@@ -792,7 +792,10 @@ struct cdp_mon_ops {
 		(struct cdp_pdev *pdev, struct cdp_monitor_filter *filter_val);
 
 	void (*txrx_monitor_record_channel)
-		(struct cdp_pdev *, int val);
+		(struct cdp_pdev *pdev, int val);
+
+	void (*txrx_monitor_record_frequency)
+		(struct cdp_pdev *pdev, qdf_freq_t val);
 
 	void (*txrx_deliver_tx_mgmt)
 		(struct cdp_pdev *pdev, qdf_nbuf_t nbuf);

+ 16 - 0
dp/wifi3.0/dp_main.c

@@ -7016,6 +7016,21 @@ void dp_pdev_set_monitor_channel(struct cdp_pdev *pdev_handle, int chan_num)
 	pdev->mon_chan_num = chan_num;
 }
 
+/**
+ * dp_pdev_set_monitor_frequency() - set monitor frequency in pdev
+ * @pdev_handle: Datapath PDEV handle
+ * @chan_freq: Channel frequency
+ *
+ * Return: None
+ */
+static
+void dp_pdev_set_monitor_frequency(struct cdp_pdev *pdev_handle, qdf_freq_t chan_freq)
+{
+	struct dp_pdev *pdev = (struct dp_pdev *)pdev_handle;
+
+	pdev->mon_chan_freq = chan_freq;
+}
+
 /**
  * dp_deliver_tx_mgmt() - Deliver mgmt frame for tx capture
  * @pdev_handle: Datapath PDEV handle
@@ -9817,6 +9832,7 @@ static struct cdp_mon_ops dp_ops_mon = {
 	/* Added support for HK advance filter */
 	.txrx_set_advance_monitor_filter = dp_pdev_set_advance_monitor_filter,
 	.txrx_monitor_record_channel = dp_pdev_set_monitor_channel,
+	.txrx_monitor_record_frequency = dp_pdev_set_monitor_frequency,
 	.txrx_deliver_tx_mgmt = dp_deliver_tx_mgmt,
 	.txrx_set_bsscolor = dp_mon_set_bsscolor,
 };

+ 1 - 7
dp/wifi3.0/dp_rx_mon_dest.c

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -961,12 +961,6 @@ QDF_STATUS dp_rx_mon_deliver(struct dp_soc *soc, uint32_t mac_id,
 		pdev->ppdu_info.rx_status.device_id = soc->device_id;
 		pdev->ppdu_info.rx_status.chan_noise_floor =
 			pdev->chan_noise_floor;
-		/*
-		 * if chan_num is not fetched correctly from ppdu RX TLV,
-		 * get it from pdev saved.
-		 */
-		if (pdev->ppdu_info.rx_status.chan_num == 0)
-			pdev->ppdu_info.rx_status.chan_num = pdev->mon_chan_num;
 
 		if (!qdf_nbuf_update_radiotap(&pdev->ppdu_info.rx_status,
 					      mon_mpdu,

+ 16 - 0
dp/wifi3.0/dp_rx_mon_status.c

@@ -1482,6 +1482,22 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id,
 				dp_rx_handle_cfr(soc, pdev, ppdu_info);
 
 			pdev->mon_ppdu_status = DP_PPDU_STATUS_DONE;
+
+			/*
+			* if chan_num is not fetched correctly from ppdu RX TLV,
+			 * get it from pdev saved.
+			 */
+			if (qdf_unlikely(pdev->ppdu_info.rx_status.chan_num == 0))
+				pdev->ppdu_info.rx_status.chan_num = pdev->mon_chan_num;
+			/*
+			 * if chan_freq is not fetched correctly from ppdu RX TLV,
+			 * get it from pdev saved.
+			 */
+			if (qdf_unlikely(pdev->ppdu_info.rx_status.chan_freq == 0)) {
+				pdev->ppdu_info.rx_status.chan_freq =
+					pdev->mon_chan_freq;
+			}
+
 			dp_rx_mon_dest_process(soc, mac_id, quota);
 			pdev->mon_ppdu_status = DP_PPDU_STATUS_START;
 		}

+ 3 - 0
dp/wifi3.0/dp_types.h

@@ -1494,6 +1494,9 @@ struct dp_pdev {
 	/* Monitor mode operation channel */
 	int mon_chan_num;
 
+	/* Monitor mode operation frequency */
+	qdf_freq_t mon_chan_freq;
+
 	/* monitor mode lock */
 	qdf_spinlock_t mon_lock;
 

+ 5 - 2
hal/wifi3.0/hal_generic_api.h

@@ -402,8 +402,11 @@ hal_rx_status_get_tlv_info_generic(void *rx_tlv_hdr, void *ppduinfo,
 				PHY_PPDU_ID);
 		/* channel number is set in PHY meta data */
 		ppdu_info->rx_status.chan_num =
-			HAL_RX_GET(rx_tlv, RX_PPDU_START_1,
-				SW_PHY_META_DATA);
+			(HAL_RX_GET(rx_tlv, RX_PPDU_START_1,
+				SW_PHY_META_DATA) & 0x0000FFFF);
+		ppdu_info->rx_status.chan_freq =
+			(HAL_RX_GET(rx_tlv, RX_PPDU_START_1,
+				SW_PHY_META_DATA) & 0xFFFF0000)>>16;
 		ppdu_info->com_info.ppdu_timestamp =
 			HAL_RX_GET(rx_tlv, RX_PPDU_START_2,
 				PPDU_START_TIMESTAMP);

+ 2 - 2
qdf/inc/qdf_nbuf.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
  *
  * Permission to use, copy, modify, and/or distribute this software for
  * any purpose with or without fee is hereby granted, provided that the
@@ -246,7 +246,7 @@ struct mon_rx_status {
 	uint64_t tsft;
 	uint32_t ppdu_timestamp;
 	uint32_t preamble_type;
-	uint16_t chan_freq;
+	qdf_freq_t chan_freq;
 	uint16_t chan_num;
 	uint16_t chan_flags;
 	uint16_t ht_flags;

+ 2 - 30
qdf/linux/src/qdf_nbuf.c

@@ -84,6 +84,7 @@
 #define CHANNEL_FREQ_2512 2512
 #define CHANNEL_FREQ_5000 5000
 #define CHANNEL_FREQ_4000 4000
+#define CHANNEL_FREQ_5150 5150
 #define FREQ_MULTIPLIER_CONST_5MHZ 5
 #define FREQ_MULTIPLIER_CONST_20MHZ 20
 #define RADIOTAP_5G_SPECTRUM_CHANNEL 0x0100
@@ -4089,34 +4090,6 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status,
 #define IEEE80211_RADIOTAP_HE_MU_OTHER	25
 uint8_t ATH_OUI[] = {0x00, 0x03, 0x7f}; /* Atheros OUI */
 
-/**
- * radiotap_num_to_freq() - Get frequency from chan number
- * @chan_num - Input channel number
- *
- * Return - Channel frequency in Mhz
- */
-static uint16_t radiotap_num_to_freq (uint16_t chan_num)
-{
-	if (chan_num == CHANNEL_NUM_14)
-		return CHANNEL_FREQ_2484;
-	if (chan_num < CHANNEL_NUM_14)
-		return CHANNEL_FREQ_2407 +
-			(chan_num * FREQ_MULTIPLIER_CONST_5MHZ);
-
-	if (chan_num < CHANNEL_NUM_27)
-		return CHANNEL_FREQ_2512 +
-			((chan_num - CHANNEL_NUM_15) *
-			 FREQ_MULTIPLIER_CONST_20MHZ);
-
-	if (chan_num > CHANNEL_NUM_182 &&
-			chan_num < CHANNEL_NUM_197)
-		return ((chan_num * FREQ_MULTIPLIER_CONST_5MHZ) +
-			CHANNEL_FREQ_4000);
-
-	return CHANNEL_FREQ_5000 +
-		(chan_num * FREQ_MULTIPLIER_CONST_5MHZ);
-}
-
 /**
  * qdf_nbuf_update_radiotap_ampdu_flags() - Update radiotap header ampdu flags
  * @rx_status: Pointer to rx_status.
@@ -4195,11 +4168,10 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status,
 
 	/* IEEE80211_RADIOTAP_CHANNEL 2 x __le16   MHz, bitmap */
 	rthdr->it_present |= (1 << IEEE80211_RADIOTAP_CHANNEL);
-	rx_status->chan_freq = radiotap_num_to_freq(rx_status->chan_num);
 	put_unaligned_le16(rx_status->chan_freq, &rtap_buf[rtap_len]);
 	rtap_len += 2;
 	/* Channel flags. */
-	if (rx_status->chan_num > CHANNEL_NUM_35)
+	if (rx_status->chan_freq > CHANNEL_FREQ_5150)
 		rx_status->chan_flags = RADIOTAP_5G_SPECTRUM_CHANNEL;
 	else
 		rx_status->chan_flags = RADIOTAP_2G_SPECTRUM_CHANNEL;