diff --git a/target_if/spectral/target_if_spectral.c b/target_if/spectral/target_if_spectral.c index 9d74da5e0299..77314fc54af3 100644 --- a/target_if/spectral/target_if_spectral.c +++ b/target_if/spectral/target_if_spectral.c @@ -2010,10 +2010,13 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) (target_type == TARGET_TYPE_QCA8074V2)) { spectral->fftbin_size_war = 1; spectral->inband_fftbin_size_adj = 1; + spectral->null_fftbin_adj = 1; } else { spectral->fftbin_size_war = 0; spectral->inband_fftbin_size_adj = 0; + spectral->null_fftbin_adj = 0; } + if ((target_type == TARGET_TYPE_QCA8074) || (target_type == TARGET_TYPE_QCA8074V2) || (target_type == TARGET_TYPE_QCA6290)) { diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index 9daf8cd992c3..1e1521b9d500 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/target_if/spectral/target_if_spectral.h @@ -767,6 +767,15 @@ struct wmi_spectral_cmd_ops { * DMA cannot change this value. On such chipsets the adjustment required at the * host driver is to check if report format is 2, and if so halve the number of * bins reported to get the number actually DMA'ed. + * @null_fftbin_adj: Whether to remove NULL FFT bins for report mode (1) in + * which only summary of metrics for each completed FFT + spectral scan summary + * report are to be provided. This would be required on some chipsets under the + * following circumstances: In report mode 1, HW reports a length corresponding + * to all bins, and provides bins with value 0. This is because the subsystem + * arranging for the FFT information does not arrange for DMA of FFT bin values + * (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. */ struct target_if_spectral { struct wlan_objmgr_pdev *pdev_obj; @@ -869,6 +878,7 @@ struct target_if_spectral { int (*send_phy_data)(struct wlan_objmgr_pdev *pdev); u_int8_t fftbin_size_war; u_int8_t inband_fftbin_size_adj; + u_int8_t null_fftbin_adj; enum spectral_160mhz_report_delivery_state state_160mhz_delivery; void *spectral_report_cache; }; diff --git a/target_if/spectral/target_if_spectral_phyerr.c b/target_if/spectral/target_if_spectral_phyerr.c index 5308127c3d40..e61b74d3f2ff 100644 --- a/target_if/spectral/target_if_spectral_phyerr.c +++ b/target_if/spectral/target_if_spectral_phyerr.c @@ -1186,15 +1186,26 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, int fft_hdr_length = (p_fft_report->fft_hdr_length * 4); int report_len = (fft_hdr_length + 8); int fft_bin_len = (fft_hdr_length - 16); - int fft_bin_len_adj = fft_bin_len >> 2; - int fft_bin_len_inband_tfer = 0; int fft_bin_len_to_dump = fft_bin_len; + int fft_bin_len_adj = 0; + int fft_bin_len_inband_tfer = 0; - if ((spectral->params.ss_rpt_mode == 2) && - spectral->inband_fftbin_size_adj) { - fft_bin_len_adj >>= 1; - fft_bin_len_inband_tfer = fft_bin_len >> 1; - fft_bin_len_to_dump = fft_bin_len_inband_tfer; + if ((spectral->params.ss_rpt_mode == 1) && + spectral->null_fftbin_adj) { + /* fft_bin_len_adj is intentionally left at 0. */ + fft_bin_len_to_dump = 0; + } else { + if (spectral->fftbin_size_war) + fft_bin_len_adj = fft_bin_len >> 2; + else + fft_bin_len_adj = fft_bin_len; + + if ((spectral->params.ss_rpt_mode == 2) && + spectral->inband_fftbin_size_adj) { + fft_bin_len_adj >>= 1; + fft_bin_len_inband_tfer = fft_bin_len >> 1; + fft_bin_len_to_dump = fft_bin_len_inband_tfer; + } } spectral_debug("#############################################################"); @@ -1208,14 +1219,20 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, fft_hdr_length, fft_hdr_length); spectral_debug("Total length of search fft report is %d(0x%x) bytes", report_len, report_len); - spectral_debug("FW reported fftbins in report is %d(0x%x)", fft_bin_len, + spectral_debug("Target reported fftbins in report is %d(0x%x)", + fft_bin_len, fft_bin_len); - if ((spectral->params.ss_rpt_mode == 2) && - spectral->inband_fftbin_size_adj) { + + if ((spectral->params.ss_rpt_mode == 1) && + spectral->null_fftbin_adj) + spectral_debug("WAR: Considering number of FFT bins as 0"); + else if ((spectral->params.ss_rpt_mode == 2) && + spectral->inband_fftbin_size_adj) { spectral_debug("FW fftbins actually transferred (in-band report mode) " "%d(0x%x)", fft_bin_len_inband_tfer, fft_bin_len_inband_tfer); } + spectral_debug("Actual number of fftbins in report is %d(0x%x)\n", fft_bin_len_adj, fft_bin_len_adj); @@ -1231,13 +1248,15 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, p_sfft->fft_peak_mag, p_sfft->fft_avgpwr_db, p_sfft->fft_relpwr_db); - spectral_debug("FFT bins:"); - for (i = 0; i < fft_bin_len_to_dump; i++) { - if (i % 16 == 0) - spectral_debug("\n%d :", i); - fft_mag = - ((uint8_t *)p_fft_report)[SPECTRAL_FFT_BINS_POS + i]; - spectral_debug("%d ", fft_mag); + if (fft_bin_len_to_dump > 0) { + spectral_debug("FFT bins:"); + for (i = 0; i < fft_bin_len_to_dump; i++) { + if (i % 16 == 0) + spectral_debug("\n%d :", i); + fft_mag = + ((uint8_t *)p_fft_report)[SPECTRAL_FFT_BINS_POS + i]; + spectral_debug("%d ", fft_mag); + } } spectral_debug("\n"); spectral_debug("#############################################################"); @@ -1491,13 +1510,28 @@ target_if_consume_spectral_report_gen3( } report_len = (fft_hdr_length + 8); - fft_bin_len = (fft_hdr_length - 16); - /* Divide fft bin length by 4 if fftbin_size_war is enabled */ - if (spectral->fftbin_size_war) - fft_bin_len >>= 2; - if ((spectral->params.ss_rpt_mode == 2) && - spectral->inband_fftbin_size_adj) { - fft_bin_len >>= 1; + + if ((spectral->params.ss_rpt_mode == 1) && + spectral->null_fftbin_adj) { + /* + * No FFT bins are expected. Explicitly set FFT bin + * length to 0. + */ + fft_bin_len = 0; + } else { + fft_bin_len = (fft_hdr_length - 16); + + /* + * Divide fft bin length by 4 if fftbin_size_war is + * enabled. + */ + if (spectral->fftbin_size_war) + fft_bin_len >>= 2; + + if ((spectral->params.ss_rpt_mode == 2) && + spectral->inband_fftbin_size_adj) { + fft_bin_len >>= 1; + } } tsf64 = p_fft_report->fft_timestamp; @@ -1603,14 +1637,28 @@ target_if_consume_spectral_report_gen3( } report_len = (fft_hdr_length + 8); - fft_bin_len = (fft_hdr_length - 16); - /* Divide fft bin length by 4 if fftbin_size_war is enabled */ - if (spectral->fftbin_size_war) { - fft_bin_len >>= 2; - } - if ((spectral->params.ss_rpt_mode == 2) && - spectral->inband_fftbin_size_adj) { - fft_bin_len >>= 1; + + if ((spectral->params.ss_rpt_mode == 1) && + spectral->null_fftbin_adj) { + /* + * No FFT bins are expected. Explicitly set FFT bin + * length to 0. + */ + fft_bin_len = 0; + } else { + fft_bin_len = (fft_hdr_length - 16); + + /* + * Divide fft bin length by 4 if fftbin_size_war is + * enabled. + */ + if (spectral->fftbin_size_war) + fft_bin_len >>= 2; + + if ((spectral->params.ss_rpt_mode == 2) && + spectral->inband_fftbin_size_adj) { + fft_bin_len >>= 1; + } } target_if_process_sfft_report_gen3(p_fft_report, p_sfft);