Bladeren bron

qcacmn: Clamp the FFT bin values before filling SAMP message

Each FFT bin value is represented as an 8 bit integer
in SAMP message. But depending on the configuration,
the FFT bin value reported by HW might exceed 8 bits.
Clamp the FFT bin value between the min and max value
which can be represented by 8 bits. For linear mode,
min and max FFT bin value which can be represented by
8 bit is 0 and U8_MAX respectively. For dBm mode,  min
and max FFT bin value which can be represented by 8 bit
is S8_MIN and S8_MAX respectively.

CRs-Fixed: 3056458
Change-Id: I9ec75f781a130d3ed0d0d9393975fd5874961ce0
Edayilliam Jayadev 3 jaren geleden
bovenliggende
commit
31da41ae4e

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

@@ -117,6 +117,16 @@ enum spectral_report_mode {
 	SPECTRAL_REPORT_MODE_MAX,
 };
 
+/**
+ * enum spectral_pwr_format: Spectral FFT bin pwr format
+ * @SPECTRAL_PWR_FORMAT_LINEAR: Linear mode
+ * @SPECTRAL_PWR_FORMAT_DBM: dBm mode
+ */
+enum spectral_pwr_format {
+	SPECTRAL_PWR_FORMAT_LINEAR = 0,
+	SPECTRAL_PWR_FORMAT_DBM = 1,
+};
+
 /**
  * enum spectral_scan_priority: Spectral scan priority
  * @SPECTRAL_SCAN_PRIORITY_LOW: Low priority Spectral scan

+ 54 - 2
target_if/spectral/target_if_spectral.h

@@ -98,9 +98,13 @@
 #define INVALID_FFT_SIZE                          (0xFFFF)
 #define SPECTRAL_PARAM_RPT_MODE_MIN               (0)
 #define SPECTRAL_PARAM_RPT_MODE_MAX               (3)
-#define MAX_FFTBIN_VALUE                          (255)
 #define SPECTRAL_DWORD_SIZE                       (4)
 
+#define MAX_FFTBIN_VALUE_LINEAR_MODE              (U8_MAX)
+#define MAX_FFTBIN_VALUE_DBM_MODE                 (S8_MAX)
+#define MIN_FFTBIN_VALUE_DBM_MODE                 (S8_MIN)
+#define MAX_FFTBIN_VALUE                          (255)
+
 /* DBR ring debug size for Spectral */
 #define SPECTRAL_DBR_RING_DEBUG_SIZE 512
 
@@ -2319,6 +2323,52 @@ bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral,
 }
 #endif
 
+/**
+ * clamp_fft_bin_value() - Clamp the FFT bin value between min and max
+ * @fft_bin_value: FFT bin value as reported by HW
+ * @pwr_format: FFT bin format (linear or dBm format)
+ *
+ * Each FFT bin value is represented as an 8 bit integer in SAMP message. But
+ * depending on the configuration, the FFT bin value reported by HW might
+ * exceed 8 bits. Clamp the FFT bin value between the min and max value
+ * which can be represented by 8 bits. For linear mode, min and max FFT bin
+ * value which can be represented by 8 bit is 0 and U8_MAX respectively. For
+ * dBm mode,  min and max FFT bin value which can be represented by 8 bit is
+ * S8_MIN and S8_MAX respectively.
+ *
+ * Return: Clamped FFT bin value
+ */
+static inline uint8_t
+clamp_fft_bin_value(uint16_t fft_bin_value, uint16_t pwr_format)
+{
+	uint8_t clamped_fft_bin_value = 0;
+
+	switch (pwr_format) {
+	case SPECTRAL_PWR_FORMAT_LINEAR:
+		if (qdf_unlikely(fft_bin_value > MAX_FFTBIN_VALUE_LINEAR_MODE))
+			clamped_fft_bin_value = MAX_FFTBIN_VALUE_LINEAR_MODE;
+		else
+			clamped_fft_bin_value = fft_bin_value;
+		break;
+
+	case SPECTRAL_PWR_FORMAT_DBM:
+		if (qdf_unlikely((int16_t)fft_bin_value >
+		    MAX_FFTBIN_VALUE_DBM_MODE))
+			clamped_fft_bin_value = MAX_FFTBIN_VALUE_DBM_MODE;
+		else if (qdf_unlikely((int16_t)fft_bin_value <
+			 MIN_FFTBIN_VALUE_DBM_MODE))
+			clamped_fft_bin_value = MIN_FFTBIN_VALUE_DBM_MODE;
+		else
+			clamped_fft_bin_value = fft_bin_value;
+		break;
+
+	default:
+		qdf_assert_always(0);
+	}
+
+	return clamped_fft_bin_value;
+}
+
 /**
  * target_if_160mhz_delivery_state_change() - State transition for 160Mhz
  *                                            Spectral
@@ -2909,6 +2959,7 @@ spectral_is_session_info_expected_from_target(struct wlan_objmgr_pdev *pdev,
  * @dest_fft_buf: Pointer to destination FFT buffer
  * @fft_bin_count: Number of FFT bins to copy
  * @bytes_copied: Number of bytes copied by this API
+ * @pwr_format: Spectral FFT bin format (linear/dBm mode)
  *
  * Different targets supports different FFT bin widths. This API encapsulates
  * all those details and copies 8-bit FFT value into the destination buffer.
@@ -2925,6 +2976,7 @@ target_if_spectral_copy_fft_bins(struct target_if_spectral *spectral,
 				 const void *src_fft_buf,
 				 void *dest_fft_buf,
 				 uint32_t fft_bin_count,
-				 uint32_t *bytes_copied);
+				 uint32_t *bytes_copied,
+				 uint16_t pwr_format);
 #endif /* WLAN_CONV_SPECTRAL_ENABLE */
 #endif /* _TARGET_IF_SPECTRAL_H_ */

+ 6 - 3
target_if/spectral/target_if_spectral_netlink.c

@@ -40,6 +40,7 @@ target_if_spectral_fill_samp_msg(struct target_if_spectral *spectral,
 	QDF_STATUS ret;
 	uint16_t dest_det_idx;
 	enum spectral_scan_mode spectral_mode;
+	uint16_t pwr_format;
 
 	if (!spectral) {
 		spectral_err_rl("Spectral LMAC object is null");
@@ -71,6 +72,8 @@ target_if_spectral_fill_samp_msg(struct target_if_spectral *spectral,
 		return QDF_STATUS_E_FAILURE;
 	}
 
+	pwr_format = spectral->params[spectral_mode].ss_pwr_format;
+
 	qdf_spin_lock_bh(&spectral->session_det_map_lock);
 
 	if (!spectral->det_map[params->hw_detector_id].det_map_valid) {
@@ -165,7 +168,7 @@ target_if_spectral_fill_samp_msg(struct target_if_spectral *spectral,
 					&spec_samp_msg->bin_pwr[
 					lb_edge_bins->start_bin_idx],
 					lb_edge_bins->num_bins,
-					&bytes_copied);
+					&bytes_copied, pwr_format);
 
 			if (QDF_IS_STATUS_ERROR(ret)) {
 				qdf_spin_unlock_bh(
@@ -183,7 +186,7 @@ target_if_spectral_fill_samp_msg(struct target_if_spectral *spectral,
 				spectral, bin_pwr_data,
 				&spec_samp_msg->bin_pwr[start_bin_index],
 				pwr_count,
-				&bytes_copied);
+				&bytes_copied, pwr_format);
 
 		if (QDF_IS_STATUS_ERROR(ret)) {
 			qdf_spin_unlock_bh(
@@ -201,7 +204,7 @@ target_if_spectral_fill_samp_msg(struct target_if_spectral *spectral,
 					&spec_samp_msg->bin_pwr[
 					rb_edge_bins->start_bin_idx],
 					rb_edge_bins->num_bins,
-					&bytes_copied);
+					&bytes_copied, pwr_format);
 
 			if (QDF_IS_STATUS_ERROR(ret)) {
 				qdf_spin_unlock_bh(

+ 6 - 14
target_if/spectral/target_if_spectral_phyerr.c

@@ -2180,7 +2180,8 @@ target_if_spectral_copy_fft_bins(struct target_if_spectral *spectral,
 				 const void *src_fft_buf,
 				 void *dest_fft_buf,
 				 uint32_t fft_bin_count,
-				 uint32_t *bytes_copied)
+				 uint32_t *bytes_copied,
+				 uint16_t pwr_format)
 {
 	uint16_t idx, dword_idx, fft_bin_idx;
 	uint8_t num_bins_per_dword, hw_fft_bin_width_bits;
@@ -2223,19 +2224,9 @@ target_if_spectral_copy_fft_bins(struct target_if_spectral *spectral,
 					dword,
 					idx * hw_fft_bin_width_bits,
 					hw_fft_bin_width_bits);
-			/**
-			 * To check whether FFT bin values exceed 8 bits,
-			 * we add a check before copying values to fft_bin_buf.
-			 * If it crosses 8 bits, we cap the values to maximum
-			 * value supported by 8 bits ie. 255. This needs to be
-			 * done as the destination array in SAMP message is
-			 * 8 bits. This is a temporary solution till an array
-			 * of 16 bits is used for SAMP message.
-			 */
-			if (qdf_unlikely(fft_bin_val > MAX_FFTBIN_VALUE))
-				fft_bin_val = MAX_FFTBIN_VALUE;
 
-			fft_bin_buf[fft_bin_idx++] = fft_bin_val;
+			fft_bin_buf[fft_bin_idx++] =
+				clamp_fft_bin_value(fft_bin_val, pwr_format);
 		}
 	}
 
@@ -2518,7 +2509,8 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral,
 
 		status = target_if_spectral_copy_fft_bins(
 				spectral, &p_fft_report->buf,
-				fft_bin_buf, fft_bin_count, &bytes_copied);
+				fft_bin_buf, fft_bin_count, &bytes_copied,
+				spectral->params[smode].ss_pwr_format);
 		if (QDF_IS_STATUS_ERROR(status)) {
 			spectral_err_rl("Unable to populate FFT bins");
 			qdf_mem_free(fft_bin_buf);