Bladeren bron

qcacmn: Enable Spectral feature for Pine

1) Enable DDMA support, FFT bin length adjustment SWARs
2) Skip 16 bytes of padding added after Spectral summary report.
3) FFT report header length is 24 instead of 16 in Pine.
4) Max FFT size is changed to 10.

CRs-Fixed: 2608215
Change-Id: If32a8995f814140f5b61041031fb842d01d24c94
Edayilliam Jayadev 5 jaren geleden
bovenliggende
commit
17ecd7493a

+ 2 - 2
os_if/linux/spectral/inc/os_if_spectral_netlink.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 2017-2020 The Linux Foundation. All rights reserved.
  *
  *
  * Permission to use, copy, modify, and/or distribute this software for
@@ -36,7 +36,7 @@ void os_if_spectral_nl_data_ready(struct sk_buff *skb);
 #ifndef SPECTRAL_NETLINK
 #define SPECTRAL_NETLINK              (NETLINK_GENERIC + 1)
 #endif
-#define MAX_SPECTRAL_PAYLOAD         1500
+#define MAX_SPECTRAL_PAYLOAD         (2004)
 
 /* Init's network namespace */
 extern struct net init_net;

+ 7 - 5
spectral/dispatcher/inc/spectral_ioctl.h

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2017-2019 The Linux Foundation. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -250,8 +250,10 @@ struct spectral_caps {
 
 #define SPECTRAL_IOCTL_PARAM_NOVAL (65535)
 
-#define MAX_SPECTRAL_CHAINS          3
-#define MAX_NUM_BINS                 520
+#define MAX_SPECTRAL_CHAINS           (3)
+#define MAX_NUM_BINS                  (1024)
+#define MAX_NUM_BINS_PRI80            (1024)
+#define MAX_NUM_BINS_SEC80            (520)
 /* 5 categories x (lower + upper) bands */
 #define MAX_INTERF                   10
 
@@ -425,8 +427,8 @@ struct spectral_samp_data {
 	uint8_t lb_edge_extrabins;
 	uint8_t rb_edge_extrabins;
 	uint16_t bin_pwr_count_sec80;
-	uint8_t bin_pwr[MAX_NUM_BINS];
-	uint8_t bin_pwr_sec80[MAX_NUM_BINS];
+	uint8_t bin_pwr[MAX_NUM_BINS_PRI80];
+	uint8_t bin_pwr_sec80[MAX_NUM_BINS_SEC80];
 	struct interf_src_rsp interf_list;
 	int16_t noise_floor;
 	int16_t noise_floor_sec80;

+ 61 - 4
target_if/spectral/target_if_spectral.c

@@ -2023,7 +2023,8 @@ static void
 target_if_spectral_len_adj_swar_init(struct spectral_fft_bin_len_adj_swar *swar,
 				     uint32_t target_type)
 {
-	if (target_type == TARGET_TYPE_QCA8074V2)
+	if (target_type == TARGET_TYPE_QCA8074V2 ||
+	    target_type == TARGET_TYPE_QCN9000)
 		swar->fftbin_size_war = SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE;
 	else if (target_type == TARGET_TYPE_QCA8074 ||
 		 target_type == TARGET_TYPE_QCA6018 ||
@@ -2034,13 +2035,63 @@ target_if_spectral_len_adj_swar_init(struct spectral_fft_bin_len_adj_swar *swar,
 
 	if (target_type == TARGET_TYPE_QCA8074 ||
 	    target_type == TARGET_TYPE_QCA8074V2 ||
-	    target_type == TARGET_TYPE_QCA6018) {
+	    target_type == TARGET_TYPE_QCA6018 ||
+	    target_type == TARGET_TYPE_QCN9000) {
 		swar->inband_fftbin_size_adj = 1;
 		swar->null_fftbin_adj = 1;
 	} else {
 		swar->inband_fftbin_size_adj = 0;
 		swar->null_fftbin_adj = 0;
 	}
+
+	if (target_type == TARGET_TYPE_QCA8074V2)
+		swar->packmode_fftbin_size_adj = 1;
+	else
+		swar->packmode_fftbin_size_adj = 0;
+}
+
+/**
+ * target_if_spectral_report_params_init() - Initialize parameters which
+ * describes the structure of Spectral reports
+ *
+ * @rparams: Pointer to Spectral report parameter object
+ * @target_type: target type
+ *
+ * Function to Initialize parameters related to the structure of Spectral
+ * reports.
+ *
+ * Return: void
+ */
+static void
+target_if_spectral_report_params_init(
+			struct spectral_report_params *rparams,
+			uint32_t target_type)
+{
+	/* This entries are currently used by gen3 chipsets only. Hence
+	 * initialization is done for gen3 alone. In future if other generations
+	 * needs to use them they have to add proper initial values.
+	 */
+	if (target_type == TARGET_TYPE_QCN9000)
+		rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_2;
+	else
+		rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_1;
+
+	switch (rparams->version) {
+	case SPECTRAL_REPORT_FORMAT_VERSION_1:
+		rparams->ssumaary_padding_bytes =
+			NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1;
+		rparams->fft_report_hdr_len =
+			FFT_REPORT_HEADER_LENGTH_GEN3_V1;
+		break;
+	case SPECTRAL_REPORT_FORMAT_VERSION_2:
+		rparams->ssumaary_padding_bytes =
+			NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2;
+		rparams->fft_report_hdr_len =
+			FFT_REPORT_HEADER_LENGTH_GEN3_V2;
+		break;
+	default:
+		qdf_assert_always(0);
+	}
 }
 
 /**
@@ -2120,11 +2171,13 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev)
 	if (target_type == TARGET_TYPE_QCA8074 ||
 	    target_type == TARGET_TYPE_QCA8074V2 ||
 	    target_type == TARGET_TYPE_QCA6018 ||
-	    target_type == TARGET_TYPE_QCA6390)
+	    target_type == TARGET_TYPE_QCA6390 ||
+	    target_type == TARGET_TYPE_QCN9000)
 		spectral->direct_dma_support = true;
 
 	target_if_spectral_len_adj_swar_init(&spectral->len_adj_swar,
 					     target_type);
+	target_if_spectral_report_params_init(&spectral->rparams, target_type);
 
 	if ((target_type == TARGET_TYPE_QCA8074) ||
 	    (target_type == TARGET_TYPE_QCA8074V2) ||
@@ -2139,7 +2192,11 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev)
 		spectral->tag_sscan_fft_exp = TLV_TAG_SEARCH_FFT_REPORT_GEN3;
 		spectral->tlvhdr_size = SPECTRAL_PHYERR_TLVSIZE_GEN3;
 		spectral->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3;
-		spectral->fft_size_max = SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3;
+		spectral->fft_size_max =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT;
+		if (target_type == TARGET_TYPE_QCN9000)
+			spectral->fft_size_max =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000;
 	} else {
 		spectral->spectral_gen = SPECTRAL_GEN2;
 		spectral->hdr_sig_exp = SPECTRAL_PHYERR_SIGNATURE_GEN2;

+ 53 - 10
target_if/spectral/target_if_spectral.h

@@ -81,12 +81,13 @@
 #define OFFSET_CH_WIDTH_160	50
 
 /* Min and max for relevant Spectral params */
-#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2   (1)
-#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2   (9)
-#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3   (5)
-#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3   (9)
-#define SPECTRAL_PARAM_RPT_MODE_MIN        (0)
-#define SPECTRAL_PARAM_RPT_MODE_MAX        (3)
+#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2          (1)
+#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2          (9)
+#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3          (5)
+#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT  (9)
+#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000  (10)
+#define SPECTRAL_PARAM_RPT_MODE_MIN               (0)
+#define SPECTRAL_PARAM_RPT_MODE_MAX               (3)
 
 /* DBR ring debug size for Spectral */
 #define SPECTRAL_DBR_RING_DEBUG_SIZE 512
@@ -252,14 +253,21 @@ struct spectral_phyerr_fft_gen2 {
 #define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_SIZE_GEN3      (10)
 #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3               (31)
 #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3              (1)
-#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3          (30)
-#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3         (1)
+#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1       (30)
+#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1      (1)
+#define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2       (16)
+#define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2      (1)
 
 #define SPECTRAL_PHYERR_SIGNATURE_GEN3                          (0xFA)
 #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3                    (0x02)
 #define TLV_TAG_SEARCH_FFT_REPORT_GEN3                          (0x03)
 #define SPECTRAL_PHYERR_TLVSIZE_GEN3                            (4)
 
+#define FFT_REPORT_HEADER_LENGTH_GEN3_V2                   (24)
+#define FFT_REPORT_HEADER_LENGTH_GEN3_V1                   (16)
+#define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1      (0)
+#define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2      (16)
+
 #define PHYERR_HDR_SIG_POS    \
 	(offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_sig))
 #define PHYERR_HDR_TAG_POS    \
@@ -374,7 +382,7 @@ struct sscan_report_fields_gen3 {
  * @hdr_a:          Header[0:31]
  * @resv:           Header[32:63]
  * @hdr_b:          Header[64:95]
- * @resv:           Header[96:127]
+ * @hdr_c:          Header[96:127]
  */
 struct spectral_sscan_summary_report_gen3 {
 	u_int32_t sscan_timestamp;
@@ -390,7 +398,7 @@ struct spectral_sscan_summary_report_gen3 {
 	u_int32_t hdr_a;
 	u_int32_t res1;
 	u_int32_t hdr_b;
-	u_int32_t res2;
+	u_int32_t hdr_c;
 } __ATTRIB_PACK;
 
 #ifdef DIRECT_BUF_RX_ENABLE
@@ -438,6 +446,17 @@ enum spectral_fftbin_size_war {
 	SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE = 2,
 };
 
+/**
+ * enum spectral_report_format_version - This represents the report format
+ * version number within each Spectral generation.
+ * @SPECTRAL_REPORT_FORMAT_VERSION_1 : version 1
+ * @SPECTRAL_REPORT_FORMAT_VERSION_2 : version 2
+ */
+enum spectral_report_format_version {
+	SPECTRAL_REPORT_FORMAT_VERSION_1,
+	SPECTRAL_REPORT_FORMAT_VERSION_2,
+};
+
 /**
  * struct spectral_fft_bin_len_adj_swar - Encapsulate information required for
  * Spectral FFT bin length adjusting software WARS.
@@ -458,14 +477,36 @@ enum spectral_fftbin_size_war {
  * (as expected), but cannot arrange for a smaller length to be reported by HW.
  * In these circumstances, the driver would have to disregard the NULL bins and
  * report a bin count of 0 to higher layers.
+ * @packmode_fftbin_size_adj: Pack mode in HW refers to packing of each Spectral
+ * FFT bin into 2 bytes. But due to a bug HW reports 2 times the expected length
+ * when packmode is enabled. This SWAR compensates this bug by dividing the
+ * length with 2.
  * @fftbin_size_war: Type of FFT bin size SWAR
  */
 struct spectral_fft_bin_len_adj_swar {
 	u_int8_t inband_fftbin_size_adj;
 	u_int8_t null_fftbin_adj;
+	uint8_t packmode_fftbin_size_adj;
 	enum spectral_fftbin_size_war fftbin_size_war;
 };
 
+/**
+ * struct spectral_report_params - Parameters related to format of Spectral
+ * report.
+ * @version: This represents the report format version number within each
+ * Spectral generation.
+ * @ssumaary_padding_bytes: Number of bytes of padding after Spectral summary
+ * report
+ * @fft_report_hdr_len: Number of bytes in the header of the FFT report. This
+ * has to be subtracted from the length field of FFT report to find the length
+ * of FFT bins.
+ */
+struct spectral_report_params {
+	enum spectral_report_format_version version;
+	uint8_t ssumaary_padding_bytes;
+	uint8_t fft_report_hdr_len;
+};
+
 #if ATH_PERF_PWR_OFFLOAD
 /**
  * enum target_if_spectral_info - Enumerations for specifying which spectral
@@ -857,6 +898,7 @@ struct spectral_param_properties {
  * @prev_tstamp: Timestamp of the previously received sample, which has to be
  * compared with the current tstamp to check descrepancy
  * @target_reset_count: Number of times target excercised the reset routine
+ * @rparams: Parameters related to Spectral report structure
  */
 struct target_if_spectral {
 	struct wlan_objmgr_pdev *pdev_obj;
@@ -975,6 +1017,7 @@ struct target_if_spectral {
 	bool direct_dma_support;
 	uint32_t prev_tstamp;
 	uint32_t target_reset_count;
+	struct spectral_report_params rparams;
 };
 
 /**

+ 37 - 20
target_if/spectral/target_if_spectral_phyerr.c

@@ -1230,11 +1230,13 @@ target_if_spectral_get_bin_count_after_len_adj(
 			fft_bin_count >>= 2;
 			break;
 		case SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE:
+			fft_bin_count >>= 1;
 			/* Ideally we should be dividing fft bin length
 			 * by 2. Due to a HW bug, actual length is two
 			 * times the expected length.
 			 */
-			fft_bin_count >>= 2;
+			if (swar->packmode_fftbin_size_adj)
+				fft_bin_count >>= 1;
 			break;
 		case SPECTRAL_FFTBIN_SIZE_NO_WAR:
 			/* No length adjustment */
@@ -1326,11 +1328,12 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral,
 {
 	size_t fft_hdr_length = (p_fft_report->fft_hdr_length * 4);
 	size_t report_len = (fft_hdr_length + 8);
-	size_t fft_bin_len = (fft_hdr_length - 16);
+	size_t fft_bin_len;
 	size_t fft_bin_count;
 	size_t fft_bin_len_inband_tfer = 0;
 	uint8_t *fft_bin_buf = NULL;
 
+	fft_bin_len = fft_hdr_length - spectral->rparams.fft_report_hdr_len;
 	fft_bin_count = target_if_spectral_get_bin_count_after_len_adj(
 			fft_bin_len,
 			spectral->params[smode].ss_rpt_mode,
@@ -1493,24 +1496,24 @@ target_if_get_detector_id_sscan_summary_report_gen3(uint8_t *data) {
 /**
  * target_if_consume_sscan_summary_report_gen3() - Consume Spectral summary
  * report
- * @spectral: Pointer to Spectral object
  * @data: Pointer to Spectral summary report
  * @fields: Pointer to structure to be populated with extracted fields
+ * @rparams: Pointer to structure with Spectral report params
  *
  * Consume Spectral summary report for gen3
  *
  * Return: void
  */
 static void
-target_if_consume_sscan_summary_report_gen3(struct target_if_spectral *spectral,
-					    uint8_t *data,
-					    struct sscan_report_fields_gen3
-						*fields) {
+target_if_consume_sscan_summary_report_gen3(
+				uint8_t *data,
+				struct sscan_report_fields_gen3 *fields,
+				struct spectral_report_params *rparams) {
 	struct spectral_sscan_summary_report_gen3 *psscan_summary_report;
 
-	qdf_assert_always(spectral);
 	qdf_assert_always(data);
 	qdf_assert_always(fields);
+	qdf_assert_always(rparams);
 
 	psscan_summary_report =
 		(struct spectral_sscan_summary_report_gen3 *)data;
@@ -1527,10 +1530,23 @@ target_if_consume_sscan_summary_report_gen3(struct target_if_spectral *spectral,
 			psscan_summary_report->hdr_a,
 			SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3,
 			SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3);
-	fields->sscan_gainchange = get_bitfield(
+
+	switch (rparams->version) {
+	case SPECTRAL_REPORT_FORMAT_VERSION_1:
+		fields->sscan_gainchange = get_bitfield(
 			psscan_summary_report->hdr_b,
-			SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3,
-			SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3);
+			SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1,
+			SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1);
+		break;
+	case SPECTRAL_REPORT_FORMAT_VERSION_2:
+		fields->sscan_gainchange = get_bitfield(
+			psscan_summary_report->hdr_c,
+			SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2,
+			SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2);
+		break;
+	default:
+		qdf_assert_always(0);
+	}
 }
 
 /**
@@ -1748,7 +1764,7 @@ target_if_consume_spectral_report_gen3(
 	uint8_t *data = report->data;
 	struct wlan_objmgr_vdev *vdev;
 	uint8_t vdev_rxchainmask;
-	struct sscan_report_fields_gen3 sscan_report_fields;
+	struct sscan_report_fields_gen3 sscan_report_fields = {0};
 	enum spectral_detector_id detector_id;
 	QDF_STATUS ret;
 
@@ -1769,10 +1785,11 @@ target_if_consume_spectral_report_gen3(
 			     detector_id);
 		goto fail;
 	}
-	target_if_consume_sscan_summary_report_gen3(spectral, data,
-						    &sscan_report_fields);
+	target_if_consume_sscan_summary_report_gen3(data, &sscan_report_fields,
+						    &spectral->rparams);
 	/* Advance buf pointer to the search fft report */
 	data += sizeof(struct spectral_sscan_summary_report_gen3);
+	data += spectral->rparams.ssumaary_padding_bytes;
 
 	if ((detector_id == SPECTRAL_DETECTOR_AGILE) ||
 	    is_primaryseg_expected(spectral)) {
@@ -1827,9 +1844,9 @@ target_if_consume_spectral_report_gen3(
 		}
 
 		fft_bin_count = target_if_spectral_get_bin_count_after_len_adj(
-				fft_hdr_length - 16,
-				spectral->params[params.smode].ss_rpt_mode,
-				&spectral->len_adj_swar);
+			fft_hdr_length - spectral->rparams.fft_report_hdr_len,
+			spectral->params[params.smode].ss_rpt_mode,
+			&spectral->len_adj_swar);
 		params.last_raw_timestamp =
 				spectral->last_fft_timestamp[params.smode];
 		params.reset_delay = 0;
@@ -1969,9 +1986,9 @@ target_if_consume_spectral_report_gen3(
 		}
 
 		fft_bin_count = target_if_spectral_get_bin_count_after_len_adj(
-				fft_hdr_length - 16,
-				spectral->params[params.smode].ss_rpt_mode,
-				&spectral->len_adj_swar);
+			fft_hdr_length - spectral->rparams.fft_report_hdr_len,
+			spectral->params[params.smode].ss_rpt_mode,
+			&spectral->len_adj_swar);
 		params.raw_timestamp_sec80 = p_sfft->timestamp;
 
 		/* Take care of state transitions for 160 MHz and 80p80 */