From b3860808e42687916c12dbca9384022e11ae64d4 Mon Sep 17 00:00:00 2001 From: Priyadarshnee S Date: Wed, 17 Oct 2018 13:18:18 +0530 Subject: [PATCH 1/8] qcacmn: Clear the radar flag when NOL count is zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Consider STA vap to be up in chan 100 VHT80 mode and stadfs enabled. Say Radar is injected on chan 100 and 100 is added to NOL list and IEEE80211_CHAN_SET_RADAR is set on it. On NOL timer expiry, during the process of nol delete, dfs nol count is decremented. So it reads 0 now. After this decrement, dfs_nol_update() is called and it returns without calling dfs_mlme_clist_update as nol count is zero. As dfs_mlme_clist_update is not invoked, IEEE80211_CHAN_CLR_RADAR flag is not set. After NOL timeout, STA vap fails to associate with Root on VHT80 mode as 100 VHT80 is not available (chan 100’s RADAR flag not cleared). CRs-Fixed: 2327546 Change-Id: Ic83ec2ac49e0fb7e887c3c7be2f8eefc419cb7c5 --- umac/dfs/core/src/misc/dfs_nol.c | 1 + 1 file changed, 1 insertion(+) diff --git a/umac/dfs/core/src/misc/dfs_nol.c b/umac/dfs/core/src/misc/dfs_nol.c index 016e81517b49..b8502a40d8fd 100644 --- a/umac/dfs/core/src/misc/dfs_nol.c +++ b/umac/dfs/core/src/misc/dfs_nol.c @@ -479,6 +479,7 @@ void dfs_nol_update(struct wlan_dfs *dfs) if (!dfs->dfs_nol_count) { dfs_debug(dfs, WLAN_DEBUG_DFS_NOL, "dfs_nol_count is zero"); + dfs_mlme_clist_update(dfs->dfs_pdev_obj, NULL, 0); return; } From 8efaac88d48e33e896bfcdf73b959de94c83397e Mon Sep 17 00:00:00 2001 From: Ashish Kumar Dhanotiya Date: Wed, 17 Oct 2018 16:45:54 +0530 Subject: [PATCH 2/8] qcacmn: Null pointer access in green ap egap status event While extracting green ap egap status info there is no sanity check for egap info event and chainmask event which may lead to NULL pointer access. To prevent this NULL pointer access add a sanity check for egap info event and chainmask event. Change-Id: Ib9cc273f12bb159bce309065279230e96925be7f CRs-Fixed: 2331873 --- 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 644851337d48..ba8fdc394cfa 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -10541,6 +10541,11 @@ static QDF_STATUS extract_green_ap_egap_status_info_tlv( chainmask_event = (wmi_ap_ps_egap_info_chainmask_list *) param_buf->chainmask_list; + if (!egap_info_event || !chainmask_event) { + WMI_LOGE("Invalid EGAP Info event or chainmask event"); + return QDF_STATUS_E_INVAL; + } + egap_status_info_params->status = egap_info_event->status; egap_status_info_params->mac_id = chainmask_event->mac_id; egap_status_info_params->tx_chainmask = chainmask_event->tx_chainmask; From 8af026a2caa7ab85414d5fc47e87237396b66064 Mon Sep 17 00:00:00 2001 From: Pratik Gandhi Date: Wed, 26 Sep 2018 20:18:34 +0530 Subject: [PATCH 3/8] qcacmn: Abstract BMI and add export symbols for ko separation Abstract BMI callback from common module and move it to specific component. Add Export symbols to support modularization in WIN. (BMI) CRs-Fixed: 2324081 Change-Id: I1ec463d41d238ce81254ecc1f0bb1dc545e1248e --- hif/src/ce/ce_service.c | 5 +++++ hif/src/dispatcher/multibus.c | 1 + hif/src/pcie/if_pci.c | 1 - target_if/init_deinit/src/init_deinit_lmac.c | 1 + utils/fwlog/fw_dbglog_api.c | 1 + 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/hif/src/ce/ce_service.c b/hif/src/ce/ce_service.c index 6c480ddcaa71..7e8c392981df 100644 --- a/hif/src/ce/ce_service.c +++ b/hif/src/ce/ce_service.c @@ -359,6 +359,7 @@ ce_send(struct CE_handle *copyeng, return status; } +qdf_export_symbol(ce_send); unsigned int ce_sendlist_sizeof(void) { @@ -887,6 +888,7 @@ ce_recv_buf_enqueue(struct CE_handle *copyeng, return hif_state->ce_services->ce_recv_buf_enqueue(copyeng, per_recv_context, buffer); } +qdf_export_symbol(ce_recv_buf_enqueue); void ce_send_watermarks_set(struct CE_handle *copyeng, @@ -1043,6 +1045,7 @@ ce_cancel_send_next(struct CE_handle *copyeng, (copyeng, per_CE_contextp, per_transfer_contextp, bufferp, nbytesp, transfer_idp, toeplitz_hash_result); } +qdf_export_symbol(ce_cancel_send_next); int ce_completed_send_next(struct CE_handle *copyeng, @@ -1765,6 +1768,7 @@ ce_send_cb_register(struct CE_handle *copyeng, hif_state->ce_services->ce_per_engine_handler_adjust(CE_state, disable_interrupts); } +qdf_export_symbol(ce_send_cb_register); /** * ce_recv_cb_register(): register completion handler @@ -1802,6 +1806,7 @@ ce_recv_cb_register(struct CE_handle *copyeng, hif_state->ce_services->ce_per_engine_handler_adjust(CE_state, disable_interrupts); } +qdf_export_symbol(ce_recv_cb_register); /** * ce_watermark_cb_register(): register completion handler diff --git a/hif/src/dispatcher/multibus.c b/hif/src/dispatcher/multibus.c index f6a5bbcc1a6b..a8e42b99c1d9 100644 --- a/hif/src/dispatcher/multibus.c +++ b/hif/src/dispatcher/multibus.c @@ -517,4 +517,5 @@ bool hif_needs_bmi(struct hif_opaque_softc *scn) return hif_sc->bus_ops.hif_needs_bmi(hif_sc); } +qdf_export_symbol(hif_needs_bmi); #endif /* WLAN_FEATURE_BMI */ diff --git a/hif/src/pcie/if_pci.c b/hif/src/pcie/if_pci.c index 7de1106d4cef..478bc70e075a 100644 --- a/hif/src/pcie/if_pci.c +++ b/hif/src/pcie/if_pci.c @@ -2000,7 +2000,6 @@ int hif_pci_bus_configure(struct hif_softc *hif_sc) HIF_INFO_MED("%s: hif_set_hia done", __func__); - hif_register_bmi_callbacks(hif_sc); } if (((hif_sc->target_info.target_type == TARGET_TYPE_QCA8074) || diff --git a/target_if/init_deinit/src/init_deinit_lmac.c b/target_if/init_deinit/src/init_deinit_lmac.c index 3a833c6f53f6..790dd6c1297e 100644 --- a/target_if/init_deinit/src/init_deinit_lmac.c +++ b/target_if/init_deinit/src/init_deinit_lmac.c @@ -136,6 +136,7 @@ uint32_t lmac_get_tgt_version(struct wlan_objmgr_psoc *psoc) return target_psoc_get_target_ver(tgt_hdl); } +qdf_export_symbol(lmac_get_tgt_version); uint32_t lmac_get_tgt_revision(struct wlan_objmgr_psoc *psoc) { diff --git a/utils/fwlog/fw_dbglog_api.c b/utils/fwlog/fw_dbglog_api.c index ee07234874df..388f9b43cb3b 100644 --- a/utils/fwlog/fw_dbglog_api.c +++ b/utils/fwlog/fw_dbglog_api.c @@ -57,6 +57,7 @@ int fwdbg_parse_debug_logs(struct common_dbglog_handle *dbg_handle, return 0; } +qdf_export_symbol(fwdbg_parse_debug_logs); void fwdbg_ratelimit_set(struct common_dbglog_handle *dbg_handle, uint32_t burst_limit) From 2f750878bca005a50fe788186f8aabcf2f90d6f9 Mon Sep 17 00:00:00 2001 From: Dustin Brown Date: Wed, 17 Oct 2018 12:16:20 -0700 Subject: [PATCH 4/8] qcacmn: Statically allocate CE desc history for MCL As part of convergence, the CE descriptor history was moved to dynamic allocation, per HIF handle. For MCL, this caused the allocation to consume limited pre-allocated memory, causing regressions. For the MCL implementation of alloc_mem_ce_debug_history(), use a static buffer instead to avoid complications. Change-Id: I8b0c0a2502d4abfd465749328a35004ffed585ca CRs-Fixed: 2335146 --- hif/src/ce/ce_main.c | 93 +++++++++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 39 deletions(-) diff --git a/hif/src/ce/ce_main.c b/hif/src/ce/ce_main.c index 29ea738ea679..36eea481675c 100644 --- a/hif/src/ce/ce_main.c +++ b/hif/src/ce/ce_main.c @@ -1241,20 +1241,46 @@ void free_mem_ce_debug_hist_data(struct hif_softc *scn, uint32_t ce_id) } #endif /* HIF_CE_DEBUG_DATA_BUF */ -/* - * Note: For MCL, #if defined (HIF_CONFIG_SLUB_DEBUG_ON) needs to be checked - * for defined here - */ -#if defined(HIF_CONFIG_SLUB_DEBUG_ON) || HIF_CE_DEBUG_DATA_BUF +#if defined(HIF_CONFIG_SLUB_DEBUG_ON) /* MCL */ +struct hif_ce_desc_event hif_ce_desc_history[CE_COUNT_MAX][HIF_CE_HISTORY_MAX]; + /** - * alloc_mem_ce_debug_history() - Allocate mem for the CE descriptors storing + * alloc_mem_ce_debug_history() - Allocate CE descriptor history * @scn: hif scn handle - * ce_id: Copy Engine Id + * @ce_id: Copy Engine Id * * Return: QDF_STATUS */ -static inline QDF_STATUS alloc_mem_ce_debug_history(struct hif_softc *scn, - unsigned int CE_id) +static QDF_STATUS +alloc_mem_ce_debug_history(struct hif_softc *scn, unsigned int ce_id) +{ + struct ce_desc_hist *ce_hist = &scn->hif_ce_desc_hist; + + ce_hist->hist_ev[ce_id] = hif_ce_desc_history[ce_id]; + ce_hist->enable[ce_id] = 1; + + return QDF_STATUS_SUCCESS; +} + +/** + * free_mem_ce_debug_history() - Free CE descriptor history + * @scn: hif scn handle + * @ce_id: Copy Engine Id + * + * Return: None + */ +static void free_mem_ce_debug_history(struct hif_softc *scn, unsigned int ce_id) +{ + struct ce_desc_hist *ce_hist = &scn->hif_ce_desc_hist; + + ce_hist->enable[ce_id] = 0; + ce_hist->hist_ev[ce_id] = NULL; +} + +#elif HIF_CE_DEBUG_DATA_BUF /* WIN */ + +static QDF_STATUS +alloc_mem_ce_debug_history(struct hif_softc *scn, unsigned int CE_id) { scn->hif_ce_desc_hist.hist_ev[CE_id] = (struct hif_ce_desc_event *) qdf_mem_malloc(HIF_CE_HISTORY_MAX * sizeof(struct hif_ce_desc_event)); @@ -1268,35 +1294,37 @@ static inline QDF_STATUS alloc_mem_ce_debug_history(struct hif_softc *scn, } } -/** - * free_mem_ce_debug_history() - Free mem allocated for the CE descriptors - * storing. - * @scn: hif scn handle - * ce_id: Copy Engine Id - * - * Return: - */ -static inline void free_mem_ce_debug_history(struct hif_softc *scn, - unsigned int CE_id) +static void free_mem_ce_debug_history(struct hif_softc *scn, unsigned int CE_id) { struct ce_desc_hist *ce_hist = &scn->hif_ce_desc_hist; - struct hif_ce_desc_event *hist_ev = - (struct hif_ce_desc_event *)ce_hist->hist_ev[CE_id]; + struct hif_ce_desc_event *hist_ev = ce_hist->hist_ev[CE_id]; if (!hist_ev) return; -#if HIF_CE_DEBUG_DATA_BUF if (ce_hist->data_enable[CE_id] == 1) { ce_hist->data_enable[CE_id] = 0; free_mem_ce_debug_hist_data(scn, CE_id); } -#endif + ce_hist->enable[CE_id] = 0; qdf_mem_free(ce_hist->hist_ev[CE_id]); ce_hist->hist_ev[CE_id] = NULL; } +#else /* Disabled */ + +static inline QDF_STATUS +alloc_mem_ce_debug_history(struct hif_softc *scn, unsigned int CE_id) +{ + return QDF_STATUS_SUCCESS; +} + +static inline void +free_mem_ce_debug_history(struct hif_softc *scn, unsigned int CE_id) { } +#endif + +#if defined(HIF_CONFIG_SLUB_DEBUG_ON) || HIF_CE_DEBUG_DATA_BUF /** * reset_ce_debug_history() - reset the index and ce id used for dumping the * CE records on the console using sysfs. @@ -1313,22 +1341,9 @@ static inline void reset_ce_debug_history(struct hif_softc *scn) ce_hist->hist_index = 0; ce_hist->hist_id = 0; } -#else /*Note: #if defined(HIF_CONFIG_SLUB_DEBUG_ON) || HIF_CE_DEBUG_DATA_BUF */ -static inline QDF_STATUS alloc_mem_ce_debug_history(struct hif_softc *scn, - unsigned int CE_id) -{ - return QDF_STATUS_SUCCESS; -} - -static inline void free_mem_ce_debug_history(struct hif_softc *scn, - unsigned int CE_id) -{ -} - -static inline void reset_ce_debug_history(struct hif_softc *scn) -{ -} -#endif /*Note: defined(HIF_CONFIG_SLUB_DEBUG_ON) || HIF_CE_DEBUG_DATA_BUF */ +#else /* defined(HIF_CONFIG_SLUB_DEBUG_ON) || HIF_CE_DEBUG_DATA_BUF */ +static inline void reset_ce_debug_history(struct hif_softc *scn) { } +#endif /* defined(HIF_CONFIG_SLUB_DEBUG_ON) || HIF_CE_DEBUG_DATA_BUF */ void ce_enable_polling(void *cestate) { From 2c0924538562b08d815f911a16fbd339a023ddaa Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Wed, 10 Oct 2018 17:03:28 +0800 Subject: [PATCH 5/8] qcacmn: Avoid OOB in create_reg_rules_from_wmi the fixed_param TLV structure is pulled from the WMI message and assigned to chan_list_event_hdr. num_2g_reg_rules and num_5g_reg_rules are assigned from the TLV structure, then passed to create_reg_rules_from_wmi without length check, out of buffer may happen. Change-Id: I70c9d74ef94161896e1c7700c73943040f3a77e1 CRs-Fixed: 2327667 --- wmi/src/wmi_unified_tlv.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index ba8fdc394cfa..b0c55191923f 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -9624,6 +9624,25 @@ static QDF_STATUS extract_reg_chan_list_update_event_tlv( reg_info->num_2g_reg_rules = chan_list_event_hdr->num_2g_reg_rules; reg_info->num_5g_reg_rules = chan_list_event_hdr->num_5g_reg_rules; + num_2g_reg_rules = reg_info->num_2g_reg_rules; + num_5g_reg_rules = reg_info->num_5g_reg_rules; + if ((num_2g_reg_rules > MAX_REG_RULES) || + (num_5g_reg_rules > MAX_REG_RULES) || + (num_2g_reg_rules + num_5g_reg_rules > MAX_REG_RULES) || + (num_2g_reg_rules + num_5g_reg_rules != + param_buf->num_reg_rule_array)) { + wmi_err_rl("Invalid num_2g_reg_rules: %u, num_5g_reg_rules: %u", + num_2g_reg_rules, num_5g_reg_rules); + return QDF_STATUS_E_FAILURE; + } + if (param_buf->num_reg_rule_array > + (WMI_SVC_MSG_MAX_SIZE - sizeof(*chan_list_event_hdr)) / + sizeof(*wmi_reg_rule)) { + wmi_err_rl("Invalid num_reg_rule_array: %u", + param_buf->num_reg_rule_array); + return QDF_STATUS_E_FAILURE; + } + qdf_mem_copy(reg_info->alpha2, &(chan_list_event_hdr->alpha2), REG_ALPHA2_LEN); reg_info->dfs_region = chan_list_event_hdr->dfs_region; @@ -9656,9 +9675,6 @@ static QDF_STATUS extract_reg_chan_list_update_event_tlv( reg_info->min_bw_5g = chan_list_event_hdr->min_bw_5g; reg_info->max_bw_5g = chan_list_event_hdr->max_bw_5g; - num_2g_reg_rules = reg_info->num_2g_reg_rules; - num_5g_reg_rules = reg_info->num_5g_reg_rules; - WMI_LOGD("%s:cc %s dsf %d BW: min_2g %d max_2g %d min_5g %d max_5g %d", __func__, reg_info->alpha2, reg_info->dfs_region, reg_info->min_bw_2g, reg_info->max_bw_2g, From 03673ae28fec80b1f44d1b5cf15c80e88a71d1a3 Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Wed, 17 Oct 2018 09:36:11 -0700 Subject: [PATCH 6/8] qcacmn: Fix integer overflow in roam scan stats extract In extract_roam_scan_stats_res_evt_tlv(), validate num_roam_scans to avoid any possible integer overflow when receive larger num_roam_scans value. Change-Id: I0f3bbf64fac8c151789de2f93a77c9af29b855d1 CRs-Fixed: 2331868 --- wmi/src/wmi_unified_tlv.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index b0c55191923f..b580484cf740 100644 --- a/wmi/src/wmi_unified_tlv.c +++ b/wmi/src/wmi_unified_tlv.c @@ -10354,7 +10354,7 @@ extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, uint32_t total_len; struct wmi_roam_scan_stats_res *res; uint32_t i, j; - uint32_t num_scans; + uint32_t num_scans, scan_param_size; *res_param = NULL; *vdev_id = 0xFF; /* Initialize to invalid vdev id */ @@ -10365,11 +10365,16 @@ extract_roam_scan_stats_res_evt_tlv(wmi_unified_t wmi_handle, void *evt_buf, } fixed_param = param_buf->fixed_param; - total_len = sizeof(*res) + fixed_param->num_roam_scans * - sizeof(struct wmi_roam_scan_stats_params); - *vdev_id = fixed_param->vdev_id; num_scans = fixed_param->num_roam_scans; + scan_param_size = sizeof(struct wmi_roam_scan_stats_params); + if ((num_scans > ((UINT_MAX - sizeof(*res)) / scan_param_size))) { + wmi_err_rl("Invalid num_roam_scans %d", num_scans); + return QDF_STATUS_E_INVAL; + } + + total_len = sizeof(*res) + num_scans * scan_param_size; + *vdev_id = fixed_param->vdev_id; res = qdf_mem_malloc(total_len); if (!res) { From e10f87bd410f9bf9bd2c6857b7afe2ae02edc438 Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Thu, 18 Oct 2018 00:14:11 +0530 Subject: [PATCH 7/8] qcacmn: add a flag in AST entry to indicate AST map Add a flag for AST entry to indicate if AST entry is mapped to AST table and use this flag while dereferncing ast table with ast_index in ast_entry Change-Id: I8c90f3c40116e24303aac8a7bd53e8f5b67e22bf --- dp/wifi3.0/dp_peer.c | 22 ++++++++++++++-------- dp/wifi3.0/dp_rx.h | 4 ++-- dp/wifi3.0/dp_rx_err.c | 1 + dp/wifi3.0/dp_types.h | 4 +++- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/dp/wifi3.0/dp_peer.c b/dp/wifi3.0/dp_peer.c index a958405e2434..52e49c867966 100644 --- a/dp/wifi3.0/dp_peer.c +++ b/dp/wifi3.0/dp_peer.c @@ -466,6 +466,7 @@ static inline void dp_peer_map_ast(struct dp_soc *soc, ast_entry->is_active = TRUE; peer_type = ast_entry->type; ast_entry->ast_hash_value = ast_hash; + ast_entry->is_mapped = TRUE; } if (ast_entry || (peer->vdev && peer->vdev->proxysta_vdev)) { @@ -574,7 +575,7 @@ add_ast_entry: ast_entry->peer = peer; ast_entry->pdev_id = vdev->pdev->pdev_id; ast_entry->vdev_id = vdev->vdev_id; - ast_entry->ast_idx = DP_INVALID_AST_IDX; + ast_entry->is_mapped = false; switch (type) { case CDP_TXRX_AST_TYPE_STATIC: @@ -649,10 +650,10 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry) dp_peer_ast_send_wds_del(soc, ast_entry); } else { /* - * For TYPE_SELF (STA mode), no T2H_PEER_MAP message to map - * the peer, hence no need to clear ast_table here. + * release the reference only if it is mapped + * to ast_table */ - if (ast_entry->type != CDP_TXRX_AST_TYPE_SELF) + if (ast_entry->is_mapped) soc->ast_table[ast_entry->ast_idx] = NULL; TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); @@ -686,10 +687,10 @@ void dp_peer_del_ast(struct dp_soc *soc, struct dp_ast_entry *ast_entry) ast_entry->mac_addr.raw); /* - * For TYPE_SELF (STA mode), no T2H_PEER_MAP message to map the peer, - * hence no need to clear ast_table here. + * release the reference only if it is mapped + * to ast_table */ - if (ast_entry->type != CDP_TXRX_AST_TYPE_SELF) + if (ast_entry->is_mapped) soc->ast_table[ast_entry->ast_idx] = NULL; TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); @@ -903,7 +904,12 @@ void dp_peer_ast_free_entry(struct dp_soc *soc, { struct dp_peer *peer = ast_entry->peer; - soc->ast_table[ast_entry->ast_idx] = NULL; + /* + * release the reference only if it is mapped + * to ast_table + */ + if (ast_entry->is_mapped) + soc->ast_table[ast_entry->ast_idx] = NULL; TAILQ_REMOVE(&peer->ast_entry_list, ast_entry, ase_list_elem); DP_STATS_INC(soc, ast.deleted, 1); dp_peer_ast_hash_remove(soc, ast_entry); diff --git a/dp/wifi3.0/dp_rx.h b/dp/wifi3.0/dp_rx.h index cf1d64858a40..f6a266ee68ac 100644 --- a/dp/wifi3.0/dp_rx.h +++ b/dp/wifi3.0/dp_rx.h @@ -479,7 +479,7 @@ dp_rx_wds_srcport_learn(struct dp_soc *soc, * There is a possibility we might arrive here without * AST MAP event , so this check is mandatory */ - if (ast->ast_idx == sa_idx) + if (ast->is_mapped && (ast->ast_idx == sa_idx)) ast->is_active = TRUE; if (sa_sw_peer_id != ta_peer->peer_ids[0]) { @@ -743,7 +743,7 @@ static inline QDF_STATUS dp_rx_ast_set_active(struct dp_soc *soc, uint16_t sa_id * There is a possibility we might arrive here without * AST MAP event , so this check is mandatory */ - if (ast && (ast->ast_idx == sa_idx)) { + if (ast && ast->is_mapped && (ast->ast_idx == sa_idx)) { ast->is_active = is_active; qdf_spin_unlock_bh(&soc->ast_lock); return QDF_STATUS_SUCCESS; diff --git a/dp/wifi3.0/dp_rx_err.c b/dp/wifi3.0/dp_rx_err.c index 492434db4e21..701e75cb4868 100644 --- a/dp/wifi3.0/dp_rx_err.c +++ b/dp/wifi3.0/dp_rx_err.c @@ -132,6 +132,7 @@ static inline bool dp_rx_mcast_echo_check(struct dp_soc *soc, if (ase) { ase->ast_idx = sa_idx; soc->ast_table[sa_idx] = ase; + ase->is_mapped = TRUE; } } } else diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index e9571365329d..e6d788293d4a 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -636,7 +636,6 @@ union dp_align_mac_addr { } align4_2; }; -#define DP_INVALID_AST_IDX 0xFFFF /* * dp_ast_entry * @@ -649,6 +648,8 @@ union dp_align_mac_addr { * (used for aging out/expiry) * @ase_list_elem: node in peer AST list * @is_bss: flag to indicate if entry corresponds to bss peer + * @is_mapped: flag to indicate that we have mapped the AST entry + * in ast_table * @pdev_id: pdev ID * @vdev_id: vdev ID * @ast_hash_value: hast value in HW @@ -666,6 +667,7 @@ struct dp_ast_entry { bool next_hop; bool is_active; bool is_bss; + bool is_mapped; uint8_t pdev_id; uint8_t vdev_id; uint16_t ast_hash_value; From 83d08110b1d38bdb895c17e0e4a781830e1bbedb Mon Sep 17 00:00:00 2001 From: Anish Nataraj Date: Wed, 17 Oct 2018 20:20:55 +0530 Subject: [PATCH 8/8] qcacmn: Check Non-zero Rx RSSI during vdev / pdev aggregate MultiVap if no sta associated or monitor mode, data packets do not carry any rx rssi or rate values while aggregating pdev or vdev stats. Do not update for vap in if rx rssi or rx rate value is zero. Do not attach monitor vdev to vdev list Change-Id: Ie64a05d795660d557d928cb9b874fa5e702f4f55 --- dp/wifi3.0/dp_internal.h | 3 ++- dp/wifi3.0/dp_main.c | 21 ++++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/dp/wifi3.0/dp_internal.h b/dp/wifi3.0/dp_internal.h index 541020beaaaf..e05051d0d2c5 100644 --- a/dp/wifi3.0/dp_internal.h +++ b/dp/wifi3.0/dp_internal.h @@ -558,7 +558,8 @@ static inline void dp_update_vdev_stats(struct cdp_vdev_stats *tgtobj, DP_STATS_AGGR(_tgtobj, _srcobj, tx.dropped.age_out); \ \ DP_STATS_AGGR(_tgtobj, _srcobj, rx.err.mic_err); \ - DP_STATS_UPD_STRUCT(_tgtobj, _srcobj, rx.rssi); \ + if (_srcobj->stats.rx.rssi != 0) \ + DP_STATS_UPD_STRUCT(_tgtobj, _srcobj, rx.rssi); \ DP_STATS_UPD_STRUCT(_tgtobj, _srcobj, rx.rx_rate); \ DP_STATS_AGGR(_tgtobj, _srcobj, rx.err.decrypt_err); \ DP_STATS_AGGR(_tgtobj, _srcobj, rx.non_ampdu_cnt); \ diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 4885503dd176..b22699de6e74 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -3599,18 +3599,21 @@ static struct cdp_vdev *dp_vdev_attach_wifi3(struct cdp_pdev *txrx_pdev, qdf_mem_copy( &vdev->mac_addr.raw[0], vdev_mac_addr, OL_TXRX_MAC_ADDR_LEN); - vdev->tx_encap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); - vdev->rx_decap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); - vdev->dscp_tid_map_id = 0; - vdev->mcast_enhancement_en = 0; - vdev->raw_mode_war = wlan_cfg_get_raw_mode_war(soc->wlan_cfg_ctx); - /* TODO: Initialize default HTT meta data that will be used in * TCL descriptors for packets transmitted from this VDEV */ TAILQ_INIT(&vdev->peer_list); + if (wlan_op_mode_monitor == vdev->opmode) + return (struct cdp_vdev *)vdev; + + vdev->tx_encap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); + vdev->rx_decap_type = wlan_cfg_pkt_type(soc->wlan_cfg_ctx); + vdev->dscp_tid_map_id = 0; + vdev->mcast_enhancement_en = 0; + vdev->raw_mode_war = wlan_cfg_get_raw_mode_war(soc->wlan_cfg_ctx); + qdf_spin_lock_bh(&pdev->vdev_list_lock); /* add this vdev into the pdev's list */ TAILQ_INSERT_TAIL(&pdev->vdev_list, vdev, vdev_list_elem); @@ -3754,6 +3757,8 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, /* preconditions */ qdf_assert(vdev); + if (wlan_op_mode_monitor == vdev->opmode) + goto free_vdev; if (wlan_op_mode_sta == vdev->opmode) dp_peer_delete_wifi3(vdev->vap_bss_peer, 0); @@ -3800,8 +3805,10 @@ static void dp_vdev_detach_wifi3(struct cdp_vdev *vdev_handle, TAILQ_REMOVE(&pdev->vdev_list, vdev, vdev_list_elem); QDF_TRACE(QDF_MODULE_ID_DP, QDF_TRACE_LEVEL_INFO_HIGH, FL("deleting vdev object %pK (%pM)"), vdev, vdev->mac_addr.raw); - qdf_mem_free(vdev); + qdf_spin_unlock_bh(&pdev->vdev_list_lock); +free_vdev: + qdf_mem_free(vdev); if (callback) callback(cb_context);