From 24a08f2ad9b111928bd049a19539119e41efdc0a Mon Sep 17 00:00:00 2001 From: Krishna Rao Date: Wed, 4 Apr 2018 16:42:33 +0530 Subject: [PATCH] qcacmn: Adjust FFT bin size for Spectral report mode 2 On IPQ8074, for report mode 2 only the in-band bins are DMA'ed. Scatter/gather is used. However, the HW generates all bins, not just in-band, and reports the number of bins accordingly. The subsystem arranging for the DMA cannot change this value. The host driver needs to check if report format is 2, and if so halve the number of bins reported to get the number actually DMA'ed. CRs-Fixed: 2218423 Change-Id: Ic0be87422c67110cf3595a4bea71dc872d5b2504 --- target_if/spectral/target_if_spectral.c | 7 ++- target_if/spectral/target_if_spectral.h | 12 ++++- .../spectral/target_if_spectral_phyerr.c | 44 +++++++++++++++---- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/target_if/spectral/target_if_spectral.c b/target_if/spectral/target_if_spectral.c index 6533c9d50649..b4637ea5f79c 100644 --- a/target_if/spectral/target_if_spectral.c +++ b/target_if/spectral/target_if_spectral.c @@ -1975,10 +1975,13 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) /* Set the default values for spectral parameters */ target_if_spectral_init_param_defaults(spectral); #ifdef CONFIG_WIN - if (target_type == TARGET_TYPE_QCA8074) + if (target_type == TARGET_TYPE_QCA8074) { spectral->fftbin_size_war = 1; - else + spectral->inband_fftbin_size_adj = 1; + } else { spectral->fftbin_size_war = 0; + spectral->inband_fftbin_size_adj = 0; + } if ((target_type == TARGET_TYPE_QCA8074) || ( target_type == TARGET_TYPE_QCA6290)) { spectral->spectral_gen = SPECTRAL_GEN3; diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index f22fae5172dd..fbf5c739c099 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/target_if/spectral/target_if_spectral.h @@ -702,6 +702,14 @@ struct wmi_spectral_cmd_ops { * @nl_cb: Netlink callbacks * @use_nl_bcast: Whether to use Netlink broadcast/unicast * @send_phy_data: Send data to the applicaton layer + * @inband_fftbin_size_adj: Whether to carry out FFT bin size adjustment for + * in-band report format. This would be required on some chipsets under the + * following circumstances: In report mode 2 only the in-band bins are DMA'ed. + * Scatter/gather is used. However, the HW generates all bins, not just in-band, + * and reports the number of bins accordingly. The subsystem arranging for the + * 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. */ struct target_if_spectral { struct wlan_objmgr_pdev *pdev_obj; @@ -803,6 +811,7 @@ struct target_if_spectral { bool use_nl_bcast; int (*send_phy_data)(struct wlan_objmgr_pdev *pdev); u_int8_t fftbin_size_war; + u_int8_t inband_fftbin_size_adj; }; /** @@ -1059,6 +1068,7 @@ int target_if_spectral_dump_phyerr_data_gen2( /** * target_if_dump_fft_report_gen3() - Dump FFT Report for gen3 + * @spectral: Pointer to Spectral object * @p_fft_report: Pointer to fft report * @p_sfft: Pointer to search fft report * @@ -1066,7 +1076,7 @@ int target_if_spectral_dump_phyerr_data_gen2( * * Return: Success/Failure */ -int target_if_dump_fft_report_gen3( +int target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, struct spectral_phyerr_fft_report_gen3 *p_fft_report, struct spectral_search_fft_info_gen3 *p_sfft); diff --git a/target_if/spectral/target_if_spectral_phyerr.c b/target_if/spectral/target_if_spectral_phyerr.c index 988b325d750c..288230d12cf9 100644 --- a/target_if/spectral/target_if_spectral_phyerr.c +++ b/target_if/spectral/target_if_spectral_phyerr.c @@ -1175,9 +1175,9 @@ target_if_process_sfft_report_gen3( } int -target_if_dump_fft_report_gen3(struct spectral_phyerr_fft_report_gen3 - *p_fft_report, - struct spectral_search_fft_info_gen3 *p_sfft) +target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, + struct spectral_phyerr_fft_report_gen3 *p_fft_report, + struct spectral_search_fft_info_gen3 *p_sfft) { int i = 0; int fft_mag = 0; @@ -1185,6 +1185,15 @@ target_if_dump_fft_report_gen3(struct spectral_phyerr_fft_report_gen3 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; + + 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("#############################################################"); spectral_debug("Spectral search fft_report"); @@ -1199,6 +1208,12 @@ target_if_dump_fft_report_gen3(struct spectral_phyerr_fft_report_gen3 report_len, report_len); spectral_debug("FW 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) { + spectral_debug("FW fftbins actually transfered (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); @@ -1215,7 +1230,7 @@ target_if_dump_fft_report_gen3(struct spectral_phyerr_fft_report_gen3 p_sfft->fft_avgpwr_db, p_sfft->fft_relpwr_db); spectral_debug("FFT bins:"); - for (i = 0; i < (fft_hdr_length - 16); i++) { + for (i = 0; i < fft_bin_len_to_dump; i++) { if (i % 16 == 0) spectral_debug("\n%d :", i); fft_mag = @@ -1376,7 +1391,14 @@ target_if_consume_spectral_report_gen3( } report_len = (fft_hdr_length + 8); + fft_bin_len = (fft_hdr_length - 16); + 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; target_if_process_sfft_report_gen3(p_fft_report, p_sfft); @@ -1389,7 +1411,7 @@ target_if_consume_spectral_report_gen3( } if (spectral_debug_level & (DEBUG_SPECTRAL2 | DEBUG_SPECTRAL4)) - target_if_dump_fft_report_gen3(p_fft_report, p_sfft); + target_if_dump_fft_report_gen3(spectral, p_fft_report, p_sfft); if (spectral->upper_is_control) rssi_up = control_rssi; @@ -1471,7 +1493,7 @@ target_if_consume_spectral_report_gen3( /* TODO: Fill proper values once FW provides them*/ params.noise_floor = DUMMY_NF_VALUE; params.datalen = (fft_hdr_length * 4); - params.pwr_count = fft_bin_len >> 2; + params.pwr_count = fft_bin_len; params.tstamp = (tsf64 & SPECTRAL_TSMASK); if (spectral->ch_width == CH_WIDTH_160MHZ) { @@ -1496,7 +1518,13 @@ target_if_consume_spectral_report_gen3( p_fft_report = (struct spectral_phyerr_fft_report_gen3 *)(data); fft_hdr_length = p_fft_report->fft_hdr_length * 4; report_len = (fft_hdr_length + 8); + fft_bin_len = (fft_hdr_length - 16); + 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); @@ -1509,7 +1537,7 @@ target_if_consume_spectral_report_gen3( if (spectral_debug_level & (DEBUG_SPECTRAL2 | DEBUG_SPECTRAL4)) - target_if_dump_fft_report_gen3(p_fft_report, p_sfft); + target_if_dump_fft_report_gen3(spectral, p_fft_report, p_sfft); params.vhtop_ch_freq_seg1 = 0; params.vhtop_ch_freq_seg2 = 0; @@ -1534,7 +1562,7 @@ target_if_consume_spectral_report_gen3( /* params.max_index_sec80 = p_sfft->peak_inx; */ /* XXX Does this definition of datalen *still hold? */ params.datalen_sec80 = fft_hdr_length; - params.pwr_count_sec80 = fft_bin_len >> 2; + params.pwr_count_sec80 = fft_bin_len; params.bin_pwr_data_sec80 = (u_int8_t *)( (uint8_t *)p_fft_report + SPECTRAL_FFT_BINS_POS); }