diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2014-07-08 11:56:26 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2014-07-08 11:56:26 -0700 |
| commit | b9df01754963a8d97ecd97c98973a7c5eb1af37e (patch) | |
| tree | 18b7d496830d93c78b8b3f318dacbc45224804af | |
| parent | 609b4c5c1c74d3717eaf52cbe193fb2bb7b03b5b (diff) | |
| parent | 94435a2de3d92f3de839f26734bad28f8b149025 (diff) | |
Merge "Release 1.0.0.140 QCACLD WLAN Driver"
51 files changed, 4183 insertions, 667 deletions
diff --git a/CORE/CLD_TXRX/HTT/htt.c b/CORE/CLD_TXRX/HTT/htt.c index 7ce284a19bae..7a9f373c4044 100644 --- a/CORE/CLD_TXRX/HTT/htt.c +++ b/CORE/CLD_TXRX/HTT/htt.c @@ -406,9 +406,7 @@ htt_htc_attach(struct htt_pdev_t *pdev) connect.MaxSendQueueDepth = HTT_MAX_SEND_QUEUE_DEPTH; /* disable flow control for HTT data message service */ -#ifndef HIF_SDIO connect.ConnectionFlags |= HTC_CONNECT_FLAGS_DISABLE_CREDIT_FLOW_CTRL; -#endif /* connect to control service */ connect.ServiceID = HTT_DATA_MSG_SVC; diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c index 9f675607fe08..ec26613ea624 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -1761,16 +1761,20 @@ VOS_STATUS WLANTL_Close(void *vos_ctx) for (i = 0; i < wdi_out_cfg_max_vdevs(((pVosContextType)vos_ctx)->cfg_ctx); i++) { -#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL - vos_event_destroy(&tl_shim->peer_authorized_events[i]); -#endif adf_os_spinlock_destroy(&tl_shim->session_flow_control[i].fc_lock); } + adf_os_mem_free(tl_shim->session_flow_control); +#endif /* QCA_LL_TX_FLOW_CT */ + #ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL + for (i = 0; + i < wdi_out_cfg_max_vdevs(((pVosContextType)vos_ctx)->cfg_ctx); + i++) { + vos_event_destroy(&tl_shim->peer_authorized_events[i]); + } adf_os_mem_free(tl_shim->peer_authorized_events); #endif - adf_os_mem_free(tl_shim->session_flow_control); -#endif /* QCA_LL_TX_FLOW_CT */ + adf_os_mem_free(tl_shim->vdev_active); #ifdef FEATURE_WLAN_ESE vos_flush_work(&tl_shim->iapp_work.deferred_work); @@ -1852,35 +1856,40 @@ VOS_STATUS WLANTL_Open(void *vos_ctx, WLANTL_ConfigInfoType *tl_cfg) return VOS_STATUS_E_NOMEM; } + for (i = 0; i < max_vdev; i++) { + tl_shim->session_flow_control[i].flowControl = NULL; + tl_shim->session_flow_control[i].sessionId = 0xFF; + tl_shim->session_flow_control[i].adpaterCtxt = NULL; + tl_shim->session_flow_control[i].vdev = NULL; + adf_os_spinlock_init(&tl_shim->session_flow_control[i].fc_lock); + } +#endif /* QCA_LL_TX_FLOW_CT */ + #ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL tl_shim->peer_authorized_events = adf_os_mem_alloc(NULL, - max_vdev * sizeof(vos_event_t)); + max_vdev * sizeof(vos_event_t)); if (!tl_shim->peer_authorized_events) { TLSHIM_LOGE("Failed to allocate memory for events"); +#ifdef QCA_LL_TX_FLOW_CT adf_os_mem_free(tl_shim->session_flow_control); +#endif vos_free_context(vos_ctx, VOS_MODULE_ID_TL, tl_shim); return VOS_STATUS_E_NOMEM; } -#endif for (i = 0; i < max_vdev; i++) { - tl_shim->session_flow_control[i].flowControl = NULL; - tl_shim->session_flow_control[i].sessionId = 0xFF; - tl_shim->session_flow_control[i].adpaterCtxt = NULL; - tl_shim->session_flow_control[i].vdev = NULL; -#ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL status = vos_event_init(&tl_shim->peer_authorized_events[i]); if (!VOS_IS_STATUS_SUCCESS(status)) { TLSHIM_LOGE("%s: Failed to initialized a event.", __func__); adf_os_mem_free(tl_shim->peer_authorized_events); +#ifdef QCA_LL_TX_FLOW_CT adf_os_mem_free(tl_shim->session_flow_control); +#endif vos_free_context(vos_ctx, VOS_MODULE_ID_TL, tl_shim); return status; } -#endif - adf_os_spinlock_init(&tl_shim->session_flow_control[i].fc_lock); } -#endif /* QCA_LL_TX_FLOW_CT */ +#endif tl_shim->ip_checksum_offload = tl_cfg->ip_checksum_offload; tl_shim->delay_interval = tl_cfg->uDelayedTriggerFrmInt; diff --git a/CORE/CLD_TXRX/TXRX/ol_tx.c b/CORE/CLD_TXRX/TXRX/ol_tx.c index 25e8a8db8dab..28178e579e04 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx.c @@ -51,8 +51,6 @@ /* internal header files relevant only for specific systems (Pronto) */ #include <ol_txrx_encap.h> /* OL_TX_ENCAP, etc */ -#define ENABLE_TX_SCHED 1 - #define ol_tx_prepare_ll(tx_desc, vdev, msdu, msdu_info) \ do { \ struct ol_txrx_pdev_t *pdev = vdev->pdev; \ @@ -478,7 +476,6 @@ ol_tx_non_std_ll( #define TX_FILTER_CHECK(tx_msdu_info) 0 /* don't filter */ #endif -#if ENABLE_TX_SCHED static inline adf_nbuf_t ol_tx_hl_base( ol_txrx_vdev_handle vdev, @@ -509,7 +506,15 @@ ol_tx_hl_base( */ next = adf_nbuf_next(msdu); +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + if (adf_os_atomic_read(&vdev->tx_desc_count) <= ((ol_tx_desc_pool_size_hl(pdev->ctrl_pdev) >> 1) - 20)) { + tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, &tx_msdu_info); + } else { + tx_desc = NULL; + } +#else tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, &tx_msdu_info); +#endif if (! tx_desc) { /* * If we're out of tx descs, there's no need to try to allocate @@ -624,112 +629,6 @@ MSDU_LOOP_BOTTOM: return NULL; /* all MSDUs were accepted */ } -#else /* ENABLE_TX_SCHED == 0 */ - -static inline adf_nbuf_t -ol_tx_hl_base( - ol_txrx_vdev_handle vdev, - enum ol_tx_spec tx_spec, - adf_nbuf_t msdu_list) -{ - struct ol_txrx_pdev_t *pdev = vdev->pdev; - adf_nbuf_t msdu = msdu_list; - struct ol_txrx_msdu_info_t tx_msdu_info; - htt_pdev_handle htt_pdev = pdev->htt_pdev; - tx_msdu_info.peer = NULL; - - /* - * The msdu_list variable could be used instead of the msdu var, - * but just to clarify which operations are done on a single MSDU - * vs. a list of MSDUs, use a distinct variable for single MSDUs - * within the list. - */ - while (msdu) { - adf_nbuf_t next; - struct ol_tx_frms_queue_t *txq; - struct ol_tx_desc_t *tx_desc; - if (adf_os_atomic_read(&vdev->pdev->target_tx_credit) <= 0) { - return msdu; - } - next = adf_nbuf_next(msdu); - - tx_desc = ol_tx_desc_hl(pdev, vdev, msdu, &tx_msdu_info); - if (! tx_desc) { - /* - * If we're out of tx descs, there's no need to try to allocate - * tx descs for the remaining MSDUs. - */ - TXRX_STATS_MSDU_LIST_INCR(pdev, tx.dropped.host_reject, msdu); - return msdu; /* the list of unaccepted MSDUs */ - } - OL_TXRX_PROT_AN_LOG(pdev->prot_an_tx_sent, msdu); - - if (tx_spec != ol_tx_spec_std) { - if (tx_spec & ol_tx_spec_no_free) { - tx_desc->pkt_type = ol_tx_frm_no_free; - } else if (tx_spec & ol_tx_spec_tso) { - tx_desc->pkt_type = ol_tx_frm_tso; - } - if (OL_TXRX_TX_IS_RAW(tx_spec)) { - // CHECK THIS: does this need to happen after htt_tx_desc_init? - /* different types of raw frames */ - u_int8_t sub_type = OL_TXRX_TX_RAW_SUBTYPE(tx_spec); - htt_tx_desc_type( - htt_pdev, tx_desc->htt_tx_desc, - htt_pkt_type_raw, sub_type); - } - } - - tx_msdu_info.htt.info.ext_tid = adf_nbuf_get_tid(msdu); - tx_msdu_info.htt.info.vdev_id = vdev->vdev_id; - tx_msdu_info.htt.info.frame_type = htt_frm_type_data; - tx_msdu_info.htt.info.l2_hdr_type = pdev->htt_pkt_type; - txq = ol_tx_classify(vdev, tx_desc, msdu, &tx_msdu_info); - if (!txq) { - adf_os_atomic_inc(&pdev->tx_queue.rsrc_cnt); - //TXRX_STATS_MSDU_LIST_INCR(vdev->pdev, tx.dropped.no_txq, msdu); - ol_tx_desc_free(vdev->pdev, tx_desc); - if (tx_msdu_info.peer) { - /* remove the peer reference added above */ - ol_txrx_peer_unref_delete(tx_msdu_info.peer); - } - return msdu; /* the list of unaccepted MSDUs */ - } - - /* Before authentication, we'll drop packets except eapol/wai frame only */ - if (tx_msdu_info.peer && tx_msdu_info.peer->state != ol_txrx_peer_state_auth) - { - if (tx_msdu_info.htt.info.ethertype != ETHERTYPE_PAE && tx_msdu_info.htt.info.ethertype != ETHERTYPE_WAI) - { - adf_os_atomic_inc(&pdev->tx_queue.rsrc_cnt); - ol_tx_desc_free(vdev->pdev, tx_desc); - /* remove the peer reference added above */ - ol_txrx_peer_unref_delete(tx_msdu_info.peer); - return msdu; /* the list of unaccepted MSDUs */ - } - } - - /* initialize the HW tx descriptor */ - htt_tx_desc_init( - pdev->htt_pdev, tx_desc->htt_tx_desc, - ol_tx_desc_id(pdev, tx_desc), - msdu, - &tx_msdu_info.htt); - /* - * If debug display is enabled, show the meta-data being - * downloaded to the target via the HTT tx descriptor. - */ - htt_tx_desc_display(tx_desc->htt_tx_desc); - - ol_tx_send(pdev, tx_desc, msdu); -MSDU_LOOP_BOTTOM: - msdu = next; - } - return NULL; /* all MSDUs were accepted */ -} - -#endif - adf_nbuf_t ol_tx_hl(ol_txrx_vdev_handle vdev, adf_nbuf_t msdu_list) { diff --git a/CORE/CLD_TXRX/TXRX/ol_tx_desc.c b/CORE/CLD_TXRX/TXRX/ol_tx_desc.c index 0cfb13947df9..969dbc290293 100644 --- a/CORE/CLD_TXRX/TXRX/ol_tx_desc.c +++ b/CORE/CLD_TXRX/TXRX/ol_tx_desc.c @@ -58,7 +58,7 @@ OL_TX_TIMESTAMP_SET(struct ol_tx_desc_t *tx_desc) #endif static inline struct ol_tx_desc_t * -ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev) +ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) { struct ol_tx_desc_t *tx_desc = NULL; @@ -95,6 +95,10 @@ ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev) if (!tx_desc) { return NULL; } +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + tx_desc->vdev = vdev; + adf_os_atomic_inc(&vdev->tx_desc_count); +#endif OL_TX_TIMESTAMP_SET(tx_desc); @@ -102,11 +106,11 @@ ol_tx_desc_alloc(struct ol_txrx_pdev_t *pdev) } static inline struct ol_tx_desc_t * -ol_tx_desc_alloc_hl(struct ol_txrx_pdev_t *pdev) +ol_tx_desc_alloc_hl(struct ol_txrx_pdev_t *pdev, struct ol_txrx_vdev_t *vdev) { struct ol_tx_desc_t *tx_desc; - tx_desc = ol_tx_desc_alloc(pdev); + tx_desc = ol_tx_desc_alloc(pdev, vdev); if (!tx_desc) return NULL; @@ -135,6 +139,10 @@ ol_tx_desc_free(struct ol_txrx_pdev_t *pdev, struct ol_tx_desc_t *tx_desc) ((union ol_tx_desc_list_elem_t *) tx_desc)->next = pdev->tx_desc.freelist; pdev->tx_desc.freelist = (union ol_tx_desc_list_elem_t *) tx_desc; pdev->tx_desc.num_free++; +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + adf_os_atomic_dec(&tx_desc->vdev->tx_desc_count); + tx_desc->vdev = NULL; +#endif adf_os_spin_unlock_bh(&pdev->tx_mutex); } @@ -167,7 +175,7 @@ ol_tx_desc_ll( } /* allocate the descriptor */ - tx_desc = ol_tx_desc_alloc(pdev); + tx_desc = ol_tx_desc_alloc(pdev, vdev); if (!tx_desc) return NULL; /* initialize the SW tx descriptor */ @@ -233,7 +241,7 @@ ol_tx_desc_hl( } /* allocate the descriptor */ - tx_desc = ol_tx_desc_alloc_hl(pdev); + tx_desc = ol_tx_desc_alloc_hl(pdev, vdev); if (!tx_desc) return NULL; /* initialize the SW tx descriptor */ diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c index 655073fabce1..8acbf44bfbe2 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.c +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -68,19 +68,7 @@ #include <ol_tx_desc.h> /* ol_tx_desc_frame_free */ #include <ol_tx_queue.h> #include <ol_tx_sched.h> /* ol_tx_sched_attach, etc. */ - -/*=== local definitions ===*/ -#ifndef OL_TX_AVG_FRM_BYTES -#define OL_TX_AVG_FRM_BYTES 1000 -#endif - -#ifndef OL_TX_DESC_POOL_SIZE_MIN_HL -#define OL_TX_DESC_POOL_SIZE_MIN_HL 500 -#endif - -#ifndef OL_TX_DESC_POOL_SIZE_MAX_HL -#define OL_TX_DESC_POOL_SIZE_MAX_HL 5000 -#endif +#include <ol_txrx.h> /*=== function definitions ===*/ @@ -831,6 +819,9 @@ ol_txrx_vdev_attach( vdev->safemode = 0; vdev->drop_unenc = 1; vdev->num_filters = 0; +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + adf_os_atomic_init(&vdev->tx_desc_count); +#endif adf_os_mem_copy( &vdev->mac_addr.raw[0], vdev_mac_addr, OL_TXRX_MAC_ADDR_LEN); diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.h b/CORE/CLD_TXRX/TXRX/ol_txrx.h index 0f0b83123b9b..41ef6fa5eaee 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -38,4 +38,17 @@ ol_txrx_peer_unref_delete(struct ol_txrx_peer_t *peer); u_int16_t ol_tx_desc_pool_size_hl(ol_pdev_handle ctrl_pdev); + +#ifndef OL_TX_AVG_FRM_BYTES +#define OL_TX_AVG_FRM_BYTES 1000 +#endif + +#ifndef OL_TX_DESC_POOL_SIZE_MIN_HL +#define OL_TX_DESC_POOL_SIZE_MIN_HL 500 +#endif + +#ifndef OL_TX_DESC_POOL_SIZE_MAX_HL +#define OL_TX_DESC_POOL_SIZE_MAX_HL 5000 +#endif + #endif /* _OL_TXRX__H_ */ diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h index f430cb7facd9..cb4600369800 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h @@ -151,6 +151,9 @@ struct ol_tx_desc_t { /* used by tx encap, to restore the os buf start offset after tx complete*/ u_int8_t orig_l2_hdr_bytes; #endif +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + struct ol_txrx_vdev_t* vdev; +#endif }; typedef TAILQ_HEAD(, ol_tx_desc_t) ol_tx_desc_list; @@ -775,6 +778,9 @@ struct ol_txrx_vdev_t { union ol_txrx_align_mac_addr_t hl_tdls_ap_mac_addr; bool hlTdlsFlag; #endif +#if defined(CONFIG_PER_VDEV_TX_DESC_POOL) + adf_os_atomic_t tx_desc_count; +#endif }; struct ol_rx_reorder_array_elem_t { diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h index 12d60caea517..0fa0d91891d0 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg80211.h +++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h @@ -120,6 +120,7 @@ typedef struct { * qca_wlan_vendor_attr is open source file src/common/qca-vendor.h in * git://w1.fi/srv/git/hostap.git; the values here are just a copy of that */ + #define QCA_NL80211_VENDOR_ID 0x001374 enum qca_nl80211_vendor_subcmds { @@ -160,23 +161,57 @@ enum qca_nl80211_vendor_subcmds { QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE = 33, }; +enum qca_nl80211_vendor_subcmds_index { +#ifdef FEATURE_WLAN_CH_AVOID + QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX = 0, +#endif /* FEATURE_WLAN_CH_AVOID */ + +#ifdef WLAN_FEATURE_STATS_EXT + QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX, +#endif /* WLAN_FEATURE_STATS_EXT */ + +#ifdef FEATURE_WLAN_EXTSCAN + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX, + QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX, +#endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX, + QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX, +#endif +}; /* WLAN_FEATURE_LINK_LAYER_STATS */ + enum qca_wlan_vendor_attr { QCA_WLAN_VENDOR_ATTR_INVALID = 0, /* used by QCA_NL80211_VENDOR_SUBCMD_DFS_CAPABILITY */ - QCA_WLAN_VENDOR_ATTR_DFS = 1, + QCA_WLAN_VENDOR_ATTR_DFS = 1, /* used by QCA_NL80211_VENDOR_SUBCMD_NAN */ - QCA_WLAN_VENDOR_ATTR_NAN = 2, + QCA_WLAN_VENDOR_ATTR_NAN = 2, /* used by QCA_NL80211_VENDOR_SUBCMD_STATS_EXT */ - QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3, - - QCA_WLAN_VENDOR_ATTR_IFINDEX = 4, - + QCA_WLAN_VENDOR_ATTR_STATS_EXT = 3, + QCA_WLAN_VENDOR_ATTR_IFINDEX = 4, /* keep last */ QCA_WLAN_VENDOR_ATTR_AFTER_LAST, - QCA_WLAN_VENDOR_ATTR_MAX = QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1, + QCA_WLAN_VENDOR_ATTR_MAX = + QCA_WLAN_VENDOR_ATTR_AFTER_LAST - 1 }; - +#ifdef FEATURE_WLAN_EXTSCAN enum qca_wlan_vendor_attr_extscan_config_params { QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_INVALID = 0, @@ -413,32 +448,285 @@ enum qca_wlan_vendor_attr_extscan_results QCA_WLAN_VENDOR_ATTR_EXTSCAN_RESULTS_AFTER_LAST - 1, }; -enum qca_nl80211_vendor_subcmds_index { -#ifdef FEATURE_WLAN_CH_AVOID - QCA_NL80211_VENDOR_SUBCMD_AVOID_FREQUENCY_INDEX = 0, -#endif /* FEATURE_WLAN_CH_AVOID */ +#endif -#ifdef WLAN_FEATURE_STATS_EXT - QCA_NL80211_VENDOR_SUBCMD_STATS_EXT_INDEX, -#endif /* WLAN_FEATURE_STATS_EXT */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS -#ifdef FEATURE_WLAN_EXTSCAN - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_START_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_STOP_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CAPABILITIES_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_GET_CACHED_RESULTS_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_RESULTS_AVAILABLE_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_FULL_SCAN_RESULT_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SCAN_EVENT_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_FOUND_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_BSSID_HOTLIST_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_BSSID_HOTLIST_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SIGNIFICANT_CHANGE_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_SET_SIGNIFICANT_CHANGE_INDEX, - QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE_INDEX, -#endif /* FEATURE_WLAN_EXTSCAN */ +enum qca_wlan_vendor_attr_ll_stats_set +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD = 1, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_AFTER_LAST - 1 }; +enum qca_wlan_vendor_attr_ll_stats_get +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_INVALID = 0, + /* Unsigned 32bit value provided by the caller issuing the GET stats + * command. When reporting the stats results, the driver uses the same + * value to indicate which GET request the results correspond to. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID, + /* Unsigned 34bit value - bit mask to identify what + * statistics are requested for retrieval. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK, + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_ll_stats_clr +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_INVALID = 0, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_AFTER_LAST - 1 +}; + +enum qca_wlan_vendor_attr_ll_stats_results +{ + QCA_WLAN_VENDOR_ATTR_LL_STATS_INVALID = 0, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_REQ_ID = 1, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA, + /* Unsigned 32bit value */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK, + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_* are + * nested within the interface stats. + */ + + /* Interface mode, e.g., STA, SOFTAP, IBSS, etc. + * Type = enum wifi_interface_mode */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, + /* Interface MAC address. An array of 6 Unsigned int8 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR, + /* Type = enum wifi_connection_state, + * e.g., DISCONNECTED, AUTHENTICATING, etc. + * valid for STA, CLI only. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE, + /* Type = enum wifi_roam_state. Roaming state, + * e.g., IDLE or ACTIVE (is that valid for STA only?) + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING, + /* Unsigned 32bit value. WIFI_CAPABILITY_XXX */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES, + /* NULL terminated SSID. An array of 33 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID, + /* BSSID. An array of 6 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID, + /* Country string advertised by AP. An array of 3 Unsigned 8bit values */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR, + /* Country string for this association. An array of 3 Unsigned 8bit values*/ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_* could + * be nested within the interface stats. + */ + + /* Type = enum wifi_traffic_ac, e.g., V0, VI, BE and BK */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES, + /* Unsigned int 32 value corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG, + /* Unsigned int 32 values corresponding to respective AC */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES, + /* Unsigned 32bit value. Number of peers */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_* are + * nested within the interface stats. + */ + + /* Type = enum wifi_peer_type. Peer type, e.g., STA, AP, P2P GO etc. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE, + /* MAC addr corresponding to respective peer. + * An array of 6 Unsigned 8bit values. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS, + /* Unsigned int 32bit value representing capabilities + * corresponding to respective peer. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES, + /* Unsigned 32bit value. Number of rates */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES, + + /* Attributes nested within the rate stats.*/ + /* Unsigned 8bit value */ + /* Unsigned int 8bit value; 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE, + /* Unsigned int 8bit value; 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS, + /* Unsigned int 8bit value; 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW, + /* Unsigned int 8bit value; OFDM/CCK rate code would be as per IEEE Std + * in the units of 0.5mbps HT/VHT it would be mcs index */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX, + + /* Unsigned 32bit value. Bit rate in units of 100Kbps */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_* could be + * nested within the peer info stats. + */ + + /* Unsigned int 32bit value. Number of successfully transmitted data pkts, + * i.e., with ACK received *corresponding to the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU, + /* Unsigned int 32bit value. Number of received data pkts + * corresponding to the respective rate. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU, + /* Unsigned int 32bit value. Number of data pkts losses, i.e., + * no ACK received corresponding to *the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST, + /* Unsigned int 32bit value. Total number of data pkt retries for + * the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES, + /* Unsigned int 32bit value. Total number of short data pkt retries for + the respective rate. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT, + /* Unsigned int 32bit value. Total number of long data pkt retries for + * the respective rate. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID, + /* Unsigned 32bit value. Total number of msecs the radio is awake + * accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * transmitting accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * in active receive accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to all scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to NAN accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to GSCAN accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to roam scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to PNO scan accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN, + /* Unsigned 32bit value. Total number of msecs the radio is + * awake due to HS2.0 scans and GAS exchange accruing over time. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20, + /* Unsigned 32bit value. Number of channels. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_ + * could be nested within the channel stats. + */ + + /* Type = enum wifi_channel_width. Channel width, e.g., 20, 40, 80, etc.*/ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH, + /* Unsigned 32bit value. Primary 20MHz channel. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ, + /* Unsigned 32bit value. Center frequency (MHz) first segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0, + /* Unsigned 32bit value. Center frequency (MHz) second segment. */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1, + + /* Attributes of type QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ could be + * nested within the radio stats. + */ + + /* Unsigned int 32bit value representing total number of msecs the radio + * s awake on that *channel accruing over time, corresponding to + * the respective channel. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME, + /* Unsigned int 32bit value representing total number of msecs the + * CCA register is busy accruing *over time corresponding to the + * respective channel. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME, + + QCA_WLAN_VENDOR_ATTR_LL_STATS_NUM_RADIOS, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO, + + /* Unsigned 8bit value. Used by the driver; if set to 1, it indicates that + * more stats, e.g., peers or radio, are to follow in the next + * QCA_NL80211_VENDOR_SUBCMD_LL_STATS_*_RESULTS event. + * Otherwise, it is set to 0. + */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_RESULTS_MORE_DATA, + + /* keep last */ + QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST, + QCA_WLAN_VENDOR_ATTR_LL_STATS_MAX = + QCA_WLAN_VENDOR_ATTR_LL_STATS_AFTER_LAST -1 +}; + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + + #ifdef FEATURE_WLAN_CH_AVOID #define HDD_MAX_AVOID_FREQ_RANGES 4 typedef struct sHddAvoidFreqRange diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 7e2497686895..b4ca03f5a293 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1115,6 +1115,13 @@ struct hdd_adapter_s unsigned int tx_flow_high_watermark_offset; #endif /* QCA_LL_TX_FLOW_CT */ v_BOOL_t offloads_configured; + + /* DSCP to UP QoS Mapping */ + sme_QosWmmUpType hddWmmDscpToUpMap[WLAN_HDD_MAX_DSCP+1]; + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + v_BOOL_t isLinkLayerStatsSet; +#endif }; #define WLAN_HDD_GET_STATION_CTX_PTR(pAdapter) (&(pAdapter)->sessionCtx.station) @@ -1697,5 +1704,9 @@ void hdd_wlan_green_ap_mc(hdd_context_t *pHddCtx, void wlan_hdd_cfg80211_stats_ext_init(hdd_context_t *pHddCtx); #endif +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +void wlan_hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx); +#endif + void hdd_update_macaddr(hdd_config_t *cfg_ini, v_MACADDR_t hw_macaddr); #endif // end #if !defined( WLAN_HDD_MAIN_H ) diff --git a/CORE/HDD/inc/wlan_hdd_wmm.h b/CORE/HDD/inc/wlan_hdd_wmm.h index 5ac0cfdec566..4326d2f924ed 100644 --- a/CORE/HDD/inc/wlan_hdd_wmm.h +++ b/CORE/HDD/inc/wlan_hdd_wmm.h @@ -205,22 +205,19 @@ extern const v_U8_t hddWmmUpToAcMap[]; extern const v_U8_t hddLinuxUpToAcMap[]; #define WLAN_HDD_MAX_DSCP 0x3f -extern sme_QosWmmUpType hddWmmDscpToUpMapInfra[WLAN_HDD_MAX_DSCP+1]; -extern sme_QosWmmUpType hddWmmDscpToUpMapP2p[WLAN_HDD_MAX_DSCP+1]; /**============================================================================ @brief hdd_wmm_init() - Function which will initialize the WMM configuation and status to an initial state. The configuration can later be overwritten via application APIs - @param pHddCtx : [in] pointer to HDD context + @param pAdapter : [in] pointer to Adapter context @return : VOS_STATUS_SUCCESS if succssful : other values if failure ===========================================================================*/ -VOS_STATUS hdd_wmm_init ( hdd_context_t* pHddCtx, - sme_QosWmmUpType* hddWmmDscpToUpMap ); +VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter ); /**============================================================================ @brief hdd_wmm_adapter_init() - Function which will initialize the WMM configuation diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 4975e721851d..9959eb268796 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -911,9 +911,7 @@ static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo * } hdd_clearRoamProfileIe( pAdapter ); wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); - if (pAdapter->device_mode == WLAN_HDD_INFRA_STATION) { - hdd_wmm_init( pHddCtx, hddWmmDscpToUpMapInfra ); - } + hdd_wmm_init( pAdapter ); // indicate 'disconnect' status to wpa_supplicant... hdd_SendAssociationEvent(dev,pRoamInfo); @@ -1770,9 +1768,7 @@ static eHalStatus hdd_AssociationCompletionHandler( hdd_adapter_t *pAdapter, tCs /*Clear the roam profile*/ hdd_clearRoamProfileIe( pAdapter ); - if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) { - hdd_wmm_init( pHddCtx, hddWmmDscpToUpMapInfra ); - } + hdd_wmm_init( pAdapter ); netif_tx_disable(dev); netif_carrier_off(dev); diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index f86c1eda4db6..1f5251be753d 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -190,6 +190,17 @@ #define EXTSCAN_EVENT_BUF_SIZE 4096 #endif +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/* + * Used to allocate the size of 4096 for the link layer stats. + * The size of 4096 is considered assuming that all data per + * respective event fit with in the limit.Please take a call + * on the limit based on the data requirements on link layer + * statistics. + */ +#define LL_STATS_EVENT_BUF_SIZE 4096 +#endif + static const u32 hdd_cipher_suites[] = { WLAN_CIPHER_SUITE_WEP40, @@ -833,6 +844,33 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_RESET_SIGNIFICANT_CHANGE }, #endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_RADIO_RESULTS + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_IFACE_RESULTS + }, + [QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_PEERS_RESULTS + }, +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ }; int is_driver_dfs_capable(struct wiphy *wiphy, struct wireless_dev *wdev, @@ -1825,6 +1863,1242 @@ fail: } #endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +static bool put_wifi_rate_stat( tpSirWifiRateStat stats, + struct sk_buff *vendor_event) +{ + if (nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_PREAMBLE, + stats->rate.preamble) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_NSS, + stats->rate.nss) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BW, + stats->rate.bw) || + nla_put_u8(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MCS_INDEX, + stats->rate.rateMcsIdx) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_BIT_RATE, + stats->rate.bitrate ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_TX_MPDU, + stats->txMpdu ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RX_MPDU, + stats->rxMpdu ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_MPDU_LOST, + stats->mpduLost ) || + nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES, + stats->retries) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_SHORT, + stats->retriesShort ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RATE_RETRIES_LONG, + stats->retriesLong)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + return FALSE; + } + + return TRUE; +} + +static bool put_wifi_peer_info( tpSirWifiPeerInfo stats, + struct sk_buff *vendor_event) +{ + u32 i = 0; + tpSirWifiRateStat pRateStats; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_TYPE, + stats->type) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_MAC_ADDRESS, + VOS_MAC_ADDR_SIZE, &stats->peerMacAddress[0]) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_CAPABILITIES, + stats->capabilities) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_NUM_RATES, + stats->numRate)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + goto error; + } + + if (stats->numRate) + { + struct nlattr *rateInfo; + struct nlattr *rates; + + rateInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO_RATE_INFO); + for (i = 0; i < stats->numRate; i++) + { + pRateStats = (tpSirWifiRateStat )((uint8 *) + stats->rateStats + + (i * sizeof(tSirWifiRateStat))); + rates = nla_nest_start(vendor_event, i); + + if (FALSE == put_wifi_rate_stat(pRateStats, vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + return FALSE; + } + nla_nest_end(vendor_event, rates); + } + nla_nest_end(vendor_event, rateInfo); + } + + return TRUE; +error: + return FALSE; +} + +static bool put_wifi_wmm_ac_stat( tpSirWifiWmmAcStat stats, + struct sk_buff *vendor_event) +{ + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_AC, + stats->ac ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MPDU, + stats->txMpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MPDU, + stats->rxMpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_MCAST, + stats->txMcast ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_MCAST, + stats->rxMcast ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RX_AMPDU, + stats->rxAmpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_TX_AMPDU, + stats->txAmpdu ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_MPDU_LOST, + stats->mpduLost )|| + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES, + stats->retries ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_SHORT, + stats->retriesShort ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_RETRIES_LONG, + stats->retriesLong ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MIN, + stats->contentionTimeMin ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_MAX, + stats->contentionTimeMax ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_TIME_AVG, + stats->contentionTimeAvg ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_AC_CONTENTION_NUM_SAMPLES, + stats->contentionNumSamples )) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + } + + return TRUE; +} + +static bool put_wifi_interface_info(tpSirWifiInterfaceInfo stats, + struct sk_buff *vendor_event) +{ + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MODE, + stats->mode ) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_MAC_ADDR, + VOS_MAC_ADDR_SIZE, stats->macAddr) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_STATE, + stats->state ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_ROAMING, + stats->roaming ) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_CAPABILITIES, + stats->capabilities ) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_SSID, + strlen(stats->ssid), stats->ssid) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_BSSID, + VOS_MAC_ADDR_SIZE, stats->bssid) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_AP_COUNTRY_STR, + WNI_CFG_COUNTRY_CODE_LEN, stats->apCountryStr) || + nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_INFO_COUNTRY_STR, + WNI_CFG_COUNTRY_CODE_LEN, stats->countryStr)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + } + + return TRUE; +} + +static bool put_wifi_iface_stats(tpSirWifiIfaceStat pWifiIfaceStat, + struct sk_buff *vendor_event) +{ + int i = 0; + struct nlattr *wmmInfo; + struct nlattr *wmmStats; + + if (FALSE == put_wifi_interface_info( + &pWifiIfaceStat->info, + vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail") ); + return FALSE; + + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_BEACON_RX, + pWifiIfaceStat->beaconRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_RX, + pWifiIfaceStat->mgmtRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_RX, + pWifiIfaceStat->mgmtActionRx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_MGMT_ACTION_TX, + pWifiIfaceStat->mgmtActionTx) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_MGMT, + pWifiIfaceStat->rssiMgmt) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_DATA, + pWifiIfaceStat->rssiData) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_RSSI_ACK, + pWifiIfaceStat->rssiAck)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + return FALSE; + } + + wmmInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_WMM_INFO); + for (i = 0; i < WIFI_AC_MAX; i++) + { + wmmStats = nla_nest_start(vendor_event, i); + if (FALSE == put_wifi_wmm_ac_stat( + &pWifiIfaceStat->AccessclassStats[i], + vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("put_wifi_wmm_ac_stat Fail")); + return FALSE; + } + + nla_nest_end(vendor_event, wmmStats); + } + nla_nest_end(vendor_event, wmmInfo); + return TRUE; +} + +static tSirWifiInterfaceMode +hdd_map_device_to_ll_iface_mode ( int deviceMode ) +{ + switch (deviceMode) + { + case WLAN_HDD_INFRA_STATION: + return WIFI_INTERFACE_STA; + case WLAN_HDD_SOFTAP: + return WIFI_INTERFACE_SOFTAP; + case WLAN_HDD_P2P_CLIENT: + return WIFI_INTERFACE_P2P_CLIENT; + case WLAN_HDD_P2P_GO: + return WIFI_INTERFACE_P2P_GO; + case WLAN_HDD_IBSS: + return WIFI_INTERFACE_IBSS; + default: + /* Return Interface Mode as STA for all the unsupported modes */ + return WIFI_INTERFACE_STA; + } +} + +static bool hdd_get_interface_info(hdd_adapter_t *pAdapter, + tpSirWifiInterfaceInfo pInfo) +{ + v_U8_t *staMac = NULL; + hdd_station_ctx_t *pHddStaCtx; + tHalHandle hHal = WLAN_HDD_GET_HAL_CTX(pAdapter); + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + + pInfo->mode = hdd_map_device_to_ll_iface_mode(pAdapter->device_mode); + + vos_mem_copy(pInfo->macAddr, + pAdapter->macAddressCurrent.bytes, sizeof(v_MACADDR_t)); + + if (((WLAN_HDD_INFRA_STATION == pAdapter->device_mode) || + (WLAN_HDD_P2P_CLIENT == pAdapter->device_mode) || + (WLAN_HDD_P2P_DEVICE == pAdapter->device_mode))) + { + pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); + if (eConnectionState_NotConnected == pHddStaCtx->conn_info.connState) + { + pInfo->state = WIFI_DISCONNECTED; + } + if (eConnectionState_Connecting == pHddStaCtx->conn_info.connState) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: Session ID %d, Connection is in progress", __func__, + pAdapter->sessionId); + pInfo->state = WIFI_ASSOCIATING; + } + if ((eConnectionState_Associated == pHddStaCtx->conn_info.connState) && + (VOS_FALSE == pHddStaCtx->conn_info.uIsAuthenticated)) + { + staMac = (v_U8_t *) &(pAdapter->macAddressCurrent.bytes[0]); + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: client " MAC_ADDRESS_STR + " is in the middle of WPS/EAPOL exchange.", __func__, + MAC_ADDR_ARRAY(staMac)); + pInfo->state = WIFI_AUTHENTICATING; + } + if (eConnectionState_Associated == pHddStaCtx->conn_info.connState) + { + pInfo->state = WIFI_ASSOCIATED; + vos_mem_copy(pInfo->bssid, + &pHddStaCtx->conn_info.bssId, VOS_MAC_ADDR_SIZE); + vos_mem_copy(pInfo->ssid, + pHddStaCtx->conn_info.SSID.SSID.ssId, + pHddStaCtx->conn_info.SSID.SSID.length); + /* + * NULL Terminate the string + */ + pInfo->ssid[pHddStaCtx->conn_info.SSID.SSID.length] = 0; + } + } + + vos_mem_copy(pInfo->countryStr, + pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); + + vos_mem_copy(pInfo->apCountryStr, + pMac->scan.countryCodeCurrent, WNI_CFG_COUNTRY_CODE_LEN); + + return TRUE; +} + +/* + * hdd_link_layer_process_peer_stats () - This function is called after + * receiving Link Layer Peer statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static void hdd_link_layer_process_peer_stats(hdd_adapter_t *pAdapter, + tpSirWifiPeerStat pData) +{ + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + tpSirWifiRateStat pWifiRateStat; + tpSirWifiPeerStat pWifiPeerStat; + tpSirWifiPeerInfo pWifiPeerInfo; + struct sk_buff *vendor_event; + int status, i, j; + struct nlattr *peers; + int numRate; + + pWifiPeerStat = pData; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_PEER_ALL : numPeers %u", + pWifiPeerStat->numPeers); + { + for (i = 0; i < pWifiPeerStat->numPeers; i++) + { + pWifiPeerInfo = (tpSirWifiPeerInfo) + ((uint8 *)pWifiPeerStat->peerInfo + + ( i * sizeof(tSirWifiPeerInfo))); + + hddLog(VOS_TRACE_LEVEL_INFO, + " %d) LL_STATS Channel Stats " + " Peer Type %u " + " peerMacAddress %pM " + " capabilities 0x%x " + " numRate %u ", + i, + pWifiPeerInfo->type, + pWifiPeerInfo->peerMacAddress, + pWifiPeerInfo->capabilities, + pWifiPeerInfo->numRate); + { + for (j = 0; j < pWifiPeerInfo->numRate; j++) + { + pWifiRateStat = (tpSirWifiRateStat) + ((tANI_U8 *) pWifiPeerInfo->rateStats + + ( j * sizeof(tSirWifiRateStat))); + + hddLog(VOS_TRACE_LEVEL_INFO, + " peer Rate Stats " + " preamble %u " + " nss %u " + " bw %u " + " rateMcsIdx %u " + " reserved %u " + " bitrate %u " + " txMpdu %u " + " rxMpdu %u " + " mpduLost %u " + " retries %u " + " retriesShort %u " + " retriesLong %u", + pWifiRateStat->rate.preamble, + pWifiRateStat->rate.nss, + pWifiRateStat->rate.bw, + pWifiRateStat->rate.rateMcsIdx, + pWifiRateStat->rate.reserved, + pWifiRateStat->rate.bitrate, + pWifiRateStat->txMpdu, + pWifiRateStat->rxMpdu, + pWifiRateStat->mpduLost, + pWifiRateStat->retries, + pWifiRateStat->retriesShort, + pWifiRateStat->retriesLong); + } + } + } + } + + /* + * Allocate a size of 4096 for the peer stats comprising + * each of size = sizeof (tSirWifiPeerInfo) + numRate * + * sizeof (tSirWifiRateStat).Each field is put with an + * NL attribute.The size of 4096 is considered assuming + * that number of rates shall not exceed beyond 50 with + * the sizeof (tSirWifiRateStat) being 32. + */ + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE + + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_LL_PEER_INFO_STATS_INDEX, + GFP_KERNEL); + + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: cfg80211_vendor_event_alloc failed", + __func__); + return; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_IFACE_NUM_PEERS, + pWifiPeerStat->numPeers)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + "%s: QCA_WLAN_VENDOR_ATTR put fail", __func__); + + kfree_skb(vendor_event); + return; + } + + pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *) + pWifiPeerStat->peerInfo); + + if (pWifiPeerStat->numPeers) + { + struct nlattr *peerInfo; + peerInfo = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_PEER_INFO); + + for (i = 1; i <= pWifiPeerStat->numPeers; i++) + { + peers = nla_nest_start(vendor_event, i); + numRate = pWifiPeerInfo->numRate; + + if (FALSE == put_wifi_peer_info( + pWifiPeerInfo, vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("put_wifi_peer_info fail")); + kfree_skb(vendor_event); + return; + } + + pWifiPeerInfo = (tpSirWifiPeerInfo) ((uint8 *) + pWifiPeerStat->peerInfo + + (i * sizeof(tSirWifiPeerInfo)) + + (numRate * sizeof (tSirWifiRateStat))); + nla_nest_end(vendor_event, peers); + } + nla_nest_end(vendor_event, peerInfo); + } + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + return; +} + +/* + * hdd_link_layer_process_iface_stats () - This function is called after + * receiving Link Layer Interface statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static void hdd_link_layer_process_iface_stats(hdd_adapter_t *pAdapter, + tpSirWifiIfaceStat pData) +{ + tpSirWifiIfaceStat pWifiIfaceStat; + struct sk_buff *vendor_event; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + int status; + int i; + + pWifiIfaceStat = pData; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid") ); + return; + } + + /* + * Allocate a size of 4096 for the interface stats comprising + * sizeof (tpSirWifiIfaceStat).The size of 4096 is considered + * assuming that all these fit with in the limit.Please take + * a call on the limit based on the data requirements on + * interface statistics. + */ + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE + + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_LL_IFACE_STATS_INDEX, + GFP_KERNEL); + + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed") ); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, "WMI_LINK_STATS_IFACE Data"); + + if (FALSE == hdd_get_interface_info(pAdapter, + &pWifiIfaceStat->info)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("hdd_get_interface_info get fail")); + kfree_skb(vendor_event); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_IFACE: " + " Mode %u " + " MAC %pM " + " State %u " + " Roaming %u " + " capabilities 0x%x " + " SSID %s " + " BSSID %pM", + pWifiIfaceStat->info.mode, + pWifiIfaceStat->info.macAddr, + pWifiIfaceStat->info.state, + pWifiIfaceStat->info.roaming, + pWifiIfaceStat->info.capabilities, + pWifiIfaceStat->info.ssid, + pWifiIfaceStat->info.bssid); + + hddLog(VOS_TRACE_LEVEL_INFO, + " AP country str: %c%c%c", + pWifiIfaceStat->info.apCountryStr[0], + pWifiIfaceStat->info.apCountryStr[1], + pWifiIfaceStat->info.apCountryStr[2]); + + hddLog(VOS_TRACE_LEVEL_INFO, + " Country Str Association: %c%c%c", + pWifiIfaceStat->info.countryStr[0], + pWifiIfaceStat->info.countryStr[1], + pWifiIfaceStat->info.countryStr[2]); + + hddLog(VOS_TRACE_LEVEL_INFO, + " beaconRx %u " + " mgmtRx %u " + " mgmtActionRx %u " + " mgmtActionTx %u " + " rssiMgmt %u " + " rssiData %u " + " rssiAck %u", + pWifiIfaceStat->beaconRx, + pWifiIfaceStat->mgmtRx, + pWifiIfaceStat->mgmtActionRx, + pWifiIfaceStat->mgmtActionTx, + pWifiIfaceStat->rssiMgmt, + pWifiIfaceStat->rssiData, + pWifiIfaceStat->rssiAck ); + + for (i = 0; i < WIFI_AC_MAX; i++) + { + hddLog(VOS_TRACE_LEVEL_INFO, + + " %d) LL_STATS IFACE: " + " ac: %u txMpdu: %u " + " rxMpdu: %u txMcast: %u " + " rxMcast: %u rxAmpdu: %u " + " txAmpdu: %u mpduLost: %u " + " retries: %u retriesShort: %u " + " retriesLong: %u contentionTimeMin: %u " + " contentionTimeMax: %u contentionTimeAvg: %u " + " contentionNumSamples: %u", + i, + pWifiIfaceStat->AccessclassStats[i].ac, + pWifiIfaceStat->AccessclassStats[i].txMpdu, + pWifiIfaceStat->AccessclassStats[i].rxMpdu, + pWifiIfaceStat->AccessclassStats[i].txMcast, + pWifiIfaceStat->AccessclassStats[i].rxMcast, + pWifiIfaceStat->AccessclassStats[i].rxAmpdu, + pWifiIfaceStat->AccessclassStats[i].txAmpdu, + pWifiIfaceStat->AccessclassStats[i].mpduLost, + pWifiIfaceStat->AccessclassStats[i].retries, + pWifiIfaceStat->AccessclassStats[i].retriesShort, + pWifiIfaceStat->AccessclassStats[i].retriesLong, + pWifiIfaceStat->AccessclassStats[i].contentionTimeMin, + pWifiIfaceStat->AccessclassStats[i].contentionTimeMax, + pWifiIfaceStat->AccessclassStats[i].contentionTimeAvg, + pWifiIfaceStat->AccessclassStats[i].contentionNumSamples); + } + + if (FALSE == put_wifi_iface_stats( pWifiIfaceStat, + vendor_event)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("put_wifi_iface_stats fail")); + kfree_skb(vendor_event); + return; + } + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + return; +} + +/* + * hdd_link_layer_process_radio_stats () - This function is called after + * receiving Link Layer Radio statistics from FW.This function converts + * the firmware data to the NL data and sends the same to the kernel/upper + * layers. + */ +static void hdd_link_layer_process_radio_stats(hdd_adapter_t *pAdapter, + tpSirWifiRadioStat pData) +{ + int status, i; + tpSirWifiRadioStat pWifiRadioStat; + tpSirWifiChannelStats pWifiChannelStats; + struct sk_buff *vendor_event; + hdd_context_t *pHddCtx = WLAN_HDD_GET_CTX(pAdapter); + + pWifiRadioStat = pData; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid") ); + return; + } + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_RADIO" + " radio is %d onTime is %u " + " txTime is %u rxTime is %u " + " onTimeScan is %u onTimeNbd is %u " + " onTimeGscan is %u onTimeRoamScan is %u " + " onTimePnoScan is %u onTimeHs20 is %u " + " numChannels is %u", + pWifiRadioStat->radio, + pWifiRadioStat->onTime, + pWifiRadioStat->txTime, + pWifiRadioStat->rxTime, + pWifiRadioStat->onTimeScan, + pWifiRadioStat->onTimeNbd, + pWifiRadioStat->onTimeGscan, + pWifiRadioStat->onTimeRoamScan, + pWifiRadioStat->onTimePnoScan, + pWifiRadioStat->onTimeHs20, + pWifiRadioStat->numChannels); + + /* + * Allocate a size of 4096 for the Radio stats comprising + * sizeof (tSirWifiRadioStat) + numChannels * sizeof + * (tSirWifiChannelStats).Each channel data is put with an + * NL attribute.The size of 4096 is considered assuming that + * number of channels shall not exceed beyond 60 with the + * sizeof (tSirWifiChannelStats) being 24 bytes. + */ + + vendor_event = cfg80211_vendor_event_alloc(pHddCtx->wiphy, + LL_STATS_EVENT_BUF_SIZE + NLMSG_HDRLEN, + QCA_NL80211_VENDOR_SUBCMD_LL_RADIO_STATS_INDEX, + GFP_KERNEL); + + if (!vendor_event) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("cfg80211_vendor_event_alloc failed")); + return; + } + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ID, + pWifiRadioStat->radio) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME, + pWifiRadioStat->onTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_TX_TIME, + pWifiRadioStat->txTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_RX_TIME, + pWifiRadioStat->rxTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_SCAN, + pWifiRadioStat->onTimeScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_NBD, + pWifiRadioStat->onTimeNbd) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_GSCAN, + pWifiRadioStat->onTimeGscan)|| + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_ROAM_SCAN, + pWifiRadioStat->onTimeRoamScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_PNO_SCAN, + pWifiRadioStat->onTimePnoScan) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_ON_TIME_HS20, + pWifiRadioStat->onTimeHs20) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_RADIO_NUM_CHANNELS, + pWifiRadioStat->numChannels)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("QCA_WLAN_VENDOR_ATTR put fail")); + + kfree_skb(vendor_event); + return ; + } + + if (pWifiRadioStat->numChannels) + { + struct nlattr *chList; + struct nlattr *chInfo; + + chList = nla_nest_start(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CH_INFO); + for (i = 0; i < pWifiRadioStat->numChannels; i++) + { + pWifiChannelStats = (tpSirWifiChannelStats) ((uint8*) + pWifiRadioStat->channels + + (i * sizeof(tSirWifiChannelStats))); + + hddLog(VOS_TRACE_LEVEL_INFO, + " %d) Channel Info" + " width is %u " + " CenterFreq %u " + " CenterFreq0 %u " + " CenterFreq1 %u " + " onTime %u " + " ccaBusyTime %u", + i, + pWifiChannelStats->channel.width, + pWifiChannelStats->channel.centerFreq, + pWifiChannelStats->channel.centerFreq0, + pWifiChannelStats->channel.centerFreq1, + pWifiChannelStats->onTime, + pWifiChannelStats->ccaBusyTime); + + chInfo = nla_nest_start(vendor_event, i); + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_WIDTH, + pWifiChannelStats->channel.width) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ, + pWifiChannelStats->channel.centerFreq) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ0, + pWifiChannelStats->channel.centerFreq0) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_INFO_CENTER_FREQ1, + pWifiChannelStats->channel.centerFreq1) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_ON_TIME, + pWifiChannelStats->onTime) || + nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CHANNEL_CCA_BUSY_TIME, + pWifiChannelStats->ccaBusyTime)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("nla_put failed")); + kfree_skb(vendor_event); + return ; + } + nla_nest_end(vendor_event, chInfo); + } + nla_nest_end(vendor_event, chList); + } + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + return; +} + +/* + * wlan_hdd_cfg80211_link_layer_stats_callback () - This function is called + * after receiving Link Layer indications from FW.This callback converts the + * firmware data to the NL data and send the same to the kernel/upper layers. + */ +static void wlan_hdd_cfg80211_link_layer_stats_callback(void *ctx, + int indType, + void *pRsp) +{ + hdd_context_t *pHddCtx = (hdd_context_t *)ctx; + hdd_adapter_t *pAdapter = NULL; + tpSirLLStatsResults linkLayerStatsResults = (tpSirLLStatsResults)pRsp; + int status; + + status = wlan_hdd_validate_context(pHddCtx); + + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return; + } + + pAdapter = hdd_get_adapter_by_vdev(pHddCtx, + linkLayerStatsResults->ifaceId); + + if (NULL == pAdapter) + { + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR, + "%s: vdev_id %d does not exist with host", + __func__, linkLayerStatsResults->ifaceId); + return; + } + + VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO, + "%s: Link Layer Indication indType: %d", __func__, indType); + + switch (indType) + { + case SIR_HAL_LL_STATS_RESULTS_RSP: + { + hddLog(VOS_TRACE_LEVEL_INFO, + FL("RESPONSE SIR_HAL_LL_STATS_RESULTS_RSP")); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE paramID = 0x%x", + linkLayerStatsResults->paramId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE ifaceId = %u", + linkLayerStatsResults->ifaceId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE respId = %u", + linkLayerStatsResults->rspId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE moreResultToFollow = %u", + linkLayerStatsResults->moreResultToFollow); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS RESULTS RESPONSE result = %p", + linkLayerStatsResults->results); + + if (linkLayerStatsResults->paramId & WMI_LINK_STATS_RADIO ) + { + hdd_link_layer_process_radio_stats(pAdapter, + (tpSirWifiRadioStat) + linkLayerStatsResults->results); + } + else if (linkLayerStatsResults->paramId & WMI_LINK_STATS_IFACE ) + { + hdd_link_layer_process_iface_stats(pAdapter, + (tpSirWifiIfaceStat) + linkLayerStatsResults->results); + } + else if (linkLayerStatsResults->paramId & WMI_LINK_STATS_ALL_PEER ) + { + hdd_link_layer_process_peer_stats(pAdapter, + (tpSirWifiPeerStat) + linkLayerStatsResults->results); + } + else + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("INVALID LL_STATS_NOTIFY RESPONSE ***********")); + } + + break; + } + default: + hddLog(VOS_TRACE_LEVEL_ERROR, "invalid event type %d", indType); + break; + } + + return; +} + + +void wlan_hdd_cfg80211_link_layer_stats_init(hdd_context_t *pHddCtx) +{ + sme_SetLinkLayerStatsIndCB(pHddCtx->hHal, + wlan_hdd_cfg80211_link_layer_stats_callback); +} + + +const struct +nla_policy +qca_wlan_vendor_ll_set_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD] = + { .type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING] = + { .type = NLA_U32 }, +}; + +static int wlan_hdd_cfg80211_ll_stats_set(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, + int data_len) +{ + int status; + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX + 1]; + tSirLLStatsSetReq LinkLayerStatsSetReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD adapter is Null")); + return -ENODEV; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_set_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("maximum attribute not present")); + return -EINVAL; + } + + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("MPDU size Not present")); + return -EINVAL; + } + + if (!tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Stats Gathering Not Present")); + return -EINVAL; + } + + /* Shall take the request Id if the Upper layers pass. 1 For now.*/ + LinkLayerStatsSetReq.reqId = 1; + + LinkLayerStatsSetReq.mpduSizeThreshold = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_MPDU_SIZE_THRESHOLD]); + + LinkLayerStatsSetReq.aggressiveStatisticsGathering = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_SET_CONFIG_AGGRESSIVE_STATS_GATHERING]); + + LinkLayerStatsSetReq.staId = pAdapter->sessionId; + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET reqId = %d", + LinkLayerStatsSetReq.reqId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET staId = %d", LinkLayerStatsSetReq.staId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET mpduSizeThreshold = %d", + LinkLayerStatsSetReq.mpduSizeThreshold); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_SET aggressive Statistics Gathering = %d", + LinkLayerStatsSetReq.aggressiveStatisticsGathering); + + + if (eHAL_STATUS_SUCCESS != sme_LLStatsSetReq(pHddCtx->hHal, + &LinkLayerStatsSetReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "sme_LLStatsSetReq Failed", __func__); + return -EINVAL; + } + + pAdapter->isLinkLayerStatsSet = 1; + + return 0; +} + +const struct +nla_policy +qca_wlan_vendor_ll_get_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX +1] = +{ + /* Unsigned 32bit value provided by the caller issuing the GET stats + * command. When reporting + * the stats results, the driver uses the same value to indicate + * which GET request the results + * correspond to. + */ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID] = { .type = NLA_U32 }, + + /* Unsigned 32bit value . bit mask to identify what statistics are + requested for retrieval */ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK] = { .type = NLA_U32 } +}; + +static int wlan_hdd_cfg80211_ll_stats_get(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, + int data_len) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX + 1]; + tSirLLStatsGetReq LinkLayerStatsGetReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + int status; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL ; + } + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + if (!pAdapter->isLinkLayerStatsSet) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: isLinkLayerStatsSet : %d", + __func__, pAdapter->isLinkLayerStatsSet); + return -EINVAL; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_get_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("max attribute not present")); + return -EINVAL; + } + + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Request Id Not present")); + return -EINVAL; + } + + if (!tb_vendor + [QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Req Mask Not present")); + return -EINVAL; + } + + LinkLayerStatsGetReq.reqId = + nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_ID]); + LinkLayerStatsGetReq.paramIdMask = + nla_get_u32(tb_vendor[ + QCA_WLAN_VENDOR_ATTR_LL_STATS_GET_CONFIG_REQ_MASK]); + + LinkLayerStatsGetReq.staId = pAdapter->sessionId; + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_GET reqId = %d", LinkLayerStatsGetReq.reqId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_GET staId = %d", LinkLayerStatsGetReq.staId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_GET paramIdMask = %d", + LinkLayerStatsGetReq.paramIdMask); + + if (eHAL_STATUS_SUCCESS != sme_LLStatsGetReq(pHddCtx->hHal, + &LinkLayerStatsGetReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, "%s:" + "sme_LLStatsGetReq Failed", __func__); + return -EINVAL; + } + + return 0; +} + +const struct +nla_policy +qca_wlan_vendor_ll_clr_policy[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX +1] = +{ + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ] = {.type = NLA_U8 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK] = {.type = NLA_U32 }, + [QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP] = {.type = NLA_U8 }, +}; + +static int wlan_hdd_cfg80211_ll_stats_clear(struct wiphy *wiphy, + struct wireless_dev *wdev, + void *data, + int data_len) +{ + hdd_context_t *pHddCtx = wiphy_priv(wiphy); + struct nlattr *tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX + 1]; + tSirLLStatsClearReq LinkLayerStatsClearReq; + struct net_device *dev = wdev->netdev; + hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(dev); + u32 statsClearReqMask; + u8 stopReq; + int status; + struct sk_buff *temp_skbuff; + + status = wlan_hdd_validate_context(pHddCtx); + if (0 != status) + { + hddLog(VOS_TRACE_LEVEL_ERROR, + FL("HDD context is not valid")); + return -EINVAL; + } + + if (NULL == pAdapter) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: HDD adapter is Null", __func__); + return -ENODEV; + } + + if (!pAdapter->isLinkLayerStatsSet) + { + hddLog(VOS_TRACE_LEVEL_FATAL, + "%s: isLinkLayerStatsSet : %d", + __func__, pAdapter->isLinkLayerStatsSet); + return -EINVAL; + } + + if (nla_parse(tb_vendor, QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_MAX, + (struct nlattr *)data, + data_len, qca_wlan_vendor_ll_clr_policy)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("STATS_CLR_MAX is not present")); + return -EINVAL; + } + + if (!tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK] || + !tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("Error in LL_STATS CLR CONFIG PARA")); + return -EINVAL; + } + + statsClearReqMask = LinkLayerStatsClearReq.statsClearReqMask = + nla_get_u32( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_REQ_MASK]); + + stopReq = LinkLayerStatsClearReq.stopReq = + nla_get_u8( + tb_vendor[QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_REQ]); + + /* + * Shall take the request Id if the Upper layers pass. 1 For now. + */ + LinkLayerStatsClearReq.reqId = 1; + + LinkLayerStatsClearReq.staId = pAdapter->sessionId; + + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR reqId = %d", LinkLayerStatsClearReq.reqId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR staId = %d", LinkLayerStatsClearReq.staId); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR statsClearReqMask = 0x%X", + LinkLayerStatsClearReq.statsClearReqMask); + hddLog(VOS_TRACE_LEVEL_INFO, + "LL_STATS_CLEAR stopReq = %d", + LinkLayerStatsClearReq.stopReq); + + if (eHAL_STATUS_SUCCESS == sme_LLStatsClearReq(pHddCtx->hHal, + &LinkLayerStatsClearReq)) + { + temp_skbuff = cfg80211_vendor_cmd_alloc_reply_skb(wiphy, + 2 * sizeof(u32) + + 2 * NLMSG_HDRLEN); + if (temp_skbuff != NULL) + { + if (nla_put_u32(temp_skbuff, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_RSP_MASK, + statsClearReqMask) || + nla_put_u32(temp_skbuff, + QCA_WLAN_VENDOR_ATTR_LL_STATS_CLR_CONFIG_STOP_RSP, + stopReq)) + { + hddLog(VOS_TRACE_LEVEL_ERROR, FL("LL_STATS_CLR put fail")); + kfree_skb(temp_skbuff); + return -EINVAL; + } + + /* If the ask is to stop the stats collection as part of clear + * (stopReq = 1) , ensure that no further requests of get + * go to the firmware by having isLinkLayerStatsSet set to 0. + * However it the stopReq as part of the clear request is 0 , + * the request to get the statistics are honoured as in this + * case the firmware is just asked to clear the statistics. + */ + if (stopReq == 1) + pAdapter->isLinkLayerStatsSet = 0; + + return cfg80211_vendor_cmd_reply(temp_skbuff); + } + return -ENOMEM; + } + + return -EINVAL; +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = { { @@ -1919,6 +3193,35 @@ const struct wiphy_vendor_command hdd_wiphy_vendor_commands[] = .doit = wlan_hdd_cfg80211_extscan_reset_significant_change }, #endif /* FEATURE_WLAN_EXTSCAN */ + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_CLR, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_ll_stats_clear + }, + + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_SET, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_ll_stats_set + }, + + { + .info.vendor_id = QCA_NL80211_VENDOR_ID, + .info.subcmd = QCA_NL80211_VENDOR_SUBCMD_LL_STATS_GET, + .flags = WIPHY_VENDOR_CMD_NEED_WDEV | + WIPHY_VENDOR_CMD_NEED_NETDEV | + WIPHY_VENDOR_CMD_NEED_RUNNING, + .doit = wlan_hdd_cfg80211_ll_stats_get + } +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ }; @@ -2784,6 +4087,7 @@ static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter, v_U8_t total_ielen = 0; int ret = 0; tsap_Config_t *pConfig; + tSirUpdateIE updateIE; pConfig = &pHostapdAdapter->sessionCtx.ap.sapConfig; @@ -2825,89 +4129,68 @@ static int wlan_hdd_cfg80211_update_apies(hdd_adapter_t* pHostapdAdapter, wlan_hdd_add_hostapd_conf_vsie(pHostapdAdapter, genie, &total_ielen); } - if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, - WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie, total_ielen, NULL, - eANI_BOOLEAN_FALSE)==eHAL_STATUS_FAILURE) - { - hddLog(LOGE, - "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM"); - ret = -EINVAL; - goto done; - } - if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, - WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL, - test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ? - eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE) - ==eHAL_STATUS_FAILURE) - { - hddLog(LOGE, - "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM"); - ret = -EINVAL; - goto done; - } + vos_mem_copy(updateIE.bssid, pHostapdAdapter->macAddressCurrent.bytes, + sizeof(tSirMacAddr)); + updateIE.smeSessionId = pHostapdAdapter->sessionId; - // Added for ProResp IE - if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) - { + if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) { + updateIE.ieBufferlength = total_ielen; + updateIE.pAdditionIEBuffer = genie; + updateIE.append = VOS_FALSE; + updateIE.notify = VOS_TRUE; if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), - pHostapdAdapter->sessionId, - pHostapdAdapter->macAddressCurrent.bytes, - (tANI_U8*)params->proberesp_ies, - params->proberesp_ies_len, - VOS_FALSE) == eHAL_STATUS_FAILURE) - { - hddLog(LOGE, FL("Could not pass on Probe Resp Add Ie")); + &updateIE, eUPDATE_IE_PROBE_BCN) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on Add Ie probe beacon data")); ret = -EINVAL; goto done; } - WLANSAP_ResetSapConfigAddIE(pConfig); - } - else - { + WLANSAP_ResetSapConfigAddIE(pConfig , eUPDATE_IE_PROBE_BCN); + } else { WLANSAP_UpdateSapConfigAddIE(pConfig, - params->proberesp_ies, - params->proberesp_ies_len); + genie, + total_ielen, + eUPDATE_IE_PROBE_BCN); } - // Added for AssocResp IE - if ( (params->assocresp_ies != NULL) && (params->assocresp_ies_len != 0) ) - { - if (ccmCfgSetStr((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, - WNI_CFG_ASSOC_RSP_ADDNIE_DATA, (tANI_U8*)params->assocresp_ies, - params->assocresp_ies_len, NULL, - eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) - { - hddLog(LOGE, - "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_DATA to CCM"); + + /* Added for Probe Response IE */ + if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) { + updateIE.ieBufferlength = params->proberesp_ies_len; + updateIE.pAdditionIEBuffer = (tANI_U8*)params->proberesp_ies; + updateIE.append = VOS_FALSE; + updateIE.notify = VOS_FALSE; + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), + &updateIE, eUPDATE_IE_PROBE_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on PROBE_RESP add Ie data")); ret = -EINVAL; goto done; - } - - if (ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, - WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 1, NULL, - test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags) ? - eANI_BOOLEAN_TRUE : eANI_BOOLEAN_FALSE) - == eHAL_STATUS_FAILURE) - { - hddLog(LOGE, - "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM"); - ret = -EINVAL; - goto done; - } + } + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_PROBE_RESP); + } else { + WLANSAP_UpdateSapConfigAddIE(pConfig, + params->proberesp_ies, + params->proberesp_ies_len, + eUPDATE_IE_PROBE_RESP); } - else - { - hddLog(VOS_TRACE_LEVEL_INFO, - "%s: No Assoc Response IE received in set beacon", - __func__); - if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pHostapdAdapter))->hHal, - WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL, - eANI_BOOLEAN_FALSE) ) - { - hddLog(LOGE, - "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM"); + /* Assoc resp Add ie Data */ + if (test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) { + updateIE.ieBufferlength = params->assocresp_ies_len; + updateIE.pAdditionIEBuffer = (tANI_U8*)params->assocresp_ies; + updateIE.append = VOS_FALSE; + updateIE.notify = VOS_FALSE; + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), + &updateIE, eUPDATE_IE_ASSOC_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on Add Ie Assoc Response data")); + ret = -EINVAL; + goto done; } + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ASSOC_RESP); + } else { + WLANSAP_UpdateSapConfigAddIE(pConfig, + params->assocresp_ies, + params->assocresp_ies_len, + eUPDATE_IE_ASSOC_RESP); } done: @@ -3655,7 +4938,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, if ( 0 != wlan_hdd_cfg80211_update_apies(pHostapdAdapter, params) ) { hddLog(LOGE, FL("SAP Not able to set AP IEs")); - WLANSAP_ResetSapConfigAddIE(pConfig); + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL); return -EINVAL; } @@ -3688,7 +4971,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, if(test_bit(SOFTAP_BSS_STARTED, &pHostapdAdapter->event_flags)) { - WLANSAP_ResetSapConfigAddIE(pConfig); + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL); //Bss already started. just return. //TODO Probably it should update some beacon params. hddLog( LOGE, "Bss Already started...Ignore the request"); @@ -3746,7 +5029,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, pSapEventCallback, pConfig, (v_PVOID_t)pHostapdAdapter->dev); if (!VOS_IS_STATUS_SUCCESS(status)) { - WLANSAP_ResetSapConfigAddIE(pConfig); + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL); hddLog(LOGE,FL("SAP Start Bss fail")); return -EINVAL; } @@ -3756,7 +5039,7 @@ static int wlan_hdd_cfg80211_start_bss(hdd_adapter_t *pHostapdAdapter, status = vos_wait_single_event(&pHostapdState->vosEvent, 10000); - WLANSAP_ResetSapConfigAddIE(pConfig); + WLANSAP_ResetSapConfigAddIE(pConfig, eUPDATE_IE_ALL); if (!VOS_IS_STATUS_SUCCESS(status)) { @@ -3941,6 +5224,7 @@ static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy, hdd_scaninfo_t *pScanInfo = NULL; hdd_adapter_t *staAdapter = NULL; VOS_STATUS status; + tSirUpdateIE updateIE; ENTER(); @@ -4055,20 +5339,21 @@ static int wlan_hdd_cfg80211_stop_ap (struct wiphy *wiphy, return -EINVAL; } - if (ccmCfgSetInt(pHddCtx->hHal, - WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 0,NULL, eANI_BOOLEAN_FALSE) - ==eHAL_STATUS_FAILURE) - { - hddLog(LOGE, - "Could not pass on WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM"); + vos_mem_copy(updateIE.bssid, pAdapter->macAddressCurrent.bytes, + sizeof(tSirMacAddr)); + updateIE.smeSessionId = pAdapter->sessionId; + updateIE.ieBufferlength = 0; + updateIE.pAdditionIEBuffer = NULL; + updateIE.append = VOS_TRUE; + updateIE.notify = VOS_TRUE; + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + &updateIE, eUPDATE_IE_PROBE_BCN) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE")); } - if ( eHAL_STATUS_FAILURE == ccmCfgSetInt(pHddCtx->hHal, - WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL, - eANI_BOOLEAN_FALSE) ) - { - hddLog(LOGE, - "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM"); + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + &updateIE, eUPDATE_IE_ASSOC_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE")); } // Reset WNI_CFG_PROBE_RSP Flags @@ -7803,53 +9088,6 @@ int wlan_hdd_cfg80211_set_ie( hdd_adapter_t *pAdapter, pWextState->roamProfile.pAddIEAssoc = pWextState->assocAddIE.addIEdata; pWextState->roamProfile.nAddIEAssocLength = pWextState->assocAddIE.length; } - - if (WLAN_HDD_IBSS == pAdapter->device_mode) { - - /* populating as ADDIE in beacon frames */ - if (ccmCfgSetStr(WLAN_HDD_GET_HAL_CTX(pAdapter), - WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, genie - 2, eLen + 2, - NULL, eANI_BOOLEAN_FALSE)== eHAL_STATUS_SUCCESS) - { - if (ccmCfgSetInt(WLAN_HDD_GET_HAL_CTX(pAdapter), - WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, 1,NULL, - eANI_BOOLEAN_FALSE) == eHAL_STATUS_FAILURE) - { - hddLog(LOGE, - "Coldn't pass " - "WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG to CCM"); - } - }/* ccmCfgSetStr(,WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, , )*/ - else - hddLog(LOGE, - "Could not pass on " - "WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA to CCM"); - - /* IBSS mode doesn't contain params->proberesp_ies still - beaconIE's need to be populated in probe response frames */ - if ( (NULL != (genie - 2)) && (0 != eLen + 2) ) - { - u16 rem_probe_resp_ie_len = eLen + 2; - if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), - pAdapter->sessionId, - pAdapter->macAddressCurrent.bytes, - (tANI_U8*)(genie - 2), - rem_probe_resp_ie_len, - VOS_TRUE) == eHAL_STATUS_FAILURE) - { - hddLog(LOGE, "Could not pass ADDNIE data to PE"); - } - } - else - { - // Reset WNI_CFG_PROBE_RSP Flags - wlan_hdd_reset_prob_rspies(pAdapter); - - hddLog(VOS_TRACE_LEVEL_INFO, - "%s: No Probe Response IE received in set beacon", - __func__); - } - } /* end of if (WLAN_HDD_IBSS == pAdapter->device_mode) */ break; case DOT11F_EID_RSN: hddLog (VOS_TRACE_LEVEL_INFO, "%s Set RSN IE(len %d)",__func__, eLen + 2); diff --git a/CORE/HDD/src/wlan_hdd_early_suspend.c b/CORE/HDD/src/wlan_hdd_early_suspend.c index 8bea82469918..c60e782d89e2 100644 --- a/CORE/HDD/src/wlan_hdd_early_suspend.c +++ b/CORE/HDD/src/wlan_hdd_early_suspend.c @@ -1812,6 +1812,7 @@ VOS_STATUS hdd_wlan_shutdown(void) vos_set_logp_in_progress(VOS_MODULE_ID_VOSS, TRUE); #endif + vos_clear_concurrent_session_count(); //Stop the traffic monitor timer if ( VOS_TIMER_STATE_RUNNING == vos_timer_getCurrentState(&pHddCtx->tx_rx_trafficTmr)) @@ -2137,15 +2138,6 @@ VOS_STATUS hdd_wlan_re_init(void *hif_sc) goto err_vosclose; } - /* Initialize the WMM module */ - vosStatus = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra); - vosStatus = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p); - if ( !VOS_IS_STATUS_SUCCESS( vosStatus )) - { - hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__); - goto err_vosclose; - } - vosStatus = vos_preStart( pHddCtx->pvosContext ); if ( !VOS_IS_STATUS_SUCCESS( vosStatus ) ) { diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 73f3d6036761..4358626497d8 100755 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -7748,6 +7748,7 @@ static hdd_adapter_t* hdd_alloc_station_adapter( hdd_context_t *pHddCtx, tSirMac pAdapter->wdev.netdev = pWlanDev; /* set pWlanDev's parent to underlying device */ SET_NETDEV_DEV(pWlanDev, pHddCtx->parent_dev); + hdd_wmm_init( pAdapter ); } return pAdapter; @@ -8849,6 +8850,7 @@ VOS_STATUS hdd_close_all_adapters( hdd_context_t *pHddCtx ) void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter) { tANI_U8 *bssid = NULL; + tSirUpdateIE updateIE; switch (pHostapdAdapter->device_mode) { case WLAN_HDD_INFRA_STATION: @@ -8878,14 +8880,16 @@ void wlan_hdd_reset_prob_rspies(hdd_adapter_t* pHostapdAdapter) pHostapdAdapter->device_mode); return; } + + vos_mem_copy(updateIE.bssid, bssid, sizeof(tSirMacAddr)); + updateIE.smeSessionId = pHostapdAdapter->sessionId; + updateIE.ieBufferlength = 0; + updateIE.pAdditionIEBuffer = NULL; + updateIE.append = VOS_TRUE; + updateIE.notify = VOS_FALSE; if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pHostapdAdapter), - pHostapdAdapter->sessionId, - bssid, - NULL, - 0, - VOS_TRUE) == eHAL_STATUS_FAILURE) - { - hddLog(LOGE, "Could not pass on Additional IE data to PE"); + &updateIE, eUPDATE_IE_PROBE_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE")); } } @@ -8895,6 +8899,7 @@ VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, eHalStatus halStatus = eHAL_STATUS_SUCCESS; hdd_wext_state_t *pWextState = WLAN_HDD_GET_WEXT_STATE_PTR(pAdapter); union iwreq_data wrqu; + tSirUpdateIE updateIE ; long ret; ENTER(); @@ -9053,21 +9058,23 @@ VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, clear_bit(SOFTAP_BSS_STARTED, &pAdapter->event_flags); wlan_hdd_decr_active_session(pHddCtx, pAdapter->device_mode); - if (eHAL_STATUS_FAILURE == - ccmCfgSetInt(pHddCtx->hHal, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, - 0, NULL, eANI_BOOLEAN_FALSE)) - { - hddLog(LOGE, - "%s: Failed to set WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG", - __func__); + vos_mem_copy(updateIE.bssid, pAdapter->macAddressCurrent.bytes, + sizeof(tSirMacAddr)); + updateIE.smeSessionId = pAdapter->sessionId; + updateIE.ieBufferlength = 0; + updateIE.pAdditionIEBuffer = NULL; + updateIE.append = VOS_FALSE; + updateIE.notify = VOS_FALSE; + /* Probe bcn reset */ + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + &updateIE, eUPDATE_IE_PROBE_BCN) + == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on PROBE_RSP_BCN data to PE")); } - - if ( eHAL_STATUS_FAILURE == ccmCfgSetInt((WLAN_HDD_GET_CTX(pAdapter))->hHal, - WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, 0, NULL, - eANI_BOOLEAN_FALSE) ) - { - hddLog(LOGE, - "Could not pass on WNI_CFG_ASSOC_RSP_ADDNIE_FLAG to CCM"); + /* Assoc resp reset */ + if (sme_UpdateAddIE(WLAN_HDD_GET_HAL_CTX(pAdapter), + &updateIE, eUPDATE_IE_ASSOC_RESP) == eHAL_STATUS_FAILURE) { + hddLog(LOGE, FL("Could not pass on ASSOC_RSP data to PE")); } // Reset WNI_CFG_PROBE_RSP Flags @@ -9215,6 +9222,8 @@ VOS_STATUS hdd_start_all_adapters( hdd_context_t *pHddCtx ) { pAdapter = pAdapterNode->pAdapter; + hdd_wmm_init( pAdapter ); + switch(pAdapter->device_mode) { case WLAN_HDD_INFRA_STATION: @@ -11483,15 +11492,6 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) goto err_wiphy_unregister; } - //Initialize the WMM module - status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapInfra); - status = hdd_wmm_init(pHddCtx, hddWmmDscpToUpMapP2p); - if (!VOS_IS_STATUS_SUCCESS(status)) - { - hddLog(VOS_TRACE_LEVEL_FATAL, "%s: hdd_wmm_init failed", __func__); - goto err_wiphy_unregister; - } - /* In the integrated architecture we update the configuration from the INI file and from NV before vOSS has been started so that the final contents are available to send down to the cCPU */ @@ -12040,6 +12040,9 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) sme_ExtScanRegisterCallback(pHddCtx->hHal, wlan_hdd_cfg80211_extscan_callback); #endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + wlan_hdd_cfg80211_link_layer_stats_init(pHddCtx); +#endif #ifdef WLAN_FEATURE_LPSS wlan_hdd_send_status_pkg(pAdapter, NULL, 1, 0); diff --git a/CORE/HDD/src/wlan_hdd_p2p.c b/CORE/HDD/src/wlan_hdd_p2p.c index 6a556257a130..89bd130f7f7c 100644 --- a/CORE/HDD/src/wlan_hdd_p2p.c +++ b/CORE/HDD/src/wlan_hdd_p2p.c @@ -2103,7 +2103,8 @@ void hdd_indicateMgmtFrame( hdd_adapter_t *pAdapter, if((pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET] == WLAN_HDD_QOS_ACTION_FRAME)&& (pbFrames[WLAN_HDD_PUBLIC_ACTION_FRAME_OFFSET+1] == WLAN_HDD_QOS_MAP_CONFIGURE) ) { - sme_UpdateDSCPtoUPMapping(pHddCtx->hHal, hddWmmDscpToUpMapInfra); + sme_UpdateDSCPtoUPMapping(pHddCtx->hHal, + pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId); } } diff --git a/CORE/HDD/src/wlan_hdd_wmm.c b/CORE/HDD/src/wlan_hdd_wmm.c index cb177fc1df42..9ca53a7d3aa5 100644 --- a/CORE/HDD/src/wlan_hdd_wmm.c +++ b/CORE/HDD/src/wlan_hdd_wmm.c @@ -89,8 +89,6 @@ #define DHCP_DESTINATION_PORT 0x4300 #define HDD_WMM_UP_TO_AC_MAP_SIZE 8 -sme_QosWmmUpType hddWmmDscpToUpMapInfra[WLAN_HDD_MAX_DSCP+1]; -sme_QosWmmUpType hddWmmDscpToUpMapP2p[WLAN_HDD_MAX_DSCP+1]; const v_U8_t hddWmmUpToAcMap[] = { WLANTL_AC_BE, @@ -1524,15 +1522,15 @@ static void hdd_wmm_do_implicit_qos(struct work_struct *work) and status to an initial state. The configuration can later be overwritten via application APIs - @param pHddCtx : [in] pointer to HDD context + @param pAdapter : [in] pointer to Adapter context - @return : VOS_STATUS_SUCCESS if succssful + @return : VOS_STATUS_SUCCESS if successful : other values if failure ===========================================================================*/ -VOS_STATUS hdd_wmm_init ( hdd_context_t* pHddCtx, - sme_QosWmmUpType* hddWmmDscpToUpMap ) +VOS_STATUS hdd_wmm_init ( hdd_adapter_t *pAdapter ) { + sme_QosWmmUpType* hddWmmDscpToUpMap = pAdapter->hddWmmDscpToUpMap; v_U8_t dscp; VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, @@ -1801,10 +1799,8 @@ v_VOID_t hdd_wmm_classify_pkt ( hdd_adapter_t* pAdapter, } dscp = (tos>>2) & 0x3f; - if (WLAN_HDD_INFRA_STATION == pAdapter->device_mode) - userPri = hddWmmDscpToUpMapInfra[dscp]; - else - userPri = hddWmmDscpToUpMapP2p[dscp]; + userPri = pAdapter->hddWmmDscpToUpMap[dscp]; + #ifdef HDD_WMM_DEBUG VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO, "%s: tos is %d, dscp is %d, up is %d", @@ -2265,9 +2261,13 @@ VOS_STATUS hdd_wmm_assoc( hdd_adapter_t* pAdapter, VOS_ASSERT( VOS_IS_STATUS_SUCCESS( status )); } - status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal, hddWmmDscpToUpMapInfra); - if (!VOS_IS_STATUS_SUCCESS( status )) { - hdd_wmm_init( pHddCtx, hddWmmDscpToUpMapInfra ); + + status = sme_UpdateDSCPtoUPMapping(pHddCtx->hHal, + pAdapter->hddWmmDscpToUpMap, pAdapter->sessionId); + + if (!VOS_IS_STATUS_SUCCESS( status )) + { + hdd_wmm_init( pAdapter ); } VOS_TRACE(VOS_MODULE_ID_HDD, WMM_TRACE_LEVEL_INFO_LOW, diff --git a/CORE/MAC/inc/aniGlobal.h b/CORE/MAC/inc/aniGlobal.h index 9f7ef0d1b8f3..84efd06b375b 100644 --- a/CORE/MAC/inc/aniGlobal.h +++ b/CORE/MAC/inc/aniGlobal.h @@ -1140,7 +1140,6 @@ typedef struct sAniSirGlobal v_BOOL_t enable5gEBT; /* Miracast session 0-Disabled, 1-Source, 2-sink*/ tANI_U8 fMiracastSessionPresent; - tSirQosMapSet QosMapSet; } tAniSirGlobal; typedef enum diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 52ec31865545..d56f4610d571 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 0 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 139 +#define QWLAN_VERSION_BUILD 140 -#define QWLAN_VERSIONSTR "1.0.0.139" +#define QWLAN_VERSIONSTR "1.0.0.140" #ifdef QCA_WIFI_2_0 diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index b67303051461..fd697239a678 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -649,8 +649,12 @@ typedef __ani_attr_pre_packed struct sSirHtConfig } __ani_attr_packed tSirHTConfig, *tpSirHTConfig; typedef __ani_attr_pre_packed struct sSirAddIeParams{ - tANI_U16 dataLen; - tANI_U8 *data_buff; + tANI_U16 probeRespDataLen; + tANI_U8 *probeRespData_buff; + tANI_U16 assocRespDataLen; + tANI_U8 *assocRespData_buff; + tANI_U16 probeRespBCNDataLen; + tANI_U8 *probeRespBCNData_buff; } tSirAddIeParams, *tpSirAddIeParams; /// Definition for kick starting BSS @@ -4957,18 +4961,65 @@ typedef struct sSirStartBeaconIndication tANI_U8 bssid[VOS_MAC_ADDR_SIZE]; }tSirStartBeaconIndication, *tpSirStartBeaconIndication; +/* additional IE type */ +typedef enum tUpdateIEsType +{ + eUPDATE_IE_NONE, + eUPDATE_IE_PROBE_BCN, + eUPDATE_IE_PROBE_RESP, + eUPDATE_IE_ASSOC_RESP, + + /* Add type above this line*/ + /* this is used to reset all buffer */ + eUPDATE_IE_ALL, + eUPDATE_IE_MAX +} eUpdateIEsType; + + +/* Modify particular IE in addition IE for prob resp Bcn */ +typedef struct sSirModifyIE +{ + tSirMacAddr bssid; + tANI_U16 smeSessionId; + boolean notify; + tANI_U8 ieID; + tANI_U8 ieIDLen; /*ie length as per spec*/ + tANI_U16 ieBufferlength; + tANI_U8 *pIEBuffer; + +}tSirModifyIE, *tpSirModifyIE; + /* Message format for Update IE message sent to PE */ -typedef struct sUpdateAIEs +typedef struct sSirModifyIEsInd { - tANI_U16 msgType; - tANI_U16 msgLen; - tSirMacAddr bssid; - tANI_U16 smeSessionId; - tANI_U8 *pAdditionIEBuffer; - tANI_U16 length; - boolean append; -}tUpdateAIEs, *tpUpdateAIEs; + tANI_U16 msgType; + tANI_U16 msgLen; + tSirModifyIE modifyIE; + eUpdateIEsType updateType; +}tSirModifyIEsInd, *tpSirModifyIEsInd; + + +/* Message format for Update IE message sent to PE */ +typedef struct sSirUpdateIE +{ + tSirMacAddr bssid; + tANI_U16 smeSessionId; + boolean append; + boolean notify; + tANI_U16 ieBufferlength; + tANI_U8 *pAdditionIEBuffer; +}tSirUpdateIE, *tpSirUpdateIE; + + +/* Message format for Update IE message sent to PE */ +typedef struct sSirUpdateIEsInd +{ + tANI_U16 msgType; + tANI_U16 msgLen; + tSirUpdateIE updateIE; + eUpdateIEsType updateType; +}tSirUpdateIEsInd, *tpSirUpdateIEsInd; /* Message format for requesting channel switch announcement to lower layers */ typedef struct sSirDfsCsaIeRequest @@ -5374,4 +5425,383 @@ typedef struct #endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 mpduSizeThreshold; + tANI_U32 aggressiveStatisticsGathering; +} tSirLLStatsSetReq, *tpSirLLStatsSetReq; + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 paramIdMask; +} tSirLLStatsGetReq, *tpSirLLStatsGetReq; + +typedef struct +{ + tANI_U32 reqId; + tANI_U8 staId; + tANI_U32 statsClearReqMask; + tANI_U8 stopReq; +} tSirLLStatsClearReq, *tpSirLLStatsClearReq; + +/*--------------------------------------------------------------------------- + WLAN_HAL_LL_NOTIFY_STATS +---------------------------------------------------------------------------*/ + + +/******************************LINK LAYER Statistics**********************/ + +typedef int tSirWifiRadio; +typedef int tSirWifiChannel; +typedef int tSirwifiTxRate; + +/* channel operating width */ +typedef enum +{ + WIFI_CHAN_WIDTH_20 = 0, + WIFI_CHAN_WIDTH_40 = 1, + WIFI_CHAN_WIDTH_80 = 2, + WIFI_CHAN_WIDTH_160 = 3, + WIFI_CHAN_WIDTH_80P80 = 4, + WIFI_CHAN_WIDTH_5 = 5, + WIFI_CHAN_WIDTH_10 = 6, +} tSirWifiChannelWidth; + +typedef enum +{ + WIFI_DISCONNECTED = 0, + WIFI_AUTHENTICATING = 1, + WIFI_ASSOCIATING = 2, + WIFI_ASSOCIATED = 3, + WIFI_EAPOL_STARTED = 4, /* if done by firmware/driver */ + WIFI_EAPOL_COMPLETED = 5, /* if done by firmware/driver */ +} tSirWifiConnectionState; + +typedef enum +{ + WIFI_ROAMING_IDLE = 0, + WIFI_ROAMING_ACTIVE = 1, +} tSirWifiRoamState; + +typedef enum +{ + WIFI_INTERFACE_STA = 0, + WIFI_INTERFACE_SOFTAP = 1, + WIFI_INTERFACE_IBSS = 2, + WIFI_INTERFACE_P2P_CLIENT = 3, + WIFI_INTERFACE_P2P_GO = 4, + WIFI_INTERFACE_NAN = 5, + WIFI_INTERFACE_MESH = 6, + } tSirWifiInterfaceMode; + +/* set for QOS association */ +#define WIFI_CAPABILITY_QOS 0x00000001 +/* set for protected association (802.11 beacon frame control protected bit set) */ +#define WIFI_CAPABILITY_PROTECTED 0x00000002 +/* set if 802.11 Extended Capabilities element interworking bit is set */ +#define WIFI_CAPABILITY_INTERWORKING 0x00000004 +/* set for HS20 association */ +#define WIFI_CAPABILITY_HS20 0x00000008 +/* set is 802.11 Extended Capabilities element UTF-8 SSID bit is set */ +#define WIFI_CAPABILITY_SSID_UTF8 0x00000010 +/* set is 802.11 Country Element is present */ +#define WIFI_CAPABILITY_COUNTRY 0x00000020 + +typedef struct +{ + /* tSirWifiInterfaceMode */ + /* interface mode */ + tANI_U8 mode; + /* interface mac address (self) */ + tSirMacAddr macAddr; + /* tSirWifiConnectionState */ + /* connection state (valid for STA, CLI only) */ + tANI_U8 state; + /* tSirWifiRoamState */ + /* roaming state */ + tANI_U32 roaming; + /* WIFI_CAPABILITY_XXX (self) */ + tANI_U32 capabilities; + /* null terminated SSID */ + tANI_U8 ssid[33]; + /* bssid */ + tSirMacAddr bssid; + /* country string advertised by AP */ + tANI_U8 apCountryStr[WNI_CFG_COUNTRY_CODE_LEN]; + /* country string for this association */ + tANI_U8 countryStr[WNI_CFG_COUNTRY_CODE_LEN]; +} tSirWifiInterfaceInfo, *tpSirWifiInterfaceInfo; + +/* channel information */ +typedef struct +{ + /* channel width (20, 40, 80, 80+80, 160) */ + tSirWifiChannelWidth width; + /* primary 20 MHz channel */ + tSirWifiChannel centerFreq; + /* center frequency (MHz) first segment */ + tSirWifiChannel centerFreq0; + /* center frequency (MHz) second segment */ + tSirWifiChannel centerFreq1; +} tSirWifiChannelInfo, *tpSirWifiChannelInfo; + +/* wifi rate info */ +typedef struct +{ + /* 0: OFDM, 1:CCK, 2:HT 3:VHT 4..7 reserved */ + tANI_U32 preamble :3; + /* 0:1x1, 1:2x2, 3:3x3, 4:4x4 */ + tANI_U32 nss :2; + /* 0:20MHz, 1:40Mhz, 2:80Mhz, 3:160Mhz */ + tANI_U32 bw :3; + /* OFDM/CCK rate code would be as per ieee std in the units of 0.5mbps */ + /* HT/VHT it would be mcs index */ + tANI_U32 rateMcsIdx :8; + /* reserved */ + tANI_U32 reserved :16; + /* units of 100 Kbps */ + tANI_U32 bitrate; +} tSirWifiRate, *tpSirWifiRate; + +/* channel statistics */ +typedef struct +{ + /* channel */ + tSirWifiChannelInfo channel; + /* msecs the radio is awake (32 bits number accruing over time) */ + tANI_U32 onTime; + /* msecs the CCA register is busy (32 bits number accruing over time) */ + tANI_U32 ccaBusyTime; +} tSirWifiChannelStats, *tpSirWifiChannelStats; + +/* radio statistics */ +typedef struct +{ + /* wifi radio (if multiple radio supported) */ + tSirWifiRadio radio; + /* msecs the radio is awake (32 bits number accruing over time) */ + tANI_U32 onTime; + /* msecs the radio is transmitting + * (32 bits number accruing over time) + */ + tANI_U32 txTime; + /* msecs the radio is in active receive + *(32 bits number accruing over time) + */ + tANI_U32 rxTime; + /* msecs the radio is awake due to all scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeScan; + /* msecs the radio is awake due to NAN + * (32 bits number accruing over time) + */ + tANI_U32 onTimeNbd; + /* msecs the radio is awake due to Gscan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeGscan; + /* msecs the radio is awake due to roam?scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimeRoamScan; + /* msecs the radio is awake due to PNO scan + * (32 bits number accruing over time) + */ + tANI_U32 onTimePnoScan; + /* msecs the radio is awake due to HS2.0 scans and GAS exchange + * (32 bits number accruing over time) + */ + tANI_U32 onTimeHs20; + /* number of channels */ + tANI_U32 numChannels; + /* channel statistics tSirWifiChannelStats */ + tSirWifiChannelStats channels[0]; +} tSirWifiRadioStat, *tpSirWifiRadioStat; + +/* per rate statistics */ +typedef struct +{ + /* rate information */ + tSirWifiRate rate; + /* number of successfully transmitted data pkts (ACK rcvd) */ + tANI_U32 txMpdu; + /* number of received data pkts */ + tANI_U32 rxMpdu; + /* number of data packet losses (no ACK) */ + tANI_U32 mpduLost; + /* total number of data pkt retries * */ + tANI_U32 retries; + /* number of short data pkt retries */ + tANI_U32 retriesShort; + /* number of long data pkt retries */ + tANI_U32 retriesLong; +} tSirWifiRateStat, *tpSirWifiRateStat; + +/* access categories */ +typedef enum +{ + WIFI_AC_VO = 0, + WIFI_AC_VI = 1, + WIFI_AC_BE = 2, + WIFI_AC_BK = 3, + WIFI_AC_MAX = 4, +} tSirWifiTrafficAc; + +/* wifi peer type */ +typedef enum +{ + WIFI_PEER_STA, + WIFI_PEER_AP, + WIFI_PEER_P2P_GO, + WIFI_PEER_P2P_CLIENT, + WIFI_PEER_NAN, + WIFI_PEER_TDLS, + WIFI_PEER_INVALID, +} tSirWifiPeerType; + +/* per peer statistics */ +typedef struct +{ + /* peer type (AP, TDLS, GO etc.) */ + tSirWifiPeerType type; + /* mac address */ + tSirMacAddr peerMacAddress; + /* peer WIFI_CAPABILITY_XXX */ + tANI_U32 capabilities; + /* number of rates */ + tANI_U32 numRate; + /* per rate statistics, number of entries = num_rate */ + tSirWifiRateStat rateStats[0]; +} tSirWifiPeerInfo, *tpSirWifiPeerInfo; + +/* per access category statistics */ +typedef struct +{ + /* tSirWifiTrafficAc */ + /* access category (VI, VO, BE, BK) */ + tANI_U32 ac; + /* number of successfully transmitted unicast data pkts (ACK rcvd) */ + tANI_U32 txMpdu; + /* number of received unicast mpdus */ + tANI_U32 rxMpdu; + /* number of succesfully transmitted multicast data packets */ + /* STA case: implies ACK received from AP for the unicast */ + /* packet in which mcast pkt was sent */ + tANI_U32 txMcast; + /* number of received multicast data packets */ + tANI_U32 rxMcast; + /* number of received unicast a-mpdus */ + tANI_U32 rxAmpdu; + /* number of transmitted unicast a-mpdus */ + tANI_U32 txAmpdu; + /* number of data pkt losses (no ACK) */ + tANI_U32 mpduLost; + /* total number of data pkt retries */ + tANI_U32 retries; + /* number of short data pkt retries */ + tANI_U32 retriesShort; + /* number of long data pkt retries */ + tANI_U32 retriesLong; + /* data pkt min contention time (usecs) */ + tANI_U32 contentionTimeMin; + /* data pkt max contention time (usecs) */ + tANI_U32 contentionTimeMax; + /* data pkt avg contention time (usecs) */ + tANI_U32 contentionTimeAvg; + /* num of data pkts used for contention statistics */ + tANI_U32 contentionNumSamples; +} tSirWifiWmmAcStat, *tpSirWifiWmmAcStat; + +/* Interface statistics - corresponding to 2nd most + * LSB in wifi statistics bitmap for getting statistics + */ +typedef struct +{ + /* current state of the interface */ + tSirWifiInterfaceInfo info; + /* access point beacon received count from connected AP */ + tANI_U32 beaconRx; + /* access point mgmt frames received count from */ + /* connected AP (including Beacon) */ + tANI_U32 mgmtRx; + /* action frames received count */ + tANI_U32 mgmtActionRx; + /* action frames transmit count */ + tANI_U32 mgmtActionTx; + /* access Point Beacon and Management frames RSSI (averaged) */ + tANI_U32 rssiMgmt; + /* access Point Data Frames RSSI (averaged) from connected AP */ + tANI_U32 rssiData; + /* access Point ACK RSSI (averaged) from connected AP */ + tANI_U32 rssiAck; + /* per ac data packet statistics */ + tSirWifiWmmAcStat AccessclassStats[WIFI_AC_MAX]; +} tSirWifiIfaceStat, *tpSirWifiIfaceStat; + +/* Peer statistics - corresponding to 3rd most LSB in + * wifi statistics bitmap for getting statistics + */ +typedef struct +{ + /* number of peers */ + tANI_U32 numPeers; + /* per peer statistics */ + tSirWifiPeerInfo peerInfo[0]; +} tSirWifiPeerStat, *tpSirWifiPeerStat; + +/* wifi statistics bitmap for getting statistics */ +#define WMI_LINK_STATS_RADIO 0x00000001 +#define WMI_LINK_STATS_IFACE 0x00000002 +#define WMI_LINK_STATS_ALL_PEER 0x00000004 +#define WMI_LINK_STATS_PER_PEER 0x00000008 + +/* wifi statistics bitmap for clearing statistics */ +/* all radio statistics */ +#define WIFI_STATS_RADIO 0x00000001 +/* cca_busy_time (within radio statistics) */ +#define WIFI_STATS_RADIO_CCA 0x00000002 +/* all channel statistics (within radio statistics) */ +#define WIFI_STATS_RADIO_CHANNELS 0x00000004 +/* all scan statistics (within radio statistics) */ +#define WIFI_STATS_RADIO_SCAN 0x00000008 +/* all interface statistics */ +#define WIFI_STATS_IFACE 0x00000010 +/* all tx rate statistics (within interface statistics) */ +#define WIFI_STATS_IFACE_TXRATE 0x00000020 +/* all ac statistics (within interface statistics) */ +#define WIFI_STATS_IFACE_AC 0x00000040 +/* all contention (min, max, avg) statistics (within ac statistics) */ +#define WIFI_STATS_IFACE_CONTENTION 0x00000080 + +typedef struct +{ + tANI_U32 paramId; + tANI_U8 ifaceId; + tANI_U32 rspId; + tANI_U32 moreResultToFollow; + union + { + tANI_U32 num_peers; + tANI_U32 num_radio; + }; + + tANI_U32 peer_event_number ; + /* Variable length field - Do not add anything after this */ + tANI_U8 results[0]; +} tSirLLStatsResults, *tpSirLLStatsResults; + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + +/* find the size of given member within a structure */ +#ifndef member_size +#define member_size(type, member) (sizeof(((type *)0)->member)) +#endif + #endif /* __SIR_API_H */ diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h index 4f420b7d48eb..9eb8fda40793 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -396,10 +396,10 @@ enum eWniMsgTypes eWNI_SME_LINK_SPEED_IND,//Indicate linkspeed response from WMA eWNI_SME_CSA_OFFLOAD_EVENT, eWNI_SME_UPDATE_ADDITIONAL_IES, // indicates Additional IE from hdd to PE + eWNI_SME_MODIFY_ADDITIONAL_IES, /* To indicate IE modify from hdd to PE */ #ifdef QCA_HT_2040_COEX eWNI_SME_SET_HT_2040_MODE, #endif - eWNI_SME_MSG_TYPES_END }; diff --git a/CORE/MAC/src/include/parserApi.h b/CORE/MAC/src/include/parserApi.h index 2ac2cee50f3a..82a240d096e6 100644 --- a/CORE/MAC/src/include/parserApi.h +++ b/CORE/MAC/src/include/parserApi.h @@ -269,6 +269,7 @@ typedef struct sSirAssocRsp tDot11fIEVHTOperation VHTOperation; #endif tDot11fIEExtCap ExtCap; + tSirQosMapSet QosMapSet; } tSirAssocRsp, *tpSirAssocRsp; #if defined(FEATURE_WLAN_ESE_UPLOAD) diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 8b8493a2fef8..01a44fc077fa 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -700,6 +700,13 @@ typedef struct sSirMbMsgP2p #define SIR_HAL_CH_AVOID_UPDATE_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 274) #endif +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +#define SIR_HAL_LL_STATS_CLEAR_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 275) +#define SIR_HAL_LL_STATS_SET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 276) +#define SIR_HAL_LL_STATS_GET_REQ (SIR_HAL_ITC_MSG_TYPES_BEGIN + 277) +#define SIR_HAL_LL_STATS_RESULTS_RSP (SIR_HAL_ITC_MSG_TYPES_BEGIN + 278) +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) // CFG message types diff --git a/CORE/MAC/src/pe/include/limSession.h b/CORE/MAC/src/pe/include/limSession.h index b280436590a9..84923b8a9952 100644 --- a/CORE/MAC/src/pe/include/limSession.h +++ b/CORE/MAC/src/pe/include/limSession.h @@ -444,6 +444,8 @@ typedef struct sPESession // Added to Support BT-AMP // Size of the trailing portion tANI_U16 schBeaconOffsetEnd; tANI_BOOLEAN isOSENConnection; + /* DSCP to UP mapping for HS 2.0 */ + tSirQosMapSet QosMapSet; }tPESession, *tpPESession; diff --git a/CORE/MAC/src/pe/lim/limProcessActionFrame.c b/CORE/MAC/src/pe/lim/limProcessActionFrame.c index 72fe8cacd1af..aaf5676b6f50 100644 --- a/CORE/MAC/src/pe/lim/limProcessActionFrame.c +++ b/CORE/MAC/src/pe/lim/limProcessActionFrame.c @@ -1090,7 +1090,7 @@ __limProcessQosMapConfigureFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, pBody = WDA_GET_RX_MPDU_DATA(pRxPacketInfo); frameLen = WDA_GET_RX_PAYLOAD_LEN(pRxPacketInfo); retval = sirConvertQosMapConfigureFrame2Struct(pMac, pBody, frameLen, - &pMac->QosMapSet); + &psessionEntry->QosMapSet); if (retval != eSIR_SUCCESS) { PELOGW(limLog(pMac, LOGE, diff --git a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c index 57fd8cdbe7a9..1618d6443c44 100644 --- a/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c +++ b/CORE/MAC/src/pe/lim/limProcessAssocRspFrame.c @@ -846,6 +846,16 @@ limProcessAssocRspFrame(tpAniSirGlobal pMac, tANI_U8 *pRxPacketInfo, tANI_U8 sub #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM //FEATURE_WLAN_DIAG_SUPPORT limDiagEventReport(pMac, WLAN_PE_DIAG_CONNECTED, psessionEntry, 0, 0); #endif + if( pAssocRsp->QosMapSet.present ) + { + vos_mem_copy(&psessionEntry->QosMapSet, + &pAssocRsp->QosMapSet, + sizeof(tSirQosMapSet)); + } + else + { + vos_mem_zero(&psessionEntry->QosMapSet, sizeof(tSirQosMapSet)); + } if (pAssocRsp->ExtCap.present) { diff --git a/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c b/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c index 17c0b7859498..2b8864f48a10 100644 --- a/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c +++ b/CORE/MAC/src/pe/lim/limProcessCfgUpdates.c @@ -224,7 +224,48 @@ static tSirRetStatus limUpdateTriggerStaBkScanFlag(tpAniSirGlobal pMac) return eSIR_FAILURE; } +/** + * limHandleParamUpdate() + * + *FUNCTION: + * This function is use to post a message whenever need indicate + * there is update of config parameter. + * + *PARAMS: + * + *LOGIC: + * + *ASSUMPTIONS: + * NA + * + *NOTE: + * + * @param pMac - Pointer to Global MAC structure + * @param cfgId - ID of CFG parameter that got updated + * @return None + */ +void +limHandleParamUpdate(tpAniSirGlobal pMac, eUpdateIEsType cfgId) +{ + tSirMsgQ msg = {0}; + tANI_U32 status; + + PELOG3(limLog(pMac, LOG3, FL("Handling CFG parameter id %X update"), cfgId);) + switch (cfgId) + { + case eUPDATE_IE_PROBE_BCN: + { + msg.type = SIR_LIM_UPDATE_BEACON; + status = limPostMsgApi(pMac, &msg); + if (status != TX_SUCCESS) + PELOGE(limLog(pMac, LOGE, FL("Failed limPostMsgApi %u"), status);) + break; + } + default: + break; + } +} /** * limHandleCFGparamUpdate() diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index 35c7dd094238..ba2549171648 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -2182,6 +2182,12 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) limMsg->bodyptr = NULL; break; + case eWNI_SME_MODIFY_ADDITIONAL_IES: + limProcessSmeReqMessages(pMac, limMsg); + vos_mem_free((v_VOID_t*)limMsg->bodyptr); + limMsg->bodyptr = NULL; + break; + #ifdef QCA_HT_2040_COEX case eWNI_SME_SET_HT_2040_MODE: limProcessSmeReqMessages(pMac, limMsg); diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index 0f73851097ba..7dbd362c77a4 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -102,6 +102,19 @@ static void limProcessSmeStartBeaconReq(tpAniSirGlobal pMac, tANI_U32 *pMsg); static void limProcessSmeDfsCsaIeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg); +static void limStartBssUpdateAddIEBuffer(tpAniSirGlobal pMac, + tANI_U8 **pDstData_buff, + tANI_U16 *pDstDataLen, + tANI_U8 *pSrcData_buff, + tANI_U16 srcDataLen); + +static void limUpdateAddIEBuffer(tpAniSirGlobal pMac, + tANI_U8 **pDstData_buff, + tANI_U16 *pDstDataLen, + tANI_U8 *pSrcData_buff, + tANI_U16 srcDataLen); +static void limProcessModifyAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg); + static void limProcessUpdateAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg); void __limProcessSmeAssocCnfNew(tpAniSirGlobal, tANI_U32, tANI_U32 *); @@ -584,27 +597,26 @@ __limHandleSmeStartBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) } } - if (pSmeStartBssReq->addIeParams.dataLen > 0 && - pSmeStartBssReq->addIeParams.data_buff != NULL) - { - psessionEntry->addIeParams.dataLen = - pSmeStartBssReq->addIeParams.dataLen; - - psessionEntry->addIeParams.data_buff = - vos_mem_malloc(psessionEntry->addIeParams.dataLen); - - if ( NULL == psessionEntry->addIeParams.data_buff ) - { - PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for " - "psessionEntry->addIeParams.data_buff "));) - // Send failure response to host - retCode = eSIR_SME_RESOURCES_UNAVAILABLE; - goto end; - } - vos_mem_copy(psessionEntry->addIeParams.data_buff, - pSmeStartBssReq->addIeParams.data_buff, - psessionEntry->addIeParams.dataLen); - } + /* Probe resp add ie */ + limStartBssUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.probeRespData_buff, + &psessionEntry->addIeParams.probeRespDataLen, + pSmeStartBssReq->addIeParams.probeRespData_buff, + pSmeStartBssReq->addIeParams.probeRespDataLen); + + /* Probe Beacon add ie */ + limStartBssUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.probeRespBCNData_buff, + &psessionEntry->addIeParams.probeRespBCNDataLen, + pSmeStartBssReq->addIeParams.probeRespBCNData_buff, + pSmeStartBssReq->addIeParams.probeRespBCNDataLen); + + /* Assoc resp IE */ + limStartBssUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.assocRespData_buff, + &psessionEntry->addIeParams.assocRespDataLen, + pSmeStartBssReq->addIeParams.assocRespData_buff, + pSmeStartBssReq->addIeParams.assocRespDataLen); /* Store the session related parameters in newly created session */ psessionEntry->pLimStartBssReq = pSmeStartBssReq; @@ -2964,7 +2976,19 @@ __limProcessSmeDeauthReq(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) // Send Deauthentication request to MLM below break; - + case eLIM_SME_WT_DEAUTH_STATE: + /* + * PE Recieved a Deauth frame. Normally it gets + * DEAUTH_CNF but it received DEAUTH_REQ. Which + * means host is also trying to disconnect. + * PE can continue processing DEAUTH_REQ and send + * the response instead of failing the request. + * SME will anyway ignore DEAUTH_IND that was sent + * for deauth frame. + */ + limLog(pMac, LOG1, FL("Rcvd SME_DEAUTH_REQ while in " + "SME_WT_DEAUTH_STATE. ")); + break; default: /** * STA is not in a state to deauthenticate with @@ -3762,9 +3786,17 @@ __limHandleSmeStopBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) } /* Free the buffer allocated in START_BSS_REQ */ - vos_mem_free(psessionEntry->addIeParams.data_buff); - psessionEntry->addIeParams.dataLen = 0; - psessionEntry->addIeParams.data_buff = NULL; + vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); + psessionEntry->addIeParams.probeRespDataLen = 0; + psessionEntry->addIeParams.probeRespData_buff = NULL; + + vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff); + psessionEntry->addIeParams.probeRespBCNDataLen = 0; + psessionEntry->addIeParams.probeRespBCNData_buff = NULL; + + vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff); + psessionEntry->addIeParams.probeRespBCNDataLen = 0; + psessionEntry->addIeParams.probeRespBCNData_buff = NULL; //limDelBss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg. pMac->lim.gLimIbssCoalescingHappened = false; @@ -6047,6 +6079,10 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) limProcessUpdateAddIEs(pMac, pMsgBuf); break; + case eWNI_SME_MODIFY_ADDITIONAL_IES: + limProcessModifyAddIEs(pMac, pMsgBuf); + break; + default: vos_mem_free((v_VOID_t*)pMsg->bodyptr); pMsg->bodyptr = NULL; @@ -6248,6 +6284,217 @@ limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg) } /****************************************************************************** + * limStartBssUpdateAddIEBuffer() + * + *FUNCTION: + * This function checks the src buffer and its length and then malloc for + * dst buffer update the same + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param **pDstData_buff A pointer to pointer of tANI_U8 dst buffer + * @param *pDstDataLen A pointer to pointer of tANI_U16 dst buffer length + * @param *pSrcData_buff A pointer of tANI_U8 src buffer + * @param srcDataLen src buffer length +******************************************************************************/ + +static void +limStartBssUpdateAddIEBuffer(tpAniSirGlobal pMac, + tANI_U8 **pDstData_buff, + tANI_U16 *pDstDataLen, + tANI_U8 *pSrcData_buff, + tANI_U16 srcDataLen) +{ + + if (srcDataLen > 0 && pSrcData_buff != NULL) + { + *pDstDataLen = srcDataLen; + + *pDstData_buff = vos_mem_malloc(*pDstDataLen); + + if (NULL == *pDstData_buff) + { + PELOGE(limLog(pMac, LOGE, FL("AllocateMemory failed for " + "pDstData_buff"));) + return; + } + vos_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen); + } + else + { + *pDstData_buff = NULL; + *pDstDataLen = 0; + } +} +/****************************************************************************** + * limUpdateAddIEBuffer() + * + *FUNCTION: + * This function checks the src buffer and length if src buffer length more + * than dst buffer length then free the dst buffer and malloc for the new src + * length, and update the dst buffer and length. But if dst buffer is bigger + * than src buffer length then it just update the dst buffer and length + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param **pDstData_buff A pointer to pointer of tANI_U8 dst buffer + * @param *pDstDataLen A pointer to pointer of tANI_U16 dst buffer length + * @param *pSrcData_buff A pointer of tANI_U8 src buffer + * @param srcDataLen src buffer length +******************************************************************************/ + +static void +limUpdateAddIEBuffer(tpAniSirGlobal pMac, + tANI_U8 **pDstData_buff, + tANI_U16 *pDstDataLen, + tANI_U8 *pSrcData_buff, + tANI_U16 srcDataLen) +{ + + if (NULL == pSrcData_buff) + { + limLog(pMac, LOGE, FL("src buffer is null.")); + return; + } + + if (srcDataLen > *pDstDataLen) + { + *pDstDataLen = srcDataLen; + /* free old buffer */ + vos_mem_free(*pDstData_buff); + /* allocate a new */ + *pDstData_buff = vos_mem_malloc(*pDstDataLen); + + if (NULL == *pDstData_buff) + { + limLog(pMac, LOGE, FL("Memory allocation failed.")); + *pDstDataLen = 0; + return; + } + } + + /* copy the content of buffer into dst buffer + */ + *pDstDataLen = srcDataLen; + vos_mem_copy(*pDstData_buff, pSrcData_buff, *pDstDataLen); + +} + +/****************************************************************************** + * limProcessModifyAddIEs() + * + *FUNCTION: + * This function is called by limProcessMessageQueue(). This + * function update the PE buffers for additional IEs. + * + *LOGIC: + * + *ASSUMPTIONS: + * + *NOTE: + * + * @param pMac Pointer to Global MAC structure + * @param *pMsgBuf A pointer to the SME message buffer +******************************************************************************/ +static void +limProcessModifyAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg) +{ + tpSirModifyIEsInd pModifyAddIEs = (tpSirModifyIEsInd)pMsg; + tANI_U8 sessionId; + tANI_U16 bufferLen = 0; + tANI_U8 *pBuffer = NULL; + + /* Incoming message has smeSession, use BSSID to find PE session*/ + tpPESession psessionEntry = peFindSessionByBssid(pMac, + pModifyAddIEs->modifyIE.bssid, + &sessionId); + + if (NULL != psessionEntry) + { + if ((0 != pModifyAddIEs->modifyIE.ieBufferlength) && + (0 != pModifyAddIEs->modifyIE.ieIDLen) && + (NULL != pModifyAddIEs->modifyIE.pIEBuffer)) + { + + switch (pModifyAddIEs->updateType) + { + case eUPDATE_IE_PROBE_RESP: + { + /* Probe resp */ + if ((bufferLen = psessionEntry->addIeParams.probeRespDataLen) + == 0) + { + limLog(pMac, LOGE, FL("probe resp add ie not present %d"), + psessionEntry->addIeParams.probeRespDataLen); + break; + } + /* vendor IE and oui 0x00, 0x16, 0x32 */ + /* search through the buffer and modify the IE */ + pBuffer = psessionEntry->addIeParams.probeRespData_buff; + break; + } + case eUPDATE_IE_ASSOC_RESP: + /* assoc resp IE */ + if (psessionEntry->addIeParams.assocRespDataLen == 0) + { + limLog(pMac, LOGE, FL("assoc resp add ie not present %d"), + psessionEntry->addIeParams.assocRespDataLen); + } + /* search through the buffer and modify the IE */ + break; + case eUPDATE_IE_PROBE_BCN: + /*probe beacon IE*/ + if ((bufferLen = psessionEntry->addIeParams.probeRespBCNDataLen) + == 0) + { + limLog(pMac, LOGE, + FL("probe resp Bcn add ie not present %d"), + psessionEntry->addIeParams.probeRespBCNDataLen); + break; + } + /* vendor IE and oui 0x00, 0x16, 0x32 */ + /* search through the buffer and modify the IE */ + pBuffer = psessionEntry->addIeParams.probeRespBCNData_buff; + break; + default: + limLog(pMac, LOGE, FL("unhandled buffer type %d."), + pModifyAddIEs->updateType); + break; + } + } + else + { + limLog(pMac, LOGE, FL("Invalid request pIEBuffer %p ieBufferlength" + " %d ieIDLen %d ieID %d. update Type %d"), + pModifyAddIEs->modifyIE.pIEBuffer, + pModifyAddIEs->modifyIE.ieBufferlength, + pModifyAddIEs->modifyIE.ieID, + pModifyAddIEs->modifyIE.ieIDLen, + pModifyAddIEs->updateType); + } + + } + else + { + limLog(pMac, LOGE, FL("Session not found for given bssid. " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pModifyAddIEs->modifyIE.bssid)); + } + vos_mem_free(pModifyAddIEs->modifyIE.pIEBuffer); + pModifyAddIEs->modifyIE.pIEBuffer = NULL; + +} + +/****************************************************************************** * limProcessUpdateAddIEs() * *FUNCTION: @@ -6266,87 +6513,121 @@ limProcessSmeChannelChangeRequest(tpAniSirGlobal pMac, tANI_U32 *pMsg) static void limProcessUpdateAddIEs(tpAniSirGlobal pMac, tANI_U32 *pMsg) { - tpUpdateAIEs pUpdateAIEs = (tpUpdateAIEs)pMsg; + tpSirUpdateIEsInd pUpdateAddIEs = (tpSirUpdateIEsInd)pMsg; tANI_U8 sessionId; /* incoming message has smeSession, use BSSID to find PE session*/ tpPESession psessionEntry = peFindSessionByBssid(pMac, - pUpdateAIEs->bssid, - &sessionId); + pUpdateAddIEs->updateIE.bssid, + &sessionId); - if (NULL != psessionEntry) { + if (NULL != psessionEntry) + { /* if len is 0, upper layer requested freeing of buffer */ - if (0 == pUpdateAIEs->length) { - /* free old buffer */ - vos_mem_free(psessionEntry->addIeParams.data_buff); - psessionEntry->addIeParams.data_buff = NULL; - psessionEntry->addIeParams.dataLen = 0; - return; - } + if (0 == pUpdateAddIEs->updateIE.ieBufferlength) + { + switch (pUpdateAddIEs->updateType) + { + case eUPDATE_IE_PROBE_RESP: + vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); + psessionEntry->addIeParams.probeRespData_buff = NULL; + psessionEntry->addIeParams.probeRespDataLen = 0; + break; + case eUPDATE_IE_ASSOC_RESP: + vos_mem_free(psessionEntry->addIeParams.assocRespData_buff); + psessionEntry->addIeParams.assocRespData_buff = NULL; + psessionEntry->addIeParams.assocRespDataLen = 0; + break; + case eUPDATE_IE_PROBE_BCN: + vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff); + psessionEntry->addIeParams.probeRespBCNData_buff = NULL; + psessionEntry->addIeParams.probeRespBCNDataLen = 0; - if (pUpdateAIEs->append) { - /* In case of append, allocate new memory with combined length */ - tANI_U16 new_length = pUpdateAIEs->length + - psessionEntry->addIeParams.dataLen; - tANI_U8 *new_ptr = vos_mem_malloc(new_length); - if (NULL == new_ptr) { - limLog(pMac, LOGE, FL("Memory allocation failed.")); - /* free incoming buffer in message */ - vos_mem_free(pUpdateAIEs->pAdditionIEBuffer); - return; + if (pUpdateAddIEs->updateIE.notify) + { + limHandleParamUpdate(pMac, pUpdateAddIEs->updateType); + } + break; + default: + break; } - /* append buffer to end of local buffers */ - vos_mem_copy(new_ptr, - psessionEntry->addIeParams.data_buff, - psessionEntry->addIeParams.dataLen); - vos_mem_copy(&new_ptr[psessionEntry->addIeParams.dataLen], - pUpdateAIEs->pAdditionIEBuffer, - pUpdateAIEs->length); - /* free old memory*/ - vos_mem_free(psessionEntry->addIeParams.data_buff); - /* adjust length accordingly */ - psessionEntry->addIeParams.dataLen = new_length; - /* save refernece of local buffer in PE session */ - psessionEntry->addIeParams.data_buff = new_ptr; - /* free incoming buffer in message */ - vos_mem_free(pUpdateAIEs->pAdditionIEBuffer); return; } - if (pUpdateAIEs->length > psessionEntry->addIeParams.dataLen) { - psessionEntry->addIeParams.dataLen = pUpdateAIEs->length; - /* free old buffer */ - vos_mem_free(psessionEntry->addIeParams.data_buff); - /* allocate a new */ - psessionEntry->addIeParams.data_buff = - vos_mem_malloc(psessionEntry->addIeParams.dataLen); - - if (NULL == psessionEntry->addIeParams.data_buff) { - limLog(pMac, LOGE, FL("Memory allocation failed.")); + switch (pUpdateAddIEs->updateType) + { + case eUPDATE_IE_PROBE_RESP: + { + if (pUpdateAddIEs->updateIE.append) + { + /* In case of append, allocate new memory with combined length */ + tANI_U16 new_length = pUpdateAddIEs->updateIE.ieBufferlength + + psessionEntry->addIeParams.probeRespDataLen; + tANI_U8 *new_ptr = vos_mem_malloc(new_length); + if (NULL == new_ptr) + { + limLog(pMac, LOGE, FL("Memory allocation failed.")); + /* free incoming buffer in message */ + vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer); + return; + } + /* append buffer to end of local buffers */ + vos_mem_copy(new_ptr, + psessionEntry->addIeParams.probeRespData_buff, + psessionEntry->addIeParams.probeRespDataLen); + vos_mem_copy(&new_ptr[psessionEntry->addIeParams.probeRespDataLen], + pUpdateAddIEs->updateIE.pAdditionIEBuffer, + pUpdateAddIEs->updateIE.ieBufferlength); + /* free old memory*/ + vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); + /* adjust length accordingly */ + psessionEntry->addIeParams.probeRespDataLen = new_length; + /* save refernece of local buffer in PE session */ + psessionEntry->addIeParams.probeRespData_buff = new_ptr; /* free incoming buffer in message */ - vos_mem_free(pUpdateAIEs->pAdditionIEBuffer); - psessionEntry->addIeParams.dataLen = 0; + vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer); return; } + limUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.probeRespData_buff, + &psessionEntry->addIeParams.probeRespDataLen, + pUpdateAddIEs->updateIE.pAdditionIEBuffer, + pUpdateAddIEs->updateIE.ieBufferlength); + break; + } + case eUPDATE_IE_ASSOC_RESP: + /*assoc resp IE*/ + limUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.assocRespData_buff, + &psessionEntry->addIeParams.assocRespDataLen, + pUpdateAddIEs->updateIE.pAdditionIEBuffer, + pUpdateAddIEs->updateIE.ieBufferlength); + break; + case eUPDATE_IE_PROBE_BCN: + /*probe resp Bcn IE*/ + limUpdateAddIEBuffer(pMac, + &psessionEntry->addIeParams.probeRespBCNData_buff, + &psessionEntry->addIeParams.probeRespBCNDataLen, + pUpdateAddIEs->updateIE.pAdditionIEBuffer, + pUpdateAddIEs->updateIE.ieBufferlength); + if (pUpdateAddIEs->updateIE.notify) + { + limHandleParamUpdate(pMac, pUpdateAddIEs->updateType); + } + break; + default: + limLog(pMac, LOGE, FL("unhandled buffer type %d."), + pUpdateAddIEs->updateType); + break; } - - /* - * copy the content of addition IE buffer in local buffer in - * PE session - */ - psessionEntry->addIeParams.dataLen = pUpdateAIEs->length; - vos_mem_copy(psessionEntry->addIeParams.data_buff, - pUpdateAIEs->pAdditionIEBuffer, - psessionEntry->addIeParams.dataLen); - /* free incoming buffer in message */ - vos_mem_free(pUpdateAIEs->pAdditionIEBuffer); } else { - /* free incoming buffer in message */ - vos_mem_free(pUpdateAIEs->pAdditionIEBuffer); - pUpdateAIEs->pAdditionIEBuffer = NULL; - limLog(pMac, LOGE, FL("Session not found for given bssid.")); + limLog(pMac, LOGE, FL("Session not found for given bssid. " + MAC_ADDRESS_STR), MAC_ADDR_ARRAY(pUpdateAddIEs->updateIE.bssid)); } + vos_mem_free(pUpdateAddIEs->updateIE.pAdditionIEBuffer); + pUpdateAddIEs->updateIE.pAdditionIEBuffer = NULL; + } /** diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c index e9b49b44fcc6..8a88ab8d5f30 100644 --- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c +++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c @@ -877,13 +877,13 @@ limSendProbeRspMgmtFrame(tpAniSirGlobal pMac, //In listening mode, probe rsp IEs is passed in the message from SME to PE else { - addnIEPresent = (psessionEntry->addIeParams.dataLen != 0); + addnIEPresent = (psessionEntry->addIeParams.probeRespDataLen != 0); } if (addnIEPresent) { - addIE = vos_mem_malloc(psessionEntry->addIeParams.dataLen); + addIE = vos_mem_malloc(psessionEntry->addIeParams.probeRespDataLen); if ( NULL == addIE ) { PELOGE(limLog(pMac, LOGE, @@ -892,11 +892,12 @@ limSendProbeRspMgmtFrame(tpAniSirGlobal pMac, return; } - vos_mem_copy(addIE, psessionEntry->addIeParams.data_buff, - psessionEntry->addIeParams.dataLen); - totalAddnIeLen = psessionEntry->addIeParams.dataLen; + vos_mem_copy(addIE, psessionEntry->addIeParams.probeRespData_buff, + psessionEntry->addIeParams.probeRespDataLen); + totalAddnIeLen = psessionEntry->addIeParams.probeRespDataLen; - if(eSIR_SUCCESS != limGetAddnIeForProbeResp(pMac, addIE, &totalAddnIeLen, probeReqP2pIe)) + if(eSIR_SUCCESS != limGetAddnIeForProbeResp(pMac, addIE, + &totalAddnIeLen, probeReqP2pIe)) { limLog(pMac, LOGP, FL("Unable to get final Additional IE for Probe Req")); @@ -1529,32 +1530,23 @@ limSendAssocRspMgmtFrame(tpAniSirGlobal pMac, if ( pAssocReq != NULL ) { - if (wlan_cfgGetInt(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_FLAG, - &addnIEPresent) != eSIR_SUCCESS) - { - limLog(pMac, LOGP, FL("Unable to get " - "WNI_CFG_ASSOC_RSP_ADDNIE_FLAG")); - return; - } + addnIEPresent = (psessionEntry->addIeParams.assocRespDataLen != 0); if (addnIEPresent) { //Assoc rsp IE available - if (wlan_cfgGetStrLen(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_DATA, - &addnIELen) != eSIR_SUCCESS) - { - limLog(pMac, LOGP, FL("Unable to get " - "WNI_CFG_ASSOC_RSP_ADDNIE_DATA length")); - return; - } + + addnIELen = psessionEntry->addIeParams.assocRespDataLen; if (addnIELen <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN && addnIELen && (nBytes + addnIELen) <= SIR_MAX_PACKET_SIZE) { - if (wlan_cfgGetStr(pMac, WNI_CFG_ASSOC_RSP_ADDNIE_DATA, - &addIE[0], &addnIELen) == eSIR_SUCCESS) - { + vos_mem_copy(addIE, psessionEntry->addIeParams.assocRespData_buff, + psessionEntry->addIeParams.assocRespDataLen); + + if (addnIELen) + { vos_mem_set(( tANI_U8* )&extractedExtCap, sizeof( tDot11fIEExtCap ), 0); @@ -1654,9 +1646,10 @@ limSendAssocRspMgmtFrame(tpAniSirGlobal pMac, } PELOG1(limPrintMacAddr(pMac, pMacHdr->da, LOG1);) - if ( addnIEPresent ) + if ( addnIEPresent && addnIELen <= WNI_CFG_ASSOC_RSP_ADDNIE_DATA_LEN ) { - vos_mem_copy ( pFrame+sizeof(tSirMacMgmtHdr)+nPayload, &addIE[0], addnIELen ) ; + vos_mem_copy( pFrame+sizeof(tSirMacMgmtHdr)+nPayload, + &addIE[0], addnIELen ) ; } if( ( SIR_BAND_5_GHZ == limGetRFBand(psessionEntry->currentOperChannel)) diff --git a/CORE/MAC/src/pe/lim/limSmeReqUtils.c b/CORE/MAC/src/pe/lim/limSmeReqUtils.c index 81439b4e249b..0eadbbddee29 100644 --- a/CORE/MAC/src/pe/lim/limSmeReqUtils.c +++ b/CORE/MAC/src/pe/lim/limSmeReqUtils.c @@ -853,6 +853,13 @@ limIsSmeScanReqValid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq) tANI_U8 valid = true; tANI_U8 i = 0; + if (pScanReq->numSsid > SIR_SCAN_MAX_NUM_SSID) + { + valid = false; + limLog(pMac, LOGE, FL("Number of SSIDs > SIR_SCAN_MAX_NUM_SSID")); + goto end; + } + for (i = 0; i < pScanReq->numSsid; i++) { if (pScanReq->ssId[i].length > SIR_MAC_MAX_SSID_LENGTH) @@ -863,31 +870,11 @@ limIsSmeScanReqValid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq) goto end; } } - if (pScanReq->bssType > eSIR_AUTO_MODE) + if ((pScanReq->bssType < 0) || (pScanReq->bssType > eSIR_AUTO_MODE)) { limLog(pMac, LOGE, FL("Invalid BSS Type")); valid = false; } - - if (limIsGroupAddr(pScanReq->bssId) && !limIsAddrBC(pScanReq->bssId)) - { - limLog(pMac, LOGE, FL("Invalid BSS Type")); - - valid = false; - limLog(pMac, LOGE, FL("BSSID is group addr and is not Broadcast Addr")); - } - if (!(pScanReq->scanType == eSIR_PASSIVE_SCAN || pScanReq->scanType == eSIR_ACTIVE_SCAN)) - { - valid = false; - limLog(pMac, LOGE, FL("Invalid Scan Type")); - } - - if (pScanReq->channelList.numChannels > SIR_MAX_NUM_CHANNELS) - { - valid = false; - limLog(pMac, LOGE, FL("Number of Channels > SIR_MAX_NUM_CHANNELS")); - } - if (limIsGroupAddr(pScanReq->bssId) && !limIsAddrBC(pScanReq->bssId)) { valid = false; @@ -904,8 +891,6 @@ limIsSmeScanReqValid(tpAniSirGlobal pMac, tpSirSmeScanReq pScanReq) limLog(pMac, LOGE, FL("Number of Channels > SIR_MAX_NUM_CHANNELS")); } - - /* ** check min/max channelTime range **/ diff --git a/CORE/MAC/src/pe/lim/limTypes.h b/CORE/MAC/src/pe/lim/limTypes.h index 7ccb6f5790a0..32fe24542450 100644 --- a/CORE/MAC/src/pe/lim/limTypes.h +++ b/CORE/MAC/src/pe/lim/limTypes.h @@ -615,6 +615,8 @@ void handleHTCapabilityandHTInfo(struct sAniSirGlobal *pMac, tpPESession psessio // Function to handle CFG parameter updates void limHandleCFGparamUpdate(tpAniSirGlobal, tANI_U32); +void limHandleParamUpdate(tpAniSirGlobal pMac, eUpdateIEsType cfgId); + // Function to apply CFG parameters before join/reassoc/start BSS void limApplyConfiguration(tpAniSirGlobal,tpPESession); diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c index 26db8b57be45..4fb055b9badc 100644 --- a/CORE/MAC/src/pe/lim/limUtils.c +++ b/CORE/MAC/src/pe/lim/limUtils.c @@ -8010,3 +8010,32 @@ limSetProtectedBit(tpAniSirGlobal pMac, } /*** end limSetProtectedBit() ***/ #endif +tANI_U8* lim_get_ie_ptr(tANI_U8 *pIes, int length, tANI_U8 eid) +{ + int left = length; + tANI_U8 *ptr = pIes; + tANI_U8 elem_id, elem_len; + + while(left >= 2) + { + elem_id = ptr[0]; + elem_len = ptr[1]; + left -= 2; + if(elem_len > left) + { + VOS_TRACE(VOS_MODULE_ID_PE, VOS_TRACE_LEVEL_ERROR, + FL("****Invalid IEs eid = %d elem_len=%d left=%d*****"), + eid,elem_len, left); + + return NULL; + } + if (elem_id == eid) + { + return ptr; + } + + left -= elem_len; + ptr += (elem_len + 2); + } + return NULL; +} diff --git a/CORE/MAC/src/pe/lim/limUtils.h b/CORE/MAC/src/pe/lim/limUtils.h index 0aa8eacf5d08..7206f74c2b30 100644 --- a/CORE/MAC/src/pe/lim/limUtils.h +++ b/CORE/MAC/src/pe/lim/limUtils.h @@ -591,4 +591,6 @@ void limSetProtectedBit(tpAniSirGlobal pMac, tSirMacAddr peer, tpSirMacMgmtHdr pMacHdr); +tANI_U8* lim_get_ie_ptr(tANI_U8 *pIes, int length, tANI_U8 eid); + #endif /* __LIM_UTILS_H */ diff --git a/CORE/MAC/src/pe/sch/schApi.c b/CORE/MAC/src/pe/sch/schApi.c index ce13038c8693..4593aaf87aad 100644 --- a/CORE/MAC/src/pe/sch/schApi.c +++ b/CORE/MAC/src/pe/sch/schApi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2013 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2014 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -375,7 +375,7 @@ tANI_U32 limSendProbeRspTemplateToHal(tpAniSirGlobal pMac,tpPESession psessionEn tANI_U32 retCode = eSIR_FAILURE; tANI_U32 nPayload,nBytes,nStatus; tpSirMacMgmtHdr pMacHdr; - tANI_U32 addnIEPresent; + tANI_U32 addnIEPresent = VOS_FALSE; tANI_U32 addnIELen=0; tSirRetStatus nSirStatus; tANI_U8 *addIE = NULL; @@ -399,19 +399,19 @@ tANI_U32 limSendProbeRspTemplateToHal(tpAniSirGlobal pMac,tpPESession psessionEn nBytes = nPayload + sizeof( tSirMacMgmtHdr ); //Check if probe response IE is present or not - addnIEPresent = (psessionEntry->addIeParams.dataLen != 0); + addnIEPresent = (psessionEntry->addIeParams.probeRespDataLen != 0); if (addnIEPresent) { //Probe rsp IE available /*need to check the data length*/ - addIE = vos_mem_malloc(psessionEntry->addIeParams.dataLen); + addIE = vos_mem_malloc(psessionEntry->addIeParams.probeRespDataLen); if ( NULL == addIE ) { schLog(pMac, LOGE, FL("Unable to get WNI_CFG_PROBE_RSP_ADDNIE_DATA1 length")); return retCode; } - addnIELen = psessionEntry->addIeParams.dataLen; + addnIELen = psessionEntry->addIeParams.probeRespDataLen; if (addnIELen <= WNI_CFG_PROBE_RSP_ADDNIE_DATA1_LEN && addnIELen && @@ -419,8 +419,8 @@ tANI_U32 limSendProbeRspTemplateToHal(tpAniSirGlobal pMac,tpPESession psessionEn { - vos_mem_copy(addIE, psessionEntry->addIeParams.data_buff, - psessionEntry->addIeParams.dataLen); + vos_mem_copy(addIE, psessionEntry->addIeParams.probeRespData_buff, + psessionEntry->addIeParams.probeRespDataLen); } } diff --git a/CORE/MAC/src/pe/sch/schBeaconGen.c b/CORE/MAC/src/pe/sch/schBeaconGen.c index 37b4930da565..844d6cb402be 100644 --- a/CORE/MAC/src/pe/sch/schBeaconGen.c +++ b/CORE/MAC/src/pe/sch/schBeaconGen.c @@ -101,29 +101,18 @@ tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, tANI_U32 present, len; tANI_U8 addIE[WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN]; - if((status = wlan_cfgGetInt(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG, - &present)) != eSIR_SUCCESS) - { - schLog(pMac, LOGP, FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_FLAG")); - return status; - } - + present = (psessionEntry->addIeParams.probeRespBCNDataLen != 0); if(present) { - if((status = wlan_cfgGetStrLen(pMac, WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, - &len)) != eSIR_SUCCESS) - { - schLog(pMac, LOGP, - FL("Unable to get WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA length")); - return status; - } + len = psessionEntry->addIeParams.probeRespBCNDataLen; if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN && len && ((len + *nBytes) <= maxBeaconSize)) { - if((status = wlan_cfgGetStr(pMac, - WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA, &addIE[0], &len)) - == eSIR_SUCCESS) + + vos_mem_copy(&addIE[0], + psessionEntry->addIeParams.probeRespBCNData_buff, len); + { tANI_U8* pP2pIe = limGetP2pIEPtr(pMac, &addIE[0], len); if ((pP2pIe != NULL) && !pMac->beacon_offload) @@ -148,8 +137,16 @@ tSirRetStatus schAppendAddnIE(tpAniSirGlobal pMac, tpPESession psessionEntry, } } } - vos_mem_copy(pFrame, &addIE[0], len); - *nBytes = *nBytes + len; + if(len <= WNI_CFG_PROBE_RSP_BCN_ADDNIE_DATA_LEN) + { + vos_mem_copy(pFrame, &addIE[0], len); + *nBytes = *nBytes + len; + } + else + { + schLog(pMac, LOGW, FL("Not able to insert because of" + " length constraint %d"), len); + } } } } diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h index 5492be8ba605..247922cda3b0 100644 --- a/CORE/SAP/inc/sapApi.h +++ b/CORE/SAP/inc/sapApi.h @@ -490,8 +490,16 @@ typedef struct sap_Config { #ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH v_U8_t cc_switch_mode; #endif - v_U16_t addnIEsBufferLen; - v_PVOID_t addnIEsBuffer; /* buffer for addn ies comes from hostapd*/ + + v_U16_t probeRespIEsBufferLen; + v_PVOID_t pProbeRespIEsBuffer; /* buffer for addn ies comes from hostapd*/ + + v_U16_t assocRespIEsLen; + v_PVOID_t pAssocRespIEsBuffer; /* buffer for addn ies comes from hostapd*/ + + v_U16_t probeRespBcnIEsLen; + v_PVOID_t pProbeRespBcnIEsBuffer; /* buffer for addn ies comes from hostapd*/ + } tsap_Config_t; typedef enum { @@ -2045,6 +2053,10 @@ WLANSAP_Set_Dfs_Target_Chnl(tHalHandle hHal, IN additionIELength - length of buffer + PARAMETERS + IN + updateType - Type of buffer + RETURN VALUE The VOS_STATUS code associated with performing the operation @@ -2054,8 +2066,9 @@ WLANSAP_Set_Dfs_Target_Chnl(tHalHandle hHal, ============================================================================*/ VOS_STATUS WLANSAP_UpdateSapConfigAddIE(tsap_Config_t *pConfig, - const tANI_U8 *additionIEBuffer, - tANI_U16 additionIELength); + const tANI_U8 *pAdditionIEBuffer, + tANI_U16 additionIELength, + eUpdateIEsType updateType); /*========================================================================== FUNCTION WLANSAP_ResetSapConfigAddIE @@ -2069,7 +2082,9 @@ VOS_STATUS WLANSAP_UpdateSapConfigAddIE(tsap_Config_t *pConfig, PARAMETERS IN OUT pConfig: Pointer to sap config - + PARAMETERS + IN + updateType: type buffer RETURN VALUE The VOS_STATUS code associated with performing the operation @@ -2078,7 +2093,10 @@ VOS_STATUS WLANSAP_UpdateSapConfigAddIE(tsap_Config_t *pConfig, SIDE EFFECTS ============================================================================*/ -VOS_STATUS WLANSAP_ResetSapConfigAddIE(tsap_Config_t *pConfig ); +VOS_STATUS +WLANSAP_ResetSapConfigAddIE(tsap_Config_t *pConfig, + eUpdateIEsType updateType); + /*========================================================================== diff --git a/CORE/SAP/src/sapFsm.c b/CORE/SAP/src/sapFsm.c index f22f19f13c77..3adcac0f23cf 100644 --- a/CORE/SAP/src/sapFsm.c +++ b/CORE/SAP/src/sapFsm.c @@ -2122,18 +2122,49 @@ sapconvertToCsrProfile(tsap_Config_t *pconfig_params, eCsrRoamBssType bssType, t profile->MFPRequired = pconfig_params->mfpRequired ? 1 : 0; #endif - if (pconfig_params->addnIEsBufferLen > 0 && - pconfig_params->addnIEsBuffer != NULL) + if (pconfig_params->probeRespIEsBufferLen > 0 && + pconfig_params->pProbeRespIEsBuffer != NULL) { - profile->addIeParams.dataLen = pconfig_params->addnIEsBufferLen; - profile->addIeParams.data_buff = pconfig_params->addnIEsBuffer; + profile->addIeParams.probeRespDataLen = + pconfig_params->probeRespIEsBufferLen; + profile->addIeParams.probeRespData_buff = + pconfig_params->pProbeRespIEsBuffer; } else { - profile->addIeParams.dataLen = 0; - profile->addIeParams.data_buff = NULL; + profile->addIeParams.probeRespDataLen = 0; + profile->addIeParams.probeRespData_buff = NULL; } - return eSAP_STATUS_SUCCESS; /* Success. */ + /*assoc resp IE */ + if (pconfig_params->assocRespIEsLen > 0 && + pconfig_params->pAssocRespIEsBuffer != NULL) + { + profile->addIeParams.assocRespDataLen = + pconfig_params->assocRespIEsLen; + profile->addIeParams.assocRespData_buff = + pconfig_params->pAssocRespIEsBuffer; + } + else + { + profile->addIeParams.assocRespDataLen = 0; + profile->addIeParams.assocRespData_buff = NULL; + } + + if (pconfig_params->probeRespBcnIEsLen > 0 && + pconfig_params->pProbeRespBcnIEsBuffer!= NULL) + { + profile->addIeParams.probeRespBCNDataLen = + pconfig_params->probeRespBcnIEsLen; + profile->addIeParams.probeRespBCNData_buff = + pconfig_params->pProbeRespBcnIEsBuffer; + } + else + { + profile->addIeParams.probeRespBCNDataLen = 0; + profile->addIeParams.probeRespBCNData_buff = NULL; + } + + return eSAP_STATUS_SUCCESS; /* Success. */ } /** diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c index f3af853b5262..c35e87b999f9 100644 --- a/CORE/SAP/src/sapModule.c +++ b/CORE/SAP/src/sapModule.c @@ -3094,49 +3094,134 @@ VOS_STATUS WLANSAP_Set_Dfs_Target_Chnl(tHalHandle hHal, v_U8_t target_channel) return VOS_STATUS_SUCCESS; } -VOS_STATUS WLANSAP_UpdateSapConfigAddIE(tsap_Config_t *pConfig, +VOS_STATUS +WLANSAP_UpdateSapConfigAddIE(tsap_Config_t *pConfig, const tANI_U8 *pAdditionIEBuffer, - tANI_U16 additionIELength) + tANI_U16 additionIELength, + eUpdateIEsType updateType) { VOS_STATUS status = VOS_STATUS_SUCCESS; + tANI_U8 bufferValid = VOS_FALSE; + tANI_U16 bufferLength = 0; + tANI_U8 *pBuffer = NULL; - if (NULL == pConfig) { + if (NULL == pConfig) + { return VOS_STATUS_E_FAULT; } - if ( (pAdditionIEBuffer != NULL) && (additionIELength != 0) ) { - /* initialize the buffer pointer so that pe can copy*/ - if (additionIELength > 0) { - pConfig->addnIEsBufferLen = additionIELength; - pConfig->addnIEsBuffer = vos_mem_malloc(additionIELength); - if (NULL == pConfig->addnIEsBuffer) { + + if ( (pAdditionIEBuffer != NULL) && (additionIELength != 0) ) + { + /* initialize the buffer pointer so that pe can copy*/ + if (additionIELength > 0) + { + bufferLength = additionIELength; + pBuffer = vos_mem_malloc(bufferLength); + if (NULL == pBuffer) + { VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, - "%s: Could not copy PROBE_RSP_ADDNIE", __func__); + FL("Could not allocate the buffer ")); return VOS_STATUS_E_NOMEM; } - vos_mem_copy(pConfig->addnIEsBuffer, - pAdditionIEBuffer, additionIELength); - } - } else { - vos_mem_free(pConfig->addnIEsBuffer); - pConfig->addnIEsBufferLen = 0; - pConfig->addnIEsBuffer = NULL; + vos_mem_copy(pBuffer, pAdditionIEBuffer, bufferLength); + bufferValid = VOS_TRUE; + } + } - VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, - "%s: No Probe Response IE received in set beacon", __func__); + switch(updateType) + { + case eUPDATE_IE_PROBE_BCN: + if (bufferValid) + { + pConfig->probeRespBcnIEsLen = bufferLength; + pConfig->pProbeRespBcnIEsBuffer = pBuffer; + } + else + { + vos_mem_free(pConfig->pProbeRespBcnIEsBuffer); + pConfig->probeRespBcnIEsLen = 0; + pConfig->pProbeRespBcnIEsBuffer = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("No Probe Resp beacone IE received in set beacon")); + } + break; + case eUPDATE_IE_PROBE_RESP: + if (bufferValid) + { + pConfig->probeRespIEsBufferLen= bufferLength; + pConfig->pProbeRespIEsBuffer = pBuffer; + } + else + { + vos_mem_free(pConfig->pProbeRespIEsBuffer); + pConfig->probeRespIEsBufferLen = 0; + pConfig->pProbeRespIEsBuffer = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("No Probe Response IE received in set beacon")); + } + break; + case eUPDATE_IE_ASSOC_RESP: + if (bufferValid) + { + pConfig->assocRespIEsLen = bufferLength; + pConfig->pAssocRespIEsBuffer = pBuffer; + } + else + { + vos_mem_free(pConfig->pAssocRespIEsBuffer); + pConfig->assocRespIEsLen = 0; + pConfig->pAssocRespIEsBuffer = NULL; + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("No Assoc Response IE received in set beacon")); + } + break; + default: + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + FL("No matching buffer type %d"), updateType); + break; } return (status); } -VOS_STATUS WLANSAP_ResetSapConfigAddIE(tsap_Config_t *pConfig ) +VOS_STATUS +WLANSAP_ResetSapConfigAddIE(tsap_Config_t *pConfig, + eUpdateIEsType updateType) { if (NULL == pConfig) { + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid Config pointer", __func__); return VOS_STATUS_E_FAULT; } - vos_mem_free( pConfig->addnIEsBuffer); - pConfig->addnIEsBufferLen = 0; - pConfig->addnIEsBuffer = NULL; + + switch (updateType) + { + case eUPDATE_IE_ALL: /*only used to reset*/ + case eUPDATE_IE_PROBE_RESP: + vos_mem_free( pConfig->pProbeRespIEsBuffer); + pConfig->probeRespIEsBufferLen = 0; + pConfig->pProbeRespIEsBuffer = NULL; + if(eUPDATE_IE_ALL != updateType) break; + + case eUPDATE_IE_ASSOC_RESP: + vos_mem_free( pConfig->pAssocRespIEsBuffer); + pConfig->assocRespIEsLen = 0; + pConfig->pAssocRespIEsBuffer = NULL; + if(eUPDATE_IE_ALL != updateType) break; + + case eUPDATE_IE_PROBE_BCN: + vos_mem_free(pConfig->pProbeRespBcnIEsBuffer ); + pConfig->probeRespBcnIEsLen = 0; + pConfig->pProbeRespBcnIEsBuffer = NULL; + if(eUPDATE_IE_ALL != updateType) break; + + default: + if(eUPDATE_IE_ALL != updateType) + VOS_TRACE( VOS_MODULE_ID_SAP, VOS_TRACE_LEVEL_ERROR, + FL("Invalid buffer type %d"), updateType); + break; + } return VOS_STATUS_SUCCESS; } diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index af3c39e53174..5a01f9f7996e 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -2239,6 +2239,425 @@ static int wma_extscan_change_results_event_handler(void *handle, } #endif +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +static int wma_unified_link_iface_stats_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_IFACE_LINK_STATS_EVENTID_param_tlvs *param_tlvs; + wmi_iface_link_stats_event_fixed_param *fixed_param; + wmi_iface_link_stats *link_stats; + wmi_wmm_ac_stats *ac_stats; + tSirLLStatsResults *link_stats_results; + u_int8_t *results, *t_link_stats, *t_ac_stats; + u_int32_t next_res_offset, next_ac_offset, count; + u_int32_t roaming_offset , roaming_size; + size_t link_stats_size, ac_stats_size, iface_info_size; + size_t link_stats_results_size; + + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + + if (!pMac) { + WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + return -EINVAL; + } + + if (!pMac->sme.pLinkLayerStatsIndCallback) { + WMA_LOGD("%s: HDD callback is null", __func__); + return -EINVAL; + } + + WMA_LOGD("%s: Posting Iface Stats event to HDD", __func__); + param_tlvs = (WMI_IFACE_LINK_STATS_EVENTID_param_tlvs *)cmd_param_info; + if (!param_tlvs) { + WMA_LOGA("%s: Invalid stats event", __func__); + return -EINVAL; + } + + /* + * cmd_param_info contains + * wmi_iface_link_stats_event_fixed_param fixed_param; + * wmi_iface_link_stats iface_link_stats; + * iface_link_stats->num_ac * size of(struct wmi_wmm_ac_stats) + */ + fixed_param = param_tlvs->fixed_param; + link_stats = param_tlvs->iface_link_stats; + ac_stats = param_tlvs->ac; + + if (!fixed_param || !link_stats || !ac_stats) { + WMA_LOGA("%s: Invalid param_tlvs for Iface Stats", __func__); + return -EINVAL; + } + + link_stats_size = sizeof(tSirWifiIfaceStat); + iface_info_size = sizeof(tSirWifiInterfaceInfo); + ac_stats_size = sizeof(tSirWifiWmmAcStat); + link_stats_results_size = sizeof(*link_stats_results) + + link_stats_size; + + link_stats_results = vos_mem_malloc(link_stats_results_size); + if (!link_stats_results) { + WMA_LOGD("%s: could not allocate mem for stats results-len %zu", + __func__, link_stats_results_size); + return -ENOMEM; + } + + WMA_LOGD("Interface stats from FW event buf"); + WMA_LOGD("Fixed Param:"); + WMA_LOGD("request_id %u vdev_id %u", + fixed_param->request_id,fixed_param->vdev_id); + + WMA_LOGD("Iface Stats:"); + WMA_LOGD("beacon_rx %u mgmt_rx %u mgmt_action_rx %u mgmt_action_tx %u " + "rssi_mgmt %u rssi_data %u rssi_ack %u num_peers %u " + "num_peer_events %u num_ac %u roam_state %u", + link_stats->beacon_rx, link_stats->mgmt_rx, + link_stats->mgmt_action_rx, link_stats->mgmt_action_tx, + link_stats->rssi_mgmt, link_stats->rssi_data, + link_stats->rssi_ack, link_stats->num_peers, + link_stats->num_peer_events, link_stats->num_ac, + link_stats->roam_state); + + vos_mem_zero(link_stats_results, link_stats_results_size); + + link_stats_results->paramId = WMI_LINK_STATS_IFACE; + link_stats_results->rspId = fixed_param->request_id; + link_stats_results->ifaceId = fixed_param->vdev_id; + link_stats_results->num_peers = 0; + link_stats_results->peer_event_number = 0; + link_stats_results->moreResultToFollow = 0; + + results = (u_int8_t *)link_stats_results->results; + t_link_stats = (u_int8_t *)link_stats; + t_ac_stats = (u_int8_t *)ac_stats; + + /* Copy roaming state */ + roaming_offset = offsetof(tSirWifiInterfaceInfo, roaming); + roaming_size = member_size(tSirWifiInterfaceInfo, roaming); + + vos_mem_copy(results + roaming_offset, &link_stats->roam_state, + roaming_size); + + vos_mem_copy(results + iface_info_size, + t_link_stats + WMI_TLV_HDR_SIZE, + link_stats_size - iface_info_size - WIFI_AC_MAX * ac_stats_size); + + next_res_offset = link_stats_size - WIFI_AC_MAX * ac_stats_size; + next_ac_offset = WMI_TLV_HDR_SIZE; + + WMA_LOGD("AC Stats:"); + for (count = 0; count < link_stats->num_ac; count++) { + WMA_LOGD("ac_type %u tx_mpdu %u rx_mpdu %u tx_mcast %u " + "rx_mcast %u rx_ampdu %u tx_ampdu %u mpdu_lost %u " + "retries %u retries_short %u retries_long %u " + "contention_time_min %u contention_time_max %u " + "contention_time_avg %u contention_num_samples %u", + ac_stats->ac_type, ac_stats->tx_mpdu, ac_stats->rx_mpdu, + ac_stats->tx_mcast, ac_stats->rx_mcast, + ac_stats->rx_ampdu,ac_stats->tx_ampdu, + ac_stats->mpdu_lost, ac_stats->retries, + ac_stats->retries_short, ac_stats->retries_long, + ac_stats->contention_time_min, + ac_stats->contention_time_max, + ac_stats->contention_time_avg, + ac_stats->contention_num_samples); + ac_stats++; + + vos_mem_copy(results + next_res_offset, + t_ac_stats + next_ac_offset, + ac_stats_size); + next_res_offset += ac_stats_size; + next_ac_offset += sizeof(*ac_stats); + } + + /* call hdd callback with Link Layer Statistics + * vdev_id/ifacId in link_stats_results will be + * used to retrieve the correct HDD context + */ + pMac->sme.pLinkLayerStatsIndCallback(pMac->pAdapter, + WDA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results); + WMA_LOGD("%s: Iface Stats event posted to HDD", __func__); + vos_mem_free(link_stats_results); + + return 0; +} + +static int wma_unified_link_peer_stats_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_PEER_LINK_STATS_EVENTID_param_tlvs *param_tlvs; + wmi_peer_stats_event_fixed_param *fixed_param; + wmi_peer_link_stats *peer_stats, *temp_peer_stats; + wmi_rate_stats *rate_stats; + tSirLLStatsResults *link_stats_results; + u_int8_t *results, *t_peer_stats, *t_rate_stats; + u_int32_t count, num_rates=0; + u_int32_t next_res_offset, next_peer_offset, next_rate_offset; + size_t peer_info_size, peer_stats_size, rate_stats_size; + size_t link_stats_results_size; + + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + + if (!pMac) { + WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + return -EINVAL; + } + + if (!pMac->sme.pLinkLayerStatsIndCallback) { + WMA_LOGD("%s: HDD callback is null", __func__); + return -EINVAL; + } + + WMA_LOGD("%s: Posting Peer Stats event to HDD", __func__); + param_tlvs = (WMI_PEER_LINK_STATS_EVENTID_param_tlvs *)cmd_param_info; + if (!param_tlvs) { + WMA_LOGA("%s: Invalid stats event", __func__); + return -EINVAL; + } + /* + * cmd_param_info contains + * wmi_peer_stats_event_fixed_param fixed_param; + * num_peers * size of(struct wmi_peer_link_stats) + * num_rates * size of(struct wmi_rate_stats) + * num_rates is the sum of the rates of all the peers. + */ + fixed_param = param_tlvs->fixed_param; + peer_stats = param_tlvs->peer_stats; + rate_stats = param_tlvs->peer_rate_stats; + + if (!fixed_param || !peer_stats || !rate_stats) { + WMA_LOGA("%s: Invalid param_tlvs for Peer Stats", __func__); + return -EINVAL; + } + + /* + * num_rates - sum of the rates of all the peers + */ + temp_peer_stats = (wmi_peer_link_stats*)peer_stats; + for (count = 0; count < fixed_param->num_peers; count++) { + num_rates += temp_peer_stats->num_rates; + temp_peer_stats++; + } + + peer_stats_size = sizeof(tSirWifiPeerStat); + peer_info_size = sizeof(tSirWifiPeerInfo); + rate_stats_size = sizeof(tSirWifiRateStat); + link_stats_results_size = sizeof(*link_stats_results) + peer_stats_size + + (fixed_param->num_peers * peer_info_size) + + (num_rates * rate_stats_size); + + link_stats_results = vos_mem_malloc(link_stats_results_size); + if (NULL == link_stats_results ) { + WMA_LOGD("%s: could not allocate mem for stats results-len %zu", + __func__, link_stats_results_size); + return -ENOMEM; + } + + WMA_LOGD("Peer stats from FW event buf"); + WMA_LOGD("Fixed Param:"); + WMA_LOGD("request_id %u num_peers %u peer_event_number %u more_data %u", + fixed_param->request_id, fixed_param->num_peers, + fixed_param->peer_event_number, fixed_param->more_data); + + vos_mem_zero(link_stats_results, link_stats_results_size); + + link_stats_results->paramId = WMI_LINK_STATS_ALL_PEER; + link_stats_results->rspId = fixed_param->request_id; + link_stats_results->ifaceId = 0; + link_stats_results->num_peers = fixed_param->num_peers; + link_stats_results->peer_event_number = fixed_param->peer_event_number; + link_stats_results->moreResultToFollow = fixed_param->more_data; + + vos_mem_copy(link_stats_results->results, + &fixed_param->num_peers, peer_stats_size); + + results = (u_int8_t *)link_stats_results->results; + t_peer_stats = (u_int8_t *)peer_stats; + t_rate_stats = (u_int8_t *)rate_stats; + next_res_offset = peer_stats_size; + next_peer_offset = WMI_TLV_HDR_SIZE; + next_rate_offset = WMI_TLV_HDR_SIZE; + for (count = 0; count < fixed_param->num_peers; count++) { + WMA_LOGD("Peer Info:"); + WMA_LOGD("peer_type %u capabilities %u num_rates %u", + peer_stats->peer_type, peer_stats->capabilities, + peer_stats->num_rates); + peer_stats++; + + vos_mem_copy(results + next_res_offset, + t_peer_stats + next_peer_offset, + peer_info_size); + next_res_offset += peer_info_size; + + /* Copy rate stats associated with this peer */ + for (count = 0; count < peer_stats->num_rates; count++) { + WMA_LOGD("Rate Stats Info:"); + WMA_LOGD("rate %u bitrate %u tx_mpdu %u rx_mpdu %u " + "mpdu_lost %u retries %u retries_short %u " + "retries_long %u", rate_stats->rate, + rate_stats->bitrate, rate_stats->tx_mpdu, + rate_stats->rx_mpdu, rate_stats->mpdu_lost, + rate_stats->retries, rate_stats->retries_short, + rate_stats->retries_long); + rate_stats++; + + vos_mem_copy(results + next_res_offset, + t_rate_stats + next_rate_offset, + rate_stats_size); + next_res_offset += rate_stats_size; + next_rate_offset += sizeof(*rate_stats); + } + next_peer_offset += sizeof(*peer_stats); + } + + /* call hdd callback with Link Layer Statistics + * vdev_id/ifacId in link_stats_results will be + * used to retrieve the correct HDD context + */ + pMac->sme.pLinkLayerStatsIndCallback(pMac->pAdapter, + WDA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results); + WMA_LOGD("%s: Peer Stats event posted to HDD", __func__); + vos_mem_free(link_stats_results); + + return 0; +} + +static int wma_unified_link_radio_stats_event_handler(void *handle, + u_int8_t *cmd_param_info, u_int32_t len) +{ + tp_wma_handle wma_handle = (tp_wma_handle) handle; + WMI_RADIO_LINK_STATS_EVENTID_param_tlvs *param_tlvs; + wmi_radio_link_stats_event_fixed_param *fixed_param; + wmi_radio_link_stats *radio_stats; + wmi_channel_stats *channel_stats; + tSirLLStatsResults *link_stats_results; + u_int8_t *results, *t_radio_stats, *t_channel_stats; + u_int32_t next_res_offset, next_chan_offset, count; + size_t radio_stats_size, chan_stats_size; + size_t link_stats_results_size; + + tpAniSirGlobal pMac = (tpAniSirGlobal )vos_get_context(VOS_MODULE_ID_PE, + wma_handle->vos_context); + + if (!pMac) { + WMA_LOGD("%s: NULL pMac ptr. Exiting", __func__); + return -EINVAL; + } + + if (!pMac->sme.pLinkLayerStatsIndCallback) { + WMA_LOGD("%s: HDD callback is null", __func__); + return -EINVAL; + } + + WMA_LOGD("%s: Posting Radio Stats event to HDD", __func__); + param_tlvs = (WMI_RADIO_LINK_STATS_EVENTID_param_tlvs *)cmd_param_info; + if (!param_tlvs) { + WMA_LOGA("%s: Invalid stats event", __func__); + return -EINVAL; + } + + /* + * cmd_param_info contains + * wmi_radio_link_stats_event_fixed_param fixed_param; + * size of(struct wmi_radio_link_stats); + * num_channels * size of(struct wmi_channel_stats) + */ + fixed_param = param_tlvs->fixed_param; + radio_stats = param_tlvs->radio_stats; + channel_stats = param_tlvs->channel_stats; + + if (!fixed_param || !radio_stats || !channel_stats) { + WMA_LOGA("%s: Invalid param_tlvs for Radio Stats", __func__); + return -EINVAL; + } + + radio_stats_size = sizeof(tSirWifiRadioStat); + chan_stats_size = sizeof(tSirWifiChannelStats); + link_stats_results_size = sizeof(*link_stats_results) + + radio_stats_size + + (radio_stats->num_channels * chan_stats_size); + + link_stats_results = vos_mem_malloc(link_stats_results_size); + if (NULL == link_stats_results ) { + WMA_LOGD("%s: could not allocate mem for stats results-len %zu", + __func__, link_stats_results_size); + return -ENOMEM; + } + + WMA_LOGD("Radio stats from FW event buf"); + WMA_LOGD("Fixed Param:"); + WMA_LOGD("request_id %u num_radio %u more_radio_events %u", + fixed_param->request_id, fixed_param->num_radio, + fixed_param->more_radio_events); + + WMA_LOGD("Radio Info"); + WMA_LOGD("radio_id %u on_time %u tx_time %u rx_time %u on_time_scan %u " + "on_time_nbd %u on_time_gscan %u on_time_roam_scan %u " + "on_time_pno_scan %u on_time_hs20 %u num_channels %u", + radio_stats->radio_id, radio_stats->on_time, + radio_stats->tx_time, radio_stats->rx_time, + radio_stats->on_time_scan, radio_stats->on_time_nbd, + radio_stats->on_time_gscan, + radio_stats->on_time_roam_scan, + radio_stats->on_time_pno_scan, + radio_stats->on_time_hs20, + radio_stats->num_channels); + + vos_mem_zero(link_stats_results, link_stats_results_size); + + link_stats_results->paramId = WMI_LINK_STATS_RADIO; + link_stats_results->rspId = fixed_param->request_id; + link_stats_results->ifaceId = 0; + link_stats_results->num_radio = fixed_param->num_radio; + link_stats_results->peer_event_number = 0; + link_stats_results->moreResultToFollow = fixed_param->more_radio_events; + + results = (u_int8_t *)link_stats_results->results; + t_radio_stats = (u_int8_t *)radio_stats; + t_channel_stats = (u_int8_t *)channel_stats; + + vos_mem_copy(results, t_radio_stats + WMI_TLV_HDR_SIZE, + radio_stats_size); + + next_res_offset = radio_stats_size; + next_chan_offset = WMI_TLV_HDR_SIZE; + WMA_LOGD("Channel Stats Info"); + for (count = 0; count < radio_stats->num_channels; count++) { + WMA_LOGD("channel_width %u center_freq %u center_freq0 %u " + "center_freq1 %u radio_awake_time %u cca_busy_time %u", + channel_stats->channel_width, channel_stats->center_freq, + channel_stats->center_freq0, channel_stats->center_freq1, + channel_stats->radio_awake_time, + channel_stats->cca_busy_time); + channel_stats++; + + vos_mem_copy(results + next_res_offset, + t_channel_stats + next_chan_offset, + chan_stats_size); + next_res_offset += chan_stats_size; + next_chan_offset += sizeof(*channel_stats); + } + + /* call hdd callback with Link Layer Statistics + * vdev_id/ifacId in link_stats_results will be + * used to retrieve the correct HDD context + */ + pMac->sme.pLinkLayerStatsIndCallback(pMac->pAdapter, + WDA_LINK_LAYER_STATS_RESULTS_RSP, + link_stats_results); + WMA_LOGD("%s: Radio Stats event posted to HDD", __func__); + vos_mem_free(link_stats_results); + + return 0; +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + #ifndef QCA_WIFI_ISOC u_int8_t *wma_add_p2p_ie(u_int8_t *frm) { @@ -3427,6 +3846,33 @@ static int wma_peer_state_change_event_handler(void *handle, return 0; } +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +/* + * Register all the Link Layer Stats related event + * handler + */ +static void +wma_register_ll_stats_event_handler(tp_wma_handle wma_handle) +{ + if (NULL == wma_handle) { + WMA_LOGE("%s: wma_handle is NULL", __func__); + return; + } + + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_IFACE_LINK_STATS_EVENTID, + wma_unified_link_iface_stats_event_handler); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_PEER_LINK_STATS_EVENTID, + wma_unified_link_peer_stats_event_handler); + wmi_unified_register_event_handler(wma_handle->wmi_handle, + WMI_RADIO_LINK_STATS_EVENTID, + wma_unified_link_radio_stats_event_handler); + + return; +} +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + /* * Send WMI_DFS_PHYERR_FILTER_ENA_CMDID or * WMI_DFS_PHYERR_FILTER_DIS_CMDID command @@ -3964,6 +4410,14 @@ VOS_STATUS WDA_open(v_VOID_t *vos_context, v_VOID_t *os_ctx, WMI_OFFLOAD_BCN_TX_STATUS_EVENTID, wma_unified_bcntx_status_event_handler); +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + /* Register event handler for processing Link Layer Stats + * response from the FW + */ + wma_register_ll_stats_event_handler(wma_handle); + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + /* Firmware debug log */ vos_status = dbglog_init(wma_handle->wmi_handle); if (vos_status != VOS_STATUS_SUCCESS) { @@ -18083,6 +18537,177 @@ void wma_hidden_ssid_vdev_restart(tp_wma_handle wma_handle, } } +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +static VOS_STATUS wma_process_ll_stats_clearReq +( + tp_wma_handle wma, + const tpSirLLStatsClearReq clearReq +) +{ + wmi_clear_link_stats_cmd_fixed_param *cmd; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + int ret; + + if (!clearReq || !wma) { + WMA_LOGE("%s: input pointer is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma->wmi_handle, len); + + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + vos_mem_zero(buf_ptr, len); + cmd = (wmi_clear_link_stats_cmd_fixed_param *) buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_clear_link_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_clear_link_stats_cmd_fixed_param)); + + cmd->stop_stats_collection_req = clearReq->stopReq; + cmd->vdev_id = clearReq->staId; + cmd->stats_clear_req_mask = clearReq->statsClearReqMask; + + WMI_CHAR_ARRAY_TO_MAC_ADDR(wma->interfaces[clearReq->staId].addr, + &cmd->peer_macaddr); + + WMA_LOGD("LINK_LAYER_STATS - Clear Request Params"); + WMA_LOGD("StopReq : %d", cmd->stop_stats_collection_req); + WMA_LOGD("Vdev Id : %d", cmd->vdev_id); + WMA_LOGD("Clear Stat Mask : %d", cmd->stats_clear_req_mask); + WMA_LOGD("Peer MAC Addr : %pM", wma->interfaces[clearReq->staId].addr); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_CLEAR_LINK_STATS_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send clear link stats req", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Clear Link Layer Stats request sent successfully"); + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_process_ll_stats_setReq +( + tp_wma_handle wma, + const tpSirLLStatsSetReq setReq +) +{ + wmi_start_link_stats_cmd_fixed_param *cmd; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + int ret; + + if (!setReq || !wma) { + WMA_LOGE("%s: input pointer is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma->wmi_handle, len); + + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + vos_mem_zero(buf_ptr, len); + cmd = (wmi_start_link_stats_cmd_fixed_param *) buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_start_link_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_start_link_stats_cmd_fixed_param)); + + cmd->mpdu_size_threshold = setReq->mpduSizeThreshold; + cmd->aggressive_statistics_gathering = setReq->aggressiveStatisticsGathering; + + WMA_LOGD("LINK_LAYER_STATS - Start/Set Request Params"); + WMA_LOGD("MPDU Size Thresh : %d", cmd->mpdu_size_threshold); + WMA_LOGD("Aggressive Gather: %d", cmd->aggressive_statistics_gathering); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_START_LINK_STATS_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send set link stats request", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Set Link Layer Stats request sent successfully"); + return VOS_STATUS_SUCCESS; +} + +static VOS_STATUS wma_process_ll_stats_getReq +( + tp_wma_handle wma, + const tpSirLLStatsGetReq getReq +) +{ + wmi_request_link_stats_cmd_fixed_param *cmd; + int32_t len; + wmi_buf_t buf; + u_int8_t *buf_ptr; + int ret; + + if (!getReq || !wma) { + WMA_LOGE("%s: input pointer is NULL", __func__); + return VOS_STATUS_E_FAILURE; + } + + len = sizeof(*cmd); + buf = wmi_buf_alloc(wma->wmi_handle, len); + + if (!buf) { + WMA_LOGE("%s: Failed allocate wmi buffer", __func__); + return VOS_STATUS_E_NOMEM; + } + + buf_ptr = (u_int8_t *) wmi_buf_data(buf); + vos_mem_zero(buf_ptr, len); + cmd = (wmi_request_link_stats_cmd_fixed_param *) buf_ptr; + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_request_link_stats_cmd_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_request_link_stats_cmd_fixed_param)); + + cmd->request_id = getReq->reqId; + cmd->stats_type = getReq->paramIdMask; + cmd->vdev_id = getReq->staId; + + WMI_CHAR_ARRAY_TO_MAC_ADDR(wma->interfaces[getReq->staId].addr, + &cmd->peer_macaddr); + + WMA_LOGD("LINK_LAYER_STATS - Get Request Params"); + WMA_LOGD("Request ID : %d", cmd->request_id); + WMA_LOGD("Stats Type : %d", cmd->stats_type); + WMA_LOGD("Vdev ID : %d", cmd->vdev_id); + WMA_LOGD("Peer MAC Addr : %pM", wma->interfaces[getReq->staId].addr); + + ret = wmi_unified_cmd_send(wma->wmi_handle, buf, len, + WMI_REQUEST_LINK_STATS_CMDID); + if (ret) { + WMA_LOGE("%s: Failed to send get link stats request", __func__); + wmi_buf_free(buf); + return VOS_STATUS_E_FAILURE; + } + + WMA_LOGD("Get Link Layer Stats request sent successfully"); + return VOS_STATUS_SUCCESS; +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + #ifdef FEATURE_WLAN_EXTSCAN VOS_STATUS wma_get_buf_extscan_start_cmd(tp_wma_handle wma_handle, tSirWifiScanCmdReqParams *pstart, @@ -19223,7 +19848,6 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) (tSirModemPowerStateInd *)msg->bodyptr); vos_mem_free(msg->bodyptr); break; - case WDA_VDEV_STOP_IND: wma_vdev_stop_ind(wma_handle, msg->bodyptr); vos_mem_free(msg->bodyptr); @@ -19299,6 +19923,23 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) vos_mem_free(msg->bodyptr); break; #endif +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + case WDA_LINK_LAYER_STATS_CLEAR_REQ: + wma_process_ll_stats_clearReq(wma_handle, + (tpSirLLStatsClearReq)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_LINK_LAYER_STATS_SET_REQ: + wma_process_ll_stats_setReq(wma_handle, + (tpSirLLStatsSetReq)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; + case WDA_LINK_LAYER_STATS_GET_REQ: + wma_process_ll_stats_getReq(wma_handle, + (tpSirLLStatsGetReq)msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ default: WMA_LOGD("unknow msg type %x", msg->type); /* Do Nothing? MSG Body should be freed at here */ diff --git a/CORE/SERVICES/WMI/wmi_unified.c b/CORE/SERVICES/WMI/wmi_unified.c index d4b8ecd9a5d0..29bca2bfcdc9 100644 --- a/CORE/SERVICES/WMI/wmi_unified.c +++ b/CORE/SERVICES/WMI/wmi_unified.c @@ -51,12 +51,17 @@ #endif #define WMI_MIN_HEAD_ROOM 64 -#ifdef WMI_INTERFACE_EVENT_LOGGING +#ifdef WMI_INTERFACE_EVENT_LOGGING +/* WMI commands */ u_int32_t g_wmi_command_buf_idx = 0; struct wmi_command_debug wmi_command_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY]; +/* WMI commands TX completed */ +u_int32_t g_wmi_command_tx_cmp_buf_idx = 0; +struct wmi_command_debug wmi_command_tx_cmp_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY]; +/* WMI events */ u_int32_t g_wmi_event_buf_idx = 0; struct wmi_event_debug wmi_event_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY]; @@ -64,22 +69,32 @@ struct wmi_event_debug wmi_event_log_buffer[WMI_EVENT_DEBUG_MAX_ENTRY]; if (WMI_EVENT_DEBUG_MAX_ENTRY <= g_wmi_command_buf_idx) \ g_wmi_command_buf_idx = 0; \ wmi_command_log_buffer[g_wmi_command_buf_idx].command = a; \ - adf_os_mem_copy(wmi_command_log_buffer[g_wmi_command_buf_idx].data, b , 16);\ + adf_os_mem_copy(wmi_command_log_buffer[g_wmi_command_buf_idx].data, b, 16);\ wmi_command_log_buffer[g_wmi_command_buf_idx].time = \ adf_get_boottime(); \ g_wmi_command_buf_idx++; \ } +#define WMI_COMMAND_TX_CMP_RECORD(a, b) { \ + if (WMI_EVENT_DEBUG_MAX_ENTRY <= g_wmi_command_tx_cmp_buf_idx) \ + g_wmi_command_tx_cmp_buf_idx = 0; \ + wmi_command_tx_cmp_log_buffer[g_wmi_command_tx_cmp_buf_idx].command = a;\ + adf_os_mem_copy(wmi_command_tx_cmp_log_buffer \ + [g_wmi_command_tx_cmp_buf_idx].data, b, 16); \ + wmi_command_tx_cmp_log_buffer[g_wmi_command_tx_cmp_buf_idx].time =\ + adf_get_boottime(); \ + g_wmi_command_tx_cmp_buf_idx++; \ +} + #define WMI_EVENT_RECORD(a, b) { \ if (WMI_EVENT_DEBUG_MAX_ENTRY <= g_wmi_event_buf_idx) \ g_wmi_event_buf_idx = 0; \ wmi_event_log_buffer[g_wmi_event_buf_idx].event = a; \ - adf_os_mem_copy(wmi_event_log_buffer[g_wmi_event_buf_idx].data, b , 16);\ + adf_os_mem_copy(wmi_event_log_buffer[g_wmi_event_buf_idx].data, b, 16);\ wmi_event_log_buffer[g_wmi_event_buf_idx].time = \ adf_get_boottime(); \ g_wmi_event_buf_idx++; \ } - #endif /*WMI_INTERFACE_EVENT_LOGGING*/ @@ -904,8 +919,21 @@ void wmi_htc_tx_complete(void *ctx, HTC_PACKET *htc_pkt) { struct wmi_unified *wmi_handle = (struct wmi_unified *)ctx; wmi_buf_t wmi_cmd_buf = GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt); +#ifdef WMI_INTERFACE_EVENT_LOGGING + u_int32_t cmd_id; +#endif ASSERT(wmi_cmd_buf); +#ifdef WMI_INTERFACE_EVENT_LOGGING + cmd_id = WMI_GET_FIELD(adf_nbuf_data(wmi_cmd_buf), + WMI_CMD_HDR, COMMANDID); + adf_os_spin_lock_bh(&wmi_handle->wmi_record_lock); + /* Record 16 bytes of WMI cmd tx complete data + - exclude TLV and WMI headers */ + WMI_COMMAND_TX_CMP_RECORD(cmd_id, + ((u_int32_t *)adf_nbuf_data(wmi_cmd_buf) + 2)); + adf_os_spin_unlock_bh(&wmi_handle->wmi_record_lock); +#endif adf_nbuf_free(wmi_cmd_buf); adf_os_mem_free(htc_pkt); adf_os_atomic_dec(&wmi_handle->pending_cmds); diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h index 10c40286bd2c..a5162b11143b 100644 --- a/CORE/SME/inc/csrInternal.h +++ b/CORE/SME/inc/csrInternal.h @@ -1493,22 +1493,30 @@ csrRoamSendChanSwIERequest(tpAniSirGlobal pMac, tCsrBssid bssid, tANI_U8 targetChannel, tANI_U8 csaIeReqd); /*---------------------------------------------------------------------------- + \fn csrRoamModifyAddIEs + \brief This function sends msg to modify the additional IE buffers in PE + \param pMac - pMac global structure + \param pModifyIE - pointer to tSirModifyIE structure + \param updateType - Type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus +csrRoamModifyAddIEs(tpAniSirGlobal pMac, + tSirModifyIE *pModifyIE, + eUpdateIEsType updateType); + + +/*---------------------------------------------------------------------------- \fn csrRoamUpdateAddIEs \brief This function sends msg to updates the additional IE buffers in PE \param pMac - pMac global structure - \param sessionId - SME session id - \param bssid - BSSID - \param additionIEBuffer - buffer containing addition IE from hostapd - \param length - length of buffer - \param append - append or replace completely + \param pUpdateIE - pointer to tSirUpdateIE structure + \param updateType, - type of buffer \- return Success or failure -----------------------------------------------------------------------------*/ eHalStatus csrRoamUpdateAddIEs(tpAniSirGlobal pMac, - tANI_U8 sessionId, - tSirMacAddr bssid, - tANI_U8 *additionIEBuffer, - tANI_U16 length, - boolean append); + tSirUpdateIE *pUpdateIE, + eUpdateIEsType updateType); #endif diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h index f0bb2744ede5..c2f457e539a7 100644 --- a/CORE/SME/inc/smeInternal.h +++ b/CORE/SME/inc/smeInternal.h @@ -149,6 +149,10 @@ typedef struct tagSmeStruct #ifdef FEATURE_WLAN_CH_AVOID void (*pChAvoidNotificationCb) (void *hdd_context, void *indi_param); #endif /* FEATURE_WLAN_CH_AVOID */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + void(*pLinkLayerStatsIndCallback)(void *callbackContext, + int indType, void *pRsp); +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ /* Maximum interfaces allowed by the host */ tANI_U8 max_intf_count; void (* StatsExtCallback) (void *, tStatsExtEvent *); diff --git a/CORE/SME/inc/sme_Api.h b/CORE/SME/inc/sme_Api.h index 49ebc2885799..6d73a75aabbf 100644 --- a/CORE/SME/inc/sme_Api.h +++ b/CORE/SME/inc/sme_Api.h @@ -3471,7 +3471,6 @@ sme_StopBatchScanInd #endif - /* * SME API to enable/disable idle mode powersave * This should be called only if powersave offload @@ -3598,22 +3597,28 @@ eHalStatus sme_GetLinkSpeed(tHalHandle hHal,tSirLinkSpeedInfo *lsReq,void *plsCo #endif /*---------------------------------------------------------------------------- + \fn sme_ModifyAddIE + \brief This function sends msg to updates the additional IE buffers in PE + \param hHal - global structure + \param pModifyIE - pointer to tSirModifyIE structure + \param updateType - type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus sme_ModifyAddIE(tHalHandle hHal, + tSirModifyIE *pModifyIE, + eUpdateIEsType updateType); + +/*---------------------------------------------------------------------------- \fn sme_UpdateAddIE \brief This function sends msg to updates the additional IE buffers in PE \param hHal - global structure - \param sessionId - SME session id - \param bssid - BSSID - \param additionIEBuffer - buffer containing addition IE from hostapd - \param length - length of buffer - \param append - append or replace completely + \param pUpdateIE - pointer to structure tSirUpdateIE + \param updateType - Type of buffer \- return Success or failure -----------------------------------------------------------------------------*/ eHalStatus sme_UpdateAddIE(tHalHandle hHal, - tANI_U8 sessionId, - tSirMacAddr bssid, - tANI_U8 *additionIEBuffer, - tANI_U16 length, - boolean append); + tSirUpdateIE *pUpdateIE, + eUpdateIEsType updateType); eHalStatus sme_UpdateConnectDebug(tHalHandle hHal, tANI_U32 set_value); eHalStatus sme_ApDisableIntraBssFwd(tHalHandle hHal, tANI_U8 sessionId, @@ -3783,4 +3788,53 @@ eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal, eHalStatus sme_abortRoamScan(tHalHandle hHal); #endif //#if WLAN_FEATURE_ROAM_SCAN_OFFLOAD + +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsClearReq + \brief SME API to clear Link Layer Statistics + \param hHal + \param pclearStatsReq: Link Layer clear stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsClearReq (tHalHandle hHal, + tSirLLStatsClearReq *pclearStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsSetReq + \brief SME API to set the Link Layer Statistics + \param hHal + \param psetStatsReq: Link Layer set stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsSetReq (tHalHandle hHal, + tSirLLStatsSetReq *psetStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsGetReq + \brief SME API to get the Link Layer Statistics + \param hHal + \param pgetStatsReq: Link Layer get stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsGetReq (tHalHandle hHal, + tSirLLStatsGetReq *pgetStatsReq); + +/* --------------------------------------------------------------------------- + \fn sme_SetLinkLayerStatsIndCB + \brief SME API to trigger the stats are available after get request + \param hHal + \param callbackRoutine - HDD callback which needs to be invoked after + getting status notification from FW + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetLinkLayerStatsIndCB +( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp) +); + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + #endif //#if !defined( __SME_API_H ) diff --git a/CORE/SME/inc/sme_QosApi.h b/CORE/SME/inc/sme_QosApi.h index 66c191391313..4c138481983b 100644 --- a/CORE/SME/inc/sme_QosApi.h +++ b/CORE/SME/inc/sme_QosApi.h @@ -382,9 +382,11 @@ void sme_QosUpdateHandOff(v_U8_t sessionId, qos mapping table maintained in HDD \param hHal - The handle returned by macOpen. \param dscpmapping - pointer to the qos mapping structure in HDD + \param sessionId - session id \sa -------------------------------------------------------------------------*/ -eHalStatus sme_UpdateDSCPtoUPMapping( tHalHandle hHal, - sme_QosWmmUpType* dscpmapping); +VOS_STATUS sme_UpdateDSCPtoUPMapping(tHalHandle hHal, + sme_QosWmmUpType* dscpmapping, v_U8_t sessionId); + #endif //#if !defined( __SME_QOSAPI_H ) diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index 476e6009aca3..3ad86f28d290 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -1138,6 +1138,7 @@ static void initConfigParam(tpAniSirGlobal pMac) //BMPS_WORKAROUND_NOT_NEEDED pMac->roam.configParam.doBMPSWorkaround = 0; + pMac->roam.configParam.nInitialDwellTime = 0; } eCsrBand csrGetCurrentBand(tHalHandle hHal) { @@ -1996,6 +1997,8 @@ eHalStatus csrGetConfigParam(tpAniSirGlobal pMac, tCsrConfigParam *pParam) pMac->roam.configParam.isCoalesingInIBSSAllowed; pParam->allowDFSChannelRoam = pMac->roam.configParam.allowDFSChannelRoam; + pParam->nInitialDwellTime = + pMac->roam.configParam.nInitialDwellTime; csrSetChannels(pMac, pParam); status = eHAL_STATUS_SUCCESS; @@ -12020,9 +12023,30 @@ eHalStatus csrRoamIssueStartBss( tpAniSirGlobal pMac, tANI_U32 sessionId, tCsrRo pParam->mfpRequired = (0 != pProfile->MFPRequired); #endif - pParam->addIeParams.dataLen = pProfile->addIeParams.dataLen; - pParam->addIeParams.data_buff = pProfile->addIeParams.data_buff; + pParam->addIeParams.probeRespDataLen = + pProfile->addIeParams.probeRespDataLen; + pParam->addIeParams.probeRespData_buff = + pProfile->addIeParams.probeRespData_buff; + pParam->addIeParams.assocRespDataLen = + pProfile->addIeParams.assocRespDataLen; + pParam->addIeParams.assocRespData_buff = + pProfile->addIeParams.assocRespData_buff; + + if (CSR_IS_IBSS( pProfile )) + { + pParam->addIeParams.probeRespBCNDataLen = + pProfile->nWPAReqIELength; + pParam->addIeParams.probeRespBCNData_buff = + pProfile->pWPAReqIE; + } + else + { + pParam->addIeParams.probeRespBCNDataLen = + pProfile->addIeParams.probeRespBCNDataLen; + pParam->addIeParams.probeRespBCNData_buff = + pProfile->addIeParams.probeRespBCNData_buff; + } // When starting an IBSS, start on the channel from the Profile. status = csrSendMBStartBssReqMsg( pMac, sessionId, pProfile->BSSType, pParam, pBssDesc ); return (status); @@ -17948,6 +17972,73 @@ eHalStatus csrRoamStartBeaconReq( tpAniSirGlobal pMac, tCsrBssid bssid, /*---------------------------------------------------------------------------- + \fn csrRoamModifyAddIEs + \brief This function sends msg to modify the additional IE buffers in PE + \param pMac - pMac global structure + \param pModifyIE - pointer to tSirModifyIE structure + \param updateType - Type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus +csrRoamModifyAddIEs(tpAniSirGlobal pMac, + tSirModifyIE *pModifyIE, + eUpdateIEsType updateType) +{ + tpSirModifyIEsInd pModifyAddIEInd = NULL; + tANI_U8 *pLocalBuffer = NULL; + eHalStatus status; + + /* following buffer will be freed by consumer (PE) */ + pLocalBuffer = vos_mem_malloc(pModifyIE->ieBufferlength); + + if (NULL == pLocalBuffer) + { + smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!")); + return eHAL_STATUS_FAILED_ALLOC; + } + + pModifyAddIEInd = vos_mem_malloc(sizeof(tSirModifyIEsInd)); + if (NULL == pModifyAddIEInd) + { + smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!")); + vos_mem_free(pLocalBuffer); + return eHAL_STATUS_FAILED_ALLOC; + } + + /*copy the IE buffer */ + vos_mem_copy(pLocalBuffer, pModifyIE->pIEBuffer, pModifyIE->ieBufferlength); + vos_mem_zero(pModifyAddIEInd, sizeof(tSirModifyIEsInd)); + + pModifyAddIEInd->msgType = + pal_cpu_to_be16((tANI_U16)eWNI_SME_MODIFY_ADDITIONAL_IES); + pModifyAddIEInd->msgLen = sizeof(tSirModifyIEsInd); + + vos_mem_copy(pModifyAddIEInd->modifyIE.bssid, pModifyIE->bssid, + sizeof(tSirMacAddr)); + + pModifyAddIEInd->modifyIE.smeSessionId = pModifyIE->smeSessionId; + pModifyAddIEInd->modifyIE.notify = pModifyIE->notify; + pModifyAddIEInd->modifyIE.ieID = pModifyIE->ieID; + pModifyAddIEInd->modifyIE.ieIDLen = pModifyIE->ieIDLen; + pModifyAddIEInd->modifyIE.pIEBuffer = pLocalBuffer; + pModifyAddIEInd->modifyIE.ieBufferlength = pModifyIE->ieBufferlength; + + pModifyAddIEInd->updateType = updateType; + + status = palSendMBMessage(pMac->hHdd, pModifyAddIEInd); + if (!HAL_STATUS_SUCCESS(status)) + { + smsLog(pMac, LOGE, + FL("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg" + "!!! status %d"), status); + vos_mem_free(pLocalBuffer); + vos_mem_free(pModifyAddIEInd); + } + return status; +} + + +/*---------------------------------------------------------------------------- \fn csrRoamUpdateAddIEs \brief This function sends msg to updates the additional IE buffers in PE \param pMac - pMac global structure @@ -17955,22 +18046,21 @@ eHalStatus csrRoamStartBeaconReq( tpAniSirGlobal pMac, tCsrBssid bssid, \param bssid - BSSID \param additionIEBuffer - buffer containing addition IE from hostapd \param length - length of buffer + \param updateType - Type of buffer \param append - append or replace completely \- return Success or failure -----------------------------------------------------------------------------*/ eHalStatus csrRoamUpdateAddIEs(tpAniSirGlobal pMac, - tANI_U8 sessionId, - tSirMacAddr bssid, - tANI_U8 *additionIEBuffer, - tANI_U16 length, - boolean append) + tSirUpdateIE *pUpdateIE, + eUpdateIEsType updateType) { - tpUpdateAIEs pUpdateAIEs = NULL; + tpSirUpdateIEsInd pUpdateAddIEs = NULL; tANI_U8 *pLocalBuffer = NULL; eHalStatus status; + /* following buffer will be freed by consumer (PE) */ - pLocalBuffer = vos_mem_malloc(length); + pLocalBuffer = vos_mem_malloc(pUpdateIE->ieBufferlength); if (NULL == pLocalBuffer) { @@ -17978,33 +18068,39 @@ csrRoamUpdateAddIEs(tpAniSirGlobal pMac, return eHAL_STATUS_FAILED_ALLOC; } - pUpdateAIEs = vos_mem_malloc(sizeof(tUpdateAIEs)); - if (NULL == pUpdateAIEs) + pUpdateAddIEs = vos_mem_malloc(sizeof(tpSirUpdateIEsInd)); + if (NULL == pUpdateAddIEs) { smsLog(pMac, LOGE, FL("Memory Allocation Failure!!!")); vos_mem_free(pLocalBuffer); return eHAL_STATUS_FAILED_ALLOC; } - vos_mem_copy(pLocalBuffer, additionIEBuffer, length); - vos_mem_zero(pUpdateAIEs, sizeof(tUpdateAIEs)); + vos_mem_copy(pLocalBuffer, pUpdateIE->pAdditionIEBuffer, + pUpdateIE->ieBufferlength); + vos_mem_zero(pUpdateAddIEs, sizeof(tpSirUpdateIEsInd)); - pUpdateAIEs->msgType = + pUpdateAddIEs->msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_UPDATE_ADDITIONAL_IES); - pUpdateAIEs->msgLen = sizeof(tUpdateAIEs); - vos_mem_copy(pUpdateAIEs->bssid, bssid, sizeof(tSirMacAddr)); - pUpdateAIEs->smeSessionId = sessionId; - pUpdateAIEs->pAdditionIEBuffer = pLocalBuffer; - pUpdateAIEs->length = length; - pUpdateAIEs->append = append; - status = palSendMBMessage(pMac->hHdd, pUpdateAIEs); + pUpdateAddIEs->msgLen = sizeof(tSirUpdateIEsInd); + + vos_mem_copy(pUpdateAddIEs->updateIE.bssid, pUpdateIE->bssid, sizeof(tSirMacAddr)); + + pUpdateAddIEs->updateIE.smeSessionId = pUpdateIE->smeSessionId; + pUpdateAddIEs->updateIE.append = pUpdateIE->append; + pUpdateAddIEs->updateIE.ieBufferlength = pUpdateIE->ieBufferlength; + pUpdateAddIEs->updateIE.pAdditionIEBuffer = pLocalBuffer; + + pUpdateAddIEs->updateType = updateType; + + status = palSendMBMessage(pMac->hHdd, pUpdateAddIEs); if (!HAL_STATUS_SUCCESS(status)) { smsLog(pMac, LOGE, FL("Failed to send eWNI_SME_UPDATE_ADDTIONAL_IES msg" "!!! status %d"), status); vos_mem_free(pLocalBuffer); - vos_mem_free(pUpdateAIEs); + vos_mem_free(pUpdateAddIEs); } return status; } diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 93caa8058f91..6dcd39b05057 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -12631,23 +12631,43 @@ v_U8_t sme_GetDFSScanMode(tHalHandle hHal) return pMac->roam.configParam.allowDFSChannelRoam; } + +/*---------------------------------------------------------------------------- + \fn sme_ModifyAddIE + \brief This function sends msg to updates the additional IE buffers in PE + \param hHal - global structure + \param pModifyIE - pointer to tModifyIE structure + \param updateType - type of buffer + \- return Success or failure +-----------------------------------------------------------------------------*/ +eHalStatus sme_ModifyAddIE(tHalHandle hHal, + tSirModifyIE *pModifyIE, + eUpdateIEsType updateType) +{ + eHalStatus status = eHAL_STATUS_FAILURE; + tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); + status = sme_AcquireGlobalLock( &pMac->sme ); + + if ( HAL_STATUS_SUCCESS( status ) ) + { + status = csrRoamModifyAddIEs(pMac, pModifyIE, updateType); + sme_ReleaseGlobalLock( &pMac->sme ); + } + return (status); +} + + /*---------------------------------------------------------------------------- - \fn sme_UpdateAIE + \fn sme_UpdateAddIE \brief This function sends msg to updates the additional IE buffers in PE \param hHal - global structure - \param sessionId - SME session id - \param bssid - BSSID - \param additionIEBuffer - buffer containing addition IE from hostapd - \param length - length of buffer - \param append - append or replace completely + \param pUpdateIE - pointer to structure tUpdateIE + \param updateType - type of buffer \- return Success or failure -----------------------------------------------------------------------------*/ eHalStatus sme_UpdateAddIE(tHalHandle hHal, - tANI_U8 sessionId, - tSirMacAddr bssid, - tANI_U8 *additionIEBuffer, - tANI_U16 length, - boolean append) + tSirUpdateIE *pUpdateIE, + eUpdateIEsType updateType) { eHalStatus status = eHAL_STATUS_FAILURE; tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); @@ -12655,8 +12675,7 @@ eHalStatus sme_UpdateAddIE(tHalHandle hHal, if ( HAL_STATUS_SUCCESS( status ) ) { - status = csrRoamUpdateAddIEs(pMac, sessionId, bssid, additionIEBuffer, - length, append); + status = csrRoamUpdateAddIEs(pMac, pUpdateIE, updateType); sme_ReleaseGlobalLock( &pMac->sme ); } return (status); @@ -12681,16 +12700,48 @@ tANI_BOOLEAN sme_staInMiddleOfRoaming(tHalHandle hHal) return ret; } -eHalStatus sme_UpdateDSCPtoUPMapping( tHalHandle hHal, - sme_QosWmmUpType *dscpmapping) +VOS_STATUS sme_UpdateDSCPtoUPMapping( tHalHandle hHal, + sme_QosWmmUpType *dscpmapping, + v_U8_t sessionId ) { tpAniSirGlobal pMac = PMAC_STRUCT( hHal ); eHalStatus status = eHAL_STATUS_SUCCESS; - v_U8_t i, j; + v_U8_t i, j, peSessionId; + tCsrRoamSession *pCsrSession = NULL; + tpPESession pSession = NULL; + status = sme_AcquireGlobalLock( &pMac->sme ); if ( HAL_STATUS_SUCCESS( status ) ) { - if ( !pMac->QosMapSet.present ) + if (!CSR_IS_SESSION_VALID( pMac, sessionId )) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Invalid session Id %u", __func__, sessionId); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + pCsrSession = CSR_GET_SESSION( pMac, sessionId ); + + if (pCsrSession == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: CSR Session lookup fails %u", __func__, sessionId); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + + pSession = peFindSessionByBssid( pMac, + pCsrSession->connectedProfile.bssid, &peSessionId ); + + if (pSession == NULL) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Session lookup fails for BSSID", __func__); + sme_ReleaseGlobalLock( &pMac->sme); + return eHAL_STATUS_FAILURE; + } + + if ( !pSession->QosMapSet.present ) { VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: QOS Mapping IE not present", __func__); @@ -12699,13 +12750,13 @@ eHalStatus sme_UpdateDSCPtoUPMapping( tHalHandle hHal, } else { - for (i = 0; i < 8; i++) + for (i = 0; i < SME_QOS_WMM_UP_MAX; i++) { - for (j = pMac->QosMapSet.dscp_range[i][0]; - j <= pMac->QosMapSet.dscp_range[i][1]; j++) + for (j = pSession->QosMapSet.dscp_range[i][0]; + j <= pSession->QosMapSet.dscp_range[i][1]; j++) { - if ((pMac->QosMapSet.dscp_range[i][0] == 255) && - (pMac->QosMapSet.dscp_range[i][1] == 255)) + if ((pSession->QosMapSet.dscp_range[i][0] == 255) && + (pSession->QosMapSet.dscp_range[i][1] == 255)) { dscpmapping[j]= 0; VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, @@ -12719,12 +12770,12 @@ eHalStatus sme_UpdateDSCPtoUPMapping( tHalHandle hHal, } } } - for (i = 0; i < pMac->QosMapSet.num_dscp_exceptions; i++) + for (i = 0; i< pSession->QosMapSet.num_dscp_exceptions; i++) { - if (pMac->QosMapSet.dscp_exceptions[i][0] != 255) + if (pSession->QosMapSet.dscp_exceptions[i][0] != 255) { - dscpmapping[pMac->QosMapSet.dscp_exceptions[i][0] ] = - pMac->QosMapSet.dscp_exceptions[i][1]; + dscpmapping[pSession->QosMapSet.dscp_exceptions[i][0] ] = + pSession->QosMapSet.dscp_exceptions[i][1]; } } } @@ -13134,3 +13185,226 @@ eHalStatus sme_ExtScanRegisterCallback (tHalHandle hHal, #endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsClearReq + \brief SME API to clear Link Layer Statistics + \param hHal + \param pclearStatsReq: Link Layer clear stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsClearReq (tHalHandle hHal, + tSirLLStatsClearReq *pclearStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsClearReq *clear_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "staId = %u", pclearStatsReq->staId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "statsClearReqMask = 0x%X", + pclearStatsReq->statsClearReqMask); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "stopReq = %u", pclearStatsReq->stopReq); + + clear_stats_req = vos_mem_malloc(sizeof(*clear_stats_req)); + + if (!clear_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_CLEAR_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *clear_stats_req = *pclearStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = clear_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_CLEAR_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_CLEAR_REQ", + __func__); + vos_mem_free(clear_stats_req); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(clear_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsSetReq + \brief SME API to set the Link Layer Statistics + \param hHal + \param psetStatsReq: Link Layer set stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsSetReq (tHalHandle hHal, + tSirLLStatsSetReq *psetStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsSetReq *set_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "%s: MPDU Size = %u", __func__, + psetStatsReq->mpduSizeThreshold); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + " Aggressive Stats Collections = %u", + psetStatsReq->aggressiveStatisticsGathering); + + set_stats_req = vos_mem_malloc(sizeof(*set_stats_req)); + + if (!set_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_SET_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *set_stats_req = *psetStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = set_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_SET_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_SET_REQ", + __func__); + vos_mem_free(set_stats_req); + status = eHAL_STATUS_FAILURE; + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(set_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_LLStatsGetReq + \brief SME API to get the Link Layer Statistics + \param hHal + \param pgetStatsReq: Link Layer get stats request params structure + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_LLStatsGetReq (tHalHandle hHal, + tSirLLStatsGetReq *pgetStatsReq) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + VOS_STATUS vosStatus = VOS_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + vos_msg_t vosMessage; + tSirLLStatsGetReq *get_stats_req; + + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "reqId = %u", pgetStatsReq->reqId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "staId = %u", pgetStatsReq->staId); + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, + "Stats Type = %u", pgetStatsReq->paramIdMask); + + get_stats_req = vos_mem_malloc(sizeof(*get_stats_req)); + + if (!get_stats_req) + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: Not able to allocate memory for WDA_LL_STATS_GET_REQ", + __func__); + return eHAL_STATUS_FAILURE; + } + + *get_stats_req = *pgetStatsReq; + + if (eHAL_STATUS_SUCCESS == sme_AcquireGlobalLock(&pMac->sme)) + { + /* Serialize the req through MC thread */ + vosMessage.bodyptr = get_stats_req; + vosMessage.type = WDA_LINK_LAYER_STATS_GET_REQ; + vosStatus = vos_mq_post_message(VOS_MQ_ID_WDA, &vosMessage); + if (!VOS_IS_STATUS_SUCCESS(vosStatus)) + { + VOS_TRACE( VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, + "%s: not able to post WDA_LL_STATS_GET_REQ", + __func__); + + vos_mem_free(get_stats_req); + status = eHAL_STATUS_FAILURE; + + } + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + vos_mem_free(get_stats_req); + status = eHAL_STATUS_FAILURE; + } + + return status; +} + +/* --------------------------------------------------------------------------- + \fn sme_SetLinkLayerStatsIndCB + \brief SME API to trigger the stats are available after get request + \param hHal + \param callbackRoutine - HDD callback which needs to be invoked after + getting status notification from FW + \- return eHalStatus + -------------------------------------------------------------------------*/ +eHalStatus sme_SetLinkLayerStatsIndCB +( + tHalHandle hHal, + void (*callbackRoutine) (void *callbackCtx, int indType, void *pRsp) +) +{ + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + + if (eHAL_STATUS_SUCCESS == (status = sme_AcquireGlobalLock(&pMac->sme))) + { + pMac->sme.pLinkLayerStatsIndCallback = callbackRoutine; + sme_ReleaseGlobalLock(&pMac->sme); + } + else + { + VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: " + "sme_AcquireGlobalLock error", __func__); + } + + return(status); +} + +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ diff --git a/CORE/SYS/legacy/src/utils/src/parserApi.c b/CORE/SYS/legacy/src/utils/src/parserApi.c index 714307e03da7..d76f08a86d7f 100644 --- a/CORE/SYS/legacy/src/utils/src/parserApi.c +++ b/CORE/SYS/legacy/src/utils/src/parserApi.c @@ -2625,10 +2625,10 @@ sirConvertAssocRespFrame2Struct(tpAniSirGlobal pMac, if ( ar.QosMapSet.present ) { - pMac->QosMapSet.present = 1; - ConvertQosMapsetFrame( pMac, &pMac->QosMapSet, &ar.QosMapSet); + pAssocRsp->QosMapSet.present = 1; + ConvertQosMapsetFrame( pMac, &pAssocRsp->QosMapSet, &ar.QosMapSet); limLog( pMac, LOG1, FL("Received Assoc Response with Qos Map Set")); - limLogQosMapSet(pMac, &pMac->QosMapSet); + limLogQosMapSet(pMac, &pAssocRsp->QosMapSet); } return eSIR_SUCCESS; @@ -4190,7 +4190,7 @@ sirConvertQosMapConfigureFrame2Struct(tpAniSirGlobal pMac, } pQosMapSet->present = mapConfigure.QosMapSet.present; ConvertQosMapsetFrame(pMac->hHdd, pQosMapSet, &mapConfigure.QosMapSet); - limLogQosMapSet(pMac, &pMac->QosMapSet); + limLogQosMapSet(pMac, pQosMapSet); return eSIR_SUCCESS; } diff --git a/CORE/VOSS/inc/vos_getBin.h b/CORE/VOSS/inc/vos_getBin.h index e5c96a35be04..ff65535ec790 100644 --- a/CORE/VOSS/inc/vos_getBin.h +++ b/CORE/VOSS/inc/vos_getBin.h @@ -139,5 +139,6 @@ tVOS_CON_MODE vos_get_conparam( void ); tVOS_CONCURRENCY_MODE vos_get_concurrency_mode( void ); v_BOOL_t vos_concurrent_open_sessions_running(void); v_BOOL_t vos_max_concurrent_connections_reached(void); +void vos_clear_concurrent_session_count(void); #endif // !defined __VOS_GETBIN_H diff --git a/CORE/VOSS/src/vos_getBin.c b/CORE/VOSS/src/vos_getBin.c index 2d10d66f5d05..c2f2b53b2f1b 100644 --- a/CORE/VOSS/src/vos_getBin.c +++ b/CORE/VOSS/src/vos_getBin.c @@ -200,3 +200,17 @@ v_BOOL_t vos_max_concurrent_connections_reached (void) return VOS_FALSE; } +void vos_clear_concurrent_session_count(void) +{ + v_U8_t i = 0; + hdd_context_t *pHddCtx; + v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL); + + if (NULL != pVosContext) { + pHddCtx = vos_get_context(VOS_MODULE_ID_HDD, pVosContext); + if (NULL != pHddCtx) { + for (i = 0; i < VOS_MAX_NO_OF_MODE; i++) + pHddCtx->no_of_active_sessions[i] = 0; + } + } +} diff --git a/CORE/WDA/inc/wlan_qct_wda.h b/CORE/WDA/inc/wlan_qct_wda.h index def5063d9646..9e4be94804db 100644 --- a/CORE/WDA/inc/wlan_qct_wda.h +++ b/CORE/WDA/inc/wlan_qct_wda.h @@ -1370,6 +1370,13 @@ tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); #endif /* FEATURE_WLAN_EXTSCAN */ +#ifdef WLAN_FEATURE_LINK_LAYER_STATS +#define WDA_LINK_LAYER_STATS_CLEAR_REQ SIR_HAL_LL_STATS_CLEAR_REQ +#define WDA_LINK_LAYER_STATS_SET_REQ SIR_HAL_LL_STATS_SET_REQ +#define WDA_LINK_LAYER_STATS_GET_REQ SIR_HAL_LL_STATS_GET_REQ +#define WDA_LINK_LAYER_STATS_RESULTS_RSP SIR_HAL_LL_STATS_RESULTS_RSP +#endif /* WLAN_FEATURE_LINK_LAYER_STATS */ + tSirRetStatus wdaPostCtrlMsg(tpAniSirGlobal pMac, tSirMsgQ *pMsg); #define HAL_USE_BD_RATE2_FOR_MANAGEMENT_FRAME 0x40 // Bit 6 will be used to control BD rate for Management frames @@ -119,6 +119,18 @@ ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) CONFIG_ATH_11AC_TXCOMPACT := 0 endif +#Enable per vdev Tx desc pool +ifeq ($(CONFIG_ROME_IF),pci) + CONFIG_PER_VDEV_TX_DESC_POOL := 0 +endif +ifeq ($(CONFIG_ROME_IF),usb) + CONFIG_PER_VDEV_TX_DESC_POOL := 1 +endif +ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) + CONFIG_PER_VDEV_TX_DESC_POOL := 0 +endif + + #Enable OS specific IRQ abstraction CONFIG_ATH_SUPPORT_SHARED_IRQ := 1 @@ -994,7 +1006,8 @@ CDEFINES := -DANI_LITTLE_BYTE_ENDIAN \ -DQCA_SUPPORT_TX_THROTTLE \ -DWMI_INTERFACE_EVENT_LOGGING \ -DATH_SUPPORT_WAPI \ - -DFEATURE_WLAN_EXTSCAN + -DFEATURE_WLAN_EXTSCAN \ + -DWLAN_FEATURE_LINK_LAYER_STATS ifeq ($(CONFIG_QCA_WIFI_SDIO), 1) CDEFINES += -DCONFIG_HL_SUPPORT \ @@ -1181,6 +1194,11 @@ ifeq ($(CONFIG_ATH_11AC_TXCOMPACT), 1) CDEFINES += -DATH_11AC_TXCOMPACT endif +#Enable per vdev Tx desc pool +ifeq ($(CONFIG_PER_VDEV_TX_DESC_POOL), 1) +CDEFINES += -DCONFIG_PER_VDEV_TX_DESC_POOL +endif + #Enable OS specific IRQ abstraction ifeq ($(CONFIG_ATH_SUPPORT_SHARED_IRQ), 1) CDEFINES += -DATH_SUPPORT_SHARED_IRQ |
