From 3c26df25986e294de4cace974d23491530466024 Mon Sep 17 00:00:00 2001 From: abhinav kumar Date: Wed, 11 Aug 2021 22:19:11 +0530 Subject: [PATCH 01/17] qcacmn: Possible Integer overflow in wifi_pos_oem_rsp_handler API "target_if_wifi_pos_oem_rsp_ev_handler" is the handler for the event with WMI_OEM_RESPONSE_EVENTID. Host receives "rsp->dma_len" from fw. The integer overflow occurs if "oem_rsp->dma_len" is big enough while calculating the total length of the Oem Data response buffer. Fix is to add a sanity check for rsp->dma_len to avoid integer overflow. Change-Id: Idfbd358f62534eae0147f03505ced5728877a269 CRs-Fixed: 3001191 --- target_if/wifi_pos/src/target_if_wifi_pos.c | 13 ++++++++++++- umac/wifi_pos/src/wifi_pos_utils_i.h | 4 +++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/target_if/wifi_pos/src/target_if_wifi_pos.c b/target_if/wifi_pos/src/target_if_wifi_pos.c index 27d4d359f48f..15e1fa69cbcb 100644 --- a/target_if/wifi_pos/src/target_if_wifi_pos.c +++ b/target_if/wifi_pos/src/target_if_wifi_pos.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2021 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 @@ -92,6 +92,7 @@ static QDF_STATUS target_if_wifi_pos_get_indirect_data( void *paddr = NULL; uint32_t addr_hi; uint8_t ring_idx = 0, num_rings; + uint32_t allocated_len; if (!indirect) { target_if_debug("no indirect data. regular event received"); @@ -104,6 +105,16 @@ static QDF_STATUS target_if_wifi_pos_get_indirect_data( target_if_err("incorrect pdev_id: %d", indirect->pdev_id); return QDF_STATUS_E_INVAL; } + + allocated_len = priv_obj->dma_cap[ring_idx].min_buf_size + + (priv_obj->dma_cap[ring_idx].min_buf_align - 1); + if (indirect->len > allocated_len || + indirect->len > OEM_DATA_DMA_BUFF_SIZE) { + target_if_err("Invalid indirect len: %d, allocated_len:%d", + indirect->len, allocated_len); + return QDF_STATUS_E_INVAL; + } + addr_hi = (uint64_t)WMI_OEM_DMA_DATA_ADDR_HI_GET( indirect->addr_hi); paddr = (void *)((uint64_t)addr_hi << 32 | indirect->addr_lo); diff --git a/umac/wifi_pos/src/wifi_pos_utils_i.h b/umac/wifi_pos/src/wifi_pos_utils_i.h index 206a729c21c1..b9fa8b69e06b 100644 --- a/umac/wifi_pos/src/wifi_pos_utils_i.h +++ b/umac/wifi_pos/src/wifi_pos_utils_i.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2021 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 @@ -64,6 +64,8 @@ struct wifi_pos_req_msg; #ifndef OEM_DATA_RSP_SIZE #define OEM_DATA_RSP_SIZE 1724 +/* Header + VHT80 CIR * 2 chains */ +#define OEM_DATA_DMA_BUFF_SIZE (64 + 512 * 4 * 2) #endif /** From 0596d2f779eceb296058a787a67b87f6cf03866c Mon Sep 17 00:00:00 2001 From: abhinav kumar Date: Wed, 11 Aug 2021 19:28:49 +0530 Subject: [PATCH 02/17] qcacmn: Possible OOB read in process_fw_diag_event_data API "fw_diag_data_event_handler" is the handler of an event WMI_DIAG_DATA_CONTAINER_EVENTID comes from FW. Arguments of this handler function come from FW. If num_data may be less than size of(struct wlan_diag_data), possible OOB while extracting event data. Fix is to add a sanity check for num_data to avoid the OOB read. Change-Id: Ia2eb62dbaa154936bdb4ea34065657d441f12810 CRs-Fixed: 3001178 --- utils/fwlog/dbglog_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/fwlog/dbglog_host.c b/utils/fwlog/dbglog_host.c index 221066dd5a82..b372897d0a78 100644 --- a/utils/fwlog/dbglog_host.c +++ b/utils/fwlog/dbglog_host.c @@ -1693,7 +1693,7 @@ process_fw_diag_event_data(uint8_t *datap, uint32_t num_data) uint32_t diag_data_len; /* each fw diag payload */ struct wlan_diag_data *diag_data; - while (num_data > 0) { + while (num_data >= sizeof(struct wlan_diag_data)) { diag_data = (struct wlan_diag_data *)datap; diag_type = WLAN_DIAG_0_TYPE_GET(diag_data->word0); diag_data_len = WLAN_DIAG_0_LEN_GET(diag_data->word0); From 985b6ed0f017e538184c963351d248d32d51b035 Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Thu, 12 Aug 2021 14:05:25 +0530 Subject: [PATCH 03/17] qcacmn: Validate the buffer length in fips event handler In the WMI_PDEV_FIPS_EVENTID event handling, add a length check to validate if the buffer length sent by the firmware in fixed params is less than or equal to the actual buffer length before processing the data. Change-Id: I7a952d3e3a2f66060451263b72118a52aa89dd06 CRs-Fixed: 3009887 --- wmi/src/wmi_unified_tlv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 9731c3f07932..96d9e17ddbc6 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -11665,6 +11665,9 @@ static QDF_STATUS extract_fips_event_data_tlv(wmi_unified_t wmi_handle, param_buf = (WMI_PDEV_FIPS_EVENTID_param_tlvs *) evt_buf; event = (wmi_pdev_fips_event_fixed_param *) param_buf->fixed_param; + if (event->data_len > param_buf->num_data) + return QDF_STATUS_E_FAILURE; + if (fips_conv_data_be(event->data_len, param_buf->data) != QDF_STATUS_SUCCESS) return QDF_STATUS_E_FAILURE; From 3fd0eae263ecf071949b8d253b53326533422eec Mon Sep 17 00:00:00 2001 From: Surya Prakash Sivaraj Date: Thu, 5 Aug 2021 11:13:12 +0530 Subject: [PATCH 04/17] qcacmn: Validate the buffer length in rx mgmt handler In the WMI_MGMT_RX_EVENTID event handling, add a length check to validate if the buffer length sent by the firmware is less than or equal to the actual buffer length. Change-Id: I7db9af48bc525543b972dcaf40aee0a05d8f5023 CRs-Fixed: 3001331 --- wmi/src/wmi_unified_tlv.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 96d9e17ddbc6..350162cb2ebf 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -10249,6 +10249,11 @@ static QDF_STATUS extract_mgmt_rx_params_tlv(wmi_unified_t wmi_handle, return QDF_STATUS_E_INVAL; } + if (ev_hdr->buf_len > param_tlvs->num_bufp) { + wmi_err("Rx mgmt frame length mismatch, discard it"); + return QDF_STATUS_E_INVAL; + } + hdr->pdev_id = wmi_handle->ops->convert_pdev_id_target_to_host( wmi_handle, ev_hdr->pdev_id); From a0e05e19946bc74d2829dcb60f2aa640eb9e6222 Mon Sep 17 00:00:00 2001 From: Utkarsh Bhatnagar Date: Wed, 18 Aug 2021 21:29:08 +0530 Subject: [PATCH 05/17] qcacmn: Add QCA vendor interface to fetch thermal stats from driver Enhance QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD to fetch thermal stats for different temperature levels from the driver to userspace. The stats will be stored in the driver/firmware for predefined temperature levels and will be reported to userspace when QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD is sent with command type QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS. The thermal stats can be cleared from userspace by sending QCA_NL80211_VENDOR_SUBCMD_THERMAL_CMD command with type QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS. Change-Id: I937bc89865df484a068c887d906df5a9502f1925 CRs-Fixed: 3016851 --- os_if/linux/qca_vendor.h | 50 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/os_if/linux/qca_vendor.h b/os_if/linux/qca_vendor.h index 1b06af7d4d31..d3b91124e082 100644 --- a/os_if/linux/qca_vendor.h +++ b/os_if/linux/qca_vendor.h @@ -5344,6 +5344,14 @@ enum qca_wlan_vendor_attr_thermal_cmd { * there is any critical ongoing operation. */ QCA_WLAN_VENDOR_ATTR_THERMAL_COMPLETION_WINDOW = 3, + /* Nested attribute, driver/firmware uses this attribute to report + * thermal stats of different thermal levels to userspace when requested + * using QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS command + * type. This attribute contains nested array of records of thermal + * statistics of multiple levels. The attributes used inside this nested + * attribute are defined in enum qca_wlan_vendor_attr_thermal_stats. + */ + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS = 4, /* keep last */ QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_AFTER_LAST, QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_MAX = @@ -5368,6 +5376,16 @@ enum qca_wlan_vendor_attr_thermal_cmd { * resume action. * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL: Configure thermal level to * the driver/firmware. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL: Request to get the current + * thermal level from the driver/firmware. The driver should respond with a + * thermal level defined in enum qca_wlan_vendor_thermal_level. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS: Request to get the + * current thermal stats from the driver/firmware. The driver should respond + * with stats of all thermal levels encapsulated in attribute + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS. + * @QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS: Request to clear + * the current thermal stats all thermal levels maintained in the + * driver/firmware and start counting from zero again. */ enum qca_wlan_vendor_attr_thermal_cmd_type { QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_PARAMS, @@ -5375,6 +5393,9 @@ enum qca_wlan_vendor_attr_thermal_cmd_type { QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SUSPEND, QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_RESUME, QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_SET_LEVEL, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_LEVEL, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_GET_THERMAL_STATS, + QCA_WLAN_VENDOR_ATTR_THERMAL_CMD_TYPE_CLEAR_THERMAL_STATS, }; /** @@ -7676,6 +7697,35 @@ enum qca_wlan_vendor_attr_mac_info { }; +/** + * enum qca_wlan_vendor_attr_thermal_stats - vendor subcmd attributes + * to get thermal status from driver/firmware. + * enum values are used for NL attributes encapsulated inside + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS nested attribute. + * + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE: Minimum temperature + * of a thermal level in Celsius. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE: Maximum temperature + * of a thermal level in Celsius. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME: The total time spent on each + * thermal level in milliseconds. u32 size. + * QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER: Indicates the number + * of times the temperature crossed into the temperature range defined by the + * thermal level from both higher and lower directions. u32 size. + */ +enum qca_wlan_vendor_attr_thermal_stats { + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MIN_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX_TEMPERATURE, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_DWELL_TIME, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_TEMP_LEVEL_COUNTER, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_MAX = + QCA_WLAN_VENDOR_ATTR_THERMAL_STATS_AFTER_LAST - 1, +}; + /** * enum he_fragmentation_val - HE fragmentation support values * Indicates level of dynamic fragmentation that is supported by From cd19ba1903a4b3f6968caa1301e53526d3e171c0 Mon Sep 17 00:00:00 2001 From: Rakshith Suresh Patkar Date: Wed, 3 Feb 2021 22:13:07 +0530 Subject: [PATCH 06/17] qcacmn: Update missing ie pointers in util_scan_copy_beacon_data util_scan_copy_beacon_data copies beacon and updates ie pointers for the cache entry. However, two of the ie pointers listed below are not updated: 1) hecap_6g - pointer to he 6ghz cap ie. 2) srp - pointer to spatial reuse parameter sub extended ie. These non updated pointers will cause use after free issues if the parent scan entry is freed. Update ie pointers for hecap_6g and srp. Change-Id: I6d0a6129941e3dc1267404a4191ab368c013a102 CRs-Fixed: 2862607 --- umac/scan/dispatcher/inc/wlan_scan_utils_api.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/umac/scan/dispatcher/inc/wlan_scan_utils_api.h b/umac/scan/dispatcher/inc/wlan_scan_utils_api.h index 980c0972eed2..c5a3081582f4 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_utils_api.h +++ b/umac/scan/dispatcher/inc/wlan_scan_utils_api.h @@ -713,7 +713,9 @@ util_scan_copy_beacon_data(struct scan_cache_entry *new_entry, ie_lst->bwnss_map = conv_ptr(ie_lst->bwnss_map, old_ptr, new_ptr); ie_lst->mdie = conv_ptr(ie_lst->mdie, old_ptr, new_ptr); ie_lst->hecap = conv_ptr(ie_lst->hecap, old_ptr, new_ptr); + ie_lst->hecap_6g = conv_ptr(ie_lst->hecap_6g, old_ptr, new_ptr); ie_lst->heop = conv_ptr(ie_lst->heop, old_ptr, new_ptr); + ie_lst->srp = conv_ptr(ie_lst->srp, old_ptr, new_ptr); ie_lst->fils_indication = conv_ptr(ie_lst->fils_indication, old_ptr, new_ptr); ie_lst->esp = conv_ptr(ie_lst->esp, old_ptr, new_ptr); From 338cca505593972b2362df692fb14c20121e48ea Mon Sep 17 00:00:00 2001 From: Yeshwanth Sriram Guntuka Date: Thu, 22 Apr 2021 14:44:30 +0530 Subject: [PATCH 07/17] qcacmn: Add support to get dp prealloc config Add support to fetch datapath prealloc related configuration params. Change-Id: Iaeac3833fd8e13df6baa9452a7d7f194b86a8bd3 CRs-Fixed: 3012651 --- wlan_cfg/wlan_cfg.c | 20 ++++++++++++++++++++ wlan_cfg/wlan_cfg.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index b0a56e24881f..aa1a106d4cab 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -1520,3 +1520,23 @@ uint32_t wlan_cfg_ipa_tx_comp_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg) return cfg->ipa_tx_comp_ring_size; } #endif + +void +wlan_cfg_get_prealloc_cfg(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct wlan_dp_prealloc_cfg *cfg) +{ + if (!ctrl_psoc || !cfg) + return; + + cfg->num_tx_ring_entries = cfg_get(ctrl_psoc, CFG_DP_TX_RING_SIZE); + cfg->num_tx_comp_ring_entries = cfg_get(ctrl_psoc, + CFG_DP_TX_COMPL_RING_SIZE); + cfg->num_wbm_rel_ring_entries = cfg_get(ctrl_psoc, + CFG_DP_WBM_RELEASE_RING); + cfg->num_rxdma_err_dst_ring_entries = cfg_get(ctrl_psoc, + CFG_DP_RXDMA_ERR_DST_RING); + cfg->num_reo_exception_ring_entries = cfg_get(ctrl_psoc, + CFG_DP_REO_EXCEPTION_RING); + cfg->num_tx_desc = cfg_get(ctrl_psoc, CFG_DP_TX_DESC); + cfg->num_tx_ext_desc = cfg_get(ctrl_psoc, CFG_DP_TX_EXT_DESC); +} diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index 5c1bf9b090ba..879fae8f2c78 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -336,6 +336,26 @@ struct wlan_cfg_dp_pdev_ctxt { int nss_enabled; }; +/** + * struct wlan_dp_prealloc_cfg - DP prealloc related config + * @num_tx_ring_entries: num of tcl data ring entries + * @num_tx_comp_ring_entries: num of tx comp ring entries + * @num_wbm_rel_ring_entries: num of wbm err ring entries + * @num_rxdma_err_dst_ring_entries: num of rxdma err ring entries + * @num_reo_exception_ring_entries: num of rx exception ring entries + * @num_tx_desc: num of tx descriptors + * @num_tx_ext_desc: num of tx ext descriptors + */ +struct wlan_dp_prealloc_cfg { + int num_tx_ring_entries; + int num_tx_comp_ring_entries; + int num_wbm_rel_ring_entries; + int num_rxdma_err_dst_ring_entries; + int num_reo_exception_ring_entries; + int num_tx_desc; + int num_tx_ext_desc; +}; + /** * wlan_cfg_soc_attach() - Attach configuration interface for SoC * @ctrl_obj - PSOC object @@ -1535,4 +1555,15 @@ uint32_t wlan_cfg_ipa_tx_comp_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg) return 0; } #endif + +/** + * wlan_cfg_get_prealloc_cfg() - Get dp prealloc related cfg param + * @ctrl_psoc - PSOC object + * @cfg - cfg ctx where values will be populated + * + * Return: None + */ +void +wlan_cfg_get_prealloc_cfg(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, + struct wlan_dp_prealloc_cfg *cfg); #endif From 8a3675f385ec84f3b0462c8635473cc078f2addd Mon Sep 17 00:00:00 2001 From: Wu Gao Date: Fri, 27 Aug 2021 07:40:40 +0800 Subject: [PATCH 08/17] qcacmn: Not change RSSI of cfr meta data to dBm Since target already converts RSSI from SNR to dBm for QCA6490 and WCN7850, so don't convert them again in host side. Change-Id: Ie35f3821a802f2e65b61f4891f2ca9c632fa1477 CRs-Fixed: 3024119 --- target_if/cfr/src/target_if_cfr_enh.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/target_if/cfr/src/target_if_cfr_enh.c b/target_if/cfr/src/target_if_cfr_enh.c index 32a2822bdb07..8a17ace66c90 100644 --- a/target_if/cfr/src/target_if_cfr_enh.c +++ b/target_if/cfr/src/target_if_cfr_enh.c @@ -44,6 +44,14 @@ static u_int32_t end_magic = 0xBEAFDEAD; * * Return: signal strength in dBm */ +#if defined(QCA_WIFI_QCA6490) || defined(QCA_WIFI_WCN7850) +static inline +u_int32_t snr_to_signal_strength(uint8_t snr) +{ + /* target onverts snr to dBm */ + return snr; +} +#else static inline u_int32_t snr_to_signal_strength(uint8_t snr) { @@ -52,6 +60,7 @@ u_int32_t snr_to_signal_strength(uint8_t snr) (((int8_t)snr) + CMN_NOISE_FLOOR) : ((int8_t)snr); } +#endif /** * get_lut_entry() - Retrieve LUT entry using cookie number From 572a87580a6775d26bb965cd23f4e617b8b4967b Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Mon, 30 Aug 2021 20:49:51 +0530 Subject: [PATCH 09/17] qcacmn: Set default value of mawc_nlo_enabled ini as 0 Set value of mawc_nlo_enabled ini as 0 by default. Change-Id: I7779072deecc9390f3df929355788ee8d73cb48f CRs-Fixed: 3024972 --- umac/scan/dispatcher/inc/wlan_scan_cfg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/umac/scan/dispatcher/inc/wlan_scan_cfg.h b/umac/scan/dispatcher/inc/wlan_scan_cfg.h index e4485f86a066..b9dc233d63b5 100644 --- a/umac/scan/dispatcher/inc/wlan_scan_cfg.h +++ b/umac/scan/dispatcher/inc/wlan_scan_cfg.h @@ -802,7 +802,7 @@ enum scan_mode_6ghz { * mawc_nlo_enabled - For NLO/PNO, enable MAWC based scan * @Min: 0 * @Max: 1 - * @Default: 1 + * @Default: 0 * * Enable/Disable the Motion Aided Wireless Connectivity * based NLO using this parameter @@ -815,7 +815,7 @@ enum scan_mode_6ghz { */ #define CFG_MAWC_NLO_ENABLED CFG_INI_BOOL( \ "mawc_nlo_enabled", \ - 1, \ + 0, \ "Enable MAWC based scan") /* From 6cdd14fb763f2abca6ac7225f80848750b16e516 Mon Sep 17 00:00:00 2001 From: Karthik Kantamneni Date: Fri, 20 Aug 2021 11:01:48 +0530 Subject: [PATCH 10/17] qcacmn: Send force wake release if force wake request times out Even though force wake request timed out there is possibility of wake request got stuck and handled later at qmi level this leads to leaving device in wake state for long time unnecessarily. To avoid this send force wake release when wake request times out. Change-Id: Ic0e1b3d3fe9d4b0e0f0d4b9be5804ef4f1d3e724 CRs-Fixed: 3019575 --- hif/src/ipcie/if_ipci.c | 1 + 1 file changed, 1 insertion(+) diff --git a/hif/src/ipcie/if_ipci.c b/hif/src/ipcie/if_ipci.c index 78f63849be79..8be39b1aa248 100644 --- a/hif/src/ipcie/if_ipci.c +++ b/hif/src/ipcie/if_ipci.c @@ -842,6 +842,7 @@ int hif_force_wake_request(struct hif_opaque_softc *hif_handle) if (pld_is_device_awake(scn->qdf_dev->dev) <= 0) { hif_err("Unable to wake up mhi"); HIF_STATS_INC(ipci_scn, mhi_force_wake_failure, 1); + hif_force_wake_release(hif_handle); return -EINVAL; } HIF_STATS_INC(ipci_scn, mhi_force_wake_success, 1); From ace451359c57606a53c24623a9530b2626e35343 Mon Sep 17 00:00:00 2001 From: Sridhar Selvaraj Date: Fri, 20 Aug 2021 19:03:59 +0530 Subject: [PATCH 11/17] qcacmn: Reset skip_bssid_copy flag in split profile parsing While parsing MBSS IE split profiles, bssid copy flag is not reset in between sub element parsing resulting in skipping the bssid copy for next non tx profile. Reset skip_bssid_copy flag for each sub element parsing so that correct bssid is copied for next non tx profile CRs-Fixed: 3019298 Change-Id: I429190b21a3ddafdc75a73e8b063f6b6f629492a --- umac/scan/dispatcher/src/wlan_scan_utils_api.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index 94ab2193859a..4979f53f2d16 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -2221,6 +2221,12 @@ util_handle_nontx_prof(uint8_t *mbssid_elem, uint8_t *subelement, mbssid_index_ie[BSS_INDEX_POS], new_bssid); } + /* In single MBSS IE, there could be subelement holding + * remaining vendor IEs of non tx profile from last MBSS IE + * [split profile] and new non tx profile, hence reset + * skip_bssid_copy flag after each subelement processing + */ + mbssid_info->skip_bssid_copy = false; return VALID_NONTX_PROF; } @@ -2331,7 +2337,6 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, mbssid_info.split_profile = util_scan_is_split_prof_found(next_elem, ie, ielen); - mbssid_info.skip_bssid_copy = false; for (subelement = mbssid_elem + SUBELEMENT_START_POS; subelement < (next_elem - 1); subelement += MIN_IE_LEN + subelement[TAG_LEN_POS]) { From 286b26877816017640b33366e9b3be01848d3af7 Mon Sep 17 00:00:00 2001 From: Varsha Mishra Date: Wed, 17 Feb 2021 18:43:51 +0530 Subject: [PATCH 12/17] qcacmn: Drop packets in wbm release ring on cce match When cce rule gets matched, drop packets in wbm error ring. Change-Id: Ie9ca88492e3f34156a33747a9043e13c6cde66c0 --- dp/wifi3.0/dp_rx.h | 17 +++++++++++++++++ dp/wifi3.0/dp_rx_err.c | 17 +++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index 822f1b9ed902..a5de867a7bbf 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -1158,6 +1158,23 @@ dp_rx_update_protocol_tag(struct dp_soc *soc, struct dp_vdev *vdev, bool is_reo_exception, bool is_update_stats) { } + +/** + * dp_rx_err_cce_drop() - Reads CCE metadata from the RX MSDU end TLV + * and returns whether cce metadata matches + * @soc: core txrx main context + * @vdev: vdev on which the packet is received + * @nbuf: QDF pkt buffer on which the protocol tag should be set + * @rx_tlv_hdr: rBbase address where the RX TLVs starts + * Return: bool + */ +static inline bool +dp_rx_err_cce_drop(struct dp_soc *soc, struct dp_vdev *vdev, + qdf_nbuf_t nbuf, uint8_t *rx_tlv_hdr) +{ + return false; +} + #endif /* WLAN_SUPPORT_RX_PROTOCOL_TYPE_TAG */ #ifndef WLAN_SUPPORT_RX_FLOW_TAG diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index c891cb7dea12..4d8dd637b714 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -1283,6 +1283,23 @@ dp_rx_null_q_desc_handle(struct dp_soc *soc, qdf_nbuf_t nbuf, /* IEEE80211_SEQ_MAX indicates invalid start_seq */ } + /* + * Drop packets in this path if cce_match is found. Packets will come + * in following path depending on whether tidQ is setup. + * 1. If tidQ is setup: WIFILI_HAL_RX_WBM_REO_PSH_RSN_ROUTE and + * cce_match = 1 + * Packets with WIFILI_HAL_RX_WBM_REO_PSH_RSN_ROUTE are already + * dropped. + * 2. If tidQ is not setup: WIFILI_HAL_RX_WBM_REO_PSH_RSN_ERROR and + * cce_match = 1 + * These packets need to be dropped and should not get delivered + * to stack. + */ + if (qdf_unlikely(dp_rx_err_cce_drop(soc, vdev, nbuf, rx_tlv_hdr))) { + qdf_nbuf_free(nbuf); + return QDF_STATUS_E_FAILURE; + } + if (qdf_unlikely(vdev->rx_decap_type == htt_cmn_pkt_type_raw)) { qdf_nbuf_set_next(nbuf, NULL); dp_rx_deliver_raw(vdev, nbuf, peer); From 0c3694df287c253068694d1c153a8874b6f7613d Mon Sep 17 00:00:00 2001 From: Adwait Nayak Date: Tue, 31 Aug 2021 13:38:56 +0530 Subject: [PATCH 13/17] qcacmn: Fix memory leak if beacon is corrupted In case of split profile, while parsing the other segment of the non transmitted profile present in the subsequent MBSSID tag, it is possible that the beacon is corrupted where the non tx profile length has gone out of bound. In case of above scenario, the MBSSIE parsing code does not free up the memory allocated for split_prof_start before returning, which could possibly result into a memmory leak. Handling the split_profile_continue bit before non tx profile length check can avoid this situation. Change-Id: Iaa491fd2803d88759e74ca5a668dddb9f8a42708 CRs-Fixed: 3023554 --- .../scan/dispatcher/src/wlan_scan_utils_api.c | 40 +++++++++++++------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/umac/scan/dispatcher/src/wlan_scan_utils_api.c b/umac/scan/dispatcher/src/wlan_scan_utils_api.c index 4979f53f2d16..0e00c2b62f2d 100644 --- a/umac/scan/dispatcher/src/wlan_scan_utils_api.c +++ b/umac/scan/dispatcher/src/wlan_scan_utils_api.c @@ -2147,18 +2147,6 @@ util_handle_nontx_prof(uint8_t *mbssid_elem, uint8_t *subelement, uint32_t prof_len; prof_len = subelement[TAG_LEN_POS]; - /* - * if prof_residue is true, that means we are - * in the continuation of the fragmented profile part, - * present in the next MBSSD IE else this profile - * is a non fragmented non tx BSSID profile. - */ - - if (mbssid_info->prof_residue) - mbssid_info->split_prof_continue = true; - else - mbssid_info->split_prof_continue = false; - /* * If we are executing the split portion of the nontx * profile present in the subsequent MBSSID, then there @@ -2342,7 +2330,25 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, subelement += MIN_IE_LEN + subelement[TAG_LEN_POS]) { subie_len = subelement[TAG_LEN_POS]; + /* + * if prof_residue is true, that means we are + * in the continuation of the fragmented profile part, + * present in the next MBSSD IE else this profile + * is a non fragmented non tx BSSID profile. + */ + + if (mbssid_info.prof_residue) + mbssid_info.split_prof_continue = true; + else + mbssid_info.split_prof_continue = false; + if (subie_len > MAX_SUBELEM_LEN) { + scm_err_rl("Corrupt frame with subie_len: %d\n" + "split_prof_continue: %d\n" + "prof_residue: %d\n", + subie_len, + mbssid_info.split_prof_continue, + mbssid_info.prof_residue); if (mbssid_info.split_prof_continue) qdf_mem_free(split_prof_start); @@ -2361,6 +2367,10 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, bssid, new_bssid); if (retval == INVALID_SPLIT_PROF) { + scm_err_rl("Corrupt frame with ID_POS: %d\n" + "TAG_LEN_POS: %d\n", + subelement[ID_POS], + subelement[TAG_LEN_POS]); qdf_mem_free(split_prof_start); qdf_mem_free(new_ie); return QDF_STATUS_E_INVAL; @@ -2395,6 +2405,7 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, split_prof_start = qdf_mem_malloc(ielen); if (!split_prof_start) { + scm_err_rl("Malloc failed"); qdf_mem_free(new_ie); return QDF_STATUS_E_NOMEM; } @@ -2492,6 +2503,9 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, if (mbssid_info.split_prof_continue) qdf_mem_free(split_prof_start); qdf_mem_free(new_ie); + scm_err_rl("Malloc for new_frame failed"); + scm_err_rl("split_prof_continue: %d", + mbssid_info.split_prof_continue); return QDF_STATUS_E_NOMEM; } @@ -2532,6 +2546,8 @@ static QDF_STATUS util_scan_parse_mbssid(struct wlan_objmgr_pdev *pdev, } qdf_mem_free(new_frame); scm_err_rl("failed to generate a scan entry"); + scm_err_rl("split_prof_continue: %d", + mbssid_info.split_prof_continue); break; } /* scan entry makes its own copy so free the frame*/ From 3e6863fdee51367f0dd6d78aea1b65a817d0fb3a Mon Sep 17 00:00:00 2001 From: Surabhi Vishnoi Date: Wed, 19 May 2021 18:32:02 +0530 Subject: [PATCH 14/17] qcacmn: Add extension2 data to radiotap header There is a requirement to get sequence number and tid for tx data packets in packet capture mode. These fields are not received as part of WBM tx completion, but are obtained from FW in ppdu stats. As WBM tx completion and FW ppdu stats are two different events, the ppdu_stats of previously sent ppdu are filled in the radiotap header of current tx ppdu in packet capture mode. Enhance code to add required fields such as ppdu_id of tx current ppdu and ppdu_id, tid, start_seq, ba_bitmap of previously sent ppdu as extension2 to radiotap header. These fields will be added in radiotap header only when add_rtap_ext2 is set. Change-Id: I448a9c03a770b61ab802d855bc5f1a6587bd01b3 CRs-Fixed: 3004472 --- qdf/inc/qdf_nbuf.h | 23 +++++++++++++++++++++++ qdf/linux/src/qdf_nbuf.c | 25 ++++++++++++++++++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/qdf/inc/qdf_nbuf.h b/qdf/inc/qdf_nbuf.h index a4b99a00789e..05a67bb7b67e 100644 --- a/qdf/inc/qdf_nbuf.h +++ b/qdf/inc/qdf_nbuf.h @@ -254,6 +254,9 @@ * @tx_status: packet tx status * @tx_retry_cnt: tx retry count * @add_rtap_ext: add radio tap extension + * @start_seq: starting sequence number + * @ba_bitmap: 256 bit block ack bitmap + * @add_rtap_ext2: add radiotap extension2 */ struct mon_rx_status { uint64_t tsft; @@ -338,6 +341,9 @@ struct mon_rx_status { uint8_t tx_status; uint8_t tx_retry_cnt; bool add_rtap_ext; + uint16_t start_seq; + uint32_t ba_bitmap[8]; + bool add_rtap_ext2; }; /** @@ -434,6 +440,23 @@ struct qdf_radiotap_vendor_ns_ath { uint32_t ppdu_start_timestamp; } __attribute__((__packed__)); +/** + * struct qdf_radiotap_ext2 - radiotap ext2 fields + * ppdu_id: ppdu_id of current msdu + * prev_ppdu_id: ppdu_id of previous msdu + * tid: tid number of previous msdu + * start_seq: start sequence of previous msdu + * ba_bitmap: block ack bitmap of previous msdu + */ +struct qdf_radiotap_ext2 { + uint32_t ppdu_id; + uint32_t prev_ppdu_id; + uint16_t tid:8, + reserved:8; + uint16_t start_seq; + uint32_t ba_bitmap[8]; +} __attribute__((__packed__)); + #define QDF_MEM_FUNC_NAME_SIZE 48 /* Masks for HE SIG known fields in mon_rx_status structure */ diff --git a/qdf/linux/src/qdf_nbuf.c b/qdf/linux/src/qdf_nbuf.c index a5c9f0f3b82f..f7963e010eb7 100644 --- a/qdf/linux/src/qdf_nbuf.c +++ b/qdf/linux/src/qdf_nbuf.c @@ -4361,6 +4361,7 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, #define IEEE80211_RADIOTAP_TX_STATUS 0 #define IEEE80211_RADIOTAP_RETRY_COUNT 1 +#define IEEE80211_RADIOTAP_EXTENSION2 2 /** * This is the length for radiotap, combined length @@ -4384,6 +4385,8 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, * 4 bytes padding for alignment */ #define RADIOTAP_HEADER_EXT_LEN (2 * sizeof(uint32_t)) +#define RADIOTAP_HEADER_EXT2_LEN \ + (sizeof(struct qdf_radiotap_ext2)) #define RADIOTAP_HEADER_LEN (sizeof(struct ieee80211_radiotap_header) + \ RADIOTAP_FIXED_HEADER_LEN + \ RADIOTAP_HT_FLAGS_LEN + \ @@ -4393,7 +4396,8 @@ qdf_nbuf_update_radiotap_he_mu_other_flags(struct mon_rx_status *rx_status, RADIOTAP_HE_MU_FLAGS_LEN + \ RADIOTAP_HE_MU_OTHER_FLAGS_LEN + \ RADIOTAP_VENDOR_NS_LEN + \ - RADIOTAP_HEADER_EXT_LEN) + RADIOTAP_HEADER_EXT_LEN + \ + RADIOTAP_HEADER_EXT2_LEN) #define IEEE80211_RADIOTAP_HE 23 #define IEEE80211_RADIOTAP_HE_MU 24 @@ -4452,6 +4456,7 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, uint32_t rtap_len = rtap_hdr_len; uint8_t length = rtap_len; struct qdf_radiotap_vendor_ns_ath *radiotap_vendor_ns_ath; + struct qdf_radiotap_ext2 *rtap_ext2; uint32_t *rtap_ext = NULL; /* Adding Extended Header space */ @@ -4657,6 +4662,24 @@ unsigned int qdf_nbuf_update_radiotap(struct mon_rx_status *rx_status, rtap_len += 1; } + /* Add Extension2 to Radiotap Header */ + if (rx_status->add_rtap_ext2) { + rthdr->it_present |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXT); + rtap_ext = (uint32_t *)&rthdr->it_present; + rtap_ext++; + *rtap_ext |= cpu_to_le32(1 << IEEE80211_RADIOTAP_EXTENSION2); + + rtap_ext2 = (struct qdf_radiotap_ext2 *)(rtap_buf + rtap_len); + rtap_ext2->ppdu_id = rx_status->ppdu_id; + rtap_ext2->prev_ppdu_id = rx_status->prev_ppdu_id; + rtap_ext2->tid = rx_status->tid; + rtap_ext2->start_seq = rx_status->start_seq; + qdf_mem_copy(rtap_ext2->ba_bitmap, + rx_status->ba_bitmap, 8 * (sizeof(uint32_t))); + + rtap_len += sizeof(*rtap_ext2); + } + rthdr->it_len = cpu_to_le16(rtap_len); rthdr->it_present = cpu_to_le32(rthdr->it_present); From 463daeb327d0353b3b73411d85bc9da9bbf87132 Mon Sep 17 00:00:00 2001 From: Karthik Kantamneni Date: Tue, 7 Sep 2021 16:53:16 +0530 Subject: [PATCH 15/17] qcacmn: Skip updating OOR/2K jump BAR frames to H.W Currently error BAR frames are routed to host, but host doesn't have complete information to check whether these frames are valid and really action need to be taken or not. If host updates H.W without validating SSN it is causing window movement and REO HW aging timeout happening for next set of RX packets and delay is induced. To avoid RX packets delay skipping BAR update to H.W Change-Id: I92c1614993b6985218a453fe528fbd274fab254f CRs-Fixed: 2995461 --- dp/wifi3.0/dp_rx_err.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 4d8dd637b714..fba5c29d46cb 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -779,6 +779,16 @@ dp_rx_chain_msdus(struct dp_soc *soc, qdf_nbuf_t nbuf, return mpdu_done; } +#ifdef WLAN_SKIP_BAR_UPDATE +static +void dp_rx_err_handle_bar(struct dp_soc *soc, + struct dp_peer *peer, + qdf_nbuf_t nbuf) +{ + dp_info_rl("BAR update to H.W is skipped"); + DP_STATS_INC(soc, rx.err.bar_handle_fail_count, 1); +} +#else static void dp_rx_err_handle_bar(struct dp_soc *soc, struct dp_peer *peer, @@ -828,6 +838,7 @@ void dp_rx_err_handle_bar(struct dp_soc *soc, DP_STATS_INC(soc, rx.err.ssn_update_count, 1); } } +#endif /** * dp_rx_bar_frame_handle() - Function to handle err BAR frames From 47fefb5962aa8d8d7f02dcb62a4885447ae78d22 Mon Sep 17 00:00:00 2001 From: Surabhi Vishnoi Date: Wed, 1 Sep 2021 10:47:49 +0530 Subject: [PATCH 16/17] qcacmn: Remove rx packet capture events processing if feature is disabled Currently, rx packet capture events processing happens even when feature is disabled by ini. This incurs per packet overhead in rx path. The fix is to move all the processing from rx path to packet capture mode component. Send only wdi event from rx path, when feature is enabled by ini. Change-Id: I647256b85117cd3373950c78a5a0ae7d6710e4e2 CRs-Fixed: 2969123 --- dp/inc/cdp_txrx_stats_struct.h | 1 + dp/wifi3.0/dp_rx.c | 31 +++++++------------------------ wlan_cfg/wlan_cfg.c | 11 +++++++++++ wlan_cfg/wlan_cfg.h | 20 ++++++++++++++++++++ 4 files changed, 39 insertions(+), 24 deletions(-) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index 668ae29e98cc..e57858821588 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -365,6 +365,7 @@ enum WDI_EVENT { WDI_EVENT_PEER_QOS_STATS, WDI_EVENT_PKT_CAPTURE_TX_DATA, WDI_EVENT_PKT_CAPTURE_RX_DATA, + WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER, WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA, /* End of new event items */ WDI_EVENT_LAST diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 044736d988cd..4b6615a75a63 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -2250,35 +2250,18 @@ void dp_rx_deliver_to_pkt_capture(struct dp_soc *soc, struct dp_pdev *pdev, uint16_t peer_id, uint32_t is_offload, qdf_nbuf_t netbuf) { - dp_wdi_event_handler(WDI_EVENT_PKT_CAPTURE_RX_DATA, soc, netbuf, - peer_id, is_offload, pdev->pdev_id); + if (wlan_cfg_get_pkt_capture_mode(soc->wlan_cfg_ctx)) + dp_wdi_event_handler(WDI_EVENT_PKT_CAPTURE_RX_DATA, soc, netbuf, + peer_id, is_offload, pdev->pdev_id); } void dp_rx_deliver_to_pkt_capture_no_peer(struct dp_soc *soc, qdf_nbuf_t nbuf, uint32_t is_offload) { - uint16_t msdu_len = 0; - uint16_t peer_id, vdev_id; - uint32_t pkt_len = 0; - uint8_t *rx_tlv_hdr; - struct hal_rx_msdu_metadata msdu_metadata; - - peer_id = QDF_NBUF_CB_RX_PEER_ID(nbuf); - vdev_id = QDF_NBUF_CB_RX_VDEV_ID(nbuf); - rx_tlv_hdr = qdf_nbuf_data(nbuf); - hal_rx_msdu_metadata_get(soc->hal_soc, rx_tlv_hdr, &msdu_metadata); - msdu_len = QDF_NBUF_CB_RX_PKT_LEN(nbuf); - pkt_len = msdu_len + msdu_metadata.l3_hdr_pad + - RX_PKT_TLVS_LEN; - - qdf_nbuf_set_pktlen(nbuf, pkt_len); - dp_rx_skip_tlvs(nbuf, msdu_metadata.l3_hdr_pad); - - dp_wdi_event_handler(WDI_EVENT_PKT_CAPTURE_RX_DATA, soc, nbuf, - HTT_INVALID_VDEV, is_offload, 0); - - qdf_nbuf_push_head(nbuf, msdu_metadata.l3_hdr_pad + - RX_PKT_TLVS_LEN); + if (wlan_cfg_get_pkt_capture_mode(soc->wlan_cfg_ctx)) + dp_wdi_event_handler(WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER, + soc, nbuf, HTT_INVALID_VDEV, + is_offload, 0); } #endif diff --git a/wlan_cfg/wlan_cfg.c b/wlan_cfg/wlan_cfg.c index aa1a106d4cab..1a7a1958fa9d 100644 --- a/wlan_cfg/wlan_cfg.c +++ b/wlan_cfg/wlan_cfg.c @@ -657,6 +657,10 @@ wlan_cfg_soc_attach(struct cdp_ctrl_objmgr_psoc *psoc) wlan_cfg_ctx->wow_check_rx_pending_enable = cfg_get(psoc, CFG_DP_WOW_CHECK_RX_PENDING); wlan_soc_ipa_cfg_attach(psoc, wlan_cfg_ctx); +#ifdef WLAN_FEATURE_PKT_CAPTURE_V2 + wlan_cfg_ctx->pkt_capture_mode = cfg_get(psoc, CFG_PKT_CAPTURE_MODE) & + PKT_CAPTURE_MODE_DATA_ONLY; +#endif return wlan_cfg_ctx; } @@ -1540,3 +1544,10 @@ wlan_cfg_get_prealloc_cfg(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, cfg->num_tx_desc = cfg_get(ctrl_psoc, CFG_DP_TX_DESC); cfg->num_tx_ext_desc = cfg_get(ctrl_psoc, CFG_DP_TX_EXT_DESC); } + +#ifdef WLAN_FEATURE_PKT_CAPTURE_V2 +uint32_t wlan_cfg_get_pkt_capture_mode(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return cfg->pkt_capture_mode; +} +#endif diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index 879fae8f2c78..0be13218df9a 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -197,6 +197,7 @@ struct wlan_srng_cfg { * @wow_check_rx_pending_enable: Enable RX frame pending check in WoW * @ipa_tx_ring_size: IPA tx ring size * @ipa_tx_comp_ring_size: IPA tx completion ring size + * @pkt_capture_mode: Packet capture mode config */ struct wlan_cfg_dp_soc_ctxt { int num_int_ctxts; @@ -316,6 +317,9 @@ struct wlan_cfg_dp_soc_ctxt { uint32_t ipa_tx_ring_size; uint32_t ipa_tx_comp_ring_size; #endif +#ifdef WLAN_FEATURE_PKT_CAPTURE_V2 + uint32_t pkt_capture_mode; +#endif }; /** @@ -1566,4 +1570,20 @@ uint32_t wlan_cfg_ipa_tx_comp_ring_size(struct wlan_cfg_dp_soc_ctxt *cfg) void wlan_cfg_get_prealloc_cfg(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, struct wlan_dp_prealloc_cfg *cfg); + +#ifdef WLAN_FEATURE_PKT_CAPTURE_V2 +/** + * wlan_cfg_get_pkt_capture_mode() - Get packet capture mode config + * @cfg: config context + * + * Return: value of packet capture mode + */ +uint32_t wlan_cfg_get_pkt_capture_mode(struct wlan_cfg_dp_soc_ctxt *cfg); +#else +static inline +uint32_t wlan_cfg_get_pkt_capture_mode(struct wlan_cfg_dp_soc_ctxt *cfg) +{ + return 0; +} +#endif #endif From 3529ba79c9ebdee9127a9e0aa61240cefc8b2038 Mon Sep 17 00:00:00 2001 From: Surabhi Vishnoi Date: Fri, 2 Jul 2021 15:14:41 +0530 Subject: [PATCH 17/17] qcacmn: Add support to parse HTT_PPDU_STATS_FOR_SMU_TLV Firmware sends some ppdu stats required for packet capture mode in new ppdu stats tlv HTT_PPDU_STATS_FOR_SMU_TLV. Add code to parse it if feature is enabled via ini and send the ppdu stats using wdi event to packet capture component. Change-Id: I5567007a91093dd342f37458760b3a61c040b779 CRs-Fixed: 3004476 --- dp/inc/cdp_txrx_stats_struct.h | 1 + dp/wifi3.0/dp_htt.c | 48 ++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/dp/inc/cdp_txrx_stats_struct.h b/dp/inc/cdp_txrx_stats_struct.h index e57858821588..11c5ec3aa0ba 100644 --- a/dp/inc/cdp_txrx_stats_struct.h +++ b/dp/inc/cdp_txrx_stats_struct.h @@ -367,6 +367,7 @@ enum WDI_EVENT { WDI_EVENT_PKT_CAPTURE_RX_DATA, WDI_EVENT_PKT_CAPTURE_RX_DATA_NO_PEER, WDI_EVENT_PKT_CAPTURE_OFFLOAD_TX_DATA, + WDI_EVENT_PKT_CAPTURE_PPDU_STATS, /* End of new event items */ WDI_EVENT_LAST }; diff --git a/dp/wifi3.0/dp_htt.c b/dp/wifi3.0/dp_htt.c index b46dc9b2b7e0..e715fadbfcf0 100644 --- a/dp/wifi3.0/dp_htt.c +++ b/dp/wifi3.0/dp_htt.c @@ -4094,6 +4094,45 @@ static struct ppdu_info *dp_htt_process_tlv(struct dp_pdev *pdev, } #endif /* FEATURE_PERPKT_INFO */ +#ifdef WLAN_FEATURE_PKT_CAPTURE_V2 +static void dp_htt_process_stats_tlv(struct dp_soc *soc, + qdf_nbuf_t htt_t2h_msg) +{ + uint32_t length; + uint8_t tlv_type; + uint32_t tlv_length, tlv_expected_size; + uint8_t *tlv_buf; + + uint32_t *msg_word = (uint32_t *) qdf_nbuf_data(htt_t2h_msg); + + length = HTT_T2H_PPDU_STATS_PAYLOAD_SIZE_GET(*msg_word); + + msg_word = msg_word + 4; + + while (length > 0) { + tlv_buf = (uint8_t *)msg_word; + tlv_type = HTT_STATS_TLV_TAG_GET(*msg_word); + tlv_length = HTT_STATS_TLV_LENGTH_GET(*msg_word); + + if (tlv_length == 0) + break; + + tlv_length += HTT_TLV_HDR_LEN; + + if (tlv_type == HTT_PPDU_STATS_FOR_SMU_TLV) { + tlv_expected_size = sizeof(htt_ppdu_stats_for_smu_tlv); + + if (tlv_length >= tlv_expected_size) + dp_wdi_event_handler( + WDI_EVENT_PKT_CAPTURE_PPDU_STATS, + soc, msg_word, HTT_INVALID_VDEV, + WDI_NO_VAL, 0); + } + msg_word = (uint32_t *)((uint8_t *)tlv_buf + tlv_length); + length -= (tlv_length); + } +} +#endif /** * dp_txrx_ppdu_stats_handler() - Function to process HTT PPDU stats from FW * @soc: DP SOC handle @@ -4140,6 +4179,15 @@ static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc, return free_buf; } +#elif defined(WLAN_FEATURE_PKT_CAPTURE_V2) +static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc, + uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg) +{ + if (wlan_cfg_get_pkt_capture_mode(soc->wlan_cfg_ctx)) + dp_htt_process_stats_tlv(soc, htt_t2h_msg); + + return true; +} #else static bool dp_txrx_ppdu_stats_handler(struct dp_soc *soc, uint8_t pdev_id, qdf_nbuf_t htt_t2h_msg)