diff --git a/spectral/dispatcher/inc/spectral_ioctl.h b/spectral/dispatcher/inc/spectral_ioctl.h index f21d698bff..888794fcb2 100644 --- a/spectral/dispatcher/inc/spectral_ioctl.h +++ b/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 diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index 164d8b5210..c974912f92 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/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_ */ diff --git a/target_if/spectral/target_if_spectral_netlink.c b/target_if/spectral/target_if_spectral_netlink.c index d18bb515be..6d966b1138 100644 --- a/target_if/spectral/target_if_spectral_netlink.c +++ b/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( diff --git a/target_if/spectral/target_if_spectral_phyerr.c b/target_if/spectral/target_if_spectral_phyerr.c index 69cfaf926f..9ccb6dd62b 100644 --- a/target_if/spectral/target_if_spectral_phyerr.c +++ b/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);