Ver código fonte

qcacmn: FFT size max based on band width

For QCN9000 max FFT size supported is 9 for 20 MHz and 10
for all other bandwidths. Add FFT bin size max based on
bandwidth to support this requirement.

Change-Id: If383dc914937d68c9f4781463a3a965c73bc78f1
CRs-Fixed: 2617674
Edayilliam Jayadev 5 anos atrás
pai
commit
ec5e46507e

+ 130 - 28
target_if/spectral/target_if_spectral.c

@@ -1336,6 +1336,71 @@ target_if_spectral_get_macaddr(void *arg, char *addr)
 	return 0;
 }
 
+/**
+ * target_if_init_spectral_param_min_max() - Initialize Spectral parameter
+ * min and max values
+ *
+ * @param_min_max: Pointer to Spectral parameter min and max structure
+ * @gen: Spectral HW generation
+ * @target_type: Target type
+ *
+ * Initialize Spectral parameter min and max values
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+target_if_init_spectral_param_min_max(
+				struct spectral_param_min_max *param_min_max,
+				enum spectral_gen gen, uint32_t target_type)
+{
+	switch (gen) {
+	case SPECTRAL_GEN3:
+		param_min_max->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3;
+		param_min_max->fft_size_max[CH_WIDTH_20MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT;
+		if (target_type == TARGET_TYPE_QCN9000) {
+			param_min_max->fft_size_max[CH_WIDTH_40MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000;
+			param_min_max->fft_size_max[CH_WIDTH_80MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000;
+			param_min_max->fft_size_max[CH_WIDTH_160MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000;
+			param_min_max->fft_size_max[CH_WIDTH_80P80MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000;
+		} else {
+			param_min_max->fft_size_max[CH_WIDTH_40MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT;
+			param_min_max->fft_size_max[CH_WIDTH_80MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT;
+			param_min_max->fft_size_max[CH_WIDTH_160MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT;
+			param_min_max->fft_size_max[CH_WIDTH_80P80MHZ] =
+				SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT;
+		}
+		break;
+
+	case SPECTRAL_GEN2:
+		param_min_max->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2;
+		param_min_max->fft_size_max[CH_WIDTH_20MHZ] =
+					SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2;
+		param_min_max->fft_size_max[CH_WIDTH_40MHZ] =
+					SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2;
+		param_min_max->fft_size_max[CH_WIDTH_80MHZ] =
+					SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2;
+		param_min_max->fft_size_max[CH_WIDTH_80P80MHZ] =
+					SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2;
+		param_min_max->fft_size_max[CH_WIDTH_160MHZ] =
+					SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2;
+		break;
+
+	default:
+		spectral_err("Invalid spectral generation %d", gen);
+		return QDF_STATUS_E_INVAL;
+	}
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * target_if_init_spectral_param_properties() - Initialize Spectral parameter
  *                                              properties
@@ -2136,6 +2201,7 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev)
 	struct wlan_objmgr_psoc *psoc;
 	struct wlan_lmac_if_target_tx_ops *tx_ops;
 	enum spectral_scan_mode smode = SPECTRAL_SCAN_MODE_NORMAL;
+	QDF_STATUS status;
 
 	if (!pdev) {
 		spectral_err("SPECTRAL: pdev is NULL!");
@@ -2213,12 +2279,6 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev)
 		    TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3;
 		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_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;
@@ -2226,8 +2286,14 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev)
 		    TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN2;
 		spectral->tag_sscan_fft_exp = TLV_TAG_SEARCH_FFT_REPORT_GEN2;
 		spectral->tlvhdr_size = sizeof(struct spectral_phyerr_tlv_gen2);
-		spectral->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2;
-		spectral->fft_size_max = SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2;
+	}
+
+	status = target_if_init_spectral_param_min_max(
+					&spectral->param_min_max,
+					spectral->spectral_gen, target_type);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		spectral_err("Failed to initialize parameter min max values");
+		goto fail;
 	}
 
 	target_if_init_spectral_param_properties(spectral);
@@ -2253,8 +2319,7 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev)
 	target_if_spectral_register_funcs(spectral, &spectral_ops);
 
 	if (target_if_spectral_check_hw_capability(spectral) == false) {
-		target_if_spectral_detach(spectral);
-		spectral = NULL;
+		goto fail;
 	} else {
 		/*
 		 * TODO: Once the driver architecture transitions to chipset
@@ -2285,6 +2350,10 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev)
 	}
 
 	return spectral;
+
+fail:
+	target_if_spectral_detach(spectral);
+	return NULL;
 }
 
 /**
@@ -2640,6 +2709,40 @@ target_if_is_agile_span_overlap_with_operating_span
 	return QDF_STATUS_SUCCESS;
 }
 
+/**
+ * target_if_spectral_populate_chwidth() - Helper routine to
+ * populate channel width for different Spectral modes
+ *
+ * @spectral: Pointer to Spectral object
+ *
+ * Helper routine to populate channel width for different Spectral modes
+ *
+ * Return: QDF_STATUS
+ */
+static QDF_STATUS
+target_if_spectral_populate_chwidth(struct target_if_spectral *spectral) {
+	struct wlan_objmgr_vdev *vdev;
+	enum phy_ch_width vdev_ch_with;
+
+	vdev = target_if_spectral_get_vdev(spectral);
+	if (!vdev) {
+		spectral_err("vdev is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+
+	vdev_ch_with = target_if_vdev_get_ch_width(vdev);
+	wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
+	if (vdev_ch_with == CH_WIDTH_INVALID) {
+		spectral_err("Invalid channel width %d", vdev_ch_with);
+		return QDF_STATUS_E_FAILURE;
+	}
+	spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] = vdev_ch_with;
+	spectral->ch_width[SPECTRAL_SCAN_MODE_AGILE] =
+			target_if_spectral_find_agile_width(vdev_ch_with);
+
+	return QDF_STATUS_SUCCESS;
+}
+
 /**
  * _target_if_set_spectral_config() - Set spectral config
  * @spectral:       Pointer to spectral object
@@ -2665,6 +2768,7 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
 	bool is_overlapping;
 	uint16_t agile_cfreq;
 	bool is_valid_chan;
+	struct spectral_param_min_max *param_min_max;
 
 	if (!err) {
 		spectral_err("Error code argument is null");
@@ -2677,6 +2781,7 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
 		return QDF_STATUS_E_FAILURE;
 	}
 	p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral);
+	param_min_max = &spectral->param_min_max;
 
 	if (smode >= SPECTRAL_SCAN_MODE_MAX) {
 		spectral_err("Invalid Spectral mode %u", smode);
@@ -2712,8 +2817,12 @@ _target_if_set_spectral_config(struct target_if_spectral *spectral,
 		sparams->ss_spectral_pri = (!!value) ? true : false;
 		break;
 	case SPECTRAL_PARAM_FFT_SIZE:
-		if ((value < spectral->fft_size_min) ||
-		    (value > spectral->fft_size_max)) {
+		status = target_if_spectral_populate_chwidth(spectral);
+		if (QDF_IS_STATUS_ERROR(status))
+			return QDF_STATUS_E_FAILURE;
+		if ((value < param_min_max->fft_size_min) ||
+		    (value > param_min_max->fft_size_max
+		     [spectral->ch_width[smode]])) {
 			*err = SPECTRAL_SCAN_ERR_PARAM_INVALID_VALUE;
 			return QDF_STATUS_E_FAILURE;
 		}
@@ -3012,7 +3121,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral,
 	int extension_channel = 0;
 	int current_channel = 0;
 	struct target_if_spectral_ops *p_sops = NULL;
-	struct wlan_objmgr_vdev *vdev = NULL;
+	QDF_STATUS status;
 
 	if (!spectral) {
 		spectral_err("Spectral LMAC object is NULL");
@@ -3038,18 +3147,11 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral,
 	extension_channel = p_sops->get_extension_channel(spectral);
 	current_channel = p_sops->get_current_channel(spectral);
 
-	vdev = target_if_spectral_get_vdev(spectral);
-	if (!vdev)
-		return 1;
-
-	spectral->ch_width = target_if_vdev_get_ch_width(vdev);
-	wlan_objmgr_vdev_release_ref(vdev, WLAN_SPECTRAL_ID);
-
-	if (spectral->ch_width == CH_WIDTH_INVALID)
+	status = target_if_spectral_populate_chwidth(spectral);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		spectral_err("Failed to get channel widths");
 		return 1;
-
-	spectral->agile_ch_width =
-			target_if_spectral_find_agile_width(spectral->ch_width);
+	}
 
 	if (spectral->capability.advncd_spectral_cap) {
 		spectral->lb_edge_extrabins = 0;
@@ -3065,7 +3167,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral,
 			spectral->rb_edge_extrabins = 4;
 		}
 
-		if (spectral->ch_width == CH_WIDTH_20MHZ) {
+		if (spectral->ch_width[smode] == CH_WIDTH_20MHZ) {
 			spectral->sc_spectral_20_40_mode = 0;
 
 			spectral->spectral_numbins =
@@ -3085,7 +3187,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral,
 			    current_channel;
 			spectral->classifier_params.upper_chan_in_mhz = 0;
 
-		} else if (spectral->ch_width == CH_WIDTH_40MHZ) {
+		} else if (spectral->ch_width[smode] == CH_WIDTH_40MHZ) {
 			/* TODO : Remove this variable */
 			spectral->sc_spectral_20_40_mode = 1;
 			spectral->spectral_numbins =
@@ -3114,7 +3216,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral,
 				    extension_channel;
 			}
 
-		} else if (spectral->ch_width == CH_WIDTH_80MHZ) {
+		} else if (spectral->ch_width[smode] == CH_WIDTH_80MHZ) {
 			/* Set the FFT Size */
 			/* TODO : Remove this variable */
 			spectral->sc_spectral_20_40_mode = 0;
@@ -3152,7 +3254,7 @@ target_if_spectral_scan_enable_params(struct target_if_spectral *spectral,
 				    extension_channel;
 			}
 
-		} else if (spectral->ch_width == CH_WIDTH_160MHZ) {
+		} else if (spectral->ch_width[smode] == CH_WIDTH_160MHZ) {
 			/* Set the FFT Size */
 
 			/* The below applies to both 160 and 80+80 cases */

+ 21 - 13
target_if/spectral/target_if_spectral.h

@@ -507,6 +507,16 @@ struct spectral_report_params {
 	uint8_t fft_report_hdr_len;
 };
 
+/**
+ * struct spectral_param_min_max - Spectral parameter minimum and maximum values
+ * @fft_size_min: Minimum value of fft_size
+ * @fft_size_max: Maximum value of fft_size for each BW
+ */
+struct spectral_param_min_max {
+	uint16_t fft_size_min;
+	uint16_t fft_size_max[CH_WIDTH_MAX];
+};
+
 /**
  * struct spectral_timestamp_swar - Spectral time stamp WAR related parameters
  * @timestamp_war_offset: Offset to be added to correct timestamp
@@ -877,8 +887,7 @@ struct spectral_param_properties {
  * @chaninfo: Channel statistics
  * @tsf64: Latest TSF Value
  * @param_info: Offload architecture Spectral parameter cache information
- * @ch_width: Indicates Channel Width 20/40/80/160 MHz with values 0, 1, 2, 3
- * respectively
+ * @ch_width: Indicates Channel Width 20/40/80/160 MHz for each Spectral mode
  * @diag_stats: Diagnostic statistics
  * @is_160_format:  Indicates whether information provided by HW is in altered
  * format for 802.11ac 160/80+80 MHz support (QCA9984 onwards)
@@ -909,6 +918,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
  * @rparams: Parameters related to Spectral report structure
+ * @param_min_max: Spectral parameter's minimum and maximum values
  */
 struct target_if_spectral {
 	struct wlan_objmgr_pdev *pdev_obj;
@@ -995,8 +1005,7 @@ struct target_if_spectral {
 	struct target_if_spectral_param_state_info
 					param_info[SPECTRAL_SCAN_MODE_MAX];
 #endif
-	uint32_t                               ch_width;
-	uint32_t                               agile_ch_width;
+	enum phy_ch_width ch_width[SPECTRAL_SCAN_MODE_MAX];
 	struct spectral_diag_stats              diag_stats;
 	bool                                    is_160_format;
 	bool                                    is_lb_edge_extrabins_format;
@@ -1018,13 +1027,12 @@ struct target_if_spectral {
 	struct spectral_fft_bin_len_adj_swar len_adj_swar;
 	struct spectral_timestamp_war timestamp_war;
 	enum spectral_160mhz_report_delivery_state state_160mhz_delivery;
-	uint16_t fft_size_min;
-	uint16_t fft_size_max;
 	bool dbr_ring_debug;
 	bool dbr_buff_debug;
 	bool direct_dma_support;
 	uint32_t prev_tstamp;
 	struct spectral_report_params rparams;
+	struct spectral_param_min_max param_min_max;
 };
 
 /**
@@ -1595,7 +1603,7 @@ reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral,
 	enum spectral_msg_type smsg_type;
 	QDF_STATUS ret;
 
-	if (spectral->ch_width == CH_WIDTH_160MHZ) {
+	if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) {
 		spectral->state_160mhz_delivery =
 			SPECTRAL_REPORT_WAIT_PRIMARY80;
 
@@ -1622,7 +1630,7 @@ static inline
 bool is_secondaryseg_expected(struct target_if_spectral *spectral)
 {
 	return
-	((spectral->ch_width == CH_WIDTH_160MHZ) &&
+	((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) &&
 	(spectral->state_160mhz_delivery == SPECTRAL_REPORT_WAIT_SECONDARY80));
 }
 
@@ -1639,8 +1647,8 @@ static inline
 bool is_primaryseg_expected(struct target_if_spectral *spectral)
 {
 	return
-	((spectral->ch_width != CH_WIDTH_160MHZ) ||
-	((spectral->ch_width == CH_WIDTH_160MHZ) &&
+	((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ) ||
+	((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) &&
 	(spectral->state_160mhz_delivery == SPECTRAL_REPORT_WAIT_PRIMARY80)));
 }
 
@@ -1656,8 +1664,8 @@ static inline
 bool is_primaryseg_rx_inprog(struct target_if_spectral *spectral)
 {
 	return
-	((spectral->ch_width != CH_WIDTH_160MHZ) ||
-	((spectral->ch_width == CH_WIDTH_160MHZ) &&
+	((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ) ||
+	((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) &&
 	((spectral->spectral_gen == SPECTRAL_GEN2) ||
 	((spectral->spectral_gen == SPECTRAL_GEN3) &&
 	(spectral->state_160mhz_delivery == SPECTRAL_REPORT_RX_PRIMARY80)))));
@@ -1675,7 +1683,7 @@ static inline
 bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral)
 {
 	return
-	((spectral->ch_width == CH_WIDTH_160MHZ) &&
+	((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) &&
 	((spectral->spectral_gen == SPECTRAL_GEN2) ||
 	((spectral->spectral_gen == SPECTRAL_GEN3) &&
 	(spectral->state_160mhz_delivery == SPECTRAL_REPORT_RX_SECONDARY80))));

+ 5 - 3
target_if/spectral/target_if_spectral_netlink.c

@@ -79,8 +79,10 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral,
 		samp_data->spectral_mode = params->smode;
 		samp_data->spectral_data_len = params->datalen;
 		samp_data->spectral_rssi = params->rssi;
-		samp_data->ch_width = spectral->ch_width;
-		samp_data->agile_ch_width = spectral->agile_ch_width;
+		samp_data->ch_width =
+				spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL];
+		samp_data->agile_ch_width =
+				spectral->ch_width[SPECTRAL_SCAN_MODE_AGILE];
 		samp_data->spectral_agc_total_gain = params->agc_total_gain;
 		samp_data->spectral_gainchange = params->gainchange;
 		samp_data->spectral_pri80ind = params->pri80ind;
@@ -237,7 +239,7 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral,
 		}
 	}
 
-	if ((spectral->ch_width != CH_WIDTH_160MHZ) ||
+	if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ ||
 	    (params->smode == SPECTRAL_SCAN_MODE_AGILE) ||
 	    is_secondaryseg_rx_inprog(spectral)) {
 		if (spectral->send_phy_data(spectral->pdev_obj,

+ 9 - 6
target_if/spectral/target_if_spectral_phyerr.c

@@ -967,8 +967,8 @@ target_if_process_phyerr_gen2(struct target_if_spectral *spectral,
 		acs_stats->nfc_ctl_rssi = control_rssi;
 		acs_stats->nfc_ext_rssi = extension_rssi;
 
-		if (spectral->is_160_format &&
-		    spectral->ch_width == CH_WIDTH_160MHZ) {
+		if (spectral->is_160_format && spectral->ch_width
+		    [SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) {
 			/*
 			 * We expect to see one more Search FFT report, and it
 			 * should be equal in size to the current one.
@@ -1096,7 +1096,8 @@ target_if_get_combrssi_sec80_seg_gen2(
 	total_gain_db = p_sfft_sec80->total_gain_info;
 
 	/* Calculate offset */
-	offset = target_if_get_offset_swar_sec80(spectral->ch_width);
+	offset = target_if_get_offset_swar_sec80(
+			spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL]);
 
 	/* Calculate RSSI */
 	comb_rssi = ((avgpwr_db - total_gain_db) + offset);
@@ -1416,7 +1417,7 @@ target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral,
 				       uint8_t detector_id) {
 	QDF_STATUS status = QDF_STATUS_SUCCESS;
 
-	if (spectral->ch_width != CH_WIDTH_160MHZ)
+	if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ)
 		return QDF_STATUS_E_FAILURE;
 
 	/* agile reports should not be coupled with 160 MHz state machine
@@ -1899,7 +1900,8 @@ target_if_consume_spectral_report_gen3(
 				target_reset_count;
 
 		/* Take care of state transitions for 160 MHz and 80p80 */
-		if (spectral->ch_width == CH_WIDTH_160MHZ) {
+		if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] ==
+		    CH_WIDTH_160MHZ) {
 			ret = target_if_160mhz_delivery_state_change(
 					spectral,
 					detector_id);
@@ -2014,7 +2016,8 @@ target_if_consume_spectral_report_gen3(
 		params.raw_timestamp_sec80 = p_sfft->timestamp;
 
 		/* Take care of state transitions for 160 MHz and 80p80 */
-		if (spectral->ch_width == CH_WIDTH_160MHZ) {
+		if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] ==
+		    CH_WIDTH_160MHZ) {
 			ret = target_if_160mhz_delivery_state_change(
 					spectral,
 					detector_id);