Explorar o código

qcacmn: Enable 165 MHz Spectral scan

QCN9000 has the capability to Spectral scan in 165 MHz/
restricted 80p80 mode of operation. Host filters the FFT bins
corresponding to the additional 5 MHz and exports to the
user space via SMAP message.

CRs-Fixed: 2630960
Change-Id: I54ec36968cb0c8d5a68ff39029004b08936cb91e
Edayilliam Jayadev %!s(int64=5) %!d(string=hai) anos
pai
achega
01106d6458

+ 58 - 0
spectral/dispatcher/inc/spectral_ioctl.h

@@ -86,6 +86,57 @@ enum spectral_params {
 	SPECTRAL_PARAM_MAX,
 };
 
+/**
+ * enum spectral_report_mode: Spectral report mode
+ * @SPECTRAL_REPORT_MODE_0: No FFT report (only spectral scan summary report)
+ * @SPECTRAL_REPORT_MODE_1: FFT report header + spectral scan summary report
+ * @SPECTRAL_REPORT_MODE_2: FFt report header + in-band bins per
+ *                          FFT (half of the number of FFT bins), where the
+ *                          FFT input is sampled at two times the channel
+ *                          bandwidth + spectral scan summary report
+ * @SPECTRAL_REPORT_MODE_3: FFT report header + all bins per FFT, where the FFT
+ *                          input is sampled at two times the channel bandwidth
+ *                          + spectral scan summary report
+ * @SPECTRAL_REPORT_MODE_MAX: Max number of report modes
+ */
+enum spectral_report_mode {
+	SPECTRAL_REPORT_MODE_0,
+	SPECTRAL_REPORT_MODE_1,
+	SPECTRAL_REPORT_MODE_2,
+	SPECTRAL_REPORT_MODE_3,
+	SPECTRAL_REPORT_MODE_MAX,
+};
+
+/**
+ * enum spectral_fft_size : FFT size values
+ * @SPECTRAL_FFT_SIZE_INVALID: Invalid FFT size
+ * @SPECTRAL_FFT_SIZE_1: FFT size 1
+ * @SPECTRAL_FFT_SIZE_2: FFT size 2
+ * @SPECTRAL_FFT_SIZE_3: FFT size 3
+ * @SPECTRAL_FFT_SIZE_4: FFT size 4
+ * @SPECTRAL_FFT_SIZE_5: FFT size 5
+ * @SPECTRAL_FFT_SIZE_6: FFT size 6
+ * @SPECTRAL_FFT_SIZE_7: FFT size 7
+ * @SPECTRAL_FFT_SIZE_8: FFT size 8
+ * @SPECTRAL_FFT_SIZE_9: FFT size 9
+ * @SPECTRAL_FFT_SIZE_10: FFT size 10
+ * @SPECTRAL_FFT_SIZE_MAX: Max number of FFT size
+ */
+enum spectral_fft_size {
+	SPECTRAL_FFT_SIZE_INVALID,
+	SPECTRAL_FFT_SIZE_1,
+	SPECTRAL_FFT_SIZE_2,
+	SPECTRAL_FFT_SIZE_3,
+	SPECTRAL_FFT_SIZE_4,
+	SPECTRAL_FFT_SIZE_5,
+	SPECTRAL_FFT_SIZE_6,
+	SPECTRAL_FFT_SIZE_7,
+	SPECTRAL_FFT_SIZE_8,
+	SPECTRAL_FFT_SIZE_9,
+	SPECTRAL_FFT_SIZE_10,
+	SPECTRAL_FFT_SIZE_MAX,
+};
+
 /**
  * enum spectral_scan_mode - Spectral scan mode
  * @SPECTRAL_SCAN_MODE_NORMAL: Normal mode
@@ -257,6 +308,7 @@ struct spectral_caps {
 #define MAX_NUM_BINS                  (1024)
 #define MAX_NUM_BINS_PRI80            (1024)
 #define MAX_NUM_BINS_SEC80            (520)
+#define MAX_NUM_BINS_5MHZ             (32)
 /* 5 categories x (lower + upper) bands */
 #define MAX_INTERF                   10
 
@@ -384,6 +436,10 @@ struct spectral_classifier_params {
  *                            via direct DMA framework.
  * @target_reset_count:       Indicates the number of times target went through
  *                            reset routine after spectral was enabled.
+ * @bin_pwr_count_5mhz:       Indicates the number of FFT bins in the extra
+ *                            5 MHz for 165 MHz/ Restricted 80p80 mode
+ * @bin_pwr_5mhz:             Contains FFT magnitudes corresponding to the extra
+ *                            5 MHz in 165 MHz/ Restricted 80p80 mode
  */
 struct spectral_samp_data {
 	int16_t spectral_data_len;
@@ -450,6 +506,8 @@ struct spectral_samp_data {
 	uint32_t reset_delay;
 	uint32_t target_reset_count;
 	uint32_t agile_ch_width;
+	uint16_t bin_pwr_count_5mhz;
+	uint8_t bin_pwr_5mhz[MAX_NUM_BINS_5MHZ];
 } __packed;
 
 /**

+ 92 - 0
target_if/spectral/target_if_spectral.c

@@ -2184,6 +2184,98 @@ target_if_spectral_report_params_init(
 		rparams->detid_mode_table[SPECTRAL_DETECTOR_ID_2] =
 						SPECTRAL_SCAN_MODE_AGILE;
 	}
+
+	if (target_type == TARGET_TYPE_QCN9000) {
+		struct spectral_fft_bin_markers_165mhz *marker;
+
+		marker = rparams->marker[SPECTRAL_REPORT_MODE_2];
+
+		marker[SPECTRAL_FFT_SIZE_5].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_5].num_pri80 = 8;
+		marker[SPECTRAL_FFT_SIZE_5].start_5mhz = 8;
+		marker[SPECTRAL_FFT_SIZE_5].num_5mhz = 1;
+		marker[SPECTRAL_FFT_SIZE_5].start_sec80 = 9;
+		marker[SPECTRAL_FFT_SIZE_5].num_sec80 = 8;
+
+		marker[SPECTRAL_FFT_SIZE_6].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_6].num_pri80 = 16;
+		marker[SPECTRAL_FFT_SIZE_6].start_5mhz = 16;
+		marker[SPECTRAL_FFT_SIZE_6].num_5mhz = 1;
+		marker[SPECTRAL_FFT_SIZE_6].start_sec80 = 17;
+		marker[SPECTRAL_FFT_SIZE_6].num_sec80 = 16;
+
+		marker[SPECTRAL_FFT_SIZE_7].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_7].num_pri80 = 32;
+		marker[SPECTRAL_FFT_SIZE_7].start_5mhz = 32;
+		marker[SPECTRAL_FFT_SIZE_7].num_5mhz = 2;
+		marker[SPECTRAL_FFT_SIZE_7].start_sec80 = 34;
+		marker[SPECTRAL_FFT_SIZE_7].num_sec80 = 32;
+
+		marker[SPECTRAL_FFT_SIZE_8].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_8].num_pri80 = 64;
+		marker[SPECTRAL_FFT_SIZE_8].start_5mhz = 64;
+		marker[SPECTRAL_FFT_SIZE_8].num_5mhz = 4;
+		marker[SPECTRAL_FFT_SIZE_8].start_sec80 = 68;
+		marker[SPECTRAL_FFT_SIZE_8].num_sec80 = 64;
+
+		marker[SPECTRAL_FFT_SIZE_9].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_9].num_pri80 = 128;
+		marker[SPECTRAL_FFT_SIZE_9].start_5mhz = 128;
+		marker[SPECTRAL_FFT_SIZE_9].num_5mhz = 8;
+		marker[SPECTRAL_FFT_SIZE_9].start_sec80 = 136;
+		marker[SPECTRAL_FFT_SIZE_9].num_sec80 = 128;
+
+		marker[SPECTRAL_FFT_SIZE_10].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_10].num_pri80 = 256;
+		marker[SPECTRAL_FFT_SIZE_10].start_5mhz = 256;
+		marker[SPECTRAL_FFT_SIZE_10].num_5mhz = 16;
+		marker[SPECTRAL_FFT_SIZE_10].start_sec80 = 272;
+		marker[SPECTRAL_FFT_SIZE_10].num_sec80 = 256;
+
+		marker = rparams->marker[SPECTRAL_REPORT_MODE_3];
+
+		marker[SPECTRAL_FFT_SIZE_5].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_5].num_pri80 = 16;
+		marker[SPECTRAL_FFT_SIZE_5].start_5mhz = 16;
+		marker[SPECTRAL_FFT_SIZE_5].num_5mhz = 1;
+		marker[SPECTRAL_FFT_SIZE_5].start_sec80 = 17;
+		marker[SPECTRAL_FFT_SIZE_5].num_sec80 = 15;
+
+		marker[SPECTRAL_FFT_SIZE_6].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_6].num_pri80 = 32;
+		marker[SPECTRAL_FFT_SIZE_6].start_5mhz = 32;
+		marker[SPECTRAL_FFT_SIZE_6].num_5mhz = 1;
+		marker[SPECTRAL_FFT_SIZE_6].start_sec80 = 33;
+		marker[SPECTRAL_FFT_SIZE_6].num_sec80 = 31;
+
+		marker[SPECTRAL_FFT_SIZE_7].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_7].num_pri80 = 64;
+		marker[SPECTRAL_FFT_SIZE_7].start_5mhz = 64;
+		marker[SPECTRAL_FFT_SIZE_7].num_5mhz = 2;
+		marker[SPECTRAL_FFT_SIZE_7].start_sec80 = 66;
+		marker[SPECTRAL_FFT_SIZE_7].num_sec80 = 62;
+
+		marker[SPECTRAL_FFT_SIZE_8].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_8].num_pri80 = 128;
+		marker[SPECTRAL_FFT_SIZE_8].start_5mhz = 128;
+		marker[SPECTRAL_FFT_SIZE_8].num_5mhz = 4;
+		marker[SPECTRAL_FFT_SIZE_8].start_sec80 = 132;
+		marker[SPECTRAL_FFT_SIZE_8].num_sec80 = 124;
+
+		marker[SPECTRAL_FFT_SIZE_9].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_9].num_pri80 = 256;
+		marker[SPECTRAL_FFT_SIZE_9].start_5mhz = 256;
+		marker[SPECTRAL_FFT_SIZE_9].num_5mhz = 8;
+		marker[SPECTRAL_FFT_SIZE_9].start_sec80 = 264;
+		marker[SPECTRAL_FFT_SIZE_9].num_sec80 = 248;
+
+		marker[SPECTRAL_FFT_SIZE_10].start_pri80 = 0;
+		marker[SPECTRAL_FFT_SIZE_10].num_pri80 = 512;
+		marker[SPECTRAL_FFT_SIZE_10].start_5mhz = 512;
+		marker[SPECTRAL_FFT_SIZE_10].num_5mhz = 16;
+		marker[SPECTRAL_FFT_SIZE_10].start_sec80 = 528;
+		marker[SPECTRAL_FFT_SIZE_10].num_sec80 = 496;
+	}
 }
 
 /**

+ 34 - 0
target_if/spectral/target_if_spectral.h

@@ -494,6 +494,31 @@ struct spectral_fft_bin_len_adj_swar {
 	enum spectral_fftbin_size_war fftbin_size_war;
 };
 
+/**
+ * struct spectral_fft_bin_markers_165mhz - Stores the start index and length of
+ * FFT bins in 165 MHz/Restricted 80p80 mode
+ * @start_pri80: Starting index of FFT bins corresponding to primary 80 MHz
+ *               in 165 MHz/Restricted 80p80 mode
+ * @num_pri80: Number of FFT bins corresponding to primary 80 MHz
+ *             in 165 MHz/Restricted 80p80 mode
+ * @start_5mhz: Starting index of FFT bins corresponding to extra 5 MHz
+ *               in 165 MHz/Restricted 80p80 mode
+ * @num_5mhz: Number of FFT bins corresponding to extra 5 MHz
+ *             in 165 MHz/Restricted 80p80 mode
+ * @start_sec80: Starting index of FFT bins corresponding to secondary 80 MHz
+ *               in 165 MHz/Restricted 80p80 mode
+ * @num_sec80: Number of FFT bins corresponding to secondary 80 MHz
+ *             in 165 MHz/Restricted 80p80 mode
+ */
+struct spectral_fft_bin_markers_165mhz {
+	size_t start_pri80;
+	size_t num_pri80;
+	size_t start_5mhz;
+	size_t num_5mhz;
+	size_t start_sec80;
+	size_t num_sec80;
+};
+
 /**
  * struct spectral_report_params - Parameters related to format of Spectral
  * report.
@@ -508,6 +533,7 @@ struct spectral_fft_bin_len_adj_swar {
  * fragmented.
  * @detid_mode_table: Detector ID to Spectral scan mode table
  * @num_spectral_detectors: Total number of Spectral detectors
+ * @marker: Describes the boundaries of pri80, 5 MHz and sec80 bins
  */
 struct spectral_report_params {
 	enum spectral_report_format_version version;
@@ -516,6 +542,8 @@ struct spectral_report_params {
 	bool fragmentation_160[SPECTRAL_SCAN_MODE_MAX];
 	enum spectral_scan_mode detid_mode_table[SPECTRAL_DETECTOR_ID_MAX];
 	uint8_t num_spectral_detectors;
+	struct spectral_fft_bin_markers_165mhz
+		marker[SPECTRAL_REPORT_MODE_MAX][SPECTRAL_FFT_SIZE_MAX];
 };
 
 /**
@@ -1068,12 +1096,16 @@ struct target_if_spectral {
  * @max_exp:  max exp
  * @peak: peak frequency (obsolete)
  * @pwr_count:  number of FFT bins (except for secondary 80 segment)
+ * @pwr_count_5mhz:  number of FFT bins in extra 5 MHz in
+ *                   165 MHz/restricted 80p80 mode
  * @pwr_count_sec80:  number of FFT bins in secondary 80 segment
  * @nb_lower: This is deprecated
  * @nb_upper: This is deprecated
  * @max_upper_index:  index of max mag in upper band
  * @max_lower_index:  index of max mag in lower band
  * @bin_pwr_data: Contains FFT magnitudes (except for secondary 80 segment)
+ * @bin_pwr_data_5mhz: Contains FFT magnitudes for the extra 5 MHz
+ *                     in 165 MHz/restricted 80p80 mode
  * @bin_pwr_data_sec80: Contains FFT magnitudes for the secondary 80 segment
  * @freq: Center frequency of primary 20MHz channel in MHz
  * @vhtop_ch_freq_seg1: VHT operation first segment center frequency in MHz
@@ -1128,12 +1160,14 @@ struct target_if_samp_msg_params {
 	uint8_t     max_exp;
 	int         peak;
 	int         pwr_count;
+	int         pwr_count_5mhz;
 	int         pwr_count_sec80;
 	int8_t      nb_lower;
 	int8_t      nb_upper;
 	uint16_t    max_lower_index;
 	uint16_t    max_upper_index;
 	uint8_t    *bin_pwr_data;
+	uint8_t    *bin_pwr_data_5mhz;
 	uint8_t    *bin_pwr_data_sec80;
 	uint16_t   freq;
 	uint16_t   vhtop_ch_freq_seg1;

+ 8 - 0
target_if/spectral/target_if_spectral_netlink.c

@@ -49,6 +49,7 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral,
 	static int samp_msg_index;
 	size_t pwr_count = 0;
 	size_t pwr_count_sec80 = 0;
+	size_t pwr_count_5mhz = 0;
 	enum spectral_msg_type msg_type;
 	QDF_STATUS ret;
 	struct spectral_fft_bin_len_adj_swar *swar = &spectral->len_adj_swar;
@@ -216,8 +217,11 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral,
 		 */
 		pwr_count_sec80 = qdf_min((size_t)params->pwr_count_sec80,
 					  sizeof(samp_data->bin_pwr_sec80));
+		pwr_count_5mhz = qdf_min((size_t)params->pwr_count_5mhz,
+					 sizeof(samp_data->bin_pwr_5mhz));
 
 		samp_data->bin_pwr_count_sec80 = pwr_count_sec80;
+		samp_data->bin_pwr_count_5mhz = pwr_count_5mhz;
 
 		bin_pwr_data = params->bin_pwr_data_sec80;
 		if (swar->fftbin_size_war ==
@@ -230,6 +234,10 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral,
 			binptr_16 = (uint16_t *)bin_pwr_data;
 			for (idx = 0; idx < pwr_count_sec80; idx++)
 				samp_data->bin_pwr_sec80[idx] = *(binptr_16++);
+
+			binptr_16 = (uint16_t *)params->bin_pwr_data_5mhz;
+			for (idx = 0; idx < pwr_count_5mhz; idx++)
+				samp_data->bin_pwr_5mhz[idx] = *(binptr_16++);
 		} else {
 			SPECTRAL_MESSAGE_COPY_CHAR_ARRAY(
 					&samp_data->bin_pwr_sec80[0],

+ 44 - 18
target_if/spectral/target_if_spectral_phyerr.c

@@ -1821,6 +1821,7 @@ target_if_consume_spectral_report_gen3(
 	enum spectral_detector_id detector_id;
 	QDF_STATUS ret;
 	enum spectral_scan_mode spectral_mode = SPECTRAL_SCAN_MODE_INVALID;
+	uint8_t *temp;
 
 	/* Process Spectral scan summary report */
 	if (target_if_verify_sig_and_tag_gen3(
@@ -1959,21 +1960,18 @@ target_if_consume_spectral_report_gen3(
 			params.agile_freq =
 				spectral->params[spectral_mode].ss_frequency;
 
-		/*
-		 * For modes upto VHT80, the noise floor is populated with
-		 * the one corresponding
-		 * to the highest enabled antenna chain
-		 */
-		/* TODO:  Fill proper values once FW provides them*/
-		params.noise_floor       =
+		params.noise_floor =
 			report->noisefloor[chn_idx_lowest_enabled];
-		params.datalen           = (fft_hdr_length * 4);
-		params.bin_pwr_data = (uint8_t *)((uint8_t *)p_fft_report +
-						   SPECTRAL_FFT_BINS_POS);
-		params.pwr_count = fft_bin_count;
+		temp = (uint8_t *)p_fft_report + SPECTRAL_FFT_BINS_POS;
 		if (is_ch_width_160_or_80p80(spectral->ch_width
 		    [spectral_mode]) && !spectral->rparams.
 		    fragmentation_160[spectral_mode]) {
+			struct wlan_objmgr_psoc *psoc;
+
+			qdf_assert_always(spectral->pdev_obj);
+			psoc = wlan_pdev_get_psoc(spectral->pdev_obj);
+			qdf_assert_always(psoc);
+
 			params.agc_total_gain_sec80 =
 				sscan_report_fields.sscan_agc_total_gain;
 			params.gainchange_sec80 =
@@ -1983,13 +1981,41 @@ target_if_consume_spectral_report_gen3(
 			params.noise_floor_sec80    =
 				report->noisefloor[chn_idx_lowest_enabled];
 			params.max_mag_sec80        = p_sfft->fft_peak_mag;
-			params.datalen_sec80        = fft_hdr_length * 4;
-			params.pwr_count = fft_bin_count / 2;
-			params.pwr_count_sec80      = fft_bin_count / 2;
-			params.bin_pwr_data_sec80   =
-				(uint8_t *)((uint8_t *)p_fft_report +
-				SPECTRAL_FFT_BINS_POS + (fft_bin_count / 2) *
-				fft_bin_size);
+			params.datalen = fft_hdr_length * 2;
+			params.datalen_sec80 = fft_hdr_length * 2;
+			if (spectral->ch_width[spectral_mode] ==
+			    CH_WIDTH_80P80MHZ && wlan_psoc_nif_fw_ext_cap_get(
+			    psoc, WLAN_SOC_RESTRICTED_80P80_SUPPORT)) {
+				struct spectral_fft_bin_markers_165mhz *marker;
+				enum spectral_report_mode rpt_mode;
+				enum spectral_fft_size fft_size;
+
+				rpt_mode = spectral->params[spectral_mode].
+					   ss_rpt_mode;
+				fft_size = spectral->params[spectral_mode].
+					   ss_fft_size;
+				marker = &spectral->rparams.marker
+					 [rpt_mode][fft_size];
+				params.bin_pwr_data = temp +
+					marker->start_pri80 * fft_bin_size;
+				params.pwr_count = marker->num_pri80;
+				params.bin_pwr_data_5mhz = temp +
+					marker->start_5mhz * fft_bin_size;
+				params.pwr_count_5mhz = marker->num_5mhz;
+				params.bin_pwr_data_sec80 = temp +
+					marker->start_sec80 * fft_bin_size;
+				params.pwr_count_sec80 = marker->num_sec80;
+			} else {
+				params.bin_pwr_data = temp;
+				params.pwr_count = fft_bin_count / 2;
+				params.pwr_count_sec80 = fft_bin_count / 2;
+				params.bin_pwr_data_sec80 = temp +
+					(fft_bin_count / 2) * fft_bin_size;
+			}
+		} else {
+			params.bin_pwr_data = temp;
+			params.pwr_count = fft_bin_count;
+			params.datalen = (fft_hdr_length * 4);
 		}
 
 		target_if_spectral_verify_ts(spectral, report->data,