diff --git a/os_if/linux/spectral/inc/os_if_spectral_netlink.h b/os_if/linux/spectral/inc/os_if_spectral_netlink.h index 156eaac00b..9028654621 100644 --- a/os_if/linux/spectral/inc/os_if_spectral_netlink.h +++ b/os_if/linux/spectral/inc/os_if_spectral_netlink.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2017-2020 The Linux Foundation. All rights reserved. * * * Permission to use, copy, modify, and/or distribute this software for @@ -36,7 +36,7 @@ void os_if_spectral_nl_data_ready(struct sk_buff *skb); #ifndef SPECTRAL_NETLINK #define SPECTRAL_NETLINK (NETLINK_GENERIC + 1) #endif -#define MAX_SPECTRAL_PAYLOAD 1500 +#define MAX_SPECTRAL_PAYLOAD (2004) /* Init's network namespace */ extern struct net init_net; diff --git a/spectral/dispatcher/inc/spectral_ioctl.h b/spectral/dispatcher/inc/spectral_ioctl.h index 2cb951bbcf..4f99495f1a 100644 --- a/spectral/dispatcher/inc/spectral_ioctl.h +++ b/spectral/dispatcher/inc/spectral_ioctl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2017-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -250,8 +250,10 @@ struct spectral_caps { #define SPECTRAL_IOCTL_PARAM_NOVAL (65535) -#define MAX_SPECTRAL_CHAINS 3 -#define MAX_NUM_BINS 520 +#define MAX_SPECTRAL_CHAINS (3) +#define MAX_NUM_BINS (1024) +#define MAX_NUM_BINS_PRI80 (1024) +#define MAX_NUM_BINS_SEC80 (520) /* 5 categories x (lower + upper) bands */ #define MAX_INTERF 10 @@ -425,8 +427,8 @@ struct spectral_samp_data { uint8_t lb_edge_extrabins; uint8_t rb_edge_extrabins; uint16_t bin_pwr_count_sec80; - uint8_t bin_pwr[MAX_NUM_BINS]; - uint8_t bin_pwr_sec80[MAX_NUM_BINS]; + uint8_t bin_pwr[MAX_NUM_BINS_PRI80]; + uint8_t bin_pwr_sec80[MAX_NUM_BINS_SEC80]; struct interf_src_rsp interf_list; int16_t noise_floor; int16_t noise_floor_sec80; diff --git a/target_if/spectral/target_if_spectral.c b/target_if/spectral/target_if_spectral.c index e61d20399d..d44c00442f 100644 --- a/target_if/spectral/target_if_spectral.c +++ b/target_if/spectral/target_if_spectral.c @@ -2023,7 +2023,8 @@ static void target_if_spectral_len_adj_swar_init(struct spectral_fft_bin_len_adj_swar *swar, uint32_t target_type) { - if (target_type == TARGET_TYPE_QCA8074V2) + if (target_type == TARGET_TYPE_QCA8074V2 || + target_type == TARGET_TYPE_QCN9000) swar->fftbin_size_war = SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE; else if (target_type == TARGET_TYPE_QCA8074 || target_type == TARGET_TYPE_QCA6018 || @@ -2034,13 +2035,63 @@ target_if_spectral_len_adj_swar_init(struct spectral_fft_bin_len_adj_swar *swar, if (target_type == TARGET_TYPE_QCA8074 || target_type == TARGET_TYPE_QCA8074V2 || - target_type == TARGET_TYPE_QCA6018) { + target_type == TARGET_TYPE_QCA6018 || + target_type == TARGET_TYPE_QCN9000) { swar->inband_fftbin_size_adj = 1; swar->null_fftbin_adj = 1; } else { swar->inband_fftbin_size_adj = 0; swar->null_fftbin_adj = 0; } + + if (target_type == TARGET_TYPE_QCA8074V2) + swar->packmode_fftbin_size_adj = 1; + else + swar->packmode_fftbin_size_adj = 0; +} + +/** + * target_if_spectral_report_params_init() - Initialize parameters which + * describes the structure of Spectral reports + * + * @rparams: Pointer to Spectral report parameter object + * @target_type: target type + * + * Function to Initialize parameters related to the structure of Spectral + * reports. + * + * Return: void + */ +static void +target_if_spectral_report_params_init( + struct spectral_report_params *rparams, + uint32_t target_type) +{ + /* 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) + rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_2; + else + rparams->version = SPECTRAL_REPORT_FORMAT_VERSION_1; + + switch (rparams->version) { + case SPECTRAL_REPORT_FORMAT_VERSION_1: + rparams->ssumaary_padding_bytes = + NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V1; + rparams->fft_report_hdr_len = + FFT_REPORT_HEADER_LENGTH_GEN3_V1; + break; + case SPECTRAL_REPORT_FORMAT_VERSION_2: + rparams->ssumaary_padding_bytes = + NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2; + rparams->fft_report_hdr_len = + FFT_REPORT_HEADER_LENGTH_GEN3_V2; + break; + default: + qdf_assert_always(0); + } } /** @@ -2120,11 +2171,13 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) if (target_type == TARGET_TYPE_QCA8074 || target_type == TARGET_TYPE_QCA8074V2 || target_type == TARGET_TYPE_QCA6018 || - target_type == TARGET_TYPE_QCA6390) + target_type == TARGET_TYPE_QCA6390 || + target_type == TARGET_TYPE_QCN9000) spectral->direct_dma_support = true; target_if_spectral_len_adj_swar_init(&spectral->len_adj_swar, target_type); + target_if_spectral_report_params_init(&spectral->rparams, target_type); if ((target_type == TARGET_TYPE_QCA8074) || (target_type == TARGET_TYPE_QCA8074V2) || @@ -2139,7 +2192,11 @@ target_if_pdev_spectral_init(struct wlan_objmgr_pdev *pdev) spectral->tag_sscan_fft_exp = TLV_TAG_SEARCH_FFT_REPORT_GEN3; spectral->tlvhdr_size = SPECTRAL_PHYERR_TLVSIZE_GEN3; spectral->fft_size_min = SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3; - spectral->fft_size_max = SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3; + spectral->fft_size_max = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT; + if (target_type == TARGET_TYPE_QCN9000) + spectral->fft_size_max = + SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000; } else { spectral->spectral_gen = SPECTRAL_GEN2; spectral->hdr_sig_exp = SPECTRAL_PHYERR_SIGNATURE_GEN2; diff --git a/target_if/spectral/target_if_spectral.h b/target_if/spectral/target_if_spectral.h index 5dfc7f98a4..6b551f62a8 100644 --- a/target_if/spectral/target_if_spectral.h +++ b/target_if/spectral/target_if_spectral.h @@ -81,12 +81,13 @@ #define OFFSET_CH_WIDTH_160 50 /* Min and max for relevant Spectral params */ -#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2 (1) -#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2 (9) -#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3 (5) -#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3 (9) -#define SPECTRAL_PARAM_RPT_MODE_MIN (0) -#define SPECTRAL_PARAM_RPT_MODE_MAX (3) +#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN2 (1) +#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN2 (9) +#define SPECTRAL_PARAM_FFT_SIZE_MIN_GEN3 (5) +#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_DEFAULT (9) +#define SPECTRAL_PARAM_FFT_SIZE_MAX_GEN3_QCN9000 (10) +#define SPECTRAL_PARAM_RPT_MODE_MIN (0) +#define SPECTRAL_PARAM_RPT_MODE_MAX (3) /* DBR ring debug size for Spectral */ #define SPECTRAL_DBR_RING_DEBUG_SIZE 512 @@ -252,14 +253,21 @@ struct spectral_phyerr_fft_gen2 { #define SSCAN_SUMMARY_REPORT_HDR_A_INBAND_PWR_DB_SIZE_GEN3 (10) #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3 (31) #define SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3 (1) -#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3 (30) -#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3 (1) +#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1 (30) +#define SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1 (1) +#define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2 (16) +#define SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2 (1) #define SPECTRAL_PHYERR_SIGNATURE_GEN3 (0xFA) #define TLV_TAG_SPECTRAL_SUMMARY_REPORT_GEN3 (0x02) #define TLV_TAG_SEARCH_FFT_REPORT_GEN3 (0x03) #define SPECTRAL_PHYERR_TLVSIZE_GEN3 (4) +#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) +#define NUM_PADDING_BYTES_SSCAN_SUMARY_REPORT_GEN3_V2 (16) + #define PHYERR_HDR_SIG_POS \ (offsetof(struct spectral_phyerr_fft_report_gen3, fft_hdr_sig)) #define PHYERR_HDR_TAG_POS \ @@ -374,7 +382,7 @@ struct sscan_report_fields_gen3 { * @hdr_a: Header[0:31] * @resv: Header[32:63] * @hdr_b: Header[64:95] - * @resv: Header[96:127] + * @hdr_c: Header[96:127] */ struct spectral_sscan_summary_report_gen3 { u_int32_t sscan_timestamp; @@ -390,7 +398,7 @@ struct spectral_sscan_summary_report_gen3 { u_int32_t hdr_a; u_int32_t res1; u_int32_t hdr_b; - u_int32_t res2; + u_int32_t hdr_c; } __ATTRIB_PACK; #ifdef DIRECT_BUF_RX_ENABLE @@ -438,6 +446,17 @@ enum spectral_fftbin_size_war { SPECTRAL_FFTBIN_SIZE_WAR_4BYTE_TO_1BYTE = 2, }; +/** + * enum spectral_report_format_version - This represents the report format + * version number within each Spectral generation. + * @SPECTRAL_REPORT_FORMAT_VERSION_1 : version 1 + * @SPECTRAL_REPORT_FORMAT_VERSION_2 : version 2 + */ +enum spectral_report_format_version { + SPECTRAL_REPORT_FORMAT_VERSION_1, + SPECTRAL_REPORT_FORMAT_VERSION_2, +}; + /** * struct spectral_fft_bin_len_adj_swar - Encapsulate information required for * Spectral FFT bin length adjusting software WARS. @@ -458,14 +477,36 @@ enum spectral_fftbin_size_war { * (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. + * @packmode_fftbin_size_adj: Pack mode in HW refers to packing of each Spectral + * FFT bin into 2 bytes. But due to a bug HW reports 2 times the expected length + * when packmode is enabled. This SWAR compensates this bug by dividing the + * length with 2. * @fftbin_size_war: Type of FFT bin size SWAR */ struct spectral_fft_bin_len_adj_swar { u_int8_t inband_fftbin_size_adj; u_int8_t null_fftbin_adj; + uint8_t packmode_fftbin_size_adj; enum spectral_fftbin_size_war fftbin_size_war; }; +/** + * struct spectral_report_params - Parameters related to format of Spectral + * report. + * @version: This represents the report format version number within each + * Spectral generation. + * @ssumaary_padding_bytes: Number of bytes of padding after Spectral summary + * report + * @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. + */ +struct spectral_report_params { + enum spectral_report_format_version version; + uint8_t ssumaary_padding_bytes; + uint8_t fft_report_hdr_len; +}; + #if ATH_PERF_PWR_OFFLOAD /** * enum target_if_spectral_info - Enumerations for specifying which spectral @@ -857,6 +898,7 @@ struct spectral_param_properties { * @prev_tstamp: Timestamp of the previously received sample, which has to be * compared with the current tstamp to check descrepancy * @target_reset_count: Number of times target excercised the reset routine + * @rparams: Parameters related to Spectral report structure */ struct target_if_spectral { struct wlan_objmgr_pdev *pdev_obj; @@ -975,6 +1017,7 @@ struct target_if_spectral { bool direct_dma_support; uint32_t prev_tstamp; uint32_t target_reset_count; + struct spectral_report_params rparams; }; /** diff --git a/target_if/spectral/target_if_spectral_phyerr.c b/target_if/spectral/target_if_spectral_phyerr.c index 9b39a2aee2..65890f6b0d 100644 --- a/target_if/spectral/target_if_spectral_phyerr.c +++ b/target_if/spectral/target_if_spectral_phyerr.c @@ -1230,11 +1230,13 @@ target_if_spectral_get_bin_count_after_len_adj( fft_bin_count >>= 2; break; case SPECTRAL_FFTBIN_SIZE_WAR_2BYTE_TO_1BYTE: + fft_bin_count >>= 1; /* Ideally we should be dividing fft bin length * by 2. Due to a HW bug, actual length is two * times the expected length. */ - fft_bin_count >>= 2; + if (swar->packmode_fftbin_size_adj) + fft_bin_count >>= 1; break; case SPECTRAL_FFTBIN_SIZE_NO_WAR: /* No length adjustment */ @@ -1326,11 +1328,12 @@ target_if_dump_fft_report_gen3(struct target_if_spectral *spectral, { size_t fft_hdr_length = (p_fft_report->fft_hdr_length * 4); size_t report_len = (fft_hdr_length + 8); - size_t fft_bin_len = (fft_hdr_length - 16); + size_t fft_bin_len; size_t fft_bin_count; size_t fft_bin_len_inband_tfer = 0; uint8_t *fft_bin_buf = NULL; + fft_bin_len = fft_hdr_length - spectral->rparams.fft_report_hdr_len; fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( fft_bin_len, spectral->params[smode].ss_rpt_mode, @@ -1493,24 +1496,24 @@ target_if_get_detector_id_sscan_summary_report_gen3(uint8_t *data) { /** * target_if_consume_sscan_summary_report_gen3() - Consume Spectral summary * report - * @spectral: Pointer to Spectral object * @data: Pointer to Spectral summary report * @fields: Pointer to structure to be populated with extracted fields + * @rparams: Pointer to structure with Spectral report params * * Consume Spectral summary report for gen3 * * Return: void */ static void -target_if_consume_sscan_summary_report_gen3(struct target_if_spectral *spectral, - uint8_t *data, - struct sscan_report_fields_gen3 - *fields) { +target_if_consume_sscan_summary_report_gen3( + uint8_t *data, + struct sscan_report_fields_gen3 *fields, + struct spectral_report_params *rparams) { struct spectral_sscan_summary_report_gen3 *psscan_summary_report; - qdf_assert_always(spectral); qdf_assert_always(data); qdf_assert_always(fields); + qdf_assert_always(rparams); psscan_summary_report = (struct spectral_sscan_summary_report_gen3 *)data; @@ -1527,10 +1530,23 @@ target_if_consume_sscan_summary_report_gen3(struct target_if_spectral *spectral, psscan_summary_report->hdr_a, SSCAN_SUMMARY_REPORT_HDR_A_PRI80_SIZE_GEN3, SSCAN_SUMMARY_REPORT_HDR_A_PRI80_POS_GEN3); - fields->sscan_gainchange = get_bitfield( + + switch (rparams->version) { + case SPECTRAL_REPORT_FORMAT_VERSION_1: + fields->sscan_gainchange = get_bitfield( psscan_summary_report->hdr_b, - SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3, - SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3); + SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_SIZE_GEN3_V1, + SSCAN_SUMMARY_REPORT_HDR_B_GAINCHANGE_POS_GEN3_V1); + break; + case SPECTRAL_REPORT_FORMAT_VERSION_2: + fields->sscan_gainchange = get_bitfield( + psscan_summary_report->hdr_c, + SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_SIZE_GEN3_V2, + SSCAN_SUMMARY_REPORT_HDR_C_GAINCHANGE_POS_GEN3_V2); + break; + default: + qdf_assert_always(0); + } } /** @@ -1748,7 +1764,7 @@ target_if_consume_spectral_report_gen3( uint8_t *data = report->data; struct wlan_objmgr_vdev *vdev; uint8_t vdev_rxchainmask; - struct sscan_report_fields_gen3 sscan_report_fields; + struct sscan_report_fields_gen3 sscan_report_fields = {0}; enum spectral_detector_id detector_id; QDF_STATUS ret; @@ -1769,10 +1785,11 @@ target_if_consume_spectral_report_gen3( detector_id); goto fail; } - target_if_consume_sscan_summary_report_gen3(spectral, data, - &sscan_report_fields); + 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)) { @@ -1827,9 +1844,9 @@ target_if_consume_spectral_report_gen3( } fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( - fft_hdr_length - 16, - spectral->params[params.smode].ss_rpt_mode, - &spectral->len_adj_swar); + fft_hdr_length - spectral->rparams.fft_report_hdr_len, + spectral->params[params.smode].ss_rpt_mode, + &spectral->len_adj_swar); params.last_raw_timestamp = spectral->last_fft_timestamp[params.smode]; params.reset_delay = 0; @@ -1969,9 +1986,9 @@ target_if_consume_spectral_report_gen3( } fft_bin_count = target_if_spectral_get_bin_count_after_len_adj( - fft_hdr_length - 16, - spectral->params[params.smode].ss_rpt_mode, - &spectral->len_adj_swar); + fft_hdr_length - spectral->rparams.fft_report_hdr_len, + spectral->params[params.smode].ss_rpt_mode, + &spectral->len_adj_swar); params.raw_timestamp_sec80 = p_sfft->timestamp; /* Take care of state transitions for 160 MHz and 80p80 */