diff --git a/spectral/dispatcher/inc/spectral_ioctl.h b/spectral/dispatcher/inc/spectral_ioctl.h index 4f99495f1a..1907599e87 100644 --- a/spectral/dispatcher/inc/spectral_ioctl.h +++ b/spectral/dispatcher/inc/spectral_ioctl.h @@ -90,11 +90,14 @@ enum spectral_params { * enum spectral_scan_mode - Spectral scan mode * @SPECTRAL_SCAN_MODE_NORMAL: Normal mode * @SPECTRAL_SCAN_MODE_AGILE: Agile mode + * @SPECTRAL_SCAN_MODE_MAX: Max number of Spectral modes + * @SPECTRAL_SCAN_MODE_INVALID: Invalid Spectral mode */ enum spectral_scan_mode { SPECTRAL_SCAN_MODE_NORMAL, SPECTRAL_SCAN_MODE_AGILE, SPECTRAL_SCAN_MODE_MAX, + SPECTRAL_SCAN_MODE_INVALID = 0xff, }; struct spectral_ioctl_params { diff --git a/target_if/spectral/target_if_spectral.c b/target_if/spectral/target_if_spectral.c index 0c7fddb409..49f824ad1b 100644 --- a/target_if/spectral/target_if_spectral.c +++ b/target_if/spectral/target_if_spectral.c @@ -2132,14 +2132,27 @@ target_if_spectral_report_params_init( struct spectral_report_params *rparams, uint32_t target_type) { + enum spectral_scan_mode smode; + /* This entries are currently used by gen3 chipsets only. Hence * initialization is done for gen3 alone. In future if other generations * needs to use them they have to add proper initial values. */ - if (target_type == TARGET_TYPE_QCN9000) + if (target_type == TARGET_TYPE_QCN9000) { rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_2; - else + rparams->num_spectral_detectors = + NUM_SPECTRAL_DETECTORS_GEN3_V2; + smode = SPECTRAL_SCAN_MODE_NORMAL; + for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) + rparams->fragmentation_160[smode] = false; + } else { rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_1; + rparams->num_spectral_detectors = + NUM_SPECTRAL_DETECTORS_GEN3_V1; + smode = SPECTRAL_SCAN_MODE_NORMAL; + for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) + rparams->fragmentation_160[smode] = true; + } switch (rparams->version) { case SPECTRAL_REPORT_FORMAT_VERSION_1: @@ -2157,6 +2170,20 @@ target_if_spectral_report_params_init( default: qdf_assert_always(0); } + + rparams->detid_mode_table[SPECTRAL_DETECTOR_ID_0] = + SPECTRAL_SCAN_MODE_NORMAL; + if (target_type == TARGET_TYPE_QCN9000) { + rparams->detid_mode_table[SPECTRAL_DETECTOR_ID_1] = + SPECTRAL_SCAN_MODE_AGILE; + rparams->detid_mode_table[SPECTRAL_DETECTOR_ID_2] = + SPECTRAL_SCAN_MODE_INVALID; + } else { + rparams->detid_mode_table[SPECTRAL_DETECTOR_ID_1] = + SPECTRAL_SCAN_MODE_NORMAL; + rparams->detid_mode_table[SPECTRAL_DETECTOR_ID_2] = + SPECTRAL_SCAN_MODE_AGILE; + } } /** diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index 18dbfd0a07..8c53d437cd 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/target_if/spectral/target_if_spectral.h @@ -139,16 +139,18 @@ enum spectral_160mhz_report_delivery_state { /** * enum spectral_detector_id - Spectral detector id - * @SPECTRAL_DETECTOR_PRIMARY: Primary detector - * @SPECTRAL_DETECTOR_SECONDARY: Secondary detector - * @SPECTRAL_DETECTOR_AGILE: Agile detector - * @SPECTRAL_DETECTOR_INVALID: Invalid detector + * @SPECTRAL_DETECTOR_ID_0: Spectral detector 0 + * @SPECTRAL_DETECTOR_ID_1: Spectral detector 1 + * @SPECTRAL_DETECTOR_ID_2: Spectral detector 2 + * @SPECTRAL_DETECTOR_ID_MAX: Max Spectral detector ID + * @SPECTRAL_DETECTOR_ID_INVALID: Invalid Spectral detector ID */ enum spectral_detector_id { - SPECTRAL_DETECTOR_PRIMARY, - SPECTRAL_DETECTOR_SECONDARY, - SPECTRAL_DETECTOR_AGILE, - SPECTRAL_DETECTOR_INVALID, + SPECTRAL_DETECTOR_ID_0, + SPECTRAL_DETECTOR_ID_1, + SPECTRAL_DETECTOR_ID_2, + SPECTRAL_DETECTOR_ID_MAX, + SPECTRAL_DETECTOR_ID_INVALID = 0xff, }; /** @@ -263,6 +265,8 @@ struct spectral_phyerr_fft_gen2 { #define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03) #define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4) +#define NUM_SPECTRAL_DETECTORS_GEN3_V1 (3) +#define NUM_SPECTRAL_DETECTORS_GEN3_V2 (2) #define FFT_REPORT_HEADER_LENGTH_GEN3_V2 (24) #define FFT_REPORT_HEADER_LENGTH_GEN3_V1 (16) #define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1 (0) @@ -500,11 +504,18 @@ struct spectral_fft_bin_len_adj_swar { * @fft_report_hdr_len: Number of bytes in the header of the FFT report. This * has to be subtracted from the length field of FFT report to find the length * of FFT bins. + * @fragmentation_160: This indicates whether Spectral reports in 160/80p80 is + * fragmented. + * @detid_mode_table: Detector ID to Spectral scan mode table + * @num_spectral_detectors: Total number of Spectral detectors */ struct spectral_report_params { enum spectral_report_format_version version; uint8_t ssumaary_padding_bytes; uint8_t fft_report_hdr_len; + bool fragmentation_160[SPECTRAL_SCAN_MODE_MAX]; + enum spectral_scan_mode detid_mode_table[SPECTRAL_DETECTOR_ID_MAX]; + uint8_t num_spectral_detectors; }; /** @@ -1026,7 +1037,8 @@ struct target_if_spectral { enum spectral_msg_type smsg_type); 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; + enum spectral_160mhz_report_delivery_state + state_160mhz_delivery[SPECTRAL_SCAN_MODE_MAX]; bool dbr_ring_debug; bool dbr_buff_debug; bool direct_dma_support; @@ -1083,7 +1095,8 @@ struct target_if_spectral { * primary 80 MHz segment instead of the secondary 80 MHz segment due to a * channel switch - Software may choose to ignore the sample if this is set. * Applicable only if smode = SPECTRAL_SCAN_MODE_NORMAL and for 160/80+80 MHz - * Spectral operation. + * Spectral operation and if the chipset supports fragmented 160/80+80 MHz + * operation. * @last_raw_timestamp: Previous FFT report's raw timestamp. In case of 160MHz * it will be primary 80 segment's timestamp as both primary & secondary * segment's timestamps are expected to be almost equal @@ -1584,8 +1597,12 @@ target_if_get_spectral_msg_type(enum spectral_scan_mode smode, static inline void init_160mhz_delivery_state_machine(struct target_if_spectral *spectral) { - spectral->state_160mhz_delivery = - SPECTRAL_REPORT_WAIT_PRIMARY80; + uint8_t smode; + + smode = 0; + for (; smode < SPECTRAL_SCAN_MODE_MAX; smode++) + spectral->state_160mhz_delivery[smode] = + SPECTRAL_REPORT_WAIT_PRIMARY80; } /** @@ -1603,13 +1620,18 @@ reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral, enum spectral_msg_type smsg_type; QDF_STATUS ret; - if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) { - spectral->state_160mhz_delivery = + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + spectral_err_rl("Invalid Spectral mode %d", smode); + return; + } + + if (spectral->ch_width[smode] == CH_WIDTH_160MHZ) { + spectral->state_160mhz_delivery[smode] = SPECTRAL_REPORT_WAIT_PRIMARY80; ret = target_if_get_spectral_msg_type(smode, &smsg_type); if (QDF_IS_STATUS_ERROR(ret)) { - spectral_err("Failed to reset 160 MHz state machine"); + spectral_err("Failed to get spectral message type"); return; } @@ -1621,22 +1643,27 @@ reset_160mhz_delivery_state_machine(struct target_if_spectral *spectral, /** * is_secondaryseg_expected() - Is waiting for secondary 80 report * @spectral: Pointer to Spectral + * @smode: Spectral scan mode * * Return true if secondary 80 report expected and mode is 160 MHz * * Return: true or false */ static inline -bool is_secondaryseg_expected(struct target_if_spectral *spectral) +bool is_secondaryseg_expected(struct target_if_spectral *spectral, + enum spectral_scan_mode smode) { return - ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) && - (spectral->state_160mhz_delivery == SPECTRAL_REPORT_WAIT_SECONDARY80)); + ((spectral->ch_width[smode] == CH_WIDTH_160MHZ) && + spectral->rparams.fragmentation_160[smode] && + (spectral->state_160mhz_delivery[smode] == + SPECTRAL_REPORT_WAIT_SECONDARY80)); } /** * is_primaryseg_expected() - Is waiting for primary 80 report * @spectral: Pointer to Spectral + * @smode: Spectral scan mode * * Return true if mode is 160 Mhz and primary 80 report expected or * mode is not 160 Mhz @@ -1644,55 +1671,67 @@ bool is_secondaryseg_expected(struct target_if_spectral *spectral) * Return: true or false */ static inline -bool is_primaryseg_expected(struct target_if_spectral *spectral) +bool is_primaryseg_expected(struct target_if_spectral *spectral, + enum spectral_scan_mode smode) { return - ((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))); + ((spectral->ch_width[smode] != CH_WIDTH_160MHZ) || + ((spectral->ch_width[smode] == CH_WIDTH_160MHZ) && + (!spectral->rparams.fragmentation_160[smode] || + spectral->state_160mhz_delivery[smode] == + SPECTRAL_REPORT_WAIT_PRIMARY80))); } /** * is_primaryseg_rx_inprog() - Is primary 80 report processing is in progress * @spectral: Pointer to Spectral + * @smode: Spectral scan mode * * Is primary 80 report processing is in progress * * Return: true or false */ static inline -bool is_primaryseg_rx_inprog(struct target_if_spectral *spectral) +bool is_primaryseg_rx_inprog(struct target_if_spectral *spectral, + enum spectral_scan_mode smode) { return - ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ) || - ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) && + ((spectral->ch_width[smode] != CH_WIDTH_160MHZ) || + ((spectral->ch_width[smode] == CH_WIDTH_160MHZ) && ((spectral->spectral_gen == SPECTRAL_GEN2) || ((spectral->spectral_gen == SPECTRAL_GEN3) && - (spectral->state_160mhz_delivery == SPECTRAL_REPORT_RX_PRIMARY80))))); + (!spectral->rparams.fragmentation_160[smode] || + spectral->state_160mhz_delivery[smode] == + SPECTRAL_REPORT_RX_PRIMARY80))))); } /** * is_secondaryseg_rx_inprog() - Is secondary80 report processing is in progress * @spectral: Pointer to Spectral + * @smode: Spectral scan mode * * Is secondary 80 report processing is in progress * * Return: true or false */ static inline -bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral) +bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral, + enum spectral_scan_mode smode) { return - ((spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == CH_WIDTH_160MHZ) && + ((spectral->ch_width[smode] == CH_WIDTH_160MHZ) && ((spectral->spectral_gen == SPECTRAL_GEN2) || ((spectral->spectral_gen == SPECTRAL_GEN3) && - (spectral->state_160mhz_delivery == SPECTRAL_REPORT_RX_SECONDARY80)))); + (!spectral->rparams.fragmentation_160[smode] || + spectral->state_160mhz_delivery[smode] == + SPECTRAL_REPORT_RX_SECONDARY80)))); } /** * target_if_160mhz_delivery_state_change() - State transition for 160Mhz * Spectral * @spectral: Pointer to spectral object + * @smode: Spectral scan mode * @detector_id: Detector id * * Move the states of state machine for 160MHz spectral scan report receive @@ -1701,6 +1740,7 @@ bool is_secondaryseg_rx_inprog(struct target_if_spectral *spectral) */ QDF_STATUS target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, + enum spectral_scan_mode smode, uint8_t detector_id); /** @@ -2043,6 +2083,7 @@ void target_if_register_wmi_spectral_cmd_ops( QDF_STATUS target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, + enum spectral_scan_mode smode, uint8_t detector_id); #ifdef DIRECT_BUF_RX_ENABLE /** diff --git a/target_if/spectral/target_if_spectral_netlink.c b/target_if/spectral/target_if_spectral_netlink.c index a2be35823b..e3f38d655e 100644 --- a/target_if/spectral/target_if_spectral_netlink.c +++ b/target_if/spectral/target_if_spectral_netlink.c @@ -57,8 +57,7 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, if (QDF_IS_STATUS_ERROR(ret)) return; - if ((params->smode == SPECTRAL_SCAN_MODE_AGILE) || - is_primaryseg_rx_inprog(spectral)) { + if (is_primaryseg_rx_inprog(spectral, params->smode)) { spec_samp_msg = (struct spectral_samp_msg *) spectral->nl_cb.get_sbuff(spectral->pdev_obj, msg_type, @@ -169,7 +168,7 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, p_sops->get_mac_address(spectral, spec_samp_msg->macaddr); } - if (is_secondaryseg_rx_inprog(spectral)) { + if (is_secondaryseg_rx_inprog(spectral, params->smode)) { spec_samp_msg = (struct spectral_samp_msg *) spectral->nl_cb.get_sbuff(spectral->pdev_obj, msg_type, @@ -239,9 +238,8 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, } } - if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ || - (params->smode == SPECTRAL_SCAN_MODE_AGILE) || - is_secondaryseg_rx_inprog(spectral)) { + if (spectral->ch_width[params->smode] != CH_WIDTH_160MHZ || + is_secondaryseg_rx_inprog(spectral, params->smode)) { if (spectral->send_phy_data(spectral->pdev_obj, msg_type) == 0) spectral->spectral_sent_msg++; @@ -249,9 +247,10 @@ target_if_spectral_create_samp_msg(struct target_if_spectral *spectral, } /* Take care of state transitions for 160MHz/ 80p80 */ - if ((spectral->spectral_gen == SPECTRAL_GEN3) && - (params->smode != SPECTRAL_SCAN_MODE_AGILE)) + if (spectral->spectral_gen == SPECTRAL_GEN3 && + spectral->ch_width[params->smode] == CH_WIDTH_160MHZ && + spectral->rparams.fragmentation_160[params->smode]) target_if_160mhz_delivery_state_change( - spectral, - SPECTRAL_DETECTOR_INVALID); + spectral, params->smode, + SPECTRAL_DETECTOR_ID_INVALID); } diff --git a/target_if/spectral/target_if_spectral_phyerr.c b/target_if/spectral/target_if_spectral_phyerr.c index cc9388fc6f..a79ab9871a 100644 --- a/target_if/spectral/target_if_spectral_phyerr.c +++ b/target_if/spectral/target_if_spectral_phyerr.c @@ -1196,12 +1196,36 @@ target_if_spectral_dump_phyerr_data_gen2(uint8_t *data, uint32_t datalen, } #ifdef DIRECT_BUF_RX_ENABLE +/** + * target_if_get_spectral_mode() - Get Spectral scan mode corresponding to a + * detector id + * @detector_id: detector id in the Spectral report + * @rparams: pointer to report params object + * + * Helper API to get Spectral scan mode from the detector ID. This mapping is + * target specific. + * + * Return: Spectral scan mode + */ +static enum spectral_scan_mode +target_if_get_spectral_mode(enum spectral_detector_id detector_id, + struct spectral_report_params *rparams) +{ + if (detector_id >= SPECTRAL_DETECTOR_ID_MAX) { + spectral_err_rl("Invalid detector id %d", detector_id); + return SPECTRAL_SCAN_MODE_INVALID; + } + + return rparams->detid_mode_table[detector_id]; +} + /** * target_if_spectral_get_bin_count_after_len_adj() - Get number of FFT bins in * Spectral FFT report * @fft_bin_len: FFT bin length reported by target * @rpt_mode: Spectral report mode * @swar: Spectral FFT bin length adjustments SWAR parameters + * @fft_bin_size: Size of one FFT bin in bytes * * Get actual number of FFT bins in the FFT report after adjusting the length * by applying the SWARs for getting correct length. @@ -1211,7 +1235,8 @@ target_if_spectral_dump_phyerr_data_gen2(uint8_t *data, uint32_t datalen, static size_t target_if_spectral_get_bin_count_after_len_adj( size_t fft_bin_len, uint8_t rpt_mode, - struct spectral_fft_bin_len_adj_swar *swar) + struct spectral_fft_bin_len_adj_swar *swar, + size_t *fft_bin_size) { size_t fft_bin_count = fft_bin_len; @@ -1221,6 +1246,7 @@ target_if_spectral_get_bin_count_after_len_adj( * count to 0. */ fft_bin_count = 0; + *fft_bin_size = 0; } else { /* * Divide fft bin length by appropriate factor depending @@ -1229,9 +1255,11 @@ target_if_spectral_get_bin_count_after_len_adj( switch (swar->fftbin_size_war) { case SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE: fft_bin_count >>= 2; + *fft_bin_size = 4; break; case SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE: fft_bin_count >>= 1; + *fft_bin_size = 2; /* Ideally we should be dividing fft bin length * by 2. Due to a HW bug, actual length is two * times the expected length. @@ -1240,6 +1268,7 @@ target_if_spectral_get_bin_count_after_len_adj( fft_bin_count >>= 1; break; case SPECTRAL_FFTBIN_SIZE_NO_WAR: + *fft_bin_size = 1; /* No length adjustment */ break; default: @@ -1331,6 +1360,7 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, size_t report_len = (fft_hdr_length + 8); size_t fft_bin_len; size_t fft_bin_count; + size_t fft_bin_size; size_t fft_bin_len_inband_tfer = 0; uint8_t *fft_bin_buf = NULL; @@ -1338,7 +1368,7 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( fft_bin_len, spectral->params[smode].ss_rpt_mode, - &spectral->len_adj_swar); + &spectral->len_adj_swar, &fft_bin_size); if ((spectral->params[smode].ss_rpt_mode == 2) && spectral->len_adj_swar.inband_fftbin_size_adj) @@ -1414,22 +1444,25 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, QDF_STATUS target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, + enum spectral_scan_mode smode, uint8_t detector_id) { QDF_STATUS status = QDF_STATUS_SUCCESS; - if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] != CH_WIDTH_160MHZ) + if (smode >= SPECTRAL_SCAN_MODE_MAX) { + spectral_err_rl("Invalid Spectral mode %d", smode); + return QDF_STATUS_E_INVAL; + } + + if (spectral->ch_width[smode] != CH_WIDTH_160MHZ) { + spectral_err_rl("Current scan BW %d is not 160 for mode %d", + spectral->ch_width[smode], smode); return QDF_STATUS_E_FAILURE; + } - /* agile reports should not be coupled with 160 MHz state machine - * for normal Spectral - */ - if (detector_id == SPECTRAL_DETECTOR_AGILE) - return QDF_STATUS_SUCCESS; - - switch (spectral->state_160mhz_delivery) { + switch (spectral->state_160mhz_delivery[smode]) { case SPECTRAL_REPORT_WAIT_PRIMARY80: - if (detector_id == SPECTRAL_DETECTOR_PRIMARY) - spectral->state_160mhz_delivery = + if (detector_id == SPECTRAL_DETECTOR_ID_0) + spectral->state_160mhz_delivery[smode] = SPECTRAL_REPORT_RX_PRIMARY80; else { status = QDF_STATUS_E_FAILURE; @@ -1438,11 +1471,11 @@ target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, break; case SPECTRAL_REPORT_WAIT_SECONDARY80: - if (detector_id == SPECTRAL_DETECTOR_SECONDARY) - spectral->state_160mhz_delivery = + if (detector_id == SPECTRAL_DETECTOR_ID_1) + spectral->state_160mhz_delivery[smode] = SPECTRAL_REPORT_RX_SECONDARY80; else { - spectral->state_160mhz_delivery = + spectral->state_160mhz_delivery[smode] = SPECTRAL_REPORT_WAIT_PRIMARY80; status = QDF_STATUS_E_FAILURE; spectral->diag_stats.spectral_vhtseg2id_mismatch++; @@ -1451,13 +1484,12 @@ target_if_160mhz_delivery_state_change(struct target_if_spectral *spectral, case SPECTRAL_REPORT_RX_SECONDARY80: /* We don't care about detector id in this state. */ - reset_160mhz_delivery_state_machine(spectral, - SPECTRAL_SCAN_MODE_NORMAL); + reset_160mhz_delivery_state_machine(spectral, smode); break; case SPECTRAL_REPORT_RX_PRIMARY80: /* We don't care about detector id in this state */ - spectral->state_160mhz_delivery = + spectral->state_160mhz_delivery[smode] = SPECTRAL_REPORT_WAIT_SECONDARY80; break; @@ -1601,27 +1633,6 @@ target_if_spectral_get_lowest_chn_idx(uint8_t chainmask) return idx; } -static QDF_STATUS -target_if_get_spectral_mode(enum spectral_detector_id detector_id, - enum spectral_scan_mode *smode) { - switch (detector_id) { - case SPECTRAL_DETECTOR_PRIMARY: - case SPECTRAL_DETECTOR_SECONDARY: - *smode = SPECTRAL_SCAN_MODE_NORMAL; - break; - - case SPECTRAL_DETECTOR_AGILE: - *smode = SPECTRAL_SCAN_MODE_AGILE; - break; - - default: - spectral_err("Invalid Spectral detector id"); - return QDF_STATUS_E_FAILURE; - } - - return QDF_STATUS_SUCCESS; -} - #ifdef DIRECT_BUF_RX_DEBUG static void target_if_spectral_check_buffer_poisoning( struct target_if_spectral *spectral, @@ -1795,6 +1806,7 @@ target_if_consume_spectral_report_gen3( int fft_hdr_length = 0; int report_len = 0; size_t fft_bin_count; + size_t fft_bin_size; struct target_if_spectral_ops *p_sops = GET_TARGET_IF_SPECTRAL_OPS(spectral); struct spectral_phyerr_fft_report_gen3 *p_fft_report; @@ -1805,8 +1817,7 @@ target_if_consume_spectral_report_gen3( struct sscan_report_fields_gen3 sscan_report_fields = {0}; enum spectral_detector_id detector_id; QDF_STATUS ret; - - params.smode = SPECTRAL_SCAN_MODE_NORMAL; + enum spectral_scan_mode spectral_mode = SPECTRAL_SCAN_MODE_INVALID; /* Process Spectral scan summary report */ if (target_if_verify_sig_and_tag_gen3( @@ -1817,20 +1828,28 @@ target_if_consume_spectral_report_gen3( } detector_id = target_if_get_detector_id_sscan_summary_report_gen3(data); - if (detector_id > SPECTRAL_DETECTOR_AGILE) { + if (detector_id >= spectral->rparams.num_spectral_detectors) { spectral->diag_stats.spectral_invalid_detector_id++; spectral_err("Invalid detector id %u, expected is 0/1/2", detector_id); goto fail; } + + spectral_mode = target_if_get_spectral_mode(detector_id, + &spectral->rparams); + if (spectral_mode == SPECTRAL_SCAN_MODE_INVALID) { + spectral_err_rl("No valid Spectral mode for detector id %u", + detector_id); + goto fail; + } + target_if_consume_sscan_summary_report_gen3(data, &sscan_report_fields, &spectral->rparams); /* Advance buf pointer to the search fft report */ data += sizeof(struct spectral_sscan_summary_report_gen3); data += spectral->rparams.ssumaary_padding_bytes; - if ((detector_id == SPECTRAL_DETECTOR_AGILE) || - is_primaryseg_expected(spectral)) { + if (is_primaryseg_expected(spectral, spectral_mode)) { /* RSSI is in 1/2 dBm steps, Covert it to dBm scale */ rssi = (sscan_report_fields.inband_pwr_db) >> 1; params.agc_total_gain = @@ -1867,50 +1886,44 @@ target_if_consume_spectral_report_gen3( goto fail; } - if (detector_id > SPECTRAL_DETECTOR_AGILE) { + if (detector_id > spectral->rparams.num_spectral_detectors) { spectral->diag_stats.spectral_invalid_detector_id++; spectral_err("Invalid detector id %u, expected is 0/2", detector_id); goto fail; } - - ret = target_if_get_spectral_mode(detector_id, ¶ms.smode); - if (QDF_IS_STATUS_ERROR(ret)) { - spectral_err_rl("Failed to get mode from detid= %u", - detector_id); - goto fail; - } + params.smode = spectral_mode; fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( fft_hdr_length - spectral->rparams.fft_report_hdr_len, - spectral->params[params.smode].ss_rpt_mode, - &spectral->len_adj_swar); + spectral->params[spectral_mode].ss_rpt_mode, + &spectral->len_adj_swar, &fft_bin_size); params.last_raw_timestamp = spectral->timestamp_war. - last_fft_timestamp[params.smode]; + last_fft_timestamp[spectral_mode]; params.reset_delay = report->reset_delay; params.raw_timestamp = p_sfft->timestamp; params.tstamp = target_if_spectral_get_adjusted_timestamp( &spectral->timestamp_war, p_sfft->timestamp, report->reset_delay, - params.smode); + spectral_mode); params.timestamp_war_offset = spectral->timestamp_war. - timestamp_war_offset[params.smode]; + timestamp_war_offset[spectral_mode]; params.target_reset_count = spectral->timestamp_war. target_reset_count; /* Take care of state transitions for 160 MHz and 80p80 */ - if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == - CH_WIDTH_160MHZ) { + if (spectral->ch_width[spectral_mode] == CH_WIDTH_160MHZ && + spectral->rparams.fragmentation_160[spectral_mode]) { ret = target_if_160mhz_delivery_state_change( - spectral, + spectral, spectral_mode, detector_id); if (ret != QDF_STATUS_SUCCESS) goto fail; } if (spectral_debug_level & (DEBUG_SPECTRAL2 | DEBUG_SPECTRAL4)) - target_if_dump_fft_report_gen3(spectral, params.smode, + target_if_dump_fft_report_gen3(spectral, spectral_mode, p_fft_report, p_sfft); params.rssi = rssi; @@ -1918,9 +1931,8 @@ target_if_consume_spectral_report_gen3( vdev = target_if_spectral_get_vdev(spectral); if (!vdev) { spectral_info("First vdev is NULL"); - reset_160mhz_delivery_state_machine - (spectral, - SPECTRAL_SCAN_MODE_NORMAL); + reset_160mhz_delivery_state_machine( + spectral, spectral_mode); return -EPERM; } vdev_rxchainmask = wlan_vdev_mlme_get_rxchainmask(vdev); @@ -1937,13 +1949,11 @@ target_if_consume_spectral_report_gen3( params.max_mag = p_sfft->fft_peak_mag; - params.bin_pwr_data = (uint8_t *)((uint8_t *)p_fft_report + - SPECTRAL_FFT_BINS_POS); params.freq = p_sops->get_current_channel(spectral); - if (params.smode == SPECTRAL_SCAN_MODE_AGILE) + if (spectral_mode == SPECTRAL_SCAN_MODE_AGILE) params.agile_freq = - spectral->params[params.smode].ss_frequency; + spectral->params[spectral_mode].ss_frequency; /* * For modes upto VHT80, the noise floor is populated with @@ -1954,11 +1964,32 @@ target_if_consume_spectral_report_gen3( params.noise_floor = report->noisefloor[chn_idx_lowest_enabled]; params.datalen = (fft_hdr_length * 4); - params.pwr_count = fft_bin_count; + params.bin_pwr_data = (uint8_t *)((uint8_t *)p_fft_report + + SPECTRAL_FFT_BINS_POS); + params.pwr_count = fft_bin_count; + if (spectral->ch_width[spectral_mode] == CH_WIDTH_160MHZ && + !spectral->rparams.fragmentation_160[spectral_mode]) { + params.agc_total_gain_sec80 = + sscan_report_fields.sscan_agc_total_gain; + params.gainchange_sec80 = + sscan_report_fields.sscan_gainchange; + params.raw_timestamp_sec80 = p_sfft->timestamp; + params.rssi_sec80 = rssi; + params.noise_floor_sec80 = + report->noisefloor[chn_idx_lowest_enabled]; + params.max_mag_sec80 = p_sfft->fft_peak_mag; + params.datalen_sec80 = fft_hdr_length * 4; + params.pwr_count = fft_bin_count / 2; + params.pwr_count_sec80 = fft_bin_count / 2; + params.bin_pwr_data_sec80 = + (uint8_t *)((uint8_t *)p_fft_report + + SPECTRAL_FFT_BINS_POS + (fft_bin_count / 2) * + fft_bin_size); + } target_if_spectral_verify_ts(spectral, report->data, params.tstamp); - } else if (is_secondaryseg_expected(spectral)) { + } else if (is_secondaryseg_expected(spectral, spectral_mode)) { /* RSSI is in 1/2 dBm steps, Covert it to dBm scale */ rssi = (sscan_report_fields.inband_pwr_db) >> 1; params.agc_total_gain_sec80 = @@ -1995,38 +2026,32 @@ target_if_consume_spectral_report_gen3( goto fail; } - if (detector_id > SPECTRAL_DETECTOR_AGILE) { + if (detector_id > spectral->rparams.num_spectral_detectors) { spectral->diag_stats.spectral_invalid_detector_id++; spectral_err("Invalid detector id %u, expected is 1", detector_id); goto fail; } - - ret = target_if_get_spectral_mode(detector_id, ¶ms.smode); - if (QDF_IS_STATUS_ERROR(ret)) { - spectral_err("Failed to get mode from detid= %u", - detector_id); - goto fail; - } + params.smode = spectral_mode; fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( fft_hdr_length - spectral->rparams.fft_report_hdr_len, - spectral->params[params.smode].ss_rpt_mode, - &spectral->len_adj_swar); + spectral->params[spectral_mode].ss_rpt_mode, + &spectral->len_adj_swar, &fft_bin_size); params.raw_timestamp_sec80 = p_sfft->timestamp; /* Take care of state transitions for 160 MHz and 80p80 */ - if (spectral->ch_width[SPECTRAL_SCAN_MODE_NORMAL] == - CH_WIDTH_160MHZ) { + if (spectral->ch_width[spectral_mode] == CH_WIDTH_160MHZ && + spectral->rparams.fragmentation_160[spectral_mode]) { ret = target_if_160mhz_delivery_state_change( - spectral, + spectral, spectral_mode, detector_id); if (ret != QDF_STATUS_SUCCESS) goto fail; } if (spectral_debug_level & (DEBUG_SPECTRAL2 | DEBUG_SPECTRAL4)) - target_if_dump_fft_report_gen3(spectral, params.smode, + target_if_dump_fft_report_gen3(spectral, spectral_mode, p_fft_report, p_sfft); params.vhtop_ch_freq_seg1 = 0; @@ -2038,8 +2063,7 @@ target_if_consume_spectral_report_gen3( if (!vdev) { spectral_info("First vdev is NULL"); reset_160mhz_delivery_state_machine - (spectral, - SPECTRAL_SCAN_MODE_NORMAL); + (spectral, spectral_mode); return -EPERM; } vdev_rxchainmask = wlan_vdev_mlme_get_rxchainmask(vdev); @@ -2071,7 +2095,7 @@ target_if_consume_spectral_report_gen3( } target_if_spectral_check_buffer_poisoning(spectral, report, - fft_bin_count, params.smode); + fft_bin_count, spectral_mode); qdf_mem_copy(¶ms.classifier_params, &spectral->classifier_params, sizeof(struct spectral_classifier_params)); @@ -2082,8 +2106,8 @@ target_if_consume_spectral_report_gen3( return 0; fail: spectral_err_rl("Error while processing Spectral report"); - reset_160mhz_delivery_state_machine(spectral, - SPECTRAL_SCAN_MODE_NORMAL); + if (spectral_mode != SPECTRAL_SCAN_MODE_INVALID) + reset_160mhz_delivery_state_machine(spectral, spectral_mode); return -EPERM; }