diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-05-27 04:35:08 -0600 |
|---|---|---|
| committer | Linux Build Service Account <lnxbuild@localhost> | 2016-05-27 04:35:08 -0600 |
| commit | 04053c06cd2d4053b3ba6453baf083ce1b7dd77f (patch) | |
| tree | 14f89af2e7c568a7f93821af2ebfc6518e016ccb | |
| parent | b2ed0531ca669023f141bf3d854e083aae0eb113 (diff) | |
| parent | 58dfe3d63681e5f0d819ec7b14f8d8fb4276c9c2 (diff) | |
Promotion of wlan-cld2.driver.lnx.1.0-00021.
CRs Change ID Subject
--------------------------------------------------------------------------------------------------------------
939678 Idf0fcc7f118aaae29dae26f0176b3093f47bd865 qcacld-2.0: Stop stats timer only when it is started
1021248 I96f99f42467ec2650794718a5b11033c031c71ec qcacld-2.0 : Avoid calling PE delete session for non val
1019037 I4f39d93e8aeb243ec3df5cc1a916aec0a1aa4819 qcacld-2.0: Dump header info for first mgmt. packet afte
1019037 I3c83991f56be34412f3f10adf58bd991ecb536ca qcacld-2.0: Dump header info for first data packet after
1019077 I4fbfd63c0f68bd1684cff6fac411f9c790b22c03 qcacld-2.0: Avoid dereferencing of NULL pointer
865207 Ic564e247baa43c58dd63e369ff3ef82ef32f6ca5 qcacld-2.0: CL 1508507 – update fw common interface file
688141 Iff0dfd98e41f8bf46c208bcc43b47d57df4cf558 Release 4.0.11.87
1002305 I3fe6101b888c70670a371a1eb45b47d756511b1d qcacld-2.0: Send ESE becaon report if request is valid
1018534 Idbdb1dabeee0400199859763fda86716c950893e qcacld-2.0: Set RPS mask for virtual interfaces
1008087 I9b80a003759c962020165c21dbe29330700c4667 qcacld-2.0: Refactor DPTRACE to support new features
1019973 I6ee8c59887ff483c0a4f07716d299d89eee4d933 Revert "qcacld-2.0: Fix Invalid PCIe link access during
1018482 Ideecb861dcc362f94a73b47d1a4766d621a38214 qcacld-2.0: Do not make a PMF connection, if supplicant
1008087 I7a8bc74f5cbb2124dec36fd922679b05ba1c58d1 qcacld-2.0: Fix issue when DP trace feature is not enabl
1018489 Iccec386d8d88d69ccc4eacd2031d5664ed948acc qcacld-2.0: Fix type mismatch and bitwise operation on d
1017278 If433aae949326af6a20df2190dd7356f211c4103 qcacld 2.0: Add ini to raise bug on SSR re-init failure
1018530 If3be2a68147dbea0109c857328df2adb47b3e413 qcacld 2.0: Perform proper clean up in SSR re-init failu
1017937 I63692816d0f4d867206a3d6b07363bbb054c6062 qcacld-2.0: Fix type mismatch in bitwise operator
1017942 I74288d09b1c1cb8e4e7c65881a6fbc67010b4670 qcacld-2.0: Fix use of uninitialized data
1018879 Ib42c80f10a9843e586bd9fec25dc33e5d13b1396 qcacld-2.0: Use WNI dot11mode while setting phy mode
1018486 I4211b41b5e30d414e45691a5bab4048587cc8499 qcacld-2.0: Fix Unitialized heap and stack usage
1019973 I07b7552dd76e56facaa08def2995dfd6a8cacaac qcacld-2.0: Collect Ramdump in panic handler only if dev
931441 I445942b64ca9f382f8d24ca19665d6bda2341a80 qcacld-2.0: Reset memory allocation of BSS description
688141 Ie3f7e41ca2b9dd009f60af2d53ccd660dbf565a5 Release 4.0.11.89
1015267 I2dade8ba5c1ddfc104a478822de3e9e543f6b1c7 qcacld-2.0: Avoid dereferencing of NULL pointer
1019037 I8837ad1b976744eeb0e7f0a836eded3a5d34124b qcacld-2.0: Add APIs to get packet type and subtype
1017282 I76f5896ae4c51d4816cc0389151e1e27b07d2193 qcacld 2.0: Prevent Null pointer access during tdls exit
974918 Ic2b774cea10516ea0b23141922ba1e16aa33f395 qcacld-2.0: Remove the PS check in suspend req
688141 Ifaf9e0c14bb5a7724687581927a41bcc747afd89 Release 4.0.11.88
1020758 I92eff1e70f31f5d89683dcf7e171a232ca2f3bad qcacld-2.0: Fix incorrect debug level in wmi_config_debu
1019043 I804735d8e85769b04a33008c3b9b72029d0c4368 qcacld-2.0: Clear Link layer PEER stats during disconnec
1014605 Ia26d06faa7878fcb198186b60b07ab66bff99e54 qcacld-2.0: Periodically update host time stamp to firmw
Change-Id: I5d655046cceba5ad0e7420910dcb501d09d98d70
CRs-Fixed: 1017937, 1014605, 1018879, 865207, 1020758, 1019077, 939678, 1021248, 1019037, 1018489, 1018482, 1017282, 931441, 1018486, 974918, 1019043, 1002305, 1015267, 1017942, 688141, 1018530, 1018534, 1019973, 1017278, 1008087
45 files changed, 2583 insertions, 591 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt_tx.c b/CORE/CLD_TXRX/HTT/htt_tx.c index 5cc2e931b7dd..3a2fa5e0b3d0 100644 --- a/CORE/CLD_TXRX/HTT/htt_tx.c +++ b/CORE/CLD_TXRX/HTT/htt_tx.c @@ -474,7 +474,7 @@ htt_tx_send_std( NBUF_UPDATE_TX_PKT_COUNT(msdu, NBUF_TX_PKT_HTT); DPTRACE(adf_dp_trace(msdu, ADF_DP_TRACE_HTT_PACKET_PTR_RECORD, - (uint8_t *)(adf_nbuf_data(msdu)), + adf_nbuf_data_addr(msdu), sizeof(adf_nbuf_data(msdu)))); if (adf_nbuf_queue_len(&pdev->txnbufq) > 0) { diff --git a/CORE/CLD_TXRX/TXRX/ol_tx.c b/CORE/CLD_TXRX/TXRX/ol_tx.c index 0cc3eb446896..dc3132f737f7 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx.c @@ -221,7 +221,7 @@ ol_tx_vdev_pause_queue_append( NBUF_UPDATE_TX_PKT_COUNT(msdu_list, NBUF_TX_PKT_TXRX_ENQUEUE); DPTRACE(adf_dp_trace(msdu_list, ADF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD, - (uint8_t *)(adf_nbuf_data(msdu_list)), + adf_nbuf_data_addr(msdu_list), sizeof(adf_nbuf_data(msdu_list)))); vdev->ll_pause.txq.depth++; diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c index 6e1d47d66d51..965380909287 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_queue.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_queue.c @@ -1059,9 +1059,6 @@ ol_txrx_vdev_pause(ol_txrx_vdev_handle vdev, u_int32_t reason) adf_os_spin_unlock_bh(&vdev->ll_pause.mutex); } - DPTRACE(adf_dp_trace(NULL, ADF_DP_TRACE_VDEV_PAUSE, - NULL, 0)); - TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } @@ -1118,9 +1115,6 @@ ol_txrx_vdev_unpause(ol_txrx_vdev_handle vdev, u_int32_t reason) } } - DPTRACE(adf_dp_trace(NULL, ADF_DP_TRACE_VDEV_UNPAUSE, - NULL, 0)); - TX_SCHED_DEBUG_PRINT("Leave %s\n", __func__); } diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_send.c b/CORE/CLD_TXRX/TXRX/ol_tx_send.c index 8e4d814a78f6..b35dc99af25c 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_send.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_send.c @@ -220,9 +220,9 @@ ol_tx_send( msdu_credit_consumed = ol_tx_send_base(pdev, tx_desc, msdu); id = ol_tx_desc_id(pdev, tx_desc); NBUF_UPDATE_TX_PKT_COUNT(msdu, NBUF_TX_PKT_TXRX); - DPTRACE(adf_dp_trace(msdu, ADF_DP_TRACE_TXRX_PACKET_PTR_RECORD, - (uint8_t *)(adf_nbuf_data(msdu)), - sizeof(adf_nbuf_data(msdu)))); + DPTRACE(adf_dp_trace_ptr(msdu, ADF_DP_TRACE_TXRX_PACKET_PTR_RECORD, + adf_nbuf_data_addr(msdu), + sizeof(adf_nbuf_data(msdu)), tx_desc->id, 0)); failed = htt_tx_send_std(pdev->htt_pdev, msdu, id); if (adf_os_unlikely(failed)) { @@ -555,7 +555,11 @@ ol_tx_completion_handler( tx_desc = td_array[tx_desc_id].tx_desc; tx_desc->status = status; netbuf = tx_desc->netbuf; - + DPTRACE(adf_dp_trace_ptr(netbuf, + ADF_DP_TRACE_FREE_PACKET_PTR_RECORD, + adf_nbuf_data_addr(netbuf), + sizeof(adf_nbuf_data(netbuf)), + tx_desc->id, status)); if (pdev->cfg.is_high_latency) { OL_TX_DESC_UPDATE_GROUP_CREDIT(pdev, tx_desc_id, 1, 0, status); } diff --git a/CORE/HDD/inc/wlan_hdd_cfg.h b/CORE/HDD/inc/wlan_hdd_cfg.h index 77bcc2bd4733..80ad64d82339 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg.h +++ b/CORE/HDD/inc/wlan_hdd_cfg.h @@ -3830,6 +3830,18 @@ enum dot11p_mode { #define CFG_CH_AVOID_SAP_RESTART_MAX (1) #define CFG_CH_AVOID_SAP_RESTART_DEFAULT (0) +/* + * This parameter will help to debug ssr reinit failure issues + * by raising vos bug so dumps can be collected. If OEM + * wants to avoid this crash, just disable this parameter. + * wlan driver will only recover after driver unload and load. + * Default: Enable + */ +#define CFG_BUG_ON_REINIT_FAILURE_NAME "g_bug_on_reinit_failure" +#define CFG_BUG_ON_REINIT_FAILURE_MIN (0) +#define CFG_BUG_ON_REINIT_FAILURE_MAX (1) +#define CFG_BUG_ON_REINIT_FAILURE_DEFAULT (1) + /*--------------------------------------------------------------------------- Type declarations -------------------------------------------------------------------------*/ @@ -4589,6 +4601,7 @@ struct hdd_config { /* parameter to control GTX */ uint32_t tgt_gtx_usr_cfg; bool sap_restrt_ch_avoid; + bool bug_on_reinit_failure; }; typedef struct hdd_config hdd_config_t; diff --git a/CORE/HDD/inc/wlan_hdd_dp_utils.h b/CORE/HDD/inc/wlan_hdd_dp_utils.h index 34134abf40ba..0a044784daf7 100644 --- a/CORE/HDD/inc/wlan_hdd_dp_utils.h +++ b/CORE/HDD/inc/wlan_hdd_dp_utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -115,11 +115,11 @@ VOS_STATUS hdd_list_peek_front( hdd_list_t *pList, hdd_list_node_t **ppNode ); VOS_STATUS hdd_list_peek_next( hdd_list_t *pList, hdd_list_node_t *pNode, hdd_list_node_t **ppNode ); VOS_STATUS hdd_string_to_hex( char *pSrcMac, int length, char *pDescMac ); -struct hdd_context_s; +struct hdd_adapter_s; #ifdef QCA_FEATURE_RPS -void hdd_dp_util_send_rps_ind(struct hdd_context_s *hdd_ctx); +void hdd_dp_util_send_rps_ind(struct hdd_adapter_s *adapter); #else -static inline void hdd_dp_util_send_rps_ind(struct hdd_context_s *hdd_ctx) +static inline void hdd_dp_util_send_rps_ind(struct hdd_adapter_s *adapter) { return; } diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 652136e6b918..7e9e60d8e1d4 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1908,6 +1908,11 @@ void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter); void hdd_prevent_suspend(uint32_t reason); void hdd_allow_suspend(uint32_t reason); void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason); +void hdd_wlan_wakelock_create (void); +void hdd_wlan_wakelock_destroy(void); +void wlan_hdd_wakelocks_destroy(hdd_context_t *hdd_ctx); +void wlan_hdd_netdev_notifiers_cleanup(hdd_context_t * hdd_ctx); + bool hdd_is_ssr_required(void); void hdd_set_ssr_required(e_hdd_ssr_required value); @@ -2227,4 +2232,5 @@ int hdd_reassoc(hdd_adapter_t *pAdapter, const tANI_U8 *bssid, void hdd_sap_restart_handle(struct work_struct *work); +void hdd_set_rps_cpu_mask(hdd_context_t *hdd_ctx); #endif // end #if !defined( WLAN_HDD_MAIN_H ) diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h index a8d223ed8287..77d61f6e1b87 100644 --- a/CORE/HDD/inc/wlan_hdd_tx_rx.h +++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h @@ -237,28 +237,6 @@ void hdd_tx_resume_cb(void *adapter_context, void hdd_tx_resume_timer_expired_handler(void *adapter_context); #endif /* QCA_LL_TX_FLOW_CT */ -#ifdef FEATURE_WLAN_DIAG_SUPPORT -/** - * wlan_hdd_log_eapol() - Function to check and extract EAPOL params - * @skb: skb data - * @event_type: One of enum wifi_connectivity_events to indicate Tx/Rx - * - * This function parses the input skb data to get the EAPOL params,if the - * packet is EAPOL and store it in the pointer passed as input - * - * Return: None - * - */ -void wlan_hdd_log_eapol(struct sk_buff *skb, - uint8_t event_type); -#else -static inline void wlan_hdd_log_eapol(struct sk_buff *skb, - uint8_t event_type) -{ - -} -#endif /* FEATURE_WLAN_DIAG_SUPPORT */ - /** * hdd_mon_rx_packet_cbk() - Receive callback registered with TL. * @vosContext: [in] pointer to VOS context diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index a4ae6863208a..911a01d3781e 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -4581,7 +4581,15 @@ REG_TABLE_ENTRY g_registry_table[] = VAR_FLAGS_OPTIONAL | VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, CFG_CH_AVOID_SAP_RESTART_DEFAULT, CFG_CH_AVOID_SAP_RESTART_MIN, - CFG_CH_AVOID_SAP_RESTART_MAX) + CFG_CH_AVOID_SAP_RESTART_MAX), + + REG_VARIABLE(CFG_BUG_ON_REINIT_FAILURE_NAME, WLAN_PARAM_Integer, + hdd_config_t, bug_on_reinit_failure, + VAR_FLAGS_OPTIONAL | + VAR_FLAGS_RANGE_CHECK_ASSUME_DEFAULT, + CFG_BUG_ON_REINIT_FAILURE_DEFAULT, + CFG_BUG_ON_REINIT_FAILURE_MIN, + CFG_BUG_ON_REINIT_FAILURE_MAX), }; @@ -5391,6 +5399,9 @@ void print_hdd_cfg(hdd_context_t *pHddCtx) hddLog(LOG2, "Name = [%s] Value = [%u]", CFG_ENABLE_VHT_DYNAMIC_STA_CHAINMASK, pHddCtx->cfg_ini->enable_dynamic_sta_chainmask); + hddLog(LOG2, "Name = [%s] Value = [%u]", + CFG_BUG_ON_REINIT_FAILURE_NAME, + pHddCtx->cfg_ini->bug_on_reinit_failure); hddLog(LOG2, "Name = [%s] Value = [%u]", CFG_TGT_GTX_USR_CFG_NAME, @@ -6241,7 +6252,7 @@ VOS_STATUS hdd_hex_string_to_u16_array(char *str, uint16_t *int_array, uint8_t *len, uint8_t int_array_max_len) { char *s = str; - int val = 0; + uint32_t val = 0; if (str == NULL || int_array == NULL || len == NULL) return VOS_STATUS_E_INVAL; diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index f939dfb10156..77c82bad9d99 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -6605,7 +6605,8 @@ void wlan_hdd_clear_link_layer_stats(hdd_adapter_t *adapter) tSirLLStatsClearReq link_layer_stats_clear_req; tHalHandle hal = WLAN_HDD_GET_HAL_CTX(adapter); - link_layer_stats_clear_req.statsClearReqMask = WIFI_STATS_IFACE_AC; + link_layer_stats_clear_req.statsClearReqMask = WIFI_STATS_IFACE_AC | + WIFI_STATS_IFACE_ALL_PEER; link_layer_stats_clear_req.stopReq = 0; link_layer_stats_clear_req.reqId = 1; link_layer_stats_clear_req.staId = adapter->sessionId; @@ -23757,18 +23758,6 @@ int __wlan_hdd_cfg80211_suspend_wlan(struct wiphy *wiphy, return -EAGAIN; } - if (pHddCtx->cfg_ini->enablePowersaveOffload && - pHddCtx->cfg_ini->fIsBmpsEnabled && - ((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || - (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode))) { - if (!sme_PsOffloadIsStaInPowerSave(pHddCtx->hHal, - pAdapter->sessionId)) { - hddLog(VOS_TRACE_LEVEL_DEBUG, - FL("STA is not in power save, Do not allow suspend")); - return -EAGAIN; - } - } - if (pScanInfo->mScanPending && pAdapter->request) { INIT_COMPLETION(pScanInfo->abortscan_event_var); diff --git a/CORE/HDD/src/wlan_hdd_dp_utils.c b/CORE/HDD/src/wlan_hdd_dp_utils.c index 16b93924670c..30d53b9213c4 100644 --- a/CORE/HDD/src/wlan_hdd_dp_utils.c +++ b/CORE/HDD/src/wlan_hdd_dp_utils.c @@ -231,13 +231,11 @@ VOS_STATUS hdd_string_to_hex( char *pSrcMac, int length, char *pDescMac ) * * Return: none */ -void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt) +void hdd_dp_util_send_rps_ind(hdd_adapter_t *adapter) { int i = 0; uint8_t cpu_map_list_len = 0; - hdd_adapter_t *adapter; - hdd_adapter_list_node_t *adapter_node, *next; - VOS_STATUS status = VOS_STATUS_SUCCESS; + hdd_context_t *hdd_ctxt = WLAN_HDD_GET_CTX(adapter); struct wlan_rps_data rps_data; rps_data.num_queues = NUM_TX_QUEUES; @@ -267,18 +265,12 @@ void hdd_dp_util_send_rps_ind(hdd_context_t *hdd_ctxt) i, rps_data.cpu_map_list[i]); } - status = hdd_get_front_adapter (hdd_ctxt, &adapter_node); - while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) { - adapter = adapter_node->pAdapter; - if (NULL != adapter) { - strlcpy(rps_data.ifname, adapter->dev->name, - sizeof(rps_data.ifname)); - wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index, - WLAN_SVC_RPS_ENABLE_IND, - &rps_data, sizeof(rps_data)); - } - status = hdd_get_next_adapter (hdd_ctxt, adapter_node, &next); - adapter_node = next; + if (NULL != adapter) { + strlcpy(rps_data.ifname, adapter->dev->name, + sizeof(rps_data.ifname)); + wlan_hdd_send_svc_nlink_msg(hdd_ctxt->radio_index, + WLAN_SVC_RPS_ENABLE_IND, + &rps_data, sizeof(rps_data)); } } #endif /* QCA_FEATURE_RPS */ diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c index a82c67d09d76..48e8bc4b067d 100644 --- a/CORE/HDD/src/wlan_hdd_early_suspend.c +++ b/CORE/HDD/src/wlan_hdd_early_suspend.c @@ -2118,6 +2118,7 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc) v_CONTEXT_t pVosContext = NULL; hdd_context_t *pHddCtx = NULL; eHalStatus halStatus; + bool bug_on_reinit_failure = 0; hdd_adapter_t *pAdapter; int i; @@ -2141,6 +2142,7 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc) hddLog(VOS_TRACE_LEVEL_FATAL, "%s: HDD context is Null", __func__); goto err_re_init; } + bug_on_reinit_failure = pHddCtx->cfg_ini->bug_on_reinit_failure; if (!hif_sc) { hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hif_sc is NULL", __func__); @@ -2343,7 +2345,6 @@ err_unregister_pmops: #ifdef CONFIG_HAS_EARLYSUSPEND hdd_unregister_mcast_bcast_filter(pHddCtx); #endif - hdd_close_all_adapters(pHddCtx); err_vosstop: vos_stop(pVosContext); @@ -2351,34 +2352,44 @@ err_vosstop: err_vosclose: vos_close(pVosContext); vos_sched_close(pVosContext); - if (pHddCtx) - { - /* Unregister the Net Device Notifier */ - unregister_netdevice_notifier(&hdd_netdev_notifier); - /* Clean up HDD Nlink Service */ - send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); - nl_srv_exit(); - /* Free up dynamically allocated members inside HDD Adapter */ - kfree(pHddCtx->cfg_ini); - pHddCtx->cfg_ini= NULL; - wlan_hdd_deinit_tx_rx_histogram(pHddCtx); - wiphy_unregister(pHddCtx->wiphy); - wlan_hdd_cfg80211_deinit(pHddCtx->wiphy); - wiphy_free(pHddCtx->wiphy); - } - vos_preClose(&pVosContext); #ifdef MEMORY_DEBUG vos_mem_exit(); #endif err_re_init: + if (bug_on_reinit_failure) + VOS_BUG(0); + else { + pr_err("SSR fails during reinit hence doing cleanup"); + /* Stop SSR timer */ + hdd_ssr_timer_del(); + if (pHddCtx) { + /* Unregister all Net Device Notifiers */ + wlan_hdd_netdev_notifiers_cleanup(pHddCtx); + /* Clean up HDD Nlink Service */ + send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); + nl_srv_exit(); + hdd_runtime_suspend_deinit(pHddCtx); + hdd_close_all_adapters(pHddCtx); + /* Free up dynamically allocated members + * inside HDD Adapter + */ + kfree(pHddCtx->cfg_ini); + pHddCtx->cfg_ini= NULL; + /* Destroy all wakelocks */ + wlan_hdd_wakelocks_destroy(pHddCtx); + wlan_hdd_deinit_tx_rx_histogram(pHddCtx); + wiphy_unregister(pHddCtx->wiphy); + wiphy_free(pHddCtx->wiphy); + } + } + vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); + vos_preClose(&pVosContext); /* Allow the phone to go to sleep */ hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_REINIT); - vos_set_reinit_in_progress(VOS_MODULE_ID_VOSS, FALSE); - VOS_BUG(0); + hdd_wlan_wakelock_destroy(); return -EPERM; - success: /* Trigger replay of BTC events */ send_btc_nlink_msg(WLAN_MODULE_DOWN_IND, 0); diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 896e359095c3..54ded248eaf9 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -8160,8 +8160,10 @@ static void hdd_update_tgt_services(hdd_context_t *hdd_ctx, cfg->per_band_chainmask_supp); #ifdef FEATURE_WLAN_TDLS cfg_ini->fEnableTDLSSupport &= cfg->en_tdls; - cfg_ini->fEnableTDLSOffChannel &= cfg->en_tdls_offchan; - cfg_ini->fEnableTDLSBufferSta &= cfg->en_tdls_uapsd_buf_sta; + cfg_ini->fEnableTDLSOffChannel = cfg_ini->fEnableTDLSOffChannel && + cfg->en_tdls_offchan; + cfg_ini->fEnableTDLSBufferSta = cfg_ini->fEnableTDLSOffChannel && + cfg->en_tdls_uapsd_buf_sta; if (cfg_ini->fTDLSUapsdMask && cfg->en_tdls_uapsd_sleep_sta) { cfg_ini->fEnableTDLSSleepSta = TRUE; @@ -10186,9 +10188,6 @@ static hdd_adapter_t* hdd_alloc_station_adapter(hdd_context_t *pHddCtx, VOS_STATUS hdd_register_interface( hdd_adapter_t *pAdapter, tANI_U8 rtnl_lock_held ) { struct net_device *pWlanDev = pAdapter->dev; - //hdd_station_ctx_t *pHddStaCtx = &pAdapter->sessionCtx.station; - //hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX( pAdapter ); - //eHalStatus halStatus = eHAL_STATUS_SUCCESS; if( rtnl_lock_held ) { @@ -13306,6 +13305,60 @@ void hdd_prevent_suspend_timeout(v_U32_t timeout, uint32_t reason) reason); } +/** + * hdd_wlan_wakelock_create() -Create wakelock named as wlan + * + * Return: none + */ +void hdd_wlan_wakelock_create(void) +{ + vos_wake_lock_init(&wlan_wake_lock, "wlan"); +} + +/** + * hdd_wlan_wakelock_destroy() -Destroy wakelock named as wlan + * + * Return: none + */ +void hdd_wlan_wakelock_destroy(void) +{ + vos_wake_lock_destroy(&wlan_wake_lock); +} + +/** + * wlan_hdd_wakelocks_destroy() -Destroy all the wakelocks + * @hdd_ctx: hdd context + * + * Return: none + */ +void wlan_hdd_wakelocks_destroy(hdd_context_t *hdd_ctx) +{ + if (hdd_ctx) { +#ifdef WLAN_FEATURE_HOLD_RX_WAKELOCK + vos_wake_lock_destroy(&hdd_ctx->rx_wake_lock); +#endif + vos_wake_lock_destroy(&hdd_ctx->sap_wake_lock); + hdd_hostapd_channel_wakelock_deinit(hdd_ctx); + } +} + +/** + * wlan_hdd_netdev_notifiers_cleanup() -unregister notifiers with kernel + * @hdd_ctx: hdd context + * + * Return: none + */ +void wlan_hdd_netdev_notifiers_cleanup(hdd_context_t * hdd_ctx) +{ + if (hdd_ctx) { + hddLog(LOGE, FL("Unregister IPv6 notifier")); + hdd_wlan_unregister_ip6_notifier(hdd_ctx); + hddLog(LOGE, FL("Unregister IPv4 notifier")); + unregister_inetaddr_notifier(&hdd_ctx->ipv4_notifier); + } + unregister_netdevice_notifier(&hdd_netdev_notifier); +} + /**--------------------------------------------------------------------------- \brief hdd_exchange_version_and_caps() - HDD function to exchange version and capability @@ -15366,7 +15419,7 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) #endif if (WLAN_HDD_RX_HANDLE_RPS == pHddCtx->cfg_ini->rxhandle) - hdd_dp_util_send_rps_ind(pHddCtx); + hdd_set_rps_cpu_mask(pHddCtx); hal_status = sme_set_lost_link_info_cb(pHddCtx->hHal, hdd_lost_link_info_cb); @@ -15621,7 +15674,7 @@ static int hdd_driver_init( void) vos_mem_init(); #endif - vos_wake_lock_init(&wlan_wake_lock, "wlan"); + hdd_wlan_wakelock_create(); hdd_prevent_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); /* @@ -15651,7 +15704,7 @@ static int hdd_driver_init( void) if (ret_status < 0) { vos_remove_pm_qos(); hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); - vos_wake_lock_destroy(&wlan_wake_lock); + hdd_wlan_wakelock_destroy(); } return ret_status; } @@ -15662,7 +15715,7 @@ static int hdd_driver_init( void) if (ret_status < 0) { vos_remove_pm_qos(); hdd_allow_suspend(WIFI_POWER_EVENT_WAKELOCK_DRIVER_INIT); - vos_wake_lock_destroy(&wlan_wake_lock); + hdd_wlan_wakelock_destroy(); } return ret_status; } @@ -15717,7 +15770,7 @@ static int hdd_driver_init( void) #ifdef MEMORY_DEBUG vos_mem_exit(); #endif - vos_wake_lock_destroy(&wlan_wake_lock); + hdd_wlan_wakelock_destroy(); #ifdef WLAN_LOGGING_SOCK_SVC_ENABLE wlan_logging_sock_deinit_svc(); @@ -15846,7 +15899,7 @@ static void hdd_driver_exit(void) #endif done: - vos_wake_lock_destroy(&wlan_wake_lock); + hdd_wlan_wakelock_destroy(); pr_info("%s: driver unloaded\n", WLAN_MODULE_NAME); } @@ -17969,6 +18022,29 @@ enum sap_acs_dfs_mode wlan_hdd_get_dfs_mode(enum dfs_mode mode) } } + +/** + * hdd_set_rps_cpu_mask - set RPS CPU mask for interfaces + * @hdd_ctx: pointer to hdd_context_t + * + * Return: none + */ +void hdd_set_rps_cpu_mask(hdd_context_t *hdd_ctx) +{ + hdd_adapter_t *adapter; + hdd_adapter_list_node_t *adapter_node, *next; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + status = hdd_get_front_adapter (hdd_ctx, &adapter_node); + while (NULL != adapter_node && VOS_STATUS_SUCCESS == status) { + adapter = adapter_node->pAdapter; + if (NULL != adapter) + hdd_dp_util_send_rps_ind(adapter); + status = hdd_get_next_adapter (hdd_ctx, adapter_node, &next); + adapter_node = next; + } +} + //Register the module init/exit functions module_init(hdd_module_init); module_exit(hdd_module_exit); diff --git a/CORE/HDD/src/wlan_hdd_oemdata.c b/CORE/HDD/src/wlan_hdd_oemdata.c index b1ac539c23b9..c8b399682065 100644 --- a/CORE/HDD/src/wlan_hdd_oemdata.c +++ b/CORE/HDD/src/wlan_hdd_oemdata.c @@ -471,9 +471,11 @@ static inline void hdd_update_channel_bw_info(hdd_context_t *hdd_ctx, uint16_t sec_ch_2g = 0; uint8_t vht_capable; WLAN_PHY_MODE phy_mode; - uint8_t dot11_mode = hdd_ctx->cfg_ini->dot11Mode; + uint32_t wni_dot11_mode; - vht_capable = IS_DOT11_MODE_VHT(dot11_mode); + wni_dot11_mode = sme_get_wni_dot11_mode(hdd_ctx->hHal); + + vht_capable = IS_DOT11_MODE_VHT(wni_dot11_mode); if (chan <= SIR_11B_CHANNEL_END) { if (chan <= 5) @@ -488,15 +490,16 @@ static inline void hdd_update_channel_bw_info(hdd_context_t *hdd_ctx, vos_set_channel_params(chan, sec_ch_2g, &ch_params); if (ch_params.center_freq_seg0) - hdd_chan_info->band_center_freq1 = ch_params.center_freq_seg0; + hdd_chan_info->band_center_freq1 = + ch_params.center_freq_seg0; hddLog(LOG1, - FL("chan %d ch_width %d sec offset %d center_freq_seg0 %d"), - chan, ch_params.ch_width, ch_params.sec_ch_offset, - ch_params.center_freq_seg0); + FL("chan %d wni_dot11_mode %d ch_width %d sec offset %d center_freq_seg0 %d"), + chan, wni_dot11_mode, ch_params.ch_width, + ch_params.sec_ch_offset, ch_params.center_freq_seg0); phy_mode = wma_chan_to_mode(chan, ch_params.sec_ch_offset, - vht_capable, dot11_mode); + vht_capable, wni_dot11_mode); WMI_SET_CHANNEL_MODE(hdd_chan_info, phy_mode); } diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index d2df4b827adc..e51d57f302d2 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -2263,6 +2263,8 @@ struct wireless_dev* __wlan_hdd_add_virtual_intf( name, p2pDeviceAddress.bytes, name_assign_type, VOS_TRUE ); + if (WLAN_HDD_RX_HANDLE_RPS == pHddCtx->cfg_ini->rxhandle) + hdd_dp_util_send_rps_ind(pAdapter); } else { @@ -2270,6 +2272,8 @@ struct wireless_dev* __wlan_hdd_add_virtual_intf( name, wlan_hdd_get_intf_addr(pHddCtx), name_assign_type, VOS_TRUE); + if (WLAN_HDD_RX_HANDLE_RPS == pHddCtx->cfg_ini->rxhandle) + hdd_dp_util_send_rps_ind(pAdapter); } if( NULL == pAdapter) diff --git a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c index 0b4077c49474..e0adb662ee3a 100644 --- a/CORE/HDD/src/wlan_hdd_softap_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_softap_tx_rx.c @@ -355,7 +355,7 @@ int __hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) ac = hdd_QdiscAcToTlAC[skb->queue_mapping]; ++pAdapter->hdd_stats.hddTxRxStats.txXmitClassifiedAC[ac]; - wlan_hdd_log_eapol(skb, + adf_dp_trace_log_pkt(pAdapter->sessionId, skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED); #ifdef QCA_PKT_PROTO_TRACE @@ -392,7 +392,7 @@ int __hdd_softap_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) adf_dp_trace_set_track(skb); DPTRACE(adf_dp_trace(skb, ADF_DP_TRACE_HDD_PACKET_PTR_RECORD, - (uint8_t *)skb->data, sizeof(skb->data))); + (uint8_t *)&skb->data, sizeof(skb->data))); DPTRACE(adf_dp_trace(skb, ADF_DP_TRACE_HDD_PACKET_RECORD, (uint8_t *)skb->data, skb->len)); if (skb->len > ADF_DP_TRACE_RECORD_SIZE) @@ -835,7 +835,8 @@ VOS_STATUS hdd_softap_rx_packet_cbk(v_VOID_t *vosContext, ++pAdapter->stats.rx_packets; pAdapter->stats.rx_bytes += skb->len; - wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED); + adf_dp_trace_log_pkt(pAdapter->sessionId, skb, + WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED); #ifdef QCA_PKT_PROTO_TRACE if ((pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_EAPOL) || (pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_DHCP)) { diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c index 29bdfe094216..7cd0b3f1a2b0 100644 --- a/CORE/HDD/src/wlan_hdd_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -88,57 +88,10 @@ const v_U8_t hdd_QdiscAcToTlAC[] = { }; /*--------------------------------------------------------------------------- - Type declarations - -------------------------------------------------------------------------*/ - -#ifdef FEATURE_WLAN_DIAG_SUPPORT -#define HDD_EAPOL_ETHER_TYPE (0x888E) -#define HDD_EAPOL_ETHER_TYPE_OFFSET (12) -#define HDD_EAPOL_PACKET_TYPE_OFFSET (15) -#define HDD_EAPOL_KEY_INFO_OFFSET (19) -#define HDD_EAPOL_DEST_MAC_OFFSET (0) -#define HDD_EAPOL_SRC_MAC_OFFSET (6) -#define EAPOL_MASK 0x8013 -#define EAPOL_M1_BIT_MASK 0x8000 -#define EAPOL_M2_BIT_MASK 0x0001 -#define EAPOL_M3_BIT_MASK 0x8013 -#define EAPOL_M4_BIT_MASK 0x0003 -#endif /* FEATURE_WLAN_DIAG_SUPPORT */ - -/*--------------------------------------------------------------------------- Function definitions and documentation -------------------------------------------------------------------------*/ /** - * wlan_hdd_is_eapol() - Function to check if frame is EAPOL or not - * @skb: skb data - * - * This function checks if the frame is an EAPOL frame or not - * - * Return: true (1) if packet is EAPOL - * - */ -static bool wlan_hdd_is_eapol(struct sk_buff *skb) -{ - uint16_t ether_type; - - if (!skb) { - hddLog(VOS_TRACE_LEVEL_ERROR, FL("skb is NULL")); - return false; - } - - ether_type = (uint16_t)(*(uint16_t *) - (skb->data + HDD_ETHERTYPE_802_1_X_FRAME_OFFSET)); - - if (ether_type == VOS_SWAP_U16(HDD_ETHERTYPE_802_1_X)) { - return true; - } else { - /* No error msg handled since this will happen often */ - return false; - } -} - -/** * wlan_hdd_is_wai() - Check if frame is EAPOL or WAPI * @skb: skb data * @@ -652,9 +605,6 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) skb->queue_mapping = hddLinuxUpToAcMap[up]; } - wlan_hdd_log_eapol(skb, - WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED); - #ifdef QCA_PKT_PROTO_TRACE if ((hddCtxt->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_EAPOL) || (hddCtxt->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_DHCP)) @@ -683,19 +633,20 @@ int __hdd_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) list_tail = list_tail->next; } vos_mem_zero(skb->cb, sizeof(skb->cb)); + adf_dp_trace_log_pkt(pAdapter->sessionId, skb, + WIFI_EVENT_DRIVER_EAPOL_FRAME_TRANSMIT_REQUESTED); NBUF_SET_PACKET_TRACK(skb, NBUF_TX_PKT_DATA_TRACK); NBUF_UPDATE_TX_PKT_COUNT(skb, NBUF_TX_PKT_HDD); adf_dp_trace_set_track(skb); DPTRACE(adf_dp_trace(skb, ADF_DP_TRACE_HDD_PACKET_PTR_RECORD, - (uint8_t *)skb->data, sizeof(skb->data))); + (uint8_t *)&skb->data, sizeof(skb->data))); DPTRACE(adf_dp_trace(skb, ADF_DP_TRACE_HDD_PACKET_RECORD, (uint8_t *)skb->data, skb->len)); if (skb->len > ADF_DP_TRACE_RECORD_SIZE) DPTRACE(adf_dp_trace(skb, ADF_DP_TRACE_HDD_PACKET_RECORD, (uint8_t *)&skb->data[ADF_DP_TRACE_RECORD_SIZE], (skb->len - ADF_DP_TRACE_RECORD_SIZE))); - skb = skb_next; continue; @@ -1278,7 +1229,8 @@ VOS_STATUS hdd_rx_packet_cbk(v_VOID_t *vosContext, continue; } - wlan_hdd_log_eapol(skb, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED); + adf_dp_trace_log_pkt(pAdapter->sessionId, skb, + WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED); #ifdef QCA_PKT_PROTO_TRACE if ((pHddCtx->cfg_ini->gEnableDebugLog & VOS_PKT_TRAC_TYPE_EAPOL) || @@ -1345,126 +1297,6 @@ VOS_STATUS hdd_rx_packet_cbk(v_VOID_t *vosContext, return VOS_STATUS_SUCCESS; } -#ifdef FEATURE_WLAN_DIAG_SUPPORT - -/** - * wlan_hdd_get_eapol_params() - Function to extract EAPOL params - * @skb: sbb data - * @eapol_params: Pointer to hold the parsed EAPOL params - * @event_type: Event type to indicate Tx/Rx - * - * This function parses the input skb data to get the EAPOL params,if the - * packet is EAPOL and store it in the pointer passed as input - * - * Return: 0 on success and negative value in failure - * - */ -static int wlan_hdd_get_eapol_params(struct sk_buff *skb, - struct vos_event_wlan_eapol *eapol_params, - uint8_t event_type) -{ - bool ret; - uint8_t packet_type=0; - - ret = wlan_hdd_is_eapol(skb); - - if (!ret) - return -1; - - packet_type = (uint8_t)(*(uint8_t *) - (skb->data + HDD_EAPOL_PACKET_TYPE_OFFSET)); - - eapol_params->eapol_packet_type = packet_type; - eapol_params->eapol_key_info = (uint16_t)(*(uint16_t *) - (skb->data + HDD_EAPOL_KEY_INFO_OFFSET)); - eapol_params->event_sub_type = event_type; - eapol_params->eapol_rate = 0;/* As of now, zero */ - - vos_mem_copy(eapol_params->dest_addr, - (skb->data + HDD_EAPOL_DEST_MAC_OFFSET), - sizeof(eapol_params->dest_addr)); - vos_mem_copy(eapol_params->src_addr, - (skb->data + HDD_EAPOL_SRC_MAC_OFFSET), - sizeof(eapol_params->src_addr)); - return 0; -} -/** - * wlan_hdd_event_eapol_log() - Function to log EAPOL events - * @eapol_params: Structure containing EAPOL params - * - * This function logs the parsed EAPOL params - * - * Return: None - * - */ -static void wlan_hdd_event_eapol_log(struct vos_event_wlan_eapol eapol_params) -{ - WLAN_VOS_DIAG_EVENT_DEF(wlan_diag_event, struct vos_event_wlan_eapol); - - wlan_diag_event.event_sub_type = eapol_params.event_sub_type; - wlan_diag_event.eapol_packet_type = eapol_params.eapol_packet_type; - wlan_diag_event.eapol_key_info = eapol_params.eapol_key_info; - wlan_diag_event.eapol_rate = eapol_params.eapol_rate; - vos_mem_copy(wlan_diag_event.dest_addr, - eapol_params.dest_addr, - sizeof (wlan_diag_event.dest_addr)); - vos_mem_copy(wlan_diag_event.src_addr, - eapol_params.src_addr, - sizeof (wlan_diag_event.src_addr)); - - WLAN_VOS_DIAG_EVENT_REPORT(&wlan_diag_event, EVENT_WLAN_EAPOL); -} - -/** - * wlan_hdd_log_eapol() - Function to check and extract EAPOL params - * @skb: skb data - * @event_type: One of enum wifi_connectivity_events to indicate Tx/Rx - * - * This function parses the input skb data to get the EAPOL params,if the - * packet is EAPOL and store it in the pointer passed as input - * - * Return: None - * - */ -void wlan_hdd_log_eapol(struct sk_buff *skb, - uint8_t event_type) -{ - int ret; - struct vos_event_wlan_eapol eapol_params; - - ret = wlan_hdd_get_eapol_params(skb, &eapol_params, event_type); - if (ret) - return; - - wlan_hdd_event_eapol_log(eapol_params); - if ((eapol_params.eapol_key_info & EAPOL_MASK) == EAPOL_M1_BIT_MASK) { - hddLog(LOG1, - FL("%s: M1 packet"), eapol_params.event_sub_type == - WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? - "RX" : "TX"); - } else if ((eapol_params.eapol_key_info & EAPOL_MASK) == - EAPOL_M2_BIT_MASK) { - hddLog(LOG1, - FL("%s: M2 packet"), eapol_params.event_sub_type == - WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? - "RX" : "TX"); - - } else if ((eapol_params.eapol_key_info & EAPOL_MASK) == - EAPOL_M3_BIT_MASK) { - hddLog(LOG1, - FL("%s: M3 packet"), eapol_params.event_sub_type == - WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? - "RX" : "TX"); - } else if ((eapol_params.eapol_key_info & EAPOL_MASK) == - EAPOL_M4_BIT_MASK) { - hddLog(LOG1, - FL("%s: M4 packet"), eapol_params.event_sub_type == - WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED ? - "RX" : "TX"); - } -} -#endif /* FEATURE_WLAN_DIAG_SUPPORT */ - /** * hdd_reason_type_to_string() - return string conversion of reason type * @reason: reason type diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index f72e5638ed5b..44ff9cfee051 100644 --- a/CORE/MAC/inc/qwlan_version.h +++ b/CORE/MAC/inc/qwlan_version.h @@ -42,9 +42,9 @@ BRIEF DESCRIPTION: #define QWLAN_VERSION_MINOR 0 #define QWLAN_VERSION_PATCH 11 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 86 +#define QWLAN_VERSION_BUILD 89 -#define QWLAN_VERSIONSTR "4.0.11.86" +#define QWLAN_VERSIONSTR "4.0.11.89" #define AR6320_REV1_VERSION 0x5000000 diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 7874c9f9e5ba..a268e2d0efbb 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -6134,6 +6134,10 @@ typedef struct #define WIFI_STATS_IFACE_AC 0x00000040 /* all contention (min, max, avg) statistics (within ac statistics) */ #define WIFI_STATS_IFACE_CONTENTION 0x00000080 +/** All peer stats on this interface */ +#define WIFI_STATS_IFACE_ALL_PEER 0x00000100 +/** Clear particular peer stats depending on the peer_mac */ +#define WIFI_STATS_IFACE_PER_PEER 0x00000200 typedef struct { diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index 1ca46f890c5f..106e1d151188 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -5222,6 +5222,7 @@ void __limProcessReportMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) tpSirBeaconReportXmitInd pBcnReport=NULL; tpPESession psessionEntry=NULL; tANI_U8 sessionId; + tpEsePEContext pEseContext = NULL; if(pMsg->bodyptr == NULL) { @@ -5234,7 +5235,10 @@ void __limProcessReportMessage(tpAniSirGlobal pMac, tpSirMsgQ pMsg) limLog(pMac, LOGE, "Session Does not exist for given bssId"); return; } - if (psessionEntry->isESEconnection) + + pEseContext = &psessionEntry->eseContext; + + if (psessionEntry->isESEconnection && pEseContext->curMeasReq.isValid) eseProcessBeaconReportXmit( pMac, pMsg->bodyptr); else #endif diff --git a/CORE/MAC/src/pe/lim/limScanResultUtils.c b/CORE/MAC/src/pe/lim/limScanResultUtils.c index db6c5f282456..09ec15a768e1 100644 --- a/CORE/MAC/src/pe/lim/limScanResultUtils.c +++ b/CORE/MAC/src/pe/lim/limScanResultUtils.c @@ -523,6 +523,8 @@ limCheckAndAddBssDescription(tpAniSirGlobal pMac, return; } + vos_mem_zero(pBssDescr, frameLen); + // In scan state, store scan result. #if defined WLAN_FEATURE_VOWIFI limCollectBssDescription(pMac, &pBssDescr->bssDescription, diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c index 60122c056b12..e4d3378f1b81 100644 --- a/CORE/MAC/src/pe/lim/limSession.c +++ b/CORE/MAC/src/pe/lim/limSession.c @@ -592,6 +592,12 @@ void peDeleteSession(tpAniSirGlobal pMac, tpPESession psessionEntry) tANI_U16 n; TX_TIMER *timer_ptr; + if (!psessionEntry->valid) { + limLog(pMac, LOG1, FL("peSession %d already deleted"), + psessionEntry->peSessionId); + return; + } + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_DEBUG, "Trying to delete PE session %d Opmode %d BssIdx %d" " BSSID: " MAC_ADDRESS_STR, psessionEntry->peSessionId, diff --git a/CORE/SERVICES/COMMON/adf/adf_nbuf.c b/CORE/SERVICES/COMMON/adf/adf_nbuf.c index 87adfe9aeb41..aed95aaa5184 100644 --- a/CORE/SERVICES/COMMON/adf/adf_nbuf.c +++ b/CORE/SERVICES/COMMON/adf/adf_nbuf.c @@ -35,6 +35,8 @@ #include <adf_os_io.h> #include <adf_os_lock.h> #include <net/ieee80211_radiotap.h> +#include "adf_trace.h" +#include "vos_trace.h" #ifdef CONFIG_WCNSS_MEM_PRE_ALLOC #include <net/cnss_prealloc.h> @@ -565,15 +567,211 @@ __adf_nbuf_reg_trace_cb(adf_nbuf_trace_update_t cb_func_ptr) return; } +/** + * __adf_nbuf_data_get_dhcp_subtype() - get the subtype + * of DHCP packet. + * @data: Pointer to DHCP packet data buffer + * + * This func. returns the subtype of DHCP packet. + * + * Return: subtype of the DHCP packet. + */ +enum adf_proto_subtype +__adf_nbuf_data_get_dhcp_subtype(uint8_t *data) +{ + enum adf_proto_subtype subtype = ADF_PROTO_INVALID; + + if ((data[DHCP_OPTION53_OFFSET] == DHCP_OPTION53) && + (data[DHCP_OPTION53_LENGTH_OFFSET] == + DHCP_OPTION53_LENGTH)) { + + switch (data[DHCP_OPTION53_STATUS_OFFSET]) { + case DHCPDISCOVER: + subtype = ADF_PROTO_DHCP_DISCOVER; + break; + case DHCPREQUEST: + subtype = ADF_PROTO_DHCP_REQUEST; + break; + case DHCPOFFER: + subtype = ADF_PROTO_DHCP_OFFER; + break; + case DHCPACK: + subtype = ADF_PROTO_DHCP_ACK; + break; + case DHCPNAK: + subtype = ADF_PROTO_DHCP_NACK; + break; + case DHCPRELEASE: + subtype = ADF_PROTO_DHCP_RELEASE; + break; + case DHCPINFORM: + subtype = ADF_PROTO_DHCP_INFORM; + break; + case DHCPDECLINE: + subtype = ADF_PROTO_DHCP_DECLINE; + break; + default: + break; + } + } + + return subtype; +} + +/** + * __adf_nbuf_data_get_eapol_subtype() - get the subtype + * of EAPOL packet. + * @data: Pointer to EAPOL packet data buffer + * + * This func. returns the subtype of EAPOL packet. + * + * Return: subtype of the EAPOL packet. + */ +enum adf_proto_subtype +__adf_nbuf_data_get_eapol_subtype(uint8_t *data) +{ + uint16_t eapol_key_info; + enum adf_proto_subtype subtype = ADF_PROTO_INVALID; + uint16_t mask; + + eapol_key_info = (uint16_t)(*(uint16_t *) + (data + EAPOL_KEY_INFO_OFFSET)); + + mask = eapol_key_info & EAPOL_MASK; + switch (mask) { + case EAPOL_M1_BIT_MASK: + subtype = ADF_PROTO_EAPOL_M1; + break; + case EAPOL_M2_BIT_MASK: + subtype = ADF_PROTO_EAPOL_M2; + break; + case EAPOL_M3_BIT_MASK: + subtype = ADF_PROTO_EAPOL_M3; + break; + case EAPOL_M4_BIT_MASK: + subtype = ADF_PROTO_EAPOL_M4; + break; + default: + break; + } + + return subtype; +} + +/** + * __adf_nbuf_data_get_arp_subtype() - get the subtype + * of ARP packet. + * @data: Pointer to ARP packet data buffer + * + * This func. returns the subtype of ARP packet. + * + * Return: subtype of the ARP packet. + */ +enum adf_proto_subtype +__adf_nbuf_data_get_arp_subtype(uint8_t *data) +{ + uint16_t subtype; + enum adf_proto_subtype proto_subtype = ADF_PROTO_INVALID; + + subtype = (uint16_t)(*(uint16_t *) + (data + ARP_SUB_TYPE_OFFSET)); + + switch (adf_os_cpu_to_be16(subtype)) { + case ARP_REQUEST: + proto_subtype = ADF_PROTO_ARP_REQ; + break; + case ARP_RESPONSE: + proto_subtype = ADF_PROTO_ARP_RES; + break; + default: + break; + } + + return proto_subtype; +} + +/** + * __adf_nbuf_data_get_icmp_subtype() - get the subtype + * of IPV4 ICMP packet. + * @data: Pointer to IPV4 ICMP packet data buffer + * + * This func. returns the subtype of ICMP packet. + * + * Return: subtype of the ICMP packet. + */ +enum adf_proto_subtype +__adf_nbuf_data_get_icmp_subtype(uint8_t *data) +{ + uint8_t subtype; + enum adf_proto_subtype proto_subtype = ADF_PROTO_INVALID; + + subtype = (uint8_t)(*(uint8_t *) + (data + ICMP_SUBTYPE_OFFSET)); + + switch (subtype) { + case ICMP_REQUEST: + proto_subtype = ADF_PROTO_ICMP_REQ; + break; + case ICMP_RESPONSE: + proto_subtype = ADF_PROTO_ICMP_RES; + break; + default: + break; + } + + return proto_subtype; +} + +/** + * __adf_nbuf_data_get_icmpv6_subtype() - get the subtype + * of IPV6 ICMPV6 packet. + * @data: Pointer to IPV6 ICMPV6 packet data buffer + * + * This func. returns the subtype of ICMPV6 packet. + * + * Return: subtype of the ICMPV6 packet. + */ +enum adf_proto_subtype +__adf_nbuf_data_get_icmpv6_subtype(uint8_t *data) +{ + uint8_t subtype; + enum adf_proto_subtype proto_subtype = ADF_PROTO_INVALID; + + subtype = (uint8_t)(*(uint8_t *) + (data + ICMPV6_SUBTYPE_OFFSET)); + + switch (subtype) { + case ICMPV6_REQUEST: + proto_subtype = ADF_PROTO_ICMPV6_REQ; + break; + case ICMPV6_RESPONSE: + proto_subtype = ADF_PROTO_ICMPV6_RES; + break; + default: + break; + } + + return proto_subtype; +} + +/** + * __adf_nbuf_data_is_dhcp_pkt() - check if it is DHCP packet. + * @data: Pointer to DHCP packet data buffer + * + * This func. checks whether it is a DHCP packet or not. + * + * Return: A_STATUS_OK if it is a DHCP packet + * A_STATUS_FAILED if not + */ a_status_t -__adf_nbuf_is_dhcp_pkt(struct sk_buff *skb) +__adf_nbuf_data_is_dhcp_pkt(uint8_t *data) { a_uint16_t SPort; a_uint16_t DPort; - SPort = (a_uint16_t)(*(a_uint16_t *)(skb->data + ADF_NBUF_TRAC_IPV4_OFFSET + + SPort = (a_uint16_t)(*(a_uint16_t *)(data + ADF_NBUF_TRAC_IPV4_OFFSET + ADF_NBUF_TRAC_IPV4_HEADER_SIZE)); - DPort = (a_uint16_t)(*(a_uint16_t *)(skb->data + ADF_NBUF_TRAC_IPV4_OFFSET + + DPort = (a_uint16_t)(*(a_uint16_t *)(data + ADF_NBUF_TRAC_IPV4_OFFSET + ADF_NBUF_TRAC_IPV4_HEADER_SIZE + sizeof(a_uint16_t))); if (((ADF_NBUF_TRAC_DHCP_SRV_PORT == adf_os_cpu_to_be16(SPort)) && @@ -589,12 +787,22 @@ __adf_nbuf_is_dhcp_pkt(struct sk_buff *skb) } } +/** + * __adf_nbuf_data_is_eapol_pkt() - check if it is EAPOL packet. + * @data: Pointer to EAPOL packet data buffer + * + * This func. checks whether it is a EAPOL packet or not. + * + * Return: A_STATUS_OK if it is a EAPOL packet + * A_STATUS_FAILED if not + */ a_status_t -__adf_nbuf_is_eapol_pkt(struct sk_buff *skb) +__adf_nbuf_data_is_eapol_pkt(uint8_t *data) { a_uint16_t ether_type; - ether_type = (a_uint16_t)(*(a_uint16_t *)(skb->data + ADF_NBUF_TRAC_ETH_TYPE_OFFSET)); + ether_type = (a_uint16_t)(*(a_uint16_t *)(data + + ADF_NBUF_TRAC_ETH_TYPE_OFFSET)); if (ADF_NBUF_TRAC_EAPOL_ETH_TYPE == adf_os_cpu_to_be16(ether_type)) { return A_STATUS_OK; @@ -605,6 +813,222 @@ __adf_nbuf_is_eapol_pkt(struct sk_buff *skb) } } +/** + * __adf_nbuf_data_is_ipv4_arp_pkt() - check if it is ARP packet. + * @data: Pointer to ARP packet data buffer + * + * This func. checks whether it is a ARP packet or not. + * + * Return: TRUE if it is a ARP packet + * FALSE if not + */ +bool __adf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data) +{ + uint16_t ether_type; + + ether_type = (uint16_t)(*(uint16_t *)(data + + ADF_NBUF_TRAC_ETH_TYPE_OFFSET)); + + if (ether_type == adf_os_cpu_to_be16(ADF_NBUF_TRAC_ARP_ETH_TYPE)) + return true; + else + return false; +} + +/** + * __adf_nbuf_data_is_ipv4_pkt() - check if it is IPV4 packet. + * @data: Pointer to IPV4 packet data buffer + * + * This func. checks whether it is a IPV4 packet or not. + * + * Return: TRUE if it is a IPV4 packet + * FALSE if not + */ +bool __adf_nbuf_data_is_ipv4_pkt(uint8_t *data) +{ + uint16_t ether_type; + + ether_type = (uint16_t)(*(uint16_t *)(data + + ADF_NBUF_TRAC_ETH_TYPE_OFFSET)); + + if (ether_type == adf_os_cpu_to_be16(ADF_NBUF_TRAC_IPV4_ETH_TYPE)) + return true; + else + return false; +} + +/** + * __adf_nbuf_data_is_ipv6_pkt() - check if it is IPV6 packet. + * @data: Pointer to IPV6 packet data buffer + * + * This func. checks whether it is a IPV6 packet or not. + * + * Return: TRUE if it is a IPV6 packet + * FALSE if not + */ +bool __adf_nbuf_data_is_ipv6_pkt(uint8_t *data) +{ + uint16_t ether_type; + + ether_type = (uint16_t)(*(uint16_t *)(data + + ADF_NBUF_TRAC_ETH_TYPE_OFFSET)); + + if (ether_type == adf_os_cpu_to_be16(ADF_NBUF_TRAC_IPV6_ETH_TYPE)) + return true; + else + return false; +} + +/** + * __adf_nbuf_data_is_icmp_pkt() - check if it is IPV4 ICMP packet. + * @data: Pointer to IPV4 ICMP packet data buffer + * + * This func. checks whether it is a ICMP packet or not. + * + * Return: TRUE if it is a ICMP packet + * FALSE if not + */ +bool __adf_nbuf_data_is_icmp_pkt(uint8_t *data) +{ + if (__adf_nbuf_data_is_ipv4_pkt(data)) { + uint8_t pkt_type; + + pkt_type = (uint8_t)(*(uint8_t *)(data + + ADF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); + + if (pkt_type == ADF_NBUF_TRAC_ICMP_TYPE) + return true; + else + return false; + } else + return false; +} + +/** + * __adf_nbuf_data_is_icmpv6_pkt() - check if it is IPV6 ICMPV6 packet. + * @data: Pointer to IPV6 ICMPV6 packet data buffer + * + * This func. checks whether it is a ICMPV6 packet or not. + * + * Return: TRUE if it is a ICMPV6 packet + * FALSE if not + */ +bool __adf_nbuf_data_is_icmpv6_pkt(uint8_t *data) +{ + if (__adf_nbuf_data_is_ipv6_pkt(data)) { + uint8_t pkt_type; + + pkt_type = (uint8_t)(*(uint8_t *)(data + + ADF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); + + if (pkt_type == ADF_NBUF_TRAC_ICMPv6_TYPE) + return true; + else + return false; + } else + return false; +} + +/** + * __adf_nbuf_data_is_ipv4_udp_pkt() - check if it is IPV4 UDP packet. + * @data: Pointer to IPV4 UDP packet data buffer + * + * This func. checks whether it is a IPV4 UDP packet or not. + * + * Return: TRUE if it is a IPV4 UDP packet + * FALSE if not + */ +bool __adf_nbuf_data_is_ipv4_udp_pkt(uint8_t *data) +{ + if (__adf_nbuf_data_is_ipv4_pkt(data)) { + uint8_t pkt_type; + + pkt_type = (uint8_t)(*(uint8_t *)(data + + ADF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); + + if (pkt_type == ADF_NBUF_TRAC_UDP_TYPE) + return true; + else + return false; + } else + return false; +} + +/** + * __adf_nbuf_data_is_ipv4_tcp_pkt() - check if it is IPV4 TCP packet. + * @data: Pointer to IPV4 TCP packet data buffer + * + * This func. checks whether it is a IPV4 TCP packet or not. + * + * Return: TRUE if it is a IPV4 TCP packet + * FALSE if not + */ +bool __adf_nbuf_data_is_ipv4_tcp_pkt(uint8_t *data) +{ + if (__adf_nbuf_data_is_ipv4_pkt(data)) { + uint8_t pkt_type; + + pkt_type = (uint8_t)(*(uint8_t *)(data + + ADF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET)); + + if (pkt_type == ADF_NBUF_TRAC_TCP_TYPE) + return true; + else + return false; + } else + return false; +} + +/** + * __adf_nbuf_data_is_ipv6_udp_pkt() - check if it is IPV6 UDP packet. + * @data: Pointer to IPV6 UDP packet data buffer + * + * This func. checks whether it is a IPV6 UDP packet or not. + * + * Return: TRUE if it is a IPV6 UDP packet + * FALSE if not + */ +bool __adf_nbuf_data_is_ipv6_udp_pkt(uint8_t *data) +{ + if (__adf_nbuf_data_is_ipv6_pkt(data)) { + uint8_t pkt_type; + + pkt_type = (uint8_t)(*(uint8_t *)(data + + ADF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); + + if (pkt_type == ADF_NBUF_TRAC_UDP_TYPE) + return true; + else + return false; + } else + return false; +} + +/** + * __adf_nbuf_data_is_ipv6_tcp_pkt() - check if it is IPV6 TCP packet. + * @data: Pointer to IPV6 TCP packet data buffer + * + * This func. checks whether it is a IPV6 TCP packet or not. + * + * Return: TRUE if it is a IPV6 TCP packet + * FALSE if not + */ +bool __adf_nbuf_data_is_ipv6_tcp_pkt(uint8_t *data) +{ + if (__adf_nbuf_data_is_ipv6_pkt(data)) { + uint8_t pkt_type; + + pkt_type = (uint8_t)(*(uint8_t *)(data + + ADF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET)); + + if (pkt_type == ADF_NBUF_TRAC_TCP_TYPE) + return true; + else + return false; + } else + return false; +} + #ifdef QCA_PKT_PROTO_TRACE void __adf_nbuf_trace_update(struct sk_buff *buf, char *event_string) diff --git a/CORE/SERVICES/COMMON/adf/adf_nbuf.h b/CORE/SERVICES/COMMON/adf/adf_nbuf.h index b64a8662f90e..860aa7f77d28 100644 --- a/CORE/SERVICES/COMMON/adf/adf_nbuf.h +++ b/CORE/SERVICES/COMMON/adf/adf_nbuf.h @@ -52,8 +52,10 @@ #define NBUF_PKT_TRAC_TYPE_EAPOL 0x02 #define NBUF_PKT_TRAC_TYPE_DHCP 0x04 #define NBUF_PKT_TRAC_TYPE_MGMT_ACTION 0x08 +#define NBUF_PKT_TRAC_TYPE_ARP 0x10 #define NBUF_PKT_TRAC_MAX_STRING 12 #define NBUF_PKT_TRAC_PROTO_STRING 4 +#define ADF_NBUF_PKT_ERROR 1 #define ADF_NBUF_TRAC_IPV4_OFFSET 14 #define ADF_NBUF_TRAC_IPV4_HEADER_SIZE 20 @@ -61,6 +63,28 @@ #define ADF_NBUF_TRAC_DHCP_CLI_PORT 68 #define ADF_NBUF_TRAC_ETH_TYPE_OFFSET 12 #define ADF_NBUF_TRAC_EAPOL_ETH_TYPE 0x888E +#define ADF_NBUF_TRAC_ARP_ETH_TYPE 0x0806 +#define ADF_NBUF_TRAC_IPV4_ETH_TYPE 0x0800 +#define ADF_NBUF_TRAC_IPV6_ETH_TYPE 0x86dd +#define ADF_NBUF_DEST_MAC_OFFSET 0 +#define ADF_NBUF_SRC_MAC_OFFSET 6 +#define ADF_NBUF_TRAC_IPV4_PROTO_TYPE_OFFSET 23 +#define ADF_NBUF_TRAC_IPV6_PROTO_TYPE_OFFSET 20 +#define ADF_NBUF_TRAC_ICMP_TYPE 1 +#define ADF_NBUF_TRAC_TCP_TYPE 6 +#define ADF_NBUF_TRAC_UDP_TYPE 17 +#define ADF_NBUF_TRAC_ICMPv6_TYPE 0x3a + +/* EAPOL Related MASK */ +#define EAPOL_PACKET_TYPE_OFFSET 15 +#define EAPOL_KEY_INFO_OFFSET 19 +#define EAPOL_PKT_LEN_OFFSET 16 +#define EAPOL_KEY_LEN_OFFSET 21 +#define EAPOL_MASK 0x8013 +#define EAPOL_M1_BIT_MASK 0x8000 +#define EAPOL_M2_BIT_MASK 0x0001 +#define EAPOL_M3_BIT_MASK 0x8013 +#define EAPOL_M4_BIT_MASK 0x0003 /* Tracked Packet types */ #define NBUF_TX_PKT_INVALID 0 @@ -102,6 +126,86 @@ struct mon_rx_status { uint8_t nr_ant; }; +/* DHCP Related Mask */ +#define DHCP_OPTION53 (0x35) +#define DHCP_OPTION53_LENGTH (1) +#define DHCP_OPTION53_OFFSET (0x11A) +#define DHCP_OPTION53_LENGTH_OFFSET (0x11B) +#define DHCP_OPTION53_STATUS_OFFSET (0x11C) +#define DHCP_PKT_LEN_OFFSET 16 +#define DHCP_TRANSACTION_ID_OFFSET 46 +#define DHCPDISCOVER (1) +#define DHCPOFFER (2) +#define DHCPREQUEST (3) +#define DHCPDECLINE (4) +#define DHCPACK (5) +#define DHCPNAK (6) +#define DHCPRELEASE (7) +#define DHCPINFORM (8) + +/* ARP Related Mask */ +#define ARP_SUB_TYPE_OFFSET 20 +#define ARP_REQUEST (1) +#define ARP_RESPONSE (2) + +/* IPV4 Related Mask */ +#define IPV4_PKT_LEN_OFFSET 16 +#define IPV4_TCP_SEQ_NUM_OFFSET 38 + +/* IPV4 ICMP Related Mask */ +#define ICMP_SEQ_NUM_OFFSET 40 +#define ICMP_SUBTYPE_OFFSET 34 +#define ICMP_REQUEST 0x08 +#define ICMP_RESPONSE 0x00 + +/* IPV6 Related Mask */ +#define IPV6_PKT_LEN_OFFSET 18 +#define IPV6_TCP_SEQ_NUM_OFFSET 58 + +/* IPV6 ICMPV6 Related Mask */ +#define ICMPV6_SEQ_NUM_OFFSET 60 +#define ICMPV6_SUBTYPE_OFFSET 54 +#define ICMPV6_REQUEST 0x80 +#define ICMPV6_RESPONSE 0x81 + +#define ADF_NBUF_IPA_CHECK_MASK 0x80000000 + +enum adf_proto_type { + ADF_PROTO_TYPE_DHCP = 0, + ADF_PROTO_TYPE_EAPOL, + ADF_PROTO_TYPE_ARP, + ADF_PROTO_TYPE_MAX +}; + +enum adf_proto_subtype { + ADF_PROTO_INVALID = 0, + ADF_PROTO_EAPOL_M1, + ADF_PROTO_EAPOL_M2, + ADF_PROTO_EAPOL_M3, + ADF_PROTO_EAPOL_M4, + ADF_PROTO_DHCP_DISCOVER, + ADF_PROTO_DHCP_REQUEST, + ADF_PROTO_DHCP_OFFER, + ADF_PROTO_DHCP_ACK, + ADF_PROTO_DHCP_NACK, + ADF_PROTO_DHCP_RELEASE, + ADF_PROTO_DHCP_INFORM, + ADF_PROTO_DHCP_DECLINE, + ADF_PROTO_ARP_REQ, + ADF_PROTO_ARP_RES, + ADF_PROTO_ARP_SUBTYPE, + ADF_PROTO_ICMP_REQ, + ADF_PROTO_ICMP_RES, + ADF_PROTO_ICMPV6_REQ, + ADF_PROTO_ICMPV6_RES, + ADF_PROTO_IPV4_UDP, + ADF_PROTO_IPV4_TCP, + ADF_PROTO_IPV6_UDP, + ADF_PROTO_IPV6_TCP, + ADF_PROTO_SUBTYPE_MAX +}; + + /** * @brief Platform indepedent packet abstraction */ @@ -568,6 +672,19 @@ adf_nbuf_data(adf_nbuf_t buf) return __adf_nbuf_data(buf); } +/** + * adf_nbuf_data_addr() - Return the address of skb->data + * @buf: buffer + * + * This function returns the address of skb->data + * + * Return: skb->data address + */ +static inline uint8_t * +adf_nbuf_data_addr(adf_nbuf_t buf) +{ + return __adf_nbuf_data_addr(buf); +} /** * @brief return the amount of headroom int the current nbuf @@ -1208,29 +1325,484 @@ adf_nbuf_get_tx_parallel_dnload_frm(adf_nbuf_t buf) } /** - * @brief this will return if the skb data is a dhcp packet or not + * adf_nbuf_get_dhcp_subtype() - get the subtype + * of DHCP packet. + * @buf: Pointer to DHCP packet buffer * - * @param[in] buf buffer + * This func. returns the subtype of DHCP packet. * - * @return A_STATUS_OK if packet is DHCP packet + * Return: subtype of the DHCP packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_get_dhcp_subtype(adf_nbuf_t buf) +{ + return __adf_nbuf_data_get_dhcp_subtype(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_get_dhcp_subtype() - get the subtype + * of DHCP packet. + * @buf: Pointer to DHCP packet data buffer + * + * This func. returns the subtype of DHCP packet. + * + * Return: subtype of the DHCP packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_data_get_dhcp_subtype(uint8_t *data) +{ + return __adf_nbuf_data_get_dhcp_subtype(data); +} + +/** + * adf_nbuf_get_eapol_subtype() - get the subtype + * of EAPOL packet. + * @buf: Pointer to EAPOL packet buffer + * + * This func. returns the subtype of EAPOL packet. + * + * Return: subtype of the EAPOL packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_get_eapol_subtype(adf_nbuf_t buf) +{ + return __adf_nbuf_data_get_eapol_subtype(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_get_eapol_subtype() - get the subtype + * of EAPOL packet. + * @data: Pointer to EAPOL packet data buffer + * + * This func. returns the subtype of EAPOL packet. + * + * Return: subtype of the EAPOL packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_data_get_eapol_subtype(uint8_t *data) +{ + return __adf_nbuf_data_get_eapol_subtype(data); +} + +/** + * adf_nbuf_get_arp_subtype() - get the subtype + * of ARP packet. + * @buf: Pointer to ARP packet buffer + * + * This func. returns the subtype of ARP packet. + * + * Return: subtype of the ARP packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_get_arp_subtype(adf_nbuf_t buf) +{ + return __adf_nbuf_data_get_arp_subtype(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_get_arp_subtype() - get the subtype + * of ARP packet. + * @data: Pointer to ARP packet data buffer + * + * This func. returns the subtype of ARP packet. + * + * Return: subtype of the ARP packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_data_get_arp_subtype(uint8_t *data) +{ + return __adf_nbuf_data_get_arp_subtype(data); +} + +/** + * adf_nbuf_get_icmp_subtype() - get the subtype + * of IPV4 ICMP packet. + * @buf: Pointer to IPV4 ICMP packet buffer + * + * This func. returns the subtype of ICMP packet. + * + * Return: subtype of the ICMP packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_get_icmp_subtype(adf_nbuf_t buf) +{ + return __adf_nbuf_data_get_icmp_subtype(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_get_icmp_subtype() - get the subtype + * of IPV4 ICMP packet. + * @data: Pointer to IPV4 ICMP packet data buffer + * + * This func. returns the subtype of ICMP packet. + * + * Return: subtype of the ICMP packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_data_get_icmp_subtype(uint8_t *data) +{ + return __adf_nbuf_data_get_icmp_subtype(data); +} + +/** + * adf_nbuf_get_icmpv6_subtype() - get the subtype + * of IPV6 ICMPV6 packet. + * @buf: Pointer to IPV6 ICMPV6 packet buffer + * + * This func. returns the subtype of ICMPV6 packet. + * + * Return: subtype of the ICMPV6 packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_get_icmpv6_subtype(adf_nbuf_t buf) +{ + return __adf_nbuf_data_get_icmpv6_subtype(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_get_icmpv6_subtype() - get the subtype + * of IPV6 ICMPV6 packet. + * @data: Pointer to IPV6 ICMPV6 packet data buffer + * + * This func. returns the subtype of ICMPV6 packet. + * + * Return: subtype of the ICMPV6 packet. + */ +static inline enum adf_proto_subtype +adf_nbuf_data_get_icmpv6_subtype(uint8_t *data) +{ + return __adf_nbuf_data_get_icmpv6_subtype(data); +} + + +/** + * adf_nbuf_is_dhcp_pkt() - check if it is DHCP packet. + * @buf: Pointer to DHCP packet buffer + * + * This func. checks whether it is a DHCP packet or not. + * + * Return: A_STATUS_OK if it is a DHCP packet + * A_STATUS_FAILED if not */ static inline a_status_t adf_nbuf_is_dhcp_pkt(adf_nbuf_t buf) { - return (__adf_nbuf_is_dhcp_pkt(buf)); + return __adf_nbuf_data_is_dhcp_pkt(adf_nbuf_data(buf)); } /** - * @brief this will return if the skb data is a eapol packet or not + * adf_nbuf_data_is_dhcp_pkt() - check if it is DHCP packet. + * @data: Pointer to DHCP packet data buffer * - * @param[in] buf buffer + * This func. checks whether it is a DHCP packet or not. + * + * Return: A_STATUS_OK if it is a DHCP packet + * A_STATUS_FAILED if not + */ +static inline a_status_t +adf_nbuf_data_is_dhcp_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_dhcp_pkt(data); +} + +/** + * adf_nbuf_is_eapol_pkt() - check if it is EAPOL packet. + * @buf: Pointer to EAPOL packet buffer + * + * This func. checks whether it is a EAPOL packet or not. * - * @return A_STATUS_OK if packet is EAPOL packet + * Return: A_STATUS_OK if it is a EAPOL packet + * A_STATUS_FAILED if not */ static inline a_status_t adf_nbuf_is_eapol_pkt(adf_nbuf_t buf) { - return (__adf_nbuf_is_eapol_pkt(buf)); + return __adf_nbuf_data_is_eapol_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_eapol_pkt() - check if it is EAPOL packet. + * @data: Pointer to EAPOL packet data buffer + * + * This func. checks whether it is a EAPOL packet or not. + * + * Return: A_STATUS_OK if it is a EAPOL packet + * A_STATUS_FAILED if not + */ +static inline a_status_t +adf_nbuf_data_is_eapol_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_eapol_pkt(data); +} + +/** + * adf_nbuf_is_ipv4_arp_pkt() - check if it is ARP packet. + * @buf: Pointer to ARP packet buffer + * + * This func. checks whether it is a ARP packet or not. + * + * Return: TRUE if it is a ARP packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_ipv4_arp_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_ipv4_arp_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_ipv4_arp_pkt() - check if it is ARP packet. + * @data: Pointer to ARP packet data buffer + * + * This func. checks whether it is a ARP packet or not. + * + * Return: TRUE if it is a ARP packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_ipv4_arp_pkt(data); +} + +/** + * adf_nbuf_is_ipv4_pkt() - check if it is IPV4 packet. + * @buf: Pointer to IPV4 packet buffer + * + * This func. checks whether it is a IPV4 packet or not. + * + * Return: TRUE if it is a IPV4 packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_ipv4_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_ipv4_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_ipv4_pkt() - check if it is IPV4 packet. + * @data: Pointer to IPV4 packet data buffer + * + * This func. checks whether it is a IPV4 packet or not. + * + * Return: TRUE if it is a IPV4 packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_ipv4_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_ipv4_pkt(data); +} + +/** + * adf_nbuf_is_ipv6_pkt() - check if it is IPV6 packet. + * @buf: Pointer to IPV6 packet buffer + * + * This func. checks whether it is a IPV6 packet or not. + * + * Return: TRUE if it is a IPV6 packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_ipv6_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_ipv6_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_ipv6_pkt() - check if it is IPV6 packet. + * @data: Pointer to IPV6 packet data buffer + * + * This func. checks whether it is a IPV6 packet or not. + * + * Return: TRUE if it is a IPV6 packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_ipv6_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_ipv6_pkt(data); +} + +/** + * adf_nbuf_is_icmp_pkt() - check if it is IPV4 ICMP packet. + * @buf: Pointer to IPV4 ICMP packet buffer + * + * This func. checks whether it is a ICMP packet or not. + * + * Return: TRUE if it is a ICMP packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_icmp_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_icmp_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_icmp_pkt() - check if it is IPV4 ICMP packet. + * @data: Pointer to IPV4 ICMP packet data buffer + * + * This func. checks whether it is a ICMP packet or not. + * + * Return: TRUE if it is a ICMP packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_icmp_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_icmp_pkt(data); +} + +/** + * adf_nbuf_is_icmpv6_pkt() - check if it is IPV6 ICMPV6 packet. + * @buf: Pointer to IPV6 ICMPV6 packet buffer + * + * This func. checks whether it is a ICMPV6 packet or not. + * + * Return: TRUE if it is a ICMPV6 packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_icmpv6_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_icmpv6_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_icmpv6_pkt() - check if it is IPV6 ICMPV6 packet. + * @data: Pointer to IPV6 ICMPV6 packet data buffer + * + * This func. checks whether it is a ICMPV6 packet or not. + * + * Return: TRUE if it is a ICMPV6 packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_icmpv6_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_icmpv6_pkt(data); +} + +/** + * adf_nbuf_is_ipv4_udp_pkt() - check if it is IPV4 UDP packet. + * @buf: Pointer to IPV4 UDP packet buffer + * + * This func. checks whether it is a IPV4 UDP packet or not. + * + * Return: TRUE if it is a IPV4 UDP packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_ipv4_udp_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_ipv4_udp_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_ipv4_udp_pkt() - check if it is IPV4 UDP packet. + * @data: Pointer to IPV4 UDP packet data buffer + * + * This func. checks whether it is a IPV4 UDP packet or not. + * + * Return: TRUE if it is a IPV4 UDP packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_ipv4_udp_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_ipv4_udp_pkt(data); +} + +/** + * adf_nbuf_is_ipv4_tcp_pkt() - check if it is IPV4 TCP packet. + * @buf: Pointer to IPV4 TCP packet buffer + * + * This func. checks whether it is a IPV4 TCP packet or not. + * + * Return: TRUE if it is a IPV4 TCP packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_ipv4_tcp_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_ipv4_tcp_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_ipv4_tcp_pkt() - check if it is IPV4 TCP packet. + * @data: Pointer to IPV4 TCP packet data buffer + * + * This func. checks whether it is a IPV4 TCP packet or not. + * + * Return: TRUE if it is a IPV4 TCP packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_ipv4_tcp_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_ipv4_tcp_pkt(data); +} + +/** + * adf_nbuf_is_ipv6_udp_pkt() - check if it is IPV6 UDP packet. + * @buf: Pointer to IPV6 UDP packet buffer + * + * This func. checks whether it is a IPV6 UDP packet or not. + * + * Return: TRUE if it is a IPV6 UDP packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_ipv6_udp_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_ipv6_udp_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_ipv6_udp_pkt() - check if it is IPV6 UDP packet. + * @data: Pointer to IPV6 UDP packet data buffer + * + * This func. checks whether it is a IPV6 UDP packet or not. + * + * Return: TRUE if it is a IPV6 UDP packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_ipv6_udp_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_ipv6_udp_pkt(data); +} + +/** + * adf_nbuf_is_ipv6_tcp_pkt() - check if it is IPV6 TCP packet. + * @buf: Pointer to IPV6 TCP packet buffer + * + * This func. checks whether it is a IPV6 TCP packet or not. + * + * Return: TRUE if it is a IPV6 TCP packet + * FALSE if not + */ +static inline +bool adf_nbuf_is_ipv6_tcp_pkt(adf_nbuf_t buf) +{ + return __adf_nbuf_data_is_ipv6_tcp_pkt(adf_nbuf_data(buf)); +} + +/** + * adf_nbuf_data_is_ipv6_tcp_pkt() - check if it is IPV6 TCP packet. + * @data: Pointer to IPV6 TCP packet data buffer + * + * This func. checks whether it is a IPV6 TCP packet or not. + * + * Return: TRUE if it is a IPV6 TCP packet + * FALSE if not + */ +static inline +bool adf_nbuf_data_is_ipv6_tcp_pkt(uint8_t *data) +{ + return __adf_nbuf_data_is_ipv6_tcp_pkt(data); } /** diff --git a/CORE/SERVICES/COMMON/adf/adf_trace.c b/CORE/SERVICES/COMMON/adf/adf_trace.c index 3926ae715a11..8311147a7aec 100644 --- a/CORE/SERVICES/COMMON/adf/adf_trace.c +++ b/CORE/SERVICES/COMMON/adf/adf_trace.c @@ -40,6 +40,9 @@ #include "adf_os_time.h" #include "vos_trace.h" #include "vos_packet.h" +#include "sirDebug.h" +#include "debug_linux.h" +#include "adf_os_io.h" /* Static and Global variables */ static spinlock_t l_dp_trace_lock; @@ -79,6 +82,15 @@ void adf_dp_trace_init(void) for (i = 0; i < ADF_DP_TRACE_MAX; i++) adf_dp_trace_cb_table[i] = adf_dp_display_record; + + adf_dp_trace_cb_table[ADF_DP_TRACE_TXRX_PACKET_PTR_RECORD] = + adf_dp_trace_cb_table[ADF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD] = + adf_dp_trace_cb_table[ADF_DP_TRACE_FREE_PACKET_PTR_RECORD] = + adf_dp_display_ptr_record; + adf_dp_trace_cb_table[ADF_DP_TRACE_EAPOL_PACKET_RECORD] = + adf_dp_trace_cb_table[ADF_DP_TRACE_DHCP_PACKET_RECORD] = + adf_dp_trace_cb_table[ADF_DP_TRACE_ARP_PACKET_RECORD] = + adf_dp_display_proto_pkt; } /** @@ -107,21 +119,37 @@ void adf_dp_trace_set_value(uint8_t proto_bitmap, uint8_t no_of_record, */ static bool adf_dp_trace_enable_track(enum ADF_DP_TRACE_ID code) { - if (g_adf_dp_trace_data.verbosity == ADF_DP_TRACE_VERBOSITY_HIGH) - return true; - else if (g_adf_dp_trace_data.verbosity == - ADF_DP_TRACE_VERBOSITY_MEDIUM && - (code <= ADF_DP_TRACE_HIF_PACKET_PTR_RECORD)) - return true; - else if (g_adf_dp_trace_data.verbosity == - ADF_DP_TRACE_VERBOSITY_LOW && - (code <= ADF_DP_TRACE_CE_PACKET_RECORD)) + switch (g_adf_dp_trace_data.verbosity) { + case ADF_DP_TRACE_VERBOSITY_HIGH: return true; - else if (g_adf_dp_trace_data.verbosity == - ADF_DP_TRACE_VERBOSITY_DEFAULT && - (code == ADF_DP_TRACE_DROP_PACKET_RECORD)) - return true; - return false; + case ADF_DP_TRACE_VERBOSITY_MEDIUM: + if (code <= ADF_DP_TRACE_MED_VERBOSITY) + return true; + return false; + case ADF_DP_TRACE_VERBOSITY_LOW: + if (code <= ADF_DP_TRACE_LOW_VERBOSITY) + return true; + return false; + case ADF_DP_TRACE_VERBOSITY_DEFAULT: + if (code <= ADF_DP_TRACE_DEFAULT_VERBOSITY) + return true; + return false; + default: + return false; + } +} + +/** + * qdf_dp_get_proto_bitmap() - get dp trace proto bitmap + * + * Return: proto bitmap + */ +uint8_t adf_dp_get_proto_bitmap(void) +{ + if (g_adf_dp_trace_data.enable) + return g_adf_dp_trace_data.proto_bitmap; + else + return 0; } /** @@ -134,12 +162,6 @@ void adf_dp_trace_set_track(adf_nbuf_t nbuf) { spin_lock_bh(&l_dp_trace_lock); g_adf_dp_trace_data.count++; - if (g_adf_dp_trace_data.proto_bitmap != 0) { - if (vos_pkt_get_proto_type(nbuf, - g_adf_dp_trace_data.proto_bitmap, 0)) { - ADF_NBUF_SET_DP_TRACE(nbuf, 1); - } - } if ((g_adf_dp_trace_data.no_of_record != 0) && (g_adf_dp_trace_data.count % g_adf_dp_trace_data.no_of_record == 0)) { @@ -150,107 +172,187 @@ void adf_dp_trace_set_track(adf_nbuf_t nbuf) /** * dump_hex_trace() - Display the data in buffer + * @str: string to print * @buf: buffer which contains data to be displayed * @buf_len: defines the size of the data to be displayed * * Return: None */ -static void dump_hex_trace(uint8_t *buf, uint8_t buf_len) +static void dump_hex_trace(char *str, uint8_t *buf, uint8_t buf_len) { uint8_t i; /* Dump the bytes in the last line */ - adf_os_print("DATA: "); + printk("%s: ", str); for (i = 0; i < buf_len; i++) - adf_os_print("%02x ", buf[i]); - adf_os_print("\n"); + printk("%02x ", buf[i]); + printk("\n"); } /** - * adf_dp_display_trace() - Displays a record in DP trace - * @pRecord : pointer to a record in DP trace - * @recIndex : record index + * adf_dp_code_to_string() - convert dptrace code to string + * @code: dptrace code * - * Return: None + * Return: string version of code */ -void adf_dp_display_record(struct adf_dp_trace_record_s *pRecord, - uint16_t recIndex) +const char *adf_dp_code_to_string(enum ADF_DP_TRACE_ID code) { - adf_os_print("INDEX: %04d TIME: %012llu CODE: %02d\n", recIndex, - pRecord->time, pRecord->code); - switch (pRecord->code) { - case ADF_DP_TRACE_HDD_TX_TIMEOUT: - VOS_TRACE(VOS_MODULE_ID_ADF, VOS_TRACE_LEVEL_ERROR, - "HDD TX Timeout\n"); - break; - case ADF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: - VOS_TRACE(VOS_MODULE_ID_ADF, VOS_TRACE_LEVEL_ERROR, - "HDD SoftAP TX Timeout\n"); - break; - case ADF_DP_TRACE_VDEV_PAUSE: - VOS_TRACE(VOS_MODULE_ID_ADF, VOS_TRACE_LEVEL_ERROR, - "VDEV Pause\n"); - break; - case ADF_DP_TRACE_VDEV_UNPAUSE: - VOS_TRACE(VOS_MODULE_ID_ADF, VOS_TRACE_LEVEL_ERROR, - "VDEV UnPause\n"); - break; + switch (code) { + case ADF_DP_TRACE_DROP_PACKET_RECORD: + return "DROP:"; + case ADF_DP_TRACE_EAPOL_PACKET_RECORD: + return "EAPOL:"; + case ADF_DP_TRACE_DHCP_PACKET_RECORD: + return "DHCP:"; + case ADF_DP_TRACE_ARP_PACKET_RECORD: + return "ARP:"; + case ADF_DP_TRACE_HDD_PACKET_PTR_RECORD: + return "HDD: PTR:"; + case ADF_DP_TRACE_HDD_PACKET_RECORD: + return "HDD: DATA:"; + case ADF_DP_TRACE_CE_PACKET_PTR_RECORD: + return "CE: PTR:"; + case ADF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD: + return "CE:F: PTR:"; + case ADF_DP_TRACE_FREE_PACKET_PTR_RECORD: + return "FREE: PTR:"; + case ADF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD: + return "TX:Q: PTR:"; + case ADF_DP_TRACE_TXRX_PACKET_PTR_RECORD: + return "TX: PTR:"; + case ADF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD: + return "TX:F: PTR:"; + case ADF_DP_TRACE_HTT_PACKET_PTR_RECORD: + return "HTT: PTR:"; + case ADF_DP_TRACE_HTC_PACKET_PTR_RECORD: + return "HTC: PTR:"; + case ADF_DP_TRACE_HIF_PACKET_PTR_RECORD: + return "HIF: PTR:"; + case ADF_DP_TRACE_HDD_TX_TIMEOUT: + return "STA: TO:"; + case ADF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: + return "SAP: TO:"; default: - dump_hex_trace(pRecord->data, pRecord->size); + return "Invalid"; } } /** - * adf_dp_trace() - Stores the data in buffer - * @nbuf : defines the netbuf - * @code : defines the event - * @data : defines the data to be stored - * @size : defines the size of the data record + * adf_dp_dir_to_str() - convert direction to string + * @dir: direction * - * Return: None + * Return: string version of direction */ -void adf_dp_trace(adf_nbuf_t nbuf, enum ADF_DP_TRACE_ID code, - uint8_t *data, uint8_t size) +const char *adf_dp_dir_to_str(enum adf_proto_dir dir) { - struct adf_dp_trace_record_s *rec; + switch (dir) { + case ADF_TX: + return "->"; + case ADF_RX: + return "<-"; + default: + return "invalid"; + } +} - /* Return when Dp trace is not enabled */ - if (!g_adf_dp_trace_data.enable) - return; +/** + * adf_dp_type_to_str() - convert packet type to string + * @type: type + * + * Return: string version of packet type + */ +const char *adf_dp_type_to_str(enum adf_proto_type type) +{ + switch (type) { + case ADF_PROTO_TYPE_DHCP: + return "DHCP"; + case ADF_PROTO_TYPE_EAPOL: + return "EAPOL"; + case ADF_PROTO_TYPE_ARP: + return "ARP"; + default: + return "invalid"; + } +} - /* If nbuf is NULL, check for VDEV PAUSE, UNPAUSE, TIMEOUT */ - if (!nbuf) { - switch (code) { - case ADF_DP_TRACE_HDD_TX_TIMEOUT: - case ADF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: - case ADF_DP_TRACE_VDEV_PAUSE: - case ADF_DP_TRACE_VDEV_UNPAUSE: - if (adf_dp_trace_enable_track(code)) - goto register_record; - else - return; - - default: - return; - } +/** + * adf_dp_subtype_to_str() - convert packet subtype to string + * @type: type + * + * Return: string version of packet subtype + */ +const char *adf_dp_subtype_to_str(enum adf_proto_subtype subtype) +{ + switch (subtype) { + case ADF_PROTO_EAPOL_M1: + return "M1"; + case ADF_PROTO_EAPOL_M2: + return "M2"; + case ADF_PROTO_EAPOL_M3: + return "M3"; + case ADF_PROTO_EAPOL_M4: + return "M4"; + case ADF_PROTO_DHCP_DISCOVER: + return "DISCOVER"; + case ADF_PROTO_DHCP_REQUEST: + return "REQUEST"; + case ADF_PROTO_DHCP_OFFER: + return "OFFER"; + case ADF_PROTO_DHCP_ACK: + return "ACK"; + case ADF_PROTO_DHCP_NACK: + return "NACK"; + case ADF_PROTO_DHCP_RELEASE: + return "RELEASE"; + case ADF_PROTO_DHCP_INFORM: + return "INFORM"; + case ADF_PROTO_DHCP_DECLINE: + return "DECLINE"; + case ADF_PROTO_ARP_REQ: + return "REQUEST"; + case ADF_PROTO_ARP_RES: + return "RESPONSE"; + default: + return "invalid"; } +} - /* Return when the packet is not a data packet */ - if (NBUF_GET_PACKET_TRACK(nbuf) != NBUF_TX_PKT_DATA_TRACK) - return; +/** + * adf_dp_enable_check() - check if dptrace is enable or not + * @nbuf: nbuf + * @code: dptrace code + * + * Return: true/false + */ +bool adf_dp_enable_check(adf_nbuf_t nbuf, enum ADF_DP_TRACE_ID code) +{ + /* Return when Dp trace is not enabled */ + if (!g_adf_dp_trace_data.enable) + return false; - /* Return when nbuf is not marked for dp tracing or - * verbosity does not allow - */ - if ((adf_dp_trace_enable_track(code) == false) || - !ADF_NBUF_GET_DP_TRACE(nbuf)) - return; + if (adf_dp_trace_enable_track(code) == false) + return false; - /* Acquire the lock so that only one thread at a time can fill the ring - * buffer - */ + if ((nbuf) && ((NBUF_GET_PACKET_TRACK(nbuf) != + NBUF_TX_PKT_DATA_TRACK) || + (!ADF_NBUF_GET_DP_TRACE(nbuf)))) + return false; -register_record: + return true; +} + +/** + * adf_dp_add_record() - add dp trace record + * @code: dptrace code + * @data: data pointer + * @size: size of buffer + * + * Return: none + */ +void adf_dp_add_record(enum ADF_DP_TRACE_ID code, + uint8_t *data, uint8_t size) +{ + struct adf_dp_trace_record_s *rec = NULL; spin_lock_bh(&l_dp_trace_lock); @@ -286,25 +388,8 @@ register_record: size = ADF_DP_TRACE_RECORD_SIZE; rec->size = size; - switch (code) { - case ADF_DP_TRACE_HDD_PACKET_PTR_RECORD: - case ADF_DP_TRACE_CE_PACKET_PTR_RECORD: - case ADF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD: - case ADF_DP_TRACE_TXRX_PACKET_PTR_RECORD: - case ADF_DP_TRACE_HTT_PACKET_PTR_RECORD: - case ADF_DP_TRACE_HTC_PACKET_PTR_RECORD: - case ADF_DP_TRACE_HIF_PACKET_PTR_RECORD: - adf_os_mem_copy(rec->data, (uint8_t *)(&data), size); - break; - - case ADF_DP_TRACE_DROP_PACKET_RECORD: - case ADF_DP_TRACE_HDD_PACKET_RECORD: - case ADF_DP_TRACE_CE_PACKET_RECORD: - adf_os_mem_copy(rec->data, data, size); - break; - default: - break; - } + adf_os_mem_copy(rec->data, data, size); + } rec->time = adf_os_gettimestamp(); rec->pid = (in_interrupt() ? 0 : current->pid); @@ -312,6 +397,270 @@ register_record: } /** + * adf_log_eapol_pkt() - log EAPOL packet + * @session_id: vdev_id + * @skb: skb pointer + * @event_type: event_type + * + * Return: true/false + */ +bool adf_log_eapol_pkt(uint8_t session_id, struct sk_buff *skb, + uint8_t event_type) +{ + enum adf_proto_subtype subtype; + + if ((adf_dp_get_proto_bitmap() & NBUF_PKT_TRAC_TYPE_EAPOL) && + adf_nbuf_is_eapol_pkt(skb) == A_STATUS_OK) { + + subtype = adf_nbuf_get_eapol_subtype(skb); + DPTRACE(adf_dp_trace_proto_pkt(ADF_DP_TRACE_EAPOL_PACKET_RECORD, + session_id, (skb->data + ADF_NBUF_SRC_MAC_OFFSET), + (skb->data + ADF_NBUF_DEST_MAC_OFFSET), + ADF_PROTO_TYPE_EAPOL, subtype, + event_type == ADF_RX ? + ADF_RX : ADF_TX)); + ADF_NBUF_SET_DP_TRACE(skb, 1); + return true; + } + return false; +} + +/** + * adf_log_dhcp_pkt() - log DHCP packet + * @session_id: vdev_id + * @skb: skb pointer + * @event_type: event_type + * + * Return: true/false + */ +bool adf_log_dhcp_pkt(uint8_t session_id, struct sk_buff *skb, + uint8_t event_type) +{ + enum adf_proto_subtype subtype = ADF_PROTO_INVALID; + + if ((adf_dp_get_proto_bitmap() & NBUF_PKT_TRAC_TYPE_DHCP) && + adf_nbuf_is_dhcp_pkt(skb) == A_STATUS_OK) { + + subtype = adf_nbuf_get_dhcp_subtype(skb); + DPTRACE(adf_dp_trace_proto_pkt(ADF_DP_TRACE_DHCP_PACKET_RECORD, + session_id, (skb->data + ADF_NBUF_SRC_MAC_OFFSET), + (skb->data + ADF_NBUF_DEST_MAC_OFFSET), + ADF_PROTO_TYPE_DHCP, subtype, + event_type == ADF_RX ? + ADF_RX : ADF_TX)); + ADF_NBUF_SET_DP_TRACE(skb, 1); + return true; + } + return false; +} + +/** + * adf_log_arp_pkt() - log ARP packet + * @session_id: vdev_id + * @skb: skb pointer + * @event_type: event_type + * + * Return: true/false + */ +bool adf_log_arp_pkt(uint8_t session_id, struct sk_buff *skb, + uint8_t event_type) +{ + enum adf_proto_subtype proto_subtype; + + if ((adf_dp_get_proto_bitmap() & NBUF_PKT_TRAC_TYPE_ARP) && + adf_nbuf_is_ipv4_arp_pkt(skb) == true) { + + proto_subtype = adf_nbuf_get_arp_subtype(skb); + + DPTRACE(adf_dp_trace_proto_pkt(ADF_DP_TRACE_ARP_PACKET_RECORD, + session_id, (skb->data + ADF_NBUF_SRC_MAC_OFFSET), + (skb->data + ADF_NBUF_DEST_MAC_OFFSET), + ADF_PROTO_TYPE_ARP, proto_subtype, + event_type == ADF_RX ? + ADF_RX : ADF_TX)); + ADF_NBUF_SET_DP_TRACE(skb, 1); + return true; + } + return false; +} + +/** + * adf_dp_trace_log_pkt() - log packet type enabled through iwpriv + * @session_id: vdev_id + * @skb: skb pointer + * @event_type: event type + * + * Return: none + */ +void adf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, + uint8_t event_type) +{ + if (adf_dp_get_proto_bitmap()) { + if (adf_log_arp_pkt(session_id, + skb, event_type) == false) { + if (adf_log_dhcp_pkt(session_id, + skb, event_type) == false) { + if (adf_log_eapol_pkt(session_id, + skb, event_type) == false) { + return; + } + } + } + } +} + +/** + * adf_dp_display_proto_pkt() - display proto packet + * @record: dptrace record + * @index: index + * + * Return: none + */ +void adf_dp_display_proto_pkt(struct adf_dp_trace_record_s *record, + uint16_t index) +{ + struct adf_dp_trace_proto_buf *buf = + (struct adf_dp_trace_proto_buf *)record->data; + + adf_os_print("%04d: %012llu: %s vdev_id %d\n", index, + record->time, adf_dp_code_to_string(record->code), + buf->vdev_id); + adf_os_print("SA: " MAC_ADDRESS_STR " %s DA: " MAC_ADDRESS_STR + " Type %s Subtype %s\n", + MAC_ADDR_ARRAY(buf->sa.bytes), adf_dp_dir_to_str(buf->dir), + MAC_ADDR_ARRAY(buf->da.bytes), adf_dp_type_to_str(buf->type), + adf_dp_subtype_to_str(buf->subtype)); +} + +/** + * adf_dp_trace_proto_pkt() - record proto packet + * @code: dptrace code + * @vdev_id: vdev id + * @sa: source mac address + * @da: destination mac address + * @type: proto type + * @subtype: proto subtype + * @dir: direction + * + * Return: none + */ +void adf_dp_trace_proto_pkt(enum ADF_DP_TRACE_ID code, uint8_t vdev_id, + uint8_t *sa, uint8_t *da, enum adf_proto_type type, + enum adf_proto_subtype subtype, enum adf_proto_dir dir) +{ + struct adf_dp_trace_proto_buf buf; + int buf_size = sizeof(struct adf_dp_trace_ptr_buf); + + if (adf_dp_enable_check(NULL, code) == false) + return; + + if (buf_size > ADF_DP_TRACE_RECORD_SIZE) + ADF_BUG(0); + + memcpy(&buf.sa, sa, ETH_ALEN); + memcpy(&buf.da, da, ETH_ALEN); + buf.dir = dir; + buf.type = type; + buf.subtype = subtype; + buf.vdev_id = vdev_id; + adf_dp_add_record(code, (uint8_t *)&buf, buf_size); +} + +/** + * adf_dp_display_ptr_record() - display record + * @record: dptrace record + * @index: index + * + * Return: none + */ +void adf_dp_display_ptr_record(struct adf_dp_trace_record_s *record, + uint16_t index) +{ + struct adf_dp_trace_ptr_buf *buf = + (struct adf_dp_trace_ptr_buf *)record->data; + + adf_os_print("%04d: %012llu: %s msdu_id: %d, status: %d", index, + record->time, adf_dp_code_to_string(record->code), + buf->msdu_id, buf->status); + dump_hex_trace("cookie", (uint8_t *)&buf->cookie, sizeof(buf->cookie)); +} + +/** + * adf_dp_trace_ptr() - record dptrace + * @code: dptrace code + * @data: data + * @size: size of data + * @msdu_id: msdu_id + * @status: return status + * + * Return: none + */ +void adf_dp_trace_ptr(adf_nbuf_t nbuf, enum ADF_DP_TRACE_ID code, + uint8_t *data, uint8_t size, uint16_t msdu_id, uint16_t status) +{ + struct adf_dp_trace_ptr_buf buf; + int buf_size = sizeof(struct adf_dp_trace_ptr_buf); + + if (adf_dp_enable_check(nbuf, code) == false) + return; + + if (buf_size > ADF_DP_TRACE_RECORD_SIZE) + ADF_BUG(0); + + adf_os_mem_copy(&buf.cookie, data, size); + buf.msdu_id = msdu_id; + buf.status = status; + adf_dp_add_record(code, (uint8_t *)&buf, buf_size); +} + +/** + * adf_dp_display_trace() - Displays a record in DP trace + * @pRecord : pointer to a record in DP trace + * @recIndex : record index + * + * Return: None + */ +void adf_dp_display_record(struct adf_dp_trace_record_s *pRecord, + uint16_t recIndex) +{ + adf_os_print("%04d: %012llu: %s", recIndex, + pRecord->time, adf_dp_code_to_string(pRecord->code)); + switch (pRecord->code) { + case ADF_DP_TRACE_HDD_TX_TIMEOUT: + VOS_TRACE(VOS_MODULE_ID_ADF, VOS_TRACE_LEVEL_ERROR, + "HDD TX Timeout\n"); + break; + case ADF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: + VOS_TRACE(VOS_MODULE_ID_ADF, VOS_TRACE_LEVEL_ERROR, + "HDD SoftAP TX Timeout\n"); + break; + case ADF_DP_TRACE_HDD_PACKET_RECORD: + dump_hex_trace("DATA", pRecord->data, pRecord->size); + break; + default: + dump_hex_trace("cookie", pRecord->data, pRecord->size); + } +} + +/** + * adf_dp_trace() - Stores the data in buffer + * @nbuf : defines the netbuf + * @code : defines the event + * @data : defines the data to be stored + * @size : defines the size of the data record + * + * Return: None + */ +void adf_dp_trace(adf_nbuf_t nbuf, enum ADF_DP_TRACE_ID code, + uint8_t *data, uint8_t size) +{ + if (adf_dp_enable_check(nbuf, code) == false) + return; + + adf_dp_add_record(code, data, size); +} + +/** * adf_dp_trace_dump_all() - Dump data from ring buffer via call back functions * registered with ADF * @code : Reason code diff --git a/CORE/SERVICES/COMMON/adf/adf_trace.h b/CORE/SERVICES/COMMON/adf/adf_trace.h index deddc7a16e43..b426edd26ae2 100644 --- a/CORE/SERVICES/COMMON/adf/adf_trace.h +++ b/CORE/SERVICES/COMMON/adf/adf_trace.h @@ -39,6 +39,7 @@ /* Include Files */ #include <adf_nbuf.h> +#include "vos_types.h" #ifdef FEATURE_DPTRACE_ENABLE /* DP Trace Implementation */ @@ -56,6 +57,14 @@ #define ADF_DP_TRACE_VERBOSITY_DEFAULT 0 /** + * struct adf_mac_addr - mac address array + * @bytes: MAC address bytes + */ +struct adf_mac_addr { + uint8_t bytes[VOS_MAC_ADDR_SIZE]; +}; + +/** * enum ADF_DP_TRACE_ID - Generic ID to identify various events in data path * @ADF_DP_TRACE_INVALID: Invalid ID * @ADF_DP_TRACE_DROP_PACKET_RECORD: Dropped packet stored with this id @@ -70,30 +79,56 @@ * @ADF_DP_TRACE_HIF_PACKET_PTR_RECORD: nbuf->data ptr of hif * @ADF_DP_TRACE_HDD_TX_TIMEOUT: hdd tx timeout event * @ADF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT: hdd tx softap timeout event - * @ADF_DP_TRACE_VDEV_PAUSE: vdev pause event - * @ADF_DP_TRACE_VDEV_UNPAUSE: vdev unpause event * */ + enum ADF_DP_TRACE_ID { - ADF_DP_TRACE_INVALID = 0, - ADF_DP_TRACE_DROP_PACKET_RECORD = 1, - ADF_DP_TRACE_HDD_PACKET_PTR_RECORD = 2, - ADF_DP_TRACE_HDD_PACKET_RECORD = 3, - ADF_DP_TRACE_CE_PACKET_PTR_RECORD = 4, - ADF_DP_TRACE_CE_PACKET_RECORD = 5, - ADF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD = 6, - ADF_DP_TRACE_TXRX_PACKET_PTR_RECORD = 7, - ADF_DP_TRACE_HTT_PACKET_PTR_RECORD = 8, - ADF_DP_TRACE_HTC_PACKET_PTR_RECORD = 9, - ADF_DP_TRACE_HIF_PACKET_PTR_RECORD = 10, - ADF_DP_TRACE_HDD_TX_TIMEOUT = 11, - ADF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT = 12, - ADF_DP_TRACE_VDEV_PAUSE = 13, - ADF_DP_TRACE_VDEV_UNPAUSE = 14, + ADF_DP_TRACE_INVALID = 0, + ADF_DP_TRACE_DROP_PACKET_RECORD, + ADF_DP_TRACE_EAPOL_PACKET_RECORD, + ADF_DP_TRACE_DHCP_PACKET_RECORD, + ADF_DP_TRACE_ARP_PACKET_RECORD, + ADF_DP_TRACE_DEFAULT_VERBOSITY, + ADF_DP_TRACE_HDD_TX_TIMEOUT, + ADF_DP_TRACE_HDD_SOFTAP_TX_TIMEOUT, + ADF_DP_TRACE_HDD_PACKET_PTR_RECORD, + ADF_DP_TRACE_CE_PACKET_PTR_RECORD, + ADF_DP_TRACE_CE_FAST_PACKET_PTR_RECORD, + ADF_DP_TRACE_FREE_PACKET_PTR_RECORD, + ADF_DP_TRACE_LOW_VERBOSITY, + ADF_DP_TRACE_TXRX_QUEUE_PACKET_PTR_RECORD, + ADF_DP_TRACE_TXRX_PACKET_PTR_RECORD, + ADF_DP_TRACE_TXRX_FAST_PACKET_PTR_RECORD, + ADF_DP_TRACE_HTT_PACKET_PTR_RECORD, + ADF_DP_TRACE_HTC_PACKET_PTR_RECORD, + ADF_DP_TRACE_HIF_PACKET_PTR_RECORD, + ADF_DP_TRACE_MED_VERBOSITY, + ADF_DP_TRACE_HDD_PACKET_RECORD, + ADF_DP_TRACE_HIGH_VERBOSITY, ADF_DP_TRACE_MAX +}; + +enum adf_proto_dir { + ADF_TX, + ADF_RX +}; +struct adf_dp_trace_ptr_buf { + uint64_t cookie; + uint16_t msdu_id; + uint16_t status; }; +struct adf_dp_trace_proto_buf { + struct adf_mac_addr sa; + struct adf_mac_addr da; + uint8_t vdev_id; + uint8_t type; + uint8_t subtype; + uint8_t dir; +}; + + /** * struct adf_dp_trace_record_s - Describes a record in DP trace * @time: time when it got stored @@ -146,6 +181,20 @@ void adf_dp_trace_dump_all(uint32_t count); typedef void (*tp_adf_dp_trace_cb)(struct adf_dp_trace_record_s* , uint16_t); void adf_dp_display_record(struct adf_dp_trace_record_s *record, uint16_t index); +void adf_dp_trace_ptr(adf_nbuf_t nbuf, enum ADF_DP_TRACE_ID code, + uint8_t *data, uint8_t size, uint16_t msdu_id, uint16_t status); + +void adf_dp_display_ptr_record(struct adf_dp_trace_record_s *pRecord, + uint16_t recIndex); +uint8_t adf_dp_get_proto_bitmap(void); +void +adf_dp_trace_proto_pkt(enum ADF_DP_TRACE_ID code, uint8_t vdev_id, + uint8_t *sa, uint8_t *da, enum adf_proto_type type, + enum adf_proto_subtype subtype, enum adf_proto_dir dir); +void adf_dp_display_proto_pkt(struct adf_dp_trace_record_s *record, + uint16_t index); +void adf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, + uint8_t event_type); #else static inline void adf_dp_trace_init(void) @@ -174,6 +223,41 @@ static inline void adf_dp_display_record(struct adf_dp_trace_record_s *record, uint16_t index) { } + +static inline void adf_dp_trace_ptr(adf_nbuf_t nbuf, enum ADF_DP_TRACE_ID code, + uint8_t *data, uint8_t size, uint16_t msdu_id, uint16_t status) +{ +} + +static inline void +adf_dp_display_ptr_record(struct adf_dp_trace_record_s *pRecord, + uint16_t recIndex) +{ +} + +static inline uint8_t adf_dp_get_proto_bitmap(void) +{ + return 0; +} + +static inline void +adf_dp_trace_proto_pkt(enum ADF_DP_TRACE_ID code, uint8_t vdev_id, + uint8_t *sa, uint8_t *da, enum adf_proto_type type, + enum adf_proto_subtype subtype, enum adf_proto_dir dir) +{ +} + +static inline void +adf_dp_display_proto_pkt(struct adf_dp_trace_record_s *record, + uint16_t index) +{ +} + +static inline void adf_dp_trace_log_pkt(uint8_t session_id, struct sk_buff *skb, + uint8_t event_type) +{ +} + #endif #endif /* __ADF_TRACE_H */ diff --git a/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h b/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h index 9ed1edb013f3..1a48042bd43e 100644 --- a/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h +++ b/CORE/SERVICES/COMMON/adf/linux/adf_nbuf_pvt.h @@ -38,6 +38,7 @@ #include <asm/types.h> #include <asm/scatterlist.h> #include <adf_os_types.h> +#include <adf_nbuf.h> #define __ADF_NBUF_NULL NULL @@ -330,8 +331,23 @@ void __adf_nbuf_dmamap_info(__adf_os_dma_map_t bmap, adf_os_dmamap_in void __adf_nbuf_frag_info(struct sk_buff *skb, adf_os_sglist_t *sg); void __adf_nbuf_dmamap_set_cb(__adf_os_dma_map_t dmap, void *cb, void *arg); void __adf_nbuf_reg_trace_cb(adf_nbuf_trace_update_t cb_func_ptr); -a_status_t __adf_nbuf_is_dhcp_pkt(struct sk_buff *skb); -a_status_t __adf_nbuf_is_eapol_pkt(struct sk_buff *skb); +bool __adf_nbuf_data_is_ipv4_pkt(uint8_t *data); +bool __adf_nbuf_data_is_ipv6_pkt(uint8_t *data); +bool __adf_nbuf_data_is_icmp_pkt(uint8_t *data); +bool __adf_nbuf_data_is_icmpv6_pkt(uint8_t *data); +bool __adf_nbuf_data_is_ipv4_udp_pkt(uint8_t *data); +bool __adf_nbuf_data_is_ipv4_tcp_pkt(uint8_t *data); +bool __adf_nbuf_data_is_ipv6_udp_pkt(uint8_t *data); +bool __adf_nbuf_data_is_ipv6_tcp_pkt(uint8_t *data); +a_status_t __adf_nbuf_data_is_dhcp_pkt(uint8_t *data); +a_status_t __adf_nbuf_data_is_eapol_pkt(uint8_t *data); +bool __adf_nbuf_data_is_ipv4_arp_pkt(uint8_t *data); +enum adf_proto_subtype __adf_nbuf_data_get_dhcp_subtype(uint8_t *data); +enum adf_proto_subtype __adf_nbuf_data_get_eapol_subtype(uint8_t *data); +enum adf_proto_subtype __adf_nbuf_data_get_arp_subtype(uint8_t *data); +enum adf_proto_subtype __adf_nbuf_data_get_icmp_subtype(uint8_t *data); +enum adf_proto_subtype __adf_nbuf_data_get_icmpv6_subtype(uint8_t *data); + #ifdef QCA_PKT_PROTO_TRACE void @@ -1008,6 +1024,21 @@ __adf_nbuf_data(struct sk_buff *skb) } /** + * __adf_nbuf_data_addr() - Return the address of skb->data + * @skb: skb + * + * This function returns the address of skb->data + * + * Return: skb->data address + */ +static inline uint8_t * +__adf_nbuf_data_addr(struct sk_buff *skb) +{ + return (uint8_t *)&skb->data; +} + + +/** * @brief return the priority value of the skb * * @param skb diff --git a/CORE/SERVICES/COMMON/wmi_tlv_defs.h b/CORE/SERVICES/COMMON/wmi_tlv_defs.h index b90cdd7f6f65..4fb2f7cfa854 100644 --- a/CORE/SERVICES/COMMON/wmi_tlv_defs.h +++ b/CORE/SERVICES/COMMON/wmi_tlv_defs.h @@ -707,8 +707,8 @@ typedef enum { WMITLV_TAG_STRUC_wmi_peer_bwf_request_fixed_param, WMITLV_TAG_STRUC_wmi_bwf_peer_info, WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, - WMITLV_TAG_STRUC_wmi_rmc_set_leader_cmd_fixed_param, - WMITLV_TAG_STRUC_wmi_rmc_manual_leader_event_fixed_param, + _place_holder_tlv_tag_1, + _place_holder_tlv_tag_2, WMITLV_TAG_STRUC_wmi_per_chain_rssi_stats, WMITLV_TAG_STRUC_wmi_rssi_stats, } WMITLV_TAG_ID; @@ -998,7 +998,6 @@ typedef enum { OP(WMI_WOW_SET_ACTION_WAKE_UP_CMDID) \ OP(WMI_PEER_BWF_REQUEST_CMDID) \ OP(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID) \ - OP(WMI_RMC_SET_MANUAL_LEADER_CMDID) \ /* add new CMD_LIST elements above this line */ /* @@ -1149,7 +1148,6 @@ typedef enum { OP(WMI_PDEV_HW_MODE_TRANSITION_EVENTID) \ OP(WMI_PDEV_SET_MAC_CONFIG_RESP_EVENTID) \ OP(WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID) \ - OP(WMI_RMC_NEW_LEADER_EVENTID) \ /* add new EVT_LIST elements above this line */ @@ -2861,10 +2859,6 @@ WMITLV_CREATE_PARAM_STRUC(WMI_PDEV_WAL_POWER_DEBUG_CMDID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_STRUC, wmi_bwf_peer_info, peer_info, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_PEER_BWF_REQUEST_CMDID); -#define WMITLV_TABLE_WMI_RMC_SET_MANUAL_LEADER_CMDID(id,op,buf,len) \ - WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_rmc_set_leader_cmd_fixed_param, wmi_rmc_set_leader_cmd_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_RMC_SET_MANUAL_LEADER_CMDID); - /************************** TLV definitions of WMI events *******************************/ /* Service Ready event */ @@ -3687,10 +3681,6 @@ WMITLV_CREATE_PARAM_STRUC(WMI_INST_RSSI_STATS_EVENTID); WMITLV_ELEM(id,op,buf,len, WMITLV_TAG_ARRAY_UINT32, A_UINT32, tx_time_per_power_level, WMITLV_SIZE_VAR) WMITLV_CREATE_PARAM_STRUC(WMI_RADIO_TX_POWER_LEVEL_STATS_EVENTID); -#define WMITLV_TABLE_WMI_RMC_NEW_LEADER_EVENTID(id, op, buf, len) \ - WMITLV_ELEM(id, op, buf, len, WMITLV_TAG_STRUC_wmi_rmc_manual_leader_event_fixed_param, wmi_rmc_manual_leader_event_fixed_param, fixed_param, WMITLV_SIZE_FIX) -WMITLV_CREATE_PARAM_STRUC(WMI_RMC_NEW_LEADER_EVENTID); - #ifdef __cplusplus } diff --git a/CORE/SERVICES/COMMON/wmi_unified.h b/CORE/SERVICES/COMMON/wmi_unified.h index 3a97eabbada9..5a4dc3f68f48 100644 --- a/CORE/SERVICES/COMMON/wmi_unified.h +++ b/CORE/SERVICES/COMMON/wmi_unified.h @@ -829,8 +829,7 @@ typedef enum { /** For debug/future enhancement purposes only, * configures/finetunes RMC algorithms */ WMI_RMC_CONFIG_CMDID, - /** select manual leader */ - WMI_RMC_SET_MANUAL_LEADER_CMDID, + _place_holder_cmd_1, /** WLAN MHF offload commands */ /** enable/disable MHF offload */ @@ -1318,9 +1317,7 @@ typedef enum { WMI_BPF_CAPABILIY_INFO_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_BPF_OFFLOAD), WMI_BPF_VDEV_STATS_INFO_EVENTID, - /* RMC specific event */ - /* RMC manual leader selected event */ - WMI_RMC_NEW_LEADER_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_RMC), + _place_holder_evt_1 = WMI_EVT_GRP_START_ID(WMI_GRP_RMC), /** Events in Prototyping phase */ WMI_NDI_CAP_RSP_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_PROTOTYPE), @@ -14681,35 +14678,6 @@ typedef struct { **/ } wmi_pdev_wal_power_debug_cmd_fixed_param; -typedef struct { - /** TLV tag and len; tag equals - * WMITLV_TAG_STRUC_wmi_rmc_set_leader_cmd_fixed_param - */ - A_UINT32 tlv_header; - /* VDEV identifier */ - A_UINT32 vdev_id; - /* Leader's mac address */ - wmi_mac_addr leader_mac_addr; -} wmi_rmc_set_leader_cmd_fixed_param; - -typedef struct { - /** TLV tag and len; tag equals - * WMITLV_TAG_STRUC_wmi_rmc_manual_leader_event_fixed_param - */ - A_UINT32 tlv_header; - /* VDEV identifier */ - A_UINT32 vdev_id; - /* 0: success - * 1: selected leader not found in network, able to find using auto selection - * -1: error - * non zero value should be return to userspace in case of failure - */ - A_INT32 status; - /* bssid of new leader */ - wmi_mac_addr leader_mac_addr; -} wmi_rmc_manual_leader_event_fixed_param; - - typedef enum { WLAN_2G_CAPABILITY = 0x1, WLAN_5G_CAPABILITY = 0x2, diff --git a/CORE/SERVICES/HIF/PCIe/copy_engine.c b/CORE/SERVICES/HIF/PCIe/copy_engine.c index e2a74cd25fbb..7ade81b38786 100644 --- a/CORE/SERVICES/HIF/PCIe/copy_engine.c +++ b/CORE/SERVICES/HIF/PCIe/copy_engine.c @@ -427,7 +427,7 @@ CE_sendlist_send(struct CE_handle *copyeng, NBUF_TX_PKT_CE); DPTRACE(adf_dp_trace((adf_nbuf_t)per_transfer_context, ADF_DP_TRACE_CE_PACKET_PTR_RECORD, - (uint8_t *)(((adf_nbuf_t)per_transfer_context)->data), + (uint8_t *)&(((adf_nbuf_t)per_transfer_context)->data), sizeof(((adf_nbuf_t)per_transfer_context)->data))); } else { /* diff --git a/CORE/SERVICES/HIF/PCIe/hif_pci.c b/CORE/SERVICES/HIF/PCIe/hif_pci.c index d65c9f3d920e..cc96b373085e 100644 --- a/CORE/SERVICES/HIF/PCIe/hif_pci.c +++ b/CORE/SERVICES/HIF/PCIe/hif_pci.c @@ -374,7 +374,7 @@ HIFSend_head(HIF_DEVICE *hif_device, NBUF_UPDATE_TX_PKT_COUNT(nbuf, NBUF_TX_PKT_HIF); DPTRACE(adf_dp_trace(nbuf, ADF_DP_TRACE_HIF_PACKET_PTR_RECORD, - (uint8_t *)(adf_nbuf_data(nbuf)), + adf_nbuf_data_addr(nbuf), sizeof(adf_nbuf_data(nbuf)))); status = CE_sendlist_send(ce_hdl, nbuf, &sendlist, transfer_id); A_ASSERT(status == A_OK); diff --git a/CORE/SERVICES/HIF/PCIe/if_pci.c b/CORE/SERVICES/HIF/PCIe/if_pci.c index 54db65e531f9..7f78e06f67f1 100644 --- a/CORE/SERVICES/HIF/PCIe/if_pci.c +++ b/CORE/SERVICES/HIF/PCIe/if_pci.c @@ -2502,66 +2502,119 @@ void hif_pci_shutdown(struct pci_dev *pdev) printk("%s: WLAN host driver shutting down completed!\n", __func__); } -void hif_pci_crash_shutdown(struct pci_dev *pdev) -{ #ifdef TARGET_RAMDUMP_AFTER_KERNEL_PANIC - struct hif_pci_softc *sc; - struct ol_softc *scn; - struct HIF_CE_state *hif_state; +#ifdef FEATURE_RUNTIME_PM +static bool is_hif_runtime_active(struct hif_pci_softc *sc) +{ + int pm_state = adf_os_atomic_read(&sc->pm_state); - sc = pci_get_drvdata(pdev); - if (!sc) - return; + if (pm_state == HIF_PM_RUNTIME_STATE_ON || + pm_state == HIF_PM_RUNTIME_STATE_NONE) + return true; - hif_state = (struct HIF_CE_state *)sc->hif_device; - if (!hif_state) - return; - - scn = sc->ol_sc; - if (!scn) - return; + return false; +} +#else /* ELSE FEATURE_RUNTIME_PM */ +static bool is_hif_runtime_active(struct hif_pci_softc *sc) +{ + return true; +} +#endif /* END FEATURE_RUNTIME_PM */ - if (OL_TRGET_STATUS_RESET == scn->target_status) { - printk("%s: Target is already asserted, ignore!\n", __func__); - return; - } +#ifdef WLAN_DEBUG +static void hif_dump_soc_and_ce_registers(struct hif_pci_softc *sc) +{ + int ret; + struct ol_softc *scn = sc->ol_sc; - if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) { - if (!vos_is_load_in_progress(VOS_MODULE_ID_VOSS, NULL)) { - pr_info("%s: Load/unload is in progress, ignore!\n", __func__); - return; - } - } + ret = hif_pci_check_soc_status(sc); - hif_pci_pm_runtime_exit(sc); - adf_os_spin_lock_irqsave(&hif_state->suspend_lock); + if (ret) { + pr_err("%s: SOC wakeup Failed\n", __func__); + return; + } - hif_irq_record(HIF_CRASH, sc); + ret = dump_CE_register(scn); -#ifdef WLAN_DEBUG - if (hif_pci_check_soc_status(scn->hif_sc) - || dump_CE_register(scn)) { - goto out; - } + if (ret) { + pr_err("%s: Failed to dump Copy Engine Registers\n", __func__); + return; + } - dump_CE_debug_register(scn->hif_sc); + dump_CE_debug_register(sc); +} +#else +static void hif_dump_soc_and_ce_registers(struct hif_pci_softc *sc) +{ +} #endif - if (ol_copy_ramdump(scn)) { - goto out; - } +static void hif_dump_crash_debug_info(struct hif_pci_softc *sc) +{ + struct HIF_CE_state *hif_state = (struct HIF_CE_state *)sc->hif_device; + struct ol_softc *scn = sc->ol_sc; + int ret; + + if (!hif_state) + return; - printk("%s: RAM dump collecting completed!\n", __func__); + adf_os_spin_lock_irqsave(&hif_state->suspend_lock); + hif_irq_record(HIF_CRASH, sc); + hif_dump_soc_and_ce_registers(sc); + + ret = ol_copy_ramdump(scn); + + if (ret) { + pr_err("%s: Failed to Copy Target Memory to Host DDR\n", + __func__); + goto out; + } + pr_info("%s: RAM dump collecting completed!\n", __func__); out: - adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); - return; -#else - printk("%s: Collecting target RAM dump after kernel panic is disabled!\n", - __func__); - return; -#endif + adf_os_spin_unlock_irqrestore(&hif_state->suspend_lock); +} + +void hif_pci_crash_shutdown(struct pci_dev *pdev) +{ + struct hif_pci_softc *sc; + struct ol_softc *scn; + + sc = pci_get_drvdata(pdev); + if (!sc) + return; + + scn = sc->ol_sc; + if (!scn) + return; + + if (OL_TRGET_STATUS_RESET == scn->target_status) { + pr_info("%s: Target is already asserted, ignore!\n", __func__); + return; + } + + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_HIF, NULL)) { + if (!vos_is_load_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + pr_info("%s: Load/unload is in progress, ignore!\n", + __func__); + return; + } + } + + if (is_hif_runtime_active(sc)) + hif_dump_crash_debug_info(sc); + else + pr_info("%s: Runtime Suspended; Ramdump Collection disabled\n", + __func__); + + pr_info("%s: Crash Shutdown Complete\n", __func__); } +#else /* TARGET_RAMDUMP_AFTER_KERNEL_PANIC */ +void hif_pci_crash_shutdown(struct pci_dev *pdev) +{ + pr_info("%s: QCA Ramdump Collected Disabled!\n", __func__); +} +#endif #endif #define OL_ATH_PCI_PM_CONTROL 0x44 diff --git a/CORE/SERVICES/HTC/htc_send.c b/CORE/SERVICES/HTC/htc_send.c index bcff00c5d2d4..ec70a40fed00 100644 --- a/CORE/SERVICES/HTC/htc_send.c +++ b/CORE/SERVICES/HTC/htc_send.c @@ -1330,7 +1330,7 @@ A_STATUS HTCSendDataPkt(HTC_HANDLE HTCHandle, adf_nbuf_t netbuf, int Epid, NBUF_UPDATE_TX_PKT_COUNT(netbuf, NBUF_TX_PKT_HTC); DPTRACE(adf_dp_trace(netbuf, ADF_DP_TRACE_HTC_PACKET_PTR_RECORD, - (uint8_t *)(adf_nbuf_data(netbuf)), + adf_nbuf_data_addr(netbuf), sizeof(adf_nbuf_data(netbuf)))); status = HIFSend_head(target->hif_dev, diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index c9365daa47ee..c7ab7ae7fd22 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -50,6 +50,7 @@ ==========================================================================*/ /* ################ Header files ################ */ +#include "ieee80211_common.h" /* ieee80211_frame */ #include "wma.h" #include "wma_api.h" #include "vos_api.h" @@ -208,6 +209,9 @@ #define WMA_LOG_COMPLETION_TIMER 10000 /* 10 seconds */ +#define WMA_FW_TIME_SYNC_TIMER 60000 /* 1 min */ +#define WMA_FW_TIME_STAMP_LOW_MASK 0xffffffff + #define WMI_TLV_HEADROOM 128 #define WMA_SUSPEND_TIMEOUT_IN_SSR 1 @@ -20241,6 +20245,14 @@ static const u8 *wma_wow_wake_reason_str(A_INT32 wake_reason, tp_wma_handle wma) return "WOW_REASON_BPF_ALLOW"; case WOW_REASON_NAN_EVENT: return "WOW_REASON_NAN_EVENT"; + case WOW_REASON_ASSOC_RES_RECV: + return "ASSOC_RES_RECV"; + case WOW_REASON_REASSOC_REQ_RECV: + return "REASSOC_REQ_RECV"; + case WOW_REASON_REASSOC_RES_RECV: + return "REASSOC_RES_RECV"; + case WOW_REASON_ACTION_FRAME_RECV: + return "ACTION_FRAME_RECV"; } return "unknown"; } @@ -20937,6 +20949,391 @@ exit_handler: wma_beacon_miss_handler(wma, wake_info->vdev_id, 0); } +/** + * wma_pkt_proto_subtype_to_string() - to convert proto subtype + * of data packet to string. + * @proto_subtype: proto subtype for data packet + * + * This function returns the string for the proto subtype of + * data packet. + * + * Return: string for proto subtype for data packet + */ +const char * +wma_pkt_proto_subtype_to_string(enum adf_proto_subtype proto_subtype) +{ + switch (proto_subtype) { + case ADF_PROTO_EAPOL_M1: + return "EAPOL M1"; + case ADF_PROTO_EAPOL_M2: + return "EAPOL M2"; + case ADF_PROTO_EAPOL_M3: + return "EAPOL M3"; + case ADF_PROTO_EAPOL_M4: + return "EAPOL M4"; + case ADF_PROTO_DHCP_DISCOVER: + return "DHCP DISCOVER"; + case ADF_PROTO_DHCP_REQUEST: + return "DHCP REQUEST"; + case ADF_PROTO_DHCP_OFFER: + return "DHCP OFFER"; + case ADF_PROTO_DHCP_ACK: + return "DHCP ACK"; + case ADF_PROTO_DHCP_NACK: + return "DHCP NACK"; + case ADF_PROTO_DHCP_RELEASE: + return "DHCP RELEASE"; + case ADF_PROTO_DHCP_INFORM: + return "DHCP INFORM"; + case ADF_PROTO_DHCP_DECLINE: + return "DHCP DECLINE"; + case ADF_PROTO_ARP_REQ: + return "ARP REQUEST"; + case ADF_PROTO_ARP_RES: + return "ARP RESPONSE"; + case ADF_PROTO_ICMP_REQ: + return "ICMP REQUEST"; + case ADF_PROTO_ICMP_RES: + return "ICMP RESPONSE"; + case ADF_PROTO_ICMPV6_REQ: + return "ICMPV6 REQUEST"; + case ADF_PROTO_ICMPV6_RES: + return "ICMPV6 RESPONSE"; + case ADF_PROTO_IPV4_UDP: + return "IPV4 UDP Packet"; + case ADF_PROTO_IPV4_TCP: + return "IPV4 TCP Packet"; + case ADF_PROTO_IPV6_UDP: + return "IPV6 UDP Packet"; + case ADF_PROTO_IPV6_TCP: + return "IPV6 TCP Packet"; + default: + return "Invalid Packet"; + } +} + +/** + * wma_wow_get_pkt_proto_subtype() - get the proto subtype + * of the packet. + * @data: Pointer to data buffer + * @len: length of the data buffer + * + * This function gives the proto subtype of the packet. + * + * Return: proto subtype of the packet. + */ +static enum adf_proto_subtype +wma_wow_get_pkt_proto_subtype(uint8_t *data, + uint32_t len) +{ + if (len >= WMA_IS_DHCP_GET_MIN_LEN) { + if (adf_nbuf_data_is_dhcp_pkt(data) == A_STATUS_OK) { + if (len >= WMA_DHCP_SUBTYPE_GET_MIN_LEN) + return adf_nbuf_data_get_dhcp_subtype(data); + VOS_TRACE(VOS_MODULE_ID_WDA, + VOS_TRACE_LEVEL_ERROR, "DHCP Packet"); + return ADF_PROTO_INVALID; + } + } + if (len >= WMA_IS_EAPOL_GET_MIN_LEN) { + if (adf_nbuf_data_is_eapol_pkt(data) == A_STATUS_OK) { + if (len >= WMA_EAPOL_SUBTYPE_GET_MIN_LEN) + return adf_nbuf_data_get_eapol_subtype(data); + VOS_TRACE(VOS_MODULE_ID_WDA, + VOS_TRACE_LEVEL_ERROR, "EAPOL Packet"); + return ADF_PROTO_INVALID; + } + } + if (len >= WMA_IS_ARP_GET_MIN_LEN) { + if (adf_nbuf_data_is_ipv4_arp_pkt(data)) { + if (len >= WMA_ARP_SUBTYPE_GET_MIN_LEN) + return adf_nbuf_data_get_arp_subtype(data); + VOS_TRACE(VOS_MODULE_ID_WDA, + VOS_TRACE_LEVEL_ERROR, "ARP Packet"); + return ADF_PROTO_INVALID; + } + } + if (len >= WMA_IPV4_PROTO_GET_MIN_LEN) { + if (adf_nbuf_data_is_icmp_pkt(data)) { + if (len >= WMA_ICMP_SUBTYPE_GET_MIN_LEN) + return adf_nbuf_data_get_icmp_subtype(data); + VOS_TRACE(VOS_MODULE_ID_WDA, + VOS_TRACE_LEVEL_ERROR, "ICMP Packet"); + return ADF_PROTO_INVALID; + } else if (adf_nbuf_data_is_ipv4_udp_pkt(data)) { + return ADF_PROTO_IPV4_UDP; + } else if (adf_nbuf_data_is_ipv4_tcp_pkt(data)) { + return ADF_PROTO_IPV4_TCP; + } + } + if (len >= WMA_IPV6_PROTO_GET_MIN_LEN) { + if (adf_nbuf_data_is_icmpv6_pkt(data)) { + if (len >= WMA_ICMPV6_SUBTYPE_GET_MIN_LEN) + return adf_nbuf_data_get_icmpv6_subtype(data); + VOS_TRACE(VOS_MODULE_ID_WDA, + VOS_TRACE_LEVEL_ERROR, "ICMPV6 Packet"); + return ADF_PROTO_INVALID; + } else if (adf_nbuf_data_is_ipv6_udp_pkt(data)) { + return ADF_PROTO_IPV6_UDP; + } else if (adf_nbuf_data_is_ipv6_tcp_pkt(data)) { + return ADF_PROTO_IPV6_TCP; + } + } + + return ADF_PROTO_INVALID; +} + +/** + * wma_wow_parse_data_pkt_buffer() - API to parse data buffer for data + * packet that resulted in WOW wakeup. + * @data: Pointer to data buffer + * @buf_len: data buffer length + * + * This function parses the data buffer received (first few bytes of + * skb->data) to get informaton like src mac addr, dst mac addr, packet + * len, seq_num, etc. + * + * Return: void + */ +static void wma_wow_parse_data_pkt_buffer(uint8_t *data, + uint32_t buf_len) +{ + enum adf_proto_subtype proto_subtype; + uint16_t pkt_len, key_len, seq_num; + uint32_t transaction_id, tcp_seq_num; + + WMA_LOGD("wow_buf_pkt_len: %d", buf_len); + if (buf_len >= ADF_NBUF_TRAC_ETH_TYPE_OFFSET) + WMA_LOGE("Src_mac: " MAC_ADDRESS_STR " Dst_mac: " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(data), + MAC_ADDR_ARRAY(data + ADF_NBUF_SRC_MAC_OFFSET)); + else + goto end; + + proto_subtype = wma_wow_get_pkt_proto_subtype(data, buf_len); + switch (proto_subtype) { + case ADF_PROTO_EAPOL_M1: + case ADF_PROTO_EAPOL_M2: + case ADF_PROTO_EAPOL_M3: + case ADF_PROTO_EAPOL_M4: + WMA_LOGE("WOW Wakeup: %s rcvd", + wma_pkt_proto_subtype_to_string(proto_subtype)); + if (buf_len >= WMA_EAPOL_INFO_GET_MIN_LEN) { + pkt_len = (uint16_t)(*(uint16_t *)(data + + EAPOL_PKT_LEN_OFFSET)); + key_len = (uint16_t)(*(uint16_t *)(data + + EAPOL_KEY_LEN_OFFSET)); + WMA_LOGE("Pkt_len: %d, Key_len: %d", + adf_os_cpu_to_be16(pkt_len), + adf_os_cpu_to_be16(key_len)); + } + break; + + case ADF_PROTO_DHCP_DISCOVER: + case ADF_PROTO_DHCP_REQUEST: + case ADF_PROTO_DHCP_OFFER: + case ADF_PROTO_DHCP_ACK: + case ADF_PROTO_DHCP_NACK: + case ADF_PROTO_DHCP_RELEASE: + case ADF_PROTO_DHCP_INFORM: + case ADF_PROTO_DHCP_DECLINE: + WMA_LOGE("WOW Wakeup: %s rcvd", + wma_pkt_proto_subtype_to_string(proto_subtype)); + if (buf_len >= WMA_DHCP_INFO_GET_MIN_LEN) { + pkt_len = (uint16_t)(*(uint16_t *)(data + + DHCP_PKT_LEN_OFFSET)); + transaction_id = (uint32_t)(*(uint32_t *)(data + + DHCP_TRANSACTION_ID_OFFSET)); + WMA_LOGE("Pkt_len: %d, Transaction_id: %d", + adf_os_cpu_to_be16(pkt_len), + adf_os_cpu_to_be32(transaction_id)); + } + break; + + case ADF_PROTO_ARP_REQ: + case ADF_PROTO_ARP_RES: + WMA_LOGE("WOW Wakeup: %s rcvd", + wma_pkt_proto_subtype_to_string(proto_subtype)); + break; + + case ADF_PROTO_ICMP_REQ: + case ADF_PROTO_ICMP_RES: + WMA_LOGE("WOW Wakeup: %s rcvd", + wma_pkt_proto_subtype_to_string(proto_subtype)); + if (buf_len >= WMA_IPV4_PKT_INFO_GET_MIN_LEN) { + pkt_len = (uint16_t)(*(uint16_t *)(data + + IPV4_PKT_LEN_OFFSET)); + seq_num = (uint16_t)(*(uint16_t *)(data + + ICMP_SEQ_NUM_OFFSET)); + WMA_LOGE("Pkt_len: %d, Seq_num: %d", + adf_os_cpu_to_be16(pkt_len), + adf_os_cpu_to_be16(seq_num)); + } + break; + + case ADF_PROTO_ICMPV6_REQ: + case ADF_PROTO_ICMPV6_RES: + WMA_LOGE("WOW Wakeup: %s rcvd", + wma_pkt_proto_subtype_to_string(proto_subtype)); + if (buf_len >= WMA_IPV6_PKT_INFO_GET_MIN_LEN) { + pkt_len = (uint16_t)(*(uint16_t *)(data + + IPV6_PKT_LEN_OFFSET)); + seq_num = (uint16_t)(*(uint16_t *)(data + + ICMPV6_SEQ_NUM_OFFSET)); + WMA_LOGE("Pkt_len: %d, Seq_num: %d", + adf_os_cpu_to_be16(pkt_len), + adf_os_cpu_to_be16(seq_num)); + } + break; + + case ADF_PROTO_IPV4_UDP: + case ADF_PROTO_IPV4_TCP: + WMA_LOGE("WOW Wakeup: %s rcvd", + wma_pkt_proto_subtype_to_string(proto_subtype)); + if (buf_len >= WMA_IPV4_PKT_INFO_GET_MIN_LEN) { + pkt_len = (uint16_t)(*(uint16_t *)(data + + IPV4_PKT_LEN_OFFSET)); + WMA_LOGE("Pkt_len: %d", + adf_os_cpu_to_be16(pkt_len)); + if (proto_subtype == ADF_PROTO_IPV4_TCP) { + tcp_seq_num = (uint32_t)(*(uint32_t *)(data + + IPV4_TCP_SEQ_NUM_OFFSET)); + WMA_LOGE("TCP_seq_num: %d", + adf_os_cpu_to_be32(tcp_seq_num)); + } + } + break; + + case ADF_PROTO_IPV6_UDP: + case ADF_PROTO_IPV6_TCP: + WMA_LOGE("WOW Wakeup: %s rcvd", + wma_pkt_proto_subtype_to_string(proto_subtype)); + if (buf_len >= WMA_IPV6_PKT_INFO_GET_MIN_LEN) { + pkt_len = (uint16_t)(*(uint16_t *)(data + + IPV6_PKT_LEN_OFFSET)); + WMA_LOGE("Pkt_len: %d", + adf_os_cpu_to_be16(pkt_len)); + if (proto_subtype == ADF_PROTO_IPV6_TCP) { + tcp_seq_num = (uint32_t)(*(uint32_t *)(data + + IPV6_TCP_SEQ_NUM_OFFSET)); + WMA_LOGE("TCP_seq_num: %d", + adf_os_cpu_to_be32(tcp_seq_num)); + } + } + break; + + default: +end: + WMA_LOGE("wow_buf_pkt_len: %d", buf_len); + WMA_LOGE("Invalid Packet Type or Smaller WOW packet buffer than expected"); + break; + } +} + +/** + * wma_wow_dump_mgmt_buffer() - API to parse data buffer for mgmt. + * packet that resulted in WOW wakeup. + * @wow_packet_buffer: Pointer to data buffer + * @buf_len: length of data buffer + * + * This function parses the data buffer received (802.11 header) + * to get informaton like src mac addr, dst mac addr, seq_num, + * frag_num, etc. + * + * Return: void + */ +static void wma_wow_dump_mgmt_buffer(uint8_t *wow_packet_buffer, + uint32_t buf_len) +{ + struct ieee80211_frame_addr4 *wh; + + WMA_LOGD("wow_buf_pkt_len: %d", buf_len); + wh = (struct ieee80211_frame_addr4 *) + (wow_packet_buffer + 4); + if (buf_len >= sizeof(struct ieee80211_frame)) { + uint8_t to_from_ds, frag_num; + uint32_t seq_num; + + WMA_LOGE("RA: " MAC_ADDRESS_STR " TA: " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(wh->i_addr1), + MAC_ADDR_ARRAY(wh->i_addr2)); + + WMA_LOGE("TO_DS: %d, FROM_DS: %d", + wh->i_fc[1] & IEEE80211_FC1_DIR_TODS, + wh->i_fc[1] & IEEE80211_FC1_DIR_FROMDS); + + to_from_ds = wh->i_fc[1] & IEEE80211_FC1_DIR_DSTODS; + + switch (to_from_ds) { + case IEEE80211_NO_DS: + WMA_LOGE("BSSID: " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(wh->i_addr3)); + break; + case IEEE80211_TO_DS: + WMA_LOGE("DA: " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(wh->i_addr3)); + break; + case IEEE80211_FROM_DS: + WMA_LOGE("SA: " MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(wh->i_addr3)); + break; + case IEEE80211_DS_TO_DS: + if (buf_len >= sizeof(struct ieee80211_frame_addr4)) + WMA_LOGE("DA: " MAC_ADDRESS_STR " SA: " + MAC_ADDRESS_STR, + MAC_ADDR_ARRAY(wh->i_addr3), + MAC_ADDR_ARRAY(wh->i_addr4)); + break; + } + + seq_num = (((*(uint16_t *)wh->i_seq) & + IEEE80211_SEQ_SEQ_MASK) >> + IEEE80211_SEQ_SEQ_SHIFT); + frag_num = (((*(uint16_t *)wh->i_seq) & + IEEE80211_SEQ_FRAG_MASK) >> + IEEE80211_SEQ_FRAG_SHIFT); + + WMA_LOGE("SEQ_NUM: %d, FRAG_NUM: %d", + seq_num, frag_num); + } else { + WMA_LOGE("Insufficient buffer length for mgmt. packet"); + } +} + +/** + * wma_wow_get_wakelock_duration() - return the wakelock duration + * for some mgmt packets received. + * @wake_reason: wow wakeup reason + * + * This function returns the wakelock duration for some mgmt packets + * received while in wow suspend. + * + * Return: wakelock duration + */ +static uint32_t wma_wow_get_wakelock_duration(int wake_reason) +{ + uint32_t wake_lock_duration = 0; + + switch (wake_reason) { + case WOW_REASON_AUTH_REQ_RECV: + wake_lock_duration = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT; + break; + case WOW_REASON_ASSOC_REQ_RECV: + wake_lock_duration = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION; + break; + case WOW_REASON_DEAUTH_RECVD: + wake_lock_duration = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION; + break; + case WOW_REASON_DISASSOC_RECVD: + wake_lock_duration = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION; + break; + default: + break; + } + + return wake_lock_duration; +} + /* * Handler to catch wow wakeup host event. This event will have * reason why the firmware has woken the host. @@ -20976,19 +21373,29 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event, switch (wake_info->wake_reason) { case WOW_REASON_AUTH_REQ_RECV: - wake_lock_duration = WMA_AUTH_REQ_RECV_WAKE_LOCK_TIMEOUT; - break; - case WOW_REASON_ASSOC_REQ_RECV: - wake_lock_duration = WMA_ASSOC_REQ_RECV_WAKE_LOCK_DURATION; - break; - case WOW_REASON_DEAUTH_RECVD: - wake_lock_duration = WMA_DEAUTH_RECV_WAKE_LOCK_DURATION; - break; - case WOW_REASON_DISASSOC_RECVD: - wake_lock_duration = WMA_DISASSOC_RECV_WAKE_LOCK_DURATION; + case WOW_REASON_ASSOC_RES_RECV: + case WOW_REASON_REASSOC_REQ_RECV: + case WOW_REASON_REASSOC_RES_RECV: + case WOW_REASON_BEACON_RECV: + case WOW_REASON_ACTION_FRAME_RECV: + wake_lock_duration = + wma_wow_get_wakelock_duration(wake_info->wake_reason); + if (param_buf->wow_packet_buffer) { + /* First 4-bytes of wow_packet_buffer is the length */ + vos_mem_copy((uint8_t *) &wow_buf_pkt_len, + param_buf->wow_packet_buffer, 4); + if (wow_buf_pkt_len) + wma_wow_dump_mgmt_buffer( + param_buf->wow_packet_buffer, + wow_buf_pkt_len); + else + WMA_LOGE("wow packet buffer is empty"); + } else { + WMA_LOGE("No wow packet buffer present"); + } break; case WOW_REASON_AP_ASSOC_LOST: @@ -21070,12 +21477,25 @@ static int wma_wow_wakeup_host_event(void *handle, u_int8_t *event, /* First 4-bytes of wow_packet_buffer is the length */ vos_mem_copy((u_int8_t *) &wow_buf_pkt_len, param_buf->wow_packet_buffer, 4); - wma_wow_wake_up_stats(wma, - param_buf->wow_packet_buffer + 4, wow_buf_pkt_len, - WOW_REASON_PATTERN_MATCH_FOUND); - vos_trace_hex_dump(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, - param_buf->wow_packet_buffer + 4, - wow_buf_pkt_len); + if (wow_buf_pkt_len) { + uint8_t *data; + + wma_wow_wake_up_stats(wma, + param_buf->wow_packet_buffer + 4, + wow_buf_pkt_len, + WOW_REASON_PATTERN_MATCH_FOUND); + vos_trace_hex_dump(VOS_MODULE_ID_WDA, + VOS_TRACE_LEVEL_DEBUG, + param_buf->wow_packet_buffer + 4, + wow_buf_pkt_len); + + data = (uint8_t *) + (param_buf->wow_packet_buffer + 4); + wma_wow_parse_data_pkt_buffer(data, + wow_buf_pkt_len); + } else { + WMA_LOGE("wow packet buffer is empty"); + } } else { WMA_LOGE("No wow packet buffer present"); } @@ -32323,6 +32743,11 @@ VOS_STATUS wma_stop(v_VOID_t *vos_ctx, tANI_U8 reason) WMA_LOGE("Failed to destroy the log completion timer"); } + /* Destroy firmware time stamp sync timer */ + vos_status = vos_timer_destroy(&wma_handle->wma_fw_time_sync_timer); + if (vos_status != VOS_STATUS_SUCCESS) + WMA_LOGE(FL("Failed to destroy the fw time sync timer")); + /* There's no need suspend target which is already down during SSR. */ if (!vos_is_logp_in_progress(VOS_MODULE_ID_HIF, NULL)) { #ifdef HIF_USB @@ -33051,6 +33476,65 @@ static wmi_buf_t wma_setup_wmi_init_msg(tp_wma_handle wma_handle, return buf; } +/** + * wma_send_time_stamp_sync_cmd() - timer callback send timestamp to + * firmware to sync with host. + * @wma_handle: wma handle + * + * Return: void + */ +static void wma_send_time_stamp_sync_cmd(void *data) +{ + tp_wma_handle wma_handle; + wmi_buf_t buf; + WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *time_stamp; + A_STATUS status = A_OK; + int len; + VOS_STATUS vos_status; + unsigned long time_ms; + + wma_handle = (tp_wma_handle) data; + len = sizeof(*time_stamp); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGP(FL("wmi_buf_alloc failed")); + return; + } + + time_stamp = + (WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param *) + (wmi_buf_data(buf)); + WMITLV_SET_HDR(&time_stamp->tlv_header, + WMITLV_TAG_STRUC_wmi_dbglog_time_stamp_sync_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + WMI_DBGLOG_TIME_STAMP_SYNC_CMD_fixed_param)); + + time_ms = vos_get_time_of_the_day_ms(); + time_stamp->mode = WMI_TIME_STAMP_SYNC_MODE_MS; + time_stamp->time_stamp_low = time_ms & + WMA_FW_TIME_STAMP_LOW_MASK; + /* + * Send time_stamp_high 0 as the time converted from HR:MIN:SEC:MS to ms + * wont exceed 27 bit + */ + time_stamp->time_stamp_high = 0; + WMA_LOGD(FL("WMA --> DBGLOG_TIME_STAMP_SYNC_CMDID mode %d time_stamp low %d high %d"), + time_stamp->mode, time_stamp->time_stamp_low, + time_stamp->time_stamp_high); + status = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, + len, WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); + if (status != EOK) { + WMA_LOGE("Failed to send WMI_DBGLOG_TIME_STAMP_SYNC_CMDID command"); + wmi_buf_free(buf); + } + + /* Start/Restart the timer */ + vos_status = vos_timer_start(&wma_handle->wma_fw_time_sync_timer, + WMA_FW_TIME_SYNC_TIMER); + if (vos_status != VOS_STATUS_SUCCESS) + WMA_LOGE("Failed to start the firmware time sync timer"); +} + /* Process service ready event and send wmi_init command */ v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info) { @@ -33060,6 +33544,7 @@ v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info) struct wma_target_cap target_cap; WMI_SERVICE_READY_EVENTID_param_tlvs *param_buf; wmi_service_ready_event_fixed_param *ev; + VOS_STATUS vos_status; int status; WMA_LOGD("%s: Enter", __func__); @@ -33221,6 +33706,17 @@ v_VOID_t wma_rx_service_ready_event(WMA_HANDLE handle, void *cmd_param_info) wmi_buf_free(buf); return; } + + /* Initialize firmware time stamp sync timer */ + vos_status = vos_timer_init(&wma_handle->wma_fw_time_sync_timer, + VOS_TIMER_TYPE_SW, + wma_send_time_stamp_sync_cmd, + wma_handle); + if (vos_status != VOS_STATUS_SUCCESS) + WMA_LOGE(FL("Failed to initialize firmware time stamp sync timer")); + + /* Start firmware time stamp sync timer */ + wma_send_time_stamp_sync_cmd(wma_handle); } /* function : wma_rx_ready_event diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index 9bd3dee0e2ab..e239070592a2 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -182,6 +182,35 @@ #define WMA_MCAST_IPV6_MAC_ADDR (0x33) #define WMA_ICMP_PROTOCOL (0x01) +#define WMA_IS_EAPOL_GET_MIN_LEN 14 +#define WMA_EAPOL_SUBTYPE_GET_MIN_LEN 21 +#define WMA_EAPOL_INFO_GET_MIN_LEN 23 +#define WMA_IS_DHCP_GET_MIN_LEN 38 +#define WMA_DHCP_SUBTYPE_GET_MIN_LEN 0x11D +#define WMA_DHCP_INFO_GET_MIN_LEN 50 +#define WMA_IS_ARP_GET_MIN_LEN 14 +#define WMA_ARP_SUBTYPE_GET_MIN_LEN 22 +#define WMA_IPV4_PROTO_GET_MIN_LEN 24 +#define WMA_IPV4_PKT_INFO_GET_MIN_LEN 42 +#define WMA_ICMP_SUBTYPE_GET_MIN_LEN 35 +#define WMA_IPV6_PROTO_GET_MIN_LEN 21 +#define WMA_IPV6_PKT_INFO_GET_MIN_LEN 62 +#define WMA_ICMPV6_SUBTYPE_GET_MIN_LEN 55 + +/* + * ds_mode: distribution system mode + * @IEEE80211_NO_DS: NO DS at either side + * @IEEE80211_TO_DS: DS at receiver side + * @IEEE80211_FROM_DS: DS at sender side + * @IEEE80211_DS_TO_DS: DS at both sender and revceiver side + */ +enum ds_mode { + IEEE80211_NO_DS, + IEEE80211_TO_DS, + IEEE80211_FROM_DS, + IEEE80211_DS_TO_DS +}; + typedef struct probeTime_dwellTime { u_int8_t dwell_time; u_int8_t probe_time; @@ -873,7 +902,7 @@ typedef struct wma_handle { /* NAN datapath support enabled in firmware */ bool nan_datapath_enabled; tSirLLStatsResults *link_stats_results; - + vos_timer_t wma_fw_time_sync_timer; struct sir_allowed_action_frames allowed_action_frames; }t_wma_handle, *tp_wma_handle; diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index 699f6c590156..c5bd9ad31b7e 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -702,7 +702,7 @@ static u_int8_t* get_wmi_cmd_string(WMI_CMD_ID wmi_command) CASE_RETURN_STRING(WMI_WOW_SET_ACTION_WAKE_UP_CMDID); CASE_RETURN_STRING(WMI_PEER_BWF_REQUEST_CMDID); CASE_RETURN_STRING(WMI_DBGLOG_TIME_STAMP_SYNC_CMDID); - CASE_RETURN_STRING(WMI_RMC_SET_MANUAL_LEADER_CMDID); + CASE_RETURN_STRING(_place_holder_cmd_1); } return "Invalid WMI cmd"; } diff --git a/CORE/SME/inc/csrNeighborRoam.h b/CORE/SME/inc/csrNeighborRoam.h index 6b5a3d6875d6..1de1430f345c 100644 --- a/CORE/SME/inc/csrNeighborRoam.h +++ b/CORE/SME/inc/csrNeighborRoam.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -357,7 +357,7 @@ eHalStatus csrNeighborRoamStartLfrScan(tpAniSirGlobal pMac, tANI_U8 sessionId); VOS_STATUS csrSetCCKMIe(tpAniSirGlobal pMac, const tANI_U8 sessionId, const tANI_U8 *pCckmIe, const tANI_U8 ccKmIeLen); -VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp, +eHalStatus csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp, const tANI_U8 sessionId); #endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ #ifdef WLAN_FEATURE_ROAM_OFFLOAD diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 06250009356b..02a42b743ccf 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -3739,6 +3739,7 @@ eHalStatus sme_SetHT2040Mode(tHalHandle hHal, tANI_U8 sessionId, eHalStatus sme_getRegInfo(tHalHandle hHal, tANI_U8 chanId, tANI_U32 *regInfo1, tANI_U32 *regInfo2); +uint32_t sme_get_wni_dot11_mode(tHalHandle hal); #ifdef FEATURE_WLAN_TDLS eHalStatus sme_UpdateFwTdlsState(tHalHandle hHal, void *psmeTdlsParams, diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index 0d313b7df2ed..43c43262f0fa 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -14142,6 +14142,10 @@ eHalStatus csrSendJoinReqMsg( tpAniSirGlobal pMac, tANI_U32 sessionId, tSirBssDe { dwTmp = pal_cpu_to_be32(eSIR_ED_NONE); } + if (pProfile->MFPEnabled && + !(pProfile->MFPRequired) && ((pIes->RSN.present) && + (!(pIes->RSN.RSN_Cap[0] >> 7) & 0x1))) + dwTmp = pal_cpu_to_be32(eSIR_ED_NONE); vos_mem_copy(pBuf, &dwTmp, sizeof(tANI_U32)); pBuf += sizeof(tANI_U32); #endif @@ -16317,6 +16321,7 @@ void csrRoamStatsRspProcessor(tpAniSirGlobal pMac, tSirSmeRsp *pSirMsg) smsLog( pMac, LOG2, FL("csrRoamStatsRspProcessor:PerSta stats")); if( CSR_MAX_STA > pSmeStatsRsp->staId ) { + status = eHAL_STATUS_SUCCESS; vos_mem_copy((tANI_U8 *)&pMac->roam.perStaStatsInfo[pSmeStatsRsp->staId], pStats, sizeof(tCsrPerStaStatsInfo)); } @@ -16906,12 +16911,13 @@ eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requeste pMac->roam.tlStatsReqInfo.periodicity = 0; pMac->roam.tlStatsReqInfo.timerRunning = FALSE; } - vos_timer_stop( &pStaEntry->timer ); - // Destroy the vos timer... - vosStatus = vos_timer_destroy( &pStaEntry->timer ); - if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) - { - smsLog(pMac, LOGE, FL("csrGetStatistics:failed to destroy Client req timer")); + + if (periodicity) { + vos_timer_stop(&pStaEntry->timer); + /* Destroy the vos timer */ + vosStatus = vos_timer_destroy(&pStaEntry->timer); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + smsLog(pMac, LOGE, FL("csrGetStatistics:failed to destroy Client req timer")); } csrRoamRemoveStatListEntry(pMac, pEntry); pStaEntry = NULL; @@ -16991,6 +16997,8 @@ eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requeste pTlStats = (WLANTL_TRANSFER_STA_TYPE *)vos_mem_malloc(sizeof(WLANTL_TRANSFER_STA_TYPE)); if (NULL != pTlStats) { + vos_mem_set(pTlStats, sizeof(*pTlStats), 0); + //req TL for class D stats if(WLANTL_GetStatistics(pMac->roam.gVosContext, pTlStats, staId)) { @@ -17052,6 +17060,8 @@ eHalStatus csrGetStatistics(tpAniSirGlobal pMac, eCsrStatsRequesterType requeste pTlStats = (WLANTL_TRANSFER_STA_TYPE *)vos_mem_malloc(sizeof(WLANTL_TRANSFER_STA_TYPE)); if (NULL != pTlStats) { + vos_mem_set(pTlStats, sizeof(*pTlStats), 0); + //req TL for class D stats if(!VOS_IS_STATUS_SUCCESS(WLANTL_GetStatistics(pMac->roam.gVosContext, pTlStats, staId))) { @@ -19005,11 +19015,14 @@ void csrRoamFTPreAuthRspProcessor( tHalHandle hHal, tpSirFTPreAuthRsp pFTPreAuth eCSR_ROAM_FT_RESPONSE, eCSR_ROAM_RESULT_NONE); #if defined(FEATURE_WLAN_ESE) && defined(FEATURE_WLAN_ESE_UPLOAD) - if (csrRoamIsESEAssoc(pMac, pFTPreAuthRsp->smeSessionId)) - { + if (csrRoamIsESEAssoc(pMac, pFTPreAuthRsp->smeSessionId)) { /* read TSF */ - csrRoamReadTSF(pMac, (tANI_U8 *)roamInfo.timestamp, - pFTPreAuthRsp->smeSessionId); + status = csrRoamReadTSF(pMac, (tANI_U8 *)roamInfo.timestamp, + pFTPreAuthRsp->smeSessionId); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(pMac, LOGE, FL("TSF read failed.Timestamp may be invalid")); + return; + } // Save the bssid from the received response vos_mem_copy((void *)&roamInfo.bssid, (void *)pFTPreAuthRsp->preAuthbssId, sizeof(tCsrBssid)); @@ -19271,15 +19284,18 @@ VOS_STATUS csrSetCCKMIe(tpAniSirGlobal pMac, const tANI_U8 sessionId, \param pTimestamp - output TSF time stamp \- return Success or failure -------------------------------------------------------------------------*/ -VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp, +eHalStatus csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp, tANI_U8 sessionId) { - eHalStatus status = eHAL_STATUS_SUCCESS; - tCsrNeighborRoamBSSInfo handoffNode; + tCsrNeighborRoamBSSInfo handoffNode = {{0}}; tANI_U32 timer_diff = 0; tANI_U32 timeStamp[2]; tpSirBssDescription pBssDescription = NULL; - csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode, sessionId); + + if (!csrNeighborRoamGetHandoffAPInfo(pMac, &handoffNode, sessionId)) { + smsLog(pMac, LOGE, FL("invalid handoff node")); + return eHAL_STATUS_FAILURE; + } pBssDescription = handoffNode.pBssDescription; // Get the time diff in milli seconds timer_diff = vos_timer_get_system_time() - pBssDescription->scanSysTimeMsec; @@ -19290,7 +19306,8 @@ VOS_STATUS csrRoamReadTSF(tpAniSirGlobal pMac, tANI_U8 *pTimestamp, UpdateCCKMTSF(&(timeStamp[0]), &(timeStamp[1]), &timer_diff); vos_mem_copy(pTimestamp, (void *) &timeStamp[0], sizeof (tANI_U32) * 2); - return status; + + return eHAL_STATUS_SUCCESS; } #endif /*FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ diff --git a/CORE/SME/src/csr/csrUtil.c b/CORE/SME/src/csr/csrUtil.c index 87cdfee1d7f0..8dce77e9b8c1 100644 --- a/CORE/SME/src/csr/csrUtil.c +++ b/CORE/SME/src/csr/csrUtil.c @@ -3054,6 +3054,12 @@ csrIsPMFCapabilitiesInRSNMatch( tHalHandle hHal, /* Extracting MFPCapable bit from RSN Ie */ apProfileMFPCapable = (pRSNIe->RSN_Cap[0] >> 7) & 0x1; apProfileMFPRequired = (pRSNIe->RSN_Cap[0] >> 6) & 0x1; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("pFilterMFPEnabled=%d pFilterMFPRequired=%d pFilterMFPCapable=%d apProfileMFPCapable=%d apProfileMFPRequired=%d"), + *pFilterMFPEnabled, *pFilterMFPRequired, *pFilterMFPCapable, + apProfileMFPCapable, apProfileMFPRequired); + if (*pFilterMFPEnabled && *pFilterMFPCapable && *pFilterMFPRequired && (apProfileMFPCapable == 0)) { @@ -3061,19 +3067,6 @@ csrIsPMFCapabilitiesInRSNMatch( tHalHandle hHal, "AP is not capable to make PMF connection"); return VOS_FALSE; } - else if (*pFilterMFPEnabled && *pFilterMFPCapable && - !(*pFilterMFPRequired) && (apProfileMFPCapable == 0)) - { - /* - * This is tricky, because supplicant asked us to make mandatory - * PMF connection even though PMF connection is optional here. - * so if AP is not capable of PMF then drop it. Don't try to - * connect with it. - */ - VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, - "we need PMF connection & AP isn't capable to make PMF connection"); - return VOS_FALSE; - } else if (!(*pFilterMFPCapable) && apProfileMFPCapable && apProfileMFPRequired) { @@ -3087,13 +3080,6 @@ csrIsPMFCapabilitiesInRSNMatch( tHalHandle hHal, "AP needs PMF connection and we are not capable of pmf connection"); return VOS_FALSE; } - else if (!(*pFilterMFPEnabled) && *pFilterMFPCapable && - (apProfileMFPCapable == 1)) - { - VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, - "we don't need PMF connection even though both parties are capable"); - return VOS_FALSE; - } } return VOS_TRUE; } @@ -3257,8 +3243,11 @@ tANI_U8 csrConstructRSNIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile } #ifdef WLAN_FEATURE_11W - if ( pProfile->MFPEnabled ) - { + /* Advertise BIP in group cipher key management only if PMF is enabled + * and AP is capable. + */ + if (pProfile->MFPEnabled && + (RSNCapabilities.MFPCapable && pProfile->MFPCapable)){ pGroupMgmtCipherSuite = (tANI_U8 *) pPMK + sizeof ( tANI_U16 ) + ( pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE ); vos_mem_copy(pGroupMgmtCipherSuite, csrRSNOui[07], CSR_WPA_OUI_SIZE); @@ -3279,8 +3268,8 @@ tANI_U8 csrConstructRSNIe( tHalHandle hHal, tANI_U32 sessionId, tCsrRoamProfile (pPMK->cPMKIDs * CSR_RSN_PMKID_SIZE)); } #ifdef WLAN_FEATURE_11W - if ( pProfile->MFPEnabled ) - { + if (pProfile->MFPEnabled && + (RSNCapabilities.MFPCapable && pProfile->MFPCapable)){ if ( 0 == pPMK->cPMKIDs ) pRSNIe->IeHeader.Length += sizeof( tANI_U16 ); pRSNIe->IeHeader.Length += CSR_WPA_OUI_SIZE; diff --git a/CORE/SME/src/rrm/sme_rrm.c b/CORE/SME/src/rrm/sme_rrm.c index 4d355653c6ae..feff4e197490 100644 --- a/CORE/SME/src/rrm/sme_rrm.c +++ b/CORE/SME/src/rrm/sme_rrm.c @@ -180,7 +180,7 @@ static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, { tpSirBssDescription pBssDesc = NULL; tpSirBeaconReportXmitInd pBeaconRep; - tANI_U16 length, ie_len; + tANI_U16 length, ie_len, tot_len; tANI_U8 bssCounter=0, msgCounter=0; tCsrScanResultInfo *pCurResult=NULL; eHalStatus status = eHAL_STATUS_FAILURE; @@ -227,10 +227,13 @@ static eHalStatus sme_RrmSendBeaconReportXmitInd( tpAniSirGlobal pMac, if(pBssDesc != NULL) { ie_len = GET_IE_LEN_IN_BSS( pBssDesc->length ); - pBeaconRep->pBssDescription[msgCounter] = vos_mem_malloc ( - ie_len+sizeof(tSirBssDescription)); + tot_len = ie_len+sizeof(tSirBssDescription); + pBeaconRep->pBssDescription[msgCounter] = + vos_mem_malloc(tot_len); if (NULL == pBeaconRep->pBssDescription[msgCounter]) break; + vos_mem_zero(pBeaconRep->pBssDescription[msgCounter], + tot_len); vos_mem_copy( pBeaconRep->pBssDescription[msgCounter], pBssDesc, sizeof(tSirBssDescription) ); diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index b36e47f5102c..7e74be03beb5 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -12189,12 +12189,13 @@ eHalStatus sme_UpdateFwTdlsState(tHalHandle hHal, void *psmeTdlsParams, tpAniSirGlobal pMac = NULL; vos_msg_t vosMessage; + pMac = PMAC_STRUCT(hHal); + if (NULL == pMac) { + return eHAL_STATUS_FAILURE; + } + /* only acquire sme global lock before state update if asked to */ if (useSmeLock) { - pMac = PMAC_STRUCT(hHal); - if (NULL == pMac) - return eHAL_STATUS_FAILURE; - status = sme_AcquireGlobalLock(&pMac->sme); if (eHAL_STATUS_SUCCESS != status) return status; @@ -14594,6 +14595,19 @@ eHalStatus sme_getRegInfo(tHalHandle hHal, tANI_U8 chanId, return status; } +/* sme_get_wni_dot11_mode() - return configured wni dot11mode + * @hHal: hal pointer + * + * Return: wni dot11 mode. + */ +uint32_t sme_get_wni_dot11_mode(tHalHandle hal) +{ + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + + return csrTranslateToWNICfgDot11Mode(mac_ctx, + mac_ctx->roam.configParam.uCfgDot11Mode); +} + #ifdef FEATURE_WLAN_AUTO_SHUTDOWN /* --------------------------------------------------------------------------- \fn sme_auto_shutdown_cb @@ -19118,7 +19132,8 @@ eHalStatus sme_update_sta_roam_policy(tHalHandle hal_handle, uint8_t reason = 0; if (!mac_ctx) { - smsLog(mac_ctx, LOGE, FL("mac_ctx is null!")); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL, + "%s: mac_ctx is null", __func__); VOS_ASSERT(0); return eHAL_STATUS_FAILURE; } diff --git a/CORE/UTILS/FWLOG/dbglog_host.c b/CORE/UTILS/FWLOG/dbglog_host.c index a1ba79c0c8b6..fa7931d94359 100644 --- a/CORE/UTILS/FWLOG/dbglog_host.c +++ b/CORE/UTILS/FWLOG/dbglog_host.c @@ -1378,7 +1378,8 @@ wmi_config_debug_module_cmd(wmi_unified_t wmi_handle, A_UINT32 param, A_UINT32 } } - AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("wmi_dbg_cfg_send: param 0x%x val 0x%x \n", + AR_DEBUG_PRINTF(ATH_DEBUG_RSVD1, + ("wmi_dbg_cfg_send: param 0x%x val 0x%x \n", param, val)); status = wmi_unified_cmd_send(wmi_handle, buf, @@ -1670,6 +1671,12 @@ send_fw_diag_nl_data(const u_int8_t *buffer, return -1; } nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG, msg_len, 0); + if (nlh == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: nlmsg_put failed\n", __func__)); + nlmsg_free(skb_out); + return -ENOMEM; + } wnl = (tAniNlHdr *)nlh; wnl->radio = radio; @@ -1719,6 +1726,12 @@ send_diag_netlink_data(const u_int8_t *buffer, A_UINT32 len, A_UINT32 cmd) } nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG, slot_len, 0); + if (nlh == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: nlmsg_put failed\n", __func__)); + nlmsg_free(skb_out); + return -ENOMEM; + } wnl = (tAniNlHdr *)nlh; wnl->radio = radio; @@ -1777,6 +1790,12 @@ dbglog_process_netlink_data(wmi_unified_t wmi_handle, const u_int8_t *buffer, } nlh = nlmsg_put(skb_out, 0, 0, WLAN_NL_MSG_CNSS_DIAG, slot_len, 0); + if (nlh == NULL) { + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, + ("%s: nlmsg_put failed\n", __func__)); + nlmsg_free(skb_out); + return -ENOMEM; + } wnl = (tAniNlHdr *)nlh; wnl->radio = radio; diff --git a/CORE/VOSS/inc/vos_timer.h b/CORE/VOSS/inc/vos_timer.h index 48805865e894..8e42742f1e4a 100644 --- a/CORE/VOSS/inc/vos_timer.h +++ b/CORE/VOSS/inc/vos_timer.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -350,5 +350,5 @@ static inline uint32_t vos_system_ticks_to_msecs(vos_time_t ticks) return __vos_system_ticks_to_msecs(ticks); } - +unsigned long vos_get_time_of_the_day_ms(void); #endif // #if !defined __VOSS_TIMER_H diff --git a/CORE/VOSS/src/vos_timer.c b/CORE/VOSS/src/vos_timer.c index f0e28a05af0e..48e3d57f439c 100644 --- a/CORE/VOSS/src/vos_timer.c +++ b/CORE/VOSS/src/vos_timer.c @@ -45,6 +45,7 @@ #include <vos_api.h> #include "wlan_qct_sys.h" #include "vos_sched.h" +#include <linux/rtc.h> /*-------------------------------------------------------------------------- Preprocessor definitions and constants @@ -847,3 +848,24 @@ v_TIME_t vos_timer_get_system_time( v_VOID_t ) do_gettimeofday(&tv); return tv.tv_sec*1000 + tv.tv_usec/1000; } + +/** + * vos_get_time_of_the_day_ms() - get time in milisec + * + * Return: time of the day in ms + */ +unsigned long vos_get_time_of_the_day_ms(void) +{ + struct timeval tv; + unsigned long local_time; + struct rtc_time tm; + + do_gettimeofday(&tv); + + local_time = (uint32_t)(tv.tv_sec - + (sys_tz.tz_minuteswest * 60)); + rtc_time_to_tm(local_time, &tm); + return ((tm.tm_hour * 60 * 60 * 1000) + + (tm.tm_min *60 * 1000) + (tm.tm_sec * 1000)+ + (tv.tv_usec/1000)); +} |
