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); 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; 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) { 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/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; } 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) diff --git a/wmi/src/wmi_unified_tlv.c b/wmi/src/wmi_unified_tlv.c index 644851337d48..b580484cf740 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, @@ -10338,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 */ @@ -10349,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) { @@ -10541,6 +10562,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;