diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-05-02 03:32:08 -0600 |
|---|---|---|
| committer | Linux Build Service Account <lnxbuild@localhost> | 2016-05-02 03:32:08 -0600 |
| commit | 3c57554e4102a41509ac3cd03bf205b8511a185e (patch) | |
| tree | e51e295ed751a4f288c7190866515438b75c7cee | |
| parent | 28cf6c82c9738aca064eeba7456e1d14964135e7 (diff) | |
| parent | da9a76ca5799911c7223a0d998d7502c1bf7e7f8 (diff) | |
Promotion of wlan-cld2.driver.lnx.1.0-00009.
CRs Change ID Subject
--------------------------------------------------------------------------------------------------------------
688141 I9181d6404f44c066bd20b4137126fdfc1db50d50 Release 4.0.11.70
1006608 I196e22e3e5ceea2a18bfd5137589b16c5e6d8e08 qcacld-2.0: Indicate FW to include TPC IE in probe reque
688141 I98ac4aaa9d289356e1d1f74f2e99c6671995cf9a Release 4.0.11.69
962367 Iddd22a83b0763dab2e7398f4d2cf5b9ada58225a qcacld-2.0: Add support for NAN Data End Request
1008197 I81e5b7d5910919573b69faf7cfa3210eace9d6d4 qcacld-2.0: Fix static code analysis error
903963 If3d32d6998bf7f65171a8d501db69e72a6ee2865 qcacld-2.0: Register Callback for fullPower before posti
688141 If4238fc244a6b01162ae085a2d3d906fa9e7c82f Release 4.0.11.68
996735 I47bc1e0ecfa2e831438534cf34d37086a306b4e9 qcacld-2.0: Refactor intra bss forwarded packets count
1009934 I9c5733bc67a0a92044d6ecd72c53502a1be57f61 qcacld-2.0: Add VOSS API to set radio index
962367 I325843ce7fb8198466cb66ce66710cef999d4581 qcacld-2.0: Process NDP data end indication
951742 Id0f4ab4a27b46af5c1f4ef0e214cf340dae6aafb qcacld-2.0: Correct No of Max channels to scan
1006946 I6f9c99a1e9b3f1c97e701451c064d43a739266db qcacld-2.0: Send VHT capability in vendor IE only if dot
1005141 I06c97db85d88decf418be602cb5f64135f61a686 qcacld-2.0: Report max MCS index 8 for VHT20
879520 Iffe7e65dc1e8c7951ce3c4be3c21ef2103091d13 qcacld-2.0: Send scan abort notification to Supplicant o
1006601 I4138434477e1de432b9547ce1aec4968a559188f qcacld-2.0: Reset use_protection when legacy AP goes awa
994677 Ib7fe63463eaaa2f124428c73857f19e65bce67a3 qcacld-2.0: Avoid ipa cmd to firmware during driver unlo
940324 I7a68d4d94745cee2274970196642d5041f09d184 qcacld-2.0: Print mac address in Hex
962367 CRs Fixed I17fe580661f836d45a518a330a63d2c6de8bcf28 qcacld-2.0: Update NAN HDD APIs as per vendor definition
1009861 I9900655861032636af1b4147ec6322e5aa76e614 qcacld-2.0: Add interface to get channel width in sap mo
892306 If6317cfe183bb30df06ae4ffba0a698895323792 qcacld-2.0: Remove redundant logs for Scanning
Change-Id: I7c82ac7ac78cddd2df2b6b792669fd3f394f27b6
CRs-Fixed: CRs, 1009861, 994677, 1006608, 1009934, 1006946, 1006601, 688141, 996735, 1005141, 1008197, 903963, 951742, 962367, 940324, 892306, Fixed, 879520
50 files changed, 1440 insertions, 304 deletions
diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.c b/CORE/CLD_TXRX/TLSHIM/tl_shim.c index 754f739767a0..a4243388e8d6 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.c +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.c @@ -488,12 +488,10 @@ static int tlshim_mgmt_rx_process(void *context, u_int8_t *data, return 0; } -#ifdef FEATURE_WLAN_D0WOW if (!wma_handle) { TLSHIM_LOGE("%s: Failed to get WMA context!", __func__); return 0; } -#endif adf_os_spin_lock_bh(&tl_shim->mgmt_lock); param_tlvs = (WMI_MGMT_RX_EVENTID_param_tlvs *) data; @@ -2653,17 +2651,21 @@ void WLANTL_clear_datapath_stats(void *vos_ctx, uint16_t bitmap) return; } -/* tlshim_get_fwd_to_tx_packet_count() - to get the total rx packets that have - * been directly forwarded to tx without coming to upper layers - * +/** + * tlshim_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets + * that have been forwarded from txrx layer without coming to upper layers. * @session_id: session id/vdev id + * @fwd_tx_packets: pointer to forwarded tx packets count parameter + * @fwd_rx_packets: pointer to forwarded rx packets count parameter * - * Returns: forwarded packet count + * Returns: status -> A_OK - success, A_ERROR - failure * */ -uint64_t tlshim_get_fwd_to_tx_packet_count(uint8_t session_id) +A_STATUS tlshim_get_intra_bss_fwd_pkts_count(uint8_t session_id, + unsigned long *fwd_tx_packets, unsigned long *fwd_rx_packets) { - return ol_rx_get_fwd_to_tx_packet_count(session_id); + return ol_get_intra_bss_fwd_pkts_count(session_id, fwd_tx_packets, + fwd_rx_packets); } /* diff --git a/CORE/CLD_TXRX/TLSHIM/tl_shim.h b/CORE/CLD_TXRX/TLSHIM/tl_shim.h index 9a0c9ef03389..984c155eee41 100644 --- a/CORE/CLD_TXRX/TLSHIM/tl_shim.h +++ b/CORE/CLD_TXRX/TLSHIM/tl_shim.h @@ -126,10 +126,11 @@ VOS_STATUS tl_shim_get_vdevid(struct ol_txrx_peer_t *peer, u_int8_t *vdev_id); int tlshim_mgmt_roam_event_ind(void *context, u_int32_t vdev_id); void *tl_shim_get_vdev_by_addr(void *vos_context, uint8_t *mac_addr); void *tl_shim_get_vdev_by_sta_id(void *vos_context, uint8_t sta_id); -uint64_t tlshim_get_fwd_to_tx_packet_count(uint8_t session_id); int tlshim_get_ll_queue_pause_bitmap(uint8_t session_id, uint8_t *pause_bitmap, __adf_time_t *pause_timestamp); +A_STATUS tlshim_get_intra_bss_fwd_pkts_count(uint8_t session_id, + unsigned long *fwd_tx_packets, unsigned long *fwd_rx_packets); #ifdef QCA_SUPPORT_TXRX_VDEV_PAUSE_LL void tl_shim_set_peer_authorized_event(void *vos_ctx, v_U8_t session_id); diff --git a/CORE/CLD_TXRX/TXRX/ol_rx_fwd.c b/CORE/CLD_TXRX/TXRX/ol_rx_fwd.c index e9cf932ff36c..d4117d73ef8c 100644 --- a/CORE/CLD_TXRX/TXRX/ol_rx_fwd.c +++ b/CORE/CLD_TXRX/TXRX/ol_rx_fwd.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2011, 2014, 2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -234,7 +234,8 @@ ol_rx_fwd_check( htt_rx_msdu_desc_free(pdev->htt_pdev, msdu); ol_rx_fwd_to_tx(tx_vdev, msdu); msdu = NULL; /* already handled this MSDU */ - vdev->fwd_to_tx_packets++; + tx_vdev->fwd_tx_packets++; + vdev->fwd_rx_packets++; TXRX_STATS_ADD(pdev, pub.rx.intra_bss_fwd.packets_fwd, 1); } else { @@ -242,6 +243,7 @@ ol_rx_fwd_check( copy = adf_nbuf_copy(msdu); if (copy) { ol_rx_fwd_to_tx(tx_vdev, copy); + tx_vdev->fwd_tx_packets++; } TXRX_STATS_ADD(pdev, pub.rx.intra_bss_fwd.packets_stack_n_fwd, 1); @@ -266,23 +268,28 @@ ol_rx_fwd_check( } } -/* ol_rx_get_fwd_to_tx_packet_count() - to get the total rx packets that has - * been forwarded to tx without going to OS layer. +/* + * ol_get_intra_bss_fwd_pkts_count() - to get the total tx and rx packets + * that has been forwarded from txrx layer without going to upper layers. * * @vdev_id: vdev id + * @fwd_tx_packets: pointer to forwarded tx packets count parameter + * @fwd_rx_packets: pointer to forwarded rx packets count parameter * - * Return: forwarded packet count if vdev is valid - * 0 if vdev is NULL + * Return: status -> A_OK - success, A_ERROR - failure * */ -uint64_t ol_rx_get_fwd_to_tx_packet_count(uint8_t vdev_id) +A_STATUS ol_get_intra_bss_fwd_pkts_count(uint8_t vdev_id, + unsigned long *fwd_tx_packets, unsigned long *fwd_rx_packets) { struct ol_txrx_vdev_t *vdev = NULL; vdev = (struct ol_txrx_vdev_t *)ol_txrx_get_vdev_from_vdev_id(vdev_id); if (!vdev) - return 0; + return A_ERROR; - return vdev->fwd_to_tx_packets; + *fwd_tx_packets = vdev->fwd_tx_packets; + *fwd_rx_packets = vdev->fwd_rx_packets; + return A_OK; } diff --git a/CORE/CLD_TXRX/TXRX/ol_rx_fwd.h b/CORE/CLD_TXRX/TXRX/ol_rx_fwd.h index 68e71b0350f3..035e91f6f843 100644 --- a/CORE/CLD_TXRX/TXRX/ol_rx_fwd.h +++ b/CORE/CLD_TXRX/TXRX/ol_rx_fwd.h @@ -80,8 +80,10 @@ ol_rx_fwd_check( unsigned tid, adf_nbuf_t msdu_list); -uint64_t -ol_rx_get_fwd_to_tx_packet_count( - uint8_t vdev_id); +A_STATUS +ol_get_intra_bss_fwd_pkts_count( + uint8_t vdev_id, + unsigned long *fwd_tx_packets, + unsigned long *fwd_rx_packets); #endif /* _OL_RX_FWD_H_ */ diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx.c b/CORE/CLD_TXRX/TXRX/ol_txrx.c index 8289b6bde0b8..2b8dbed9411f 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx.c +++ b/CORE/CLD_TXRX/TXRX/ol_txrx.c @@ -1041,7 +1041,8 @@ ol_txrx_vdev_attach( vdev->safemode = 0; vdev->drop_unenc = 1; vdev->num_filters = 0; - vdev->fwd_to_tx_packets = 0; + vdev->fwd_tx_packets = 0; + vdev->fwd_rx_packets = 0; #if defined(CONFIG_PER_VDEV_TX_DESC_POOL) adf_os_atomic_init(&vdev->tx_desc_count); #endif diff --git a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h index b1a1798ed85e..b529e852deee 100644 --- a/CORE/CLD_TXRX/TXRX/ol_txrx_types.h +++ b/CORE/CLD_TXRX/TXRX/ol_txrx_types.h @@ -973,8 +973,9 @@ struct ol_txrx_vdev_t { /* Default OCB TX parameter */ struct ocb_tx_ctrl_hdr_t *ocb_def_tx_param; - /* packet count that only forwarded and not dent to OS layer */ - uint64_t fwd_to_tx_packets; + /* intra bss forwarded tx and rx packets count */ + uint64_t fwd_tx_packets; + uint64_t fwd_rx_packets; }; struct ol_rx_reorder_array_elem_t { diff --git a/CORE/HDD/inc/qc_sap_ioctl.h b/CORE/HDD/inc/qc_sap_ioctl.h index 439b4d77243b..570e6c03001a 100644 --- a/CORE/HDD/inc/qc_sap_ioctl.h +++ b/CORE/HDD/inc/qc_sap_ioctl.h @@ -267,6 +267,7 @@ enum { QCASAP_PARAM_TX_STBC, QCASAP_PARAM_RX_STBC, QCASAP_SET_RADAR_DBG, + QCSAP_PARAM_CHAN_WIDTH, }; int iw_get_channel_list(struct net_device *dev, diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h index 5a7f278d1953..26feb4442270 100644 --- a/CORE/HDD/inc/wlan_hdd_assoc.h +++ b/CORE/HDD/inc/wlan_hdd_assoc.h @@ -49,6 +49,8 @@ /* Timeout in ms for peer info request completion */ #define IBSS_PEER_INFO_REQ_TIMOEUT 1000 +#define INVALID_PEER_IDX -1 + /** * enum eConnectionState - connection state values at HDD * @eConnectionState_NotConnected: Not associated in Infra or participating in @@ -180,4 +182,9 @@ VOS_STATUS hdd_roamRegisterSTA(hdd_adapter_t *adapter, tCsrRoamInfo *roam_info, bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id, v_MACADDR_t *peer_mac_addr); +void hdd_delete_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id); + +int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *addr); +VOS_STATUS hdd_roamDeregisterSTA(hdd_adapter_t *adapter, uint8_t sta_id); + #endif diff --git a/CORE/HDD/inc/wlan_hdd_cfg80211.h b/CORE/HDD/inc/wlan_hdd_cfg80211.h index 414519694e35..23256e602464 100644 --- a/CORE/HDD/inc/wlan_hdd_cfg80211.h +++ b/CORE/HDD/inc/wlan_hdd_cfg80211.h @@ -109,7 +109,7 @@ #endif -#define MAX_CHANNEL (MAX_2_4GHZ_CHANNEL + NUM_5GHZ_CHANNELS) +#define MAX_CHANNEL (NUM_2_4GHZ_CHANNELS + NUM_5GHZ_CHANNELS) typedef struct { u8 element_id; diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 9a80fc9009c5..c04571a2e686 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -1169,7 +1169,8 @@ struct hdd_adapter_s #ifdef FEATURE_BUS_BANDWIDTH unsigned long prev_rx_packets; unsigned long prev_tx_packets; - unsigned long prev_fwd_packets; + unsigned long prev_fwd_tx_packets; + unsigned long prev_fwd_rx_packets; unsigned long prev_tx_bytes; int connection; #endif diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h index 9e46f119190d..a8d223ed8287 100644 --- a/CORE/HDD/inc/wlan_hdd_tx_rx.h +++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h @@ -190,6 +190,8 @@ extern v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket ); VOS_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *peer_mac_addr, uint8_t *sta_id); +int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *addr); + /**============================================================================ @brief hdd_flush_ibss_tx_queues() - Flush tx queues in IBSS mode diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 99b82ca16c13..da8f8875dd0b 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -796,8 +796,8 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo spin_lock_bh(&pHddCtx->bus_bw_lock); pAdapter->prev_tx_packets = pAdapter->stats.tx_packets; pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; - pAdapter->prev_fwd_packets = - tlshim_get_fwd_to_tx_packet_count(pAdapter->sessionId); + tlshim_get_intra_bss_fwd_pkts_count(pAdapter->sessionId, + &pAdapter->prev_fwd_tx_packets, &pAdapter->prev_fwd_rx_packets); pAdapter->prev_tx_bytes = pAdapter->stats.tx_bytes; spin_unlock_bh(&pHddCtx->bus_bw_lock); hdd_start_bus_bw_compute_timer(pAdapter); @@ -847,7 +847,8 @@ static void hdd_SendAssociationEvent(struct net_device *dev,tCsrRoamInfo *pCsrRo spin_lock_bh(&pHddCtx->bus_bw_lock); pAdapter->prev_tx_packets = 0; pAdapter->prev_rx_packets = 0; - pAdapter->prev_fwd_packets = 0; + pAdapter->prev_fwd_tx_packets = 0; + pAdapter->prev_fwd_rx_packets = 0; pAdapter->prev_tx_bytes = 0; spin_unlock_bh(&pHddCtx->bus_bw_lock); hdd_stop_bus_bw_compute_timer(pAdapter); @@ -895,8 +896,15 @@ static void hdd_connRemoveConnectInfo(hdd_station_ctx_t *pHddStaCtx) vos_mem_zero( &pHddStaCtx->conn_info.SSID, sizeof( tCsrSSIDInfo ) ); } -/* TODO Revisit this function. and data path */ -static VOS_STATUS hdd_roamDeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId ) + +/** + * hdd_roamDeregisterSTA() - Deregister STA from data path + * @pAdapter - HDD context + * @staId - Station ID + * + * Return: 0 or VOS_STATUS error code + */ +VOS_STATUS hdd_roamDeregisterSTA(hdd_adapter_t *pAdapter, tANI_U8 staId) { VOS_STATUS vosStatus; hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter); @@ -2404,6 +2412,9 @@ bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id, for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) { if (0 == sta_ctx->conn_info.staId[idx]) { + hddLog(VOS_TRACE_LEVEL_DEBUG, + FL("adding peer: %pM, sta_id: %d, at idx: %d"), + peer_mac_addr, sta_id, idx); sta_ctx->conn_info.staId[idx] = sta_id; vos_copy_macaddr( &sta_ctx->conn_info.peerMacAddress[idx], @@ -2414,6 +2425,27 @@ bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id, return false; } +/** + * hdd_delete_peer() - removes peer from hdd station context peer table + * @sta_ctx: pointer to hdd station context + * @sta_id: station ID + * + * Return: none + */ +void hdd_delete_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id) +{ + int i; + + for (i = 0; i < HDD_MAX_NUM_IBSS_STA; i++) { + if (sta_id == sta_ctx->conn_info.staId[i]) { + sta_ctx->conn_info.staId[i] = 0; + return; + } + } + + hddLog(LOGE, FL("sta_id %d is not present in peer table"), sta_id); +} + /**============================================================================ * @brief roamRemoveIbssStation() - Remove the IBSS peer MAC address in the adapter. @@ -5395,4 +5427,3 @@ int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info, return ret; } - diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 9cc5c762ff22..825ed9eab295 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -19864,11 +19864,17 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, } else if (DATA_RATE_11AC_MAX_MCS_9 == vhtMaxMcs) { - //VHT20 is supporting 0~8 - if (rate_flags & eHAL_TX_RATE_VHT20) + /* + * 'IEEE_P802.11ac_2013.pdf' page 325, 326 + * - MCS9 is valid for VHT20 when Nss = 3 or Nss = 6 + * - MCS9 is not valid for VHT20 when Nss = 1,2,4,5,7,8 + */ + if ((rate_flags & eHAL_TX_RATE_VHT20) && + (nss != 3 && nss != 6)) { maxMCSIdx = 8; - else + } else { maxMCSIdx = 9; + } } if (rssidx != 0) @@ -19975,6 +19981,20 @@ static int __wlan_hdd_cfg80211_get_station(struct wiphy *wiphy, { maxSpeedMCS = 1; maxMCSIdx = pAdapter->hdd_stats.ClassA_stat.mcs_index; + /* + * 'IEEE_P802.11ac_2013.pdf' page 325, 326 + * - MCS9 is valid for VHT20 when Nss = 3 or Nss = 6 + * - MCS9 is not valid for VHT20 when Nss = 1,2,4,5,7,8 + */ + if ((rate_flags & eHAL_TX_RATE_VHT20) && + (maxMCSIdx > 8) && + (nss != 3 && nss != 6)) { +#ifdef LINKSPEED_DEBUG_ENABLED + pr_info("MCS%d is not valid for VHT20 when nss=%d, hence report MCS8.", + maxMCSIdx, nss); +#endif + maxMCSIdx = 8; + } } } diff --git a/CORE/HDD/src/wlan_hdd_hostapd.c b/CORE/HDD/src/wlan_hdd_hostapd.c index f56a73301fac..f821fc1c8673 100644 --- a/CORE/HDD/src/wlan_hdd_hostapd.c +++ b/CORE/HDD/src/wlan_hdd_hostapd.c @@ -1809,8 +1809,10 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa spin_lock_bh(&pHddCtx->bus_bw_lock); pHostapdAdapter->prev_tx_packets = pHostapdAdapter->stats.tx_packets; pHostapdAdapter->prev_rx_packets = pHostapdAdapter->stats.rx_packets; - pHostapdAdapter->prev_fwd_packets = - tlshim_get_fwd_to_tx_packet_count(pHostapdAdapter->sessionId); + tlshim_get_intra_bss_fwd_pkts_count( + pHostapdAdapter->sessionId, + &pHostapdAdapter->prev_fwd_tx_packets, + &pHostapdAdapter->prev_fwd_rx_packets); pHostapdAdapter->prev_tx_bytes = pHostapdAdapter->stats.tx_bytes; spin_unlock_bh(&pHddCtx->bus_bw_lock); @@ -2004,7 +2006,8 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa spin_lock_bh(&pHddCtx->bus_bw_lock); pHostapdAdapter->prev_tx_packets = 0; pHostapdAdapter->prev_rx_packets = 0; - pHostapdAdapter->prev_fwd_packets = 0; + pHostapdAdapter->prev_fwd_tx_packets = 0; + pHostapdAdapter->prev_fwd_rx_packets = 0; pHostapdAdapter->prev_tx_bytes = 0; spin_unlock_bh(&pHddCtx->bus_bw_lock); hdd_stop_bus_bw_compute_timer(pHostapdAdapter); @@ -2469,6 +2472,42 @@ int hdd_softap_set_channel_change(struct net_device *dev, int target_channel) return ret; } +/** + * hdd_sap_get_chan_width() - get channel width of sap + * @adapter: adapter being queried + * @value: where to store the value + * + * Return: 0 on success, negative errno on failure + */ +static int hdd_sap_get_chan_width(hdd_adapter_t *adapter, int *value) +{ + void *pvosctx; + uint32_t vht_channel_width = 0; + hdd_context_t *hdd_ctx; + hdd_hostapd_state_t *phostapdstate; + + ENTER(); + hdd_ctx = WLAN_HDD_GET_CTX(adapter); + phostapdstate = WLAN_HDD_GET_HOSTAP_STATE_PTR(adapter); + + if (phostapdstate->bssState != BSS_START) { + *value = -EINVAL; + return -EINVAL; + } + +#ifdef WLAN_FEATURE_MBSSID + pvosctx = WLAN_HDD_GET_SAP_CTX_PTR(adapter); +#else + pvosctx = hdd_ctx->pvosContext; +#endif + + wlansap_get_chan_width(pvosctx, &vht_channel_width); + *value = vht_channel_width; + hddLog(LOGW, FL("chan_width = %d"), vht_channel_width); + + return 0; +} + int static __iw_softap_set_ini_cfg(struct net_device *dev, struct iw_request_info *info, @@ -3789,6 +3828,9 @@ static __iw_softap_getparam(struct net_device *dev, ret = hdd_get_rx_stbc(pHostapdAdapter, value); break; + case QCSAP_PARAM_CHAN_WIDTH: + ret = hdd_sap_get_chan_width(pHostapdAdapter, value); + break; default: hddLog(LOGE, FL("Invalid getparam command %d"), sub_cmd); ret = -EINVAL; @@ -6684,6 +6726,8 @@ static const struct iw_priv_args hostapd_private_args[] = { IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_tx_stbc" }, { QCASAP_PARAM_RX_STBC, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_rx_stbc" }, + { QCSAP_PARAM_CHAN_WIDTH, 0, + IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_chwidth" }, #ifdef WLAN_FEATURE_TSF { QCSAP_CAP_TSF, 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "cap_tsf" }, diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index d6383694ba6d..8f91ba2738f1 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -13550,10 +13550,13 @@ static void hdd_bus_bw_compute_cbk(void *priv) { hdd_context_t *pHddCtx = (hdd_context_t *)priv; hdd_adapter_t *pAdapter = NULL; - uint64_t tx_packets = 0, rx_packets = 0, fwd_packets = 0, tx_bytes = 0; + uint64_t tx_packets = 0, rx_packets = 0, tx_bytes = 0; + unsigned long fwd_tx_packets = 0, fwd_rx_packets = 0; + unsigned long fwd_tx_packets_diff = 0, fwd_rx_packets_diff = 0; uint64_t total_tx = 0, total_rx = 0; hdd_adapter_list_node_t *pAdapterNode = NULL; VOS_STATUS status = 0; + A_STATUS ret; v_BOOL_t connected = FALSE; #ifdef IPA_UC_OFFLOAD uint32_t ipa_tx_packets = 0, ipa_rx_packets = 0; @@ -13597,9 +13600,20 @@ static void hdd_bus_bw_compute_cbk(void *priv) pAdapter->prev_tx_bytes); rx_packets += HDD_BW_GET_DIFF(pAdapter->stats.rx_packets, pAdapter->prev_rx_packets); - fwd_packets = tlshim_get_fwd_to_tx_packet_count(pAdapter->sessionId); - tx_packets += HDD_BW_GET_DIFF(fwd_packets, - pAdapter->prev_fwd_packets); + + if (pAdapter->device_mode == WLAN_HDD_SOFTAP || + pAdapter->device_mode == WLAN_HDD_P2P_GO || + pAdapter->device_mode == WLAN_HDD_IBSS) { + + ret = tlshim_get_intra_bss_fwd_pkts_count(pAdapter->sessionId, + &fwd_tx_packets, &fwd_rx_packets); + if (ret == A_OK) { + fwd_tx_packets_diff += HDD_BW_GET_DIFF(fwd_tx_packets, + pAdapter->prev_fwd_tx_packets); + fwd_rx_packets_diff += HDD_BW_GET_DIFF(fwd_tx_packets, + pAdapter->prev_fwd_rx_packets); + } + } hdd_set_bundle_require(pAdapter->sessionId, pHddCtx, tx_bytes); @@ -13611,7 +13625,8 @@ static void hdd_bus_bw_compute_cbk(void *priv) pAdapter->prev_tx_packets = pAdapter->stats.tx_packets; pAdapter->prev_tx_bytes = pAdapter->stats.tx_bytes; pAdapter->prev_rx_packets = pAdapter->stats.rx_packets; - pAdapter->prev_fwd_packets = fwd_packets; + pAdapter->prev_fwd_tx_packets = fwd_tx_packets; + pAdapter->prev_fwd_rx_packets = fwd_rx_packets; spin_unlock_bh(&pHddCtx->bus_bw_lock); connected = TRUE; } @@ -13621,6 +13636,10 @@ static void hdd_bus_bw_compute_cbk(void *priv) pHddCtx->hdd_txrx_hist[pHddCtx->hdd_txrx_hist_idx].interval_rx = rx_packets; pHddCtx->hdd_txrx_hist[pHddCtx->hdd_txrx_hist_idx].interval_tx = tx_packets; + /* add intra bss forwarded tx and rx packets */ + tx_packets += fwd_tx_packets_diff; + rx_packets += fwd_rx_packets_diff; + #ifdef IPA_UC_OFFLOAD hdd_ipa_uc_stat_query(pHddCtx, &ipa_tx_packets, &ipa_rx_packets); tx_packets += (uint64_t)ipa_tx_packets; @@ -14581,6 +14600,7 @@ int hdd_wlan_startup(struct device *dev, v_VOID_t *hif_sc) hddLog(LOGP, FL("nl_srv_init failed")); goto err_config; } + vos_set_radio_index(pHddCtx->radio_index); if (VOS_FTM_MODE == hdd_get_conparam()) goto ftm_processing; diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.c b/CORE/HDD/src/wlan_hdd_nan_datapath.c index 333a0ebc1d82..8635bfbd65cb 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.c +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.c @@ -50,14 +50,14 @@ qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 }, [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY, .len = NDP_QOS_INFO_LEN }, - [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN] = { .type = NLA_U16 }, [QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO] = { .type = NLA_BINARY, .len = NDP_APP_INFO_LEN }, [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID] = { .type = NLA_U32 }, [QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE] = { .type = NLA_U16 }, - [QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_STATUS_CODE] = { .type = NLA_U16 }, [QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR] = { .type = NLA_BINARY, .len = VOS_MAC_ADDR_SIZE }, + [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY, + .len = NDP_NUM_INSTANCE_ID }, }; /** @@ -424,10 +424,10 @@ static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx, return -EINVAL; } - /* check if there are active NDP sessions on the adapter */ - if (ndp_ctx->active_ndp_sessions > 0) { - hddLog(LOGE, FL("NDP sessions active %d, cannot delete NDI"), - ndp_ctx->active_ndp_sessions); + /* check if there are active peers on the adapter */ + if (ndp_ctx->active_ndp_peers > 0) { + hddLog(LOGE, FL("NDP peers active: %d, cannot delete NDI"), + ndp_ctx->active_ndp_peers); return -EINVAL; } @@ -529,19 +529,12 @@ static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx, nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]), VOS_MAC_ADDR_SIZE); - if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN]) { - hddLog(LOGE, FL("NDP app info len is unavailable")); - return -EINVAL; - } - req.ndp_info.ndp_app_info_len = - nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN]); - - if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { - hddLog(LOGE, FL("NDP app info is unavailable")); - return -EINVAL; + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { + req.ndp_info.ndp_app_info_len = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + req.ndp_info.ndp_app_info = + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); } - req.ndp_info.ndp_app_info = - nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); if (tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]) { /* at present ndp config stores 4 bytes QOS info only */ @@ -689,9 +682,51 @@ static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx, * * Return: 0 on success or error code on failure */ -static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, - struct nlattr **tb) +static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb) { + struct ndp_end_req req = {0}; + VOS_STATUS status; + tHalHandle hal = hdd_ctx->hHal; + + ENTER(); + + /* NAN data path coexists only with STA interface */ + if (!hdd_is_ndp_allowed(hdd_ctx)) { + hddLog(LOGE, FL("Unsupported concurrency for NAN datapath")); + return -EINVAL; + } + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { + hddLog(LOGE, FL("Transaction ID is unavailable")); + return -EINVAL; + } + req.transaction_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) { + hddLog(LOGE, FL("NDP instance ID array is unavailable")); + return -EINVAL; + } + + req.num_ndp_instances = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) / + sizeof(uint32_t); + if (0 >= req.num_ndp_instances) { + hddLog(LOGE, FL("Num NDP instances is 0")); + return -EINVAL; + } + req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]); + + hddLog(LOG1, FL("sending ndp_end_req to SME, transaction_id: %d"), + req.transaction_id); + + status = sme_ndp_end_req_handler(hal, &req); + if (status != VOS_STATUS_SUCCESS) { + hddLog(LOGE, FL("sme_ndp_end_req_handler failed, status: %d"), + status); + return -ECOMM; + } + EXIT(); return 0; } @@ -1066,6 +1101,9 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter, hddLog(LOGE, FL("Invalid new NDP peer params")); return; } + hddLog(LOG1, FL("session_id: %d, peer_mac: %pM, sta_id: %d"), + new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes, + new_peer_ind->sta_id); /* save peer in ndp ctx */ if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id, @@ -1076,6 +1114,8 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter, /* this function is called for each new peer */ ndp_ctx->active_ndp_peers++; + hddLog(LOG1, FL("vdev_id: %d, num_peers: %d"), + adapter->sessionId, ndp_ctx->active_ndp_peers); hdd_roamRegisterSTA(adapter, &roam_info, new_peer_ind->sta_id, &new_peer_ind->peer_mac_addr, &tmp_bss_descp); @@ -1083,7 +1123,7 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter, /* perform following steps for first new peer ind */ if (ndp_ctx->active_ndp_peers == 1) { hdd_ctx->sta_to_adapter[NDP_BROADCAST_STAID] = adapter; - hdd_save_peer(sta_ctx, new_peer_ind->sta_id, &bc_mac_addr); + hdd_save_peer(sta_ctx, NDP_BROADCAST_STAID, &bc_mac_addr); hdd_roamRegisterSTA(adapter, &roam_info, NDP_BROADCAST_STAID, &bc_mac_addr, &tmp_bss_descp); hddLog(LOG1, FL("Set ctx connection state to connected")); @@ -1096,16 +1136,32 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter, EXIT(); } /** - * hdd_ndp_peer_departed_ind_handler() - NDP peer departed indication handler + * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication * @adapter: pointer to adapter context * @ind_params: indication parameters * * Return: none */ -static void hdd_ndp_peer_departed_ind_handler( - hdd_adapter_t *adapter, void *ind_params) +static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter, + void *ind_params) { - return; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct sme_ndp_peer_ind *peer_ind = ind_params; + struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + hdd_roamDeregisterSTA(adapter, peer_ind->sta_id); + hdd_delete_peer(sta_ctx, peer_ind->sta_id); + hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0; + + if (--ndp_ctx->active_ndp_peers == 0) { + hddLog(LOG1, FL("No more ndp peers.")); + sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected; + hdd_connSetConnectionState(adapter, + eConnectionState_NdiDisconnected); + hddLog(LOG1, FL("Stop netif tx queues.")); + netif_tx_stop_all_queues(adapter->dev); + } } /** @@ -1118,11 +1174,13 @@ static void hdd_ndp_peer_departed_ind_handler( static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter, void *ind_params) { + int idx; uint32_t ndp_qos_config = 0; struct ndp_confirm_event *ndp_confirm = ind_params; struct sk_buff *vendor_event; hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); uint32_t data_len; ENTER(); @@ -1134,11 +1192,17 @@ static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter, if (0 != wlan_hdd_validate_context(hdd_ctx)) return; - /* ndp_confirm is called each time user generated npd req succeeds */ - ndp_ctx->active_ndp_sessions++; + /* ndp_confirm is called each time user generated ndp req succeeds */ + idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr); + if (idx == INVALID_PEER_IDX) + hddLog(LOGE, + FL("can't find addr: %pM in vdev_id: %d, peer table."), + &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId); + else + ndp_ctx->active_ndp_sessions[idx]++; - data_len = (4 * sizeof(uint32_t)) + VOS_MAC_ADDR_SIZE + IFNAMSIZ + - sizeof(uint16_t) + NLMSG_HDRLEN + (8 * NLA_HDRLEN) + + data_len = (3 * sizeof(uint32_t)) + VOS_MAC_ADDR_SIZE + IFNAMSIZ + + sizeof(uint16_t) + NLMSG_HDRLEN + (7 * NLA_HDRLEN) + ndp_confirm->ndp_info.ndp_app_info_len; vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL, @@ -1165,25 +1229,12 @@ static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter, IFNAMSIZ, adapter->dev->name)) goto ndp_confirm_nla_failed; - if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN, - ndp_confirm->ndp_info.ndp_app_info_len)) - goto ndp_confirm_nla_failed; - if (ndp_confirm->ndp_info.ndp_app_info_len && nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, ndp_confirm->ndp_info.ndp_app_info_len, ndp_confirm->ndp_info.ndp_app_info)) goto ndp_confirm_nla_failed; - if (ndp_confirm->ndp_config.ndp_cfg_len) { - ndp_qos_config = *((uint32_t *)ndp_confirm->ndp_config.ndp_cfg); - /* at present ndp config stores 4 bytes QOS info only */ - if (nla_put_u32(vendor_event, - QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, - ndp_qos_config)) - goto ndp_confirm_nla_failed; - } - if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, ndp_confirm->rsp_code)) @@ -1422,12 +1473,97 @@ ndp_responder_rsp_nla_failed: * @adapter: pointer to adapter context * @rsp_params: response parameters * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VELUE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) + * * Return: none */ -static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, - void *rsp_params) +static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, void *rsp_params) { + struct sk_buff *vendor_event; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct ndp_end_rsp_event *rsp = rsp_params; + struct nan_datapath_ctx *ndp_ctx; + uint32_t data_len, i; + int idx; + hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + + ENTER(); + + if (!rsp) { + hddLog(LOGE, FL("Invalid ndp end response")); + return; + } + + if (0 != wlan_hdd_validate_context(hdd_ctx)) + return; + + /* adjust active ndp instances per peer */ + if (rsp->status == NDP_CMD_RSP_STATUS_SUCCESS) { + for (i = 0; i < rsp->num_peers; i++) { + adapter = hdd_get_adapter_by_vdev(hdd_ctx, + rsp->ndp_map[i].vdev_id); + if (NULL == adapter) { + hddLog(LOGE, + FL("adapter for vdev_id: %d not found"), + rsp->ndp_map[i].vdev_id); + continue; + } + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + idx = hdd_get_peer_idx(sta_ctx, + &rsp->ndp_map[i].peer_ndi_mac_addr); + if (idx == INVALID_PEER_IDX) + hddLog(LOGE, + FL("can't find addr: %pM in vdev_id: %d, peer table."), + &rsp->ndp_map[i].peer_ndi_mac_addr, + rsp->ndp_map[i].vdev_id); + else + ndp_ctx->active_ndp_sessions[idx] = + rsp->ndp_map[i].num_active_ndp_sessions; + } + } + + data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) + + sizeof(uint16_t); + + vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_KERNEL); + if (!vendor_event) { + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_END_RESPONSE)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, + rsp->status)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + rsp->reason)) + goto ndp_end_rsp_nla_failed; + + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + rsp->transaction_id)) + goto ndp_end_rsp_nla_failed; + + hddLog(LOG1, FL("NDP End rsp sent, transaction id: %d, status: %d, reason: %d"), + rsp->transaction_id, rsp->status, rsp->reason); + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + EXIT(); return; + +ndp_end_rsp_nla_failed: + hddLog(LOGE, FL("nla_put api failed")); + kfree_skb(vendor_event); + EXIT(); } /** @@ -1435,12 +1571,89 @@ static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter, * @adapter: pointer to adapter context * @ind_params: indication parameters * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * NUM_INSTANCE_ID bytes) + * * Return: none */ static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter, void *ind_params) { + struct sk_buff *vendor_event; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct ndp_end_indication_event *end_ind = ind_params; + uint32_t data_len, i; + struct nan_datapath_ctx *ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + uint32_t *ndp_instance_array; + + ENTER(); + + if (!end_ind) { + hddLog(LOGE, FL("Invalid ndp end indication")); + return; + } + + if (0 != wlan_hdd_validate_context(hdd_ctx)) + return; + + ndp_instance_array = vos_mem_malloc(end_ind->num_ndp_ids * + sizeof(*ndp_instance_array)); + if (!ndp_instance_array) { + hddLog(LOGE, "Failed to allocate ndp_instance_array"); + return; + } + for (i = 0; i < end_ind->num_ndp_ids; i++) { + int idx; + + ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id; + ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR( + hdd_get_adapter_by_vdev(hdd_ctx, + end_ind->ndp_map[i].vdev_id)); + idx = hdd_get_peer_idx(sta_ctx, + &end_ind->ndp_map[i].peer_ndi_mac_addr); + if (idx == INVALID_PEER_IDX) { + hddLog(LOGE, + FL("can't find addr: %pM in sta_ctx."), + &end_ind->ndp_map[i].peer_ndi_mac_addr); + continue; + } + /* save the value of active sessions on each peer */ + ndp_ctx->active_ndp_sessions[idx] = + end_ind->ndp_map[i].num_active_ndp_sessions; + } + + data_len = (sizeof(uint32_t)) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) + + end_ind->num_ndp_ids * sizeof(*ndp_instance_array); + + vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL, + data_len, QCA_NL80211_VENDOR_SUBCMD_NDP_INDEX, + GFP_KERNEL); + if (!vendor_event) { + hddLog(LOGE, FL("cfg80211_vendor_event_alloc failed")); + return; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_END_IND)) + goto ndp_end_ind_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, + end_ind->num_ndp_ids * sizeof(*ndp_instance_array), + ndp_instance_array)) + goto ndp_end_ind_nla_failed; + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + vos_mem_free(ndp_instance_array); + EXIT(); return; + +ndp_end_ind_nla_failed: + hddLog(LOGE, FL("nla_put api failed")); + kfree_skb(vendor_event); + vos_mem_free(ndp_instance_array); + EXIT(); } /** @@ -1506,7 +1719,7 @@ void hdd_ndp_event_handler(hdd_adapter_t *adapter, break; case eCSR_ROAM_RESULT_NDP_END_RSP: hdd_ndp_end_rsp_handler(adapter, - &roam_info->ndp.ndp_end_rsp_params); + roam_info->ndp.ndp_end_rsp_params); break; case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND: hdd_ndp_peer_departed_ind_handler(adapter, @@ -1514,7 +1727,7 @@ void hdd_ndp_event_handler(hdd_adapter_t *adapter, break; case eCSR_ROAM_RESULT_NDP_END_IND: hdd_ndp_end_ind_handler(adapter, - &roam_info->ndp.ndp_end_ind_params); + roam_info->ndp.ndp_end_ind_params); break; default: hddLog(LOGE, @@ -1581,14 +1794,15 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy, transaction_id = nla_get_u16( tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); - if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { - hddLog(LOGE, FL("Interface name string is unavailable")); - return -EINVAL; + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + hddLog(LOG2, FL("Transaction Id: %d NDP Cmd: %d iface_name: %s"), + transaction_id, ndp_cmd_type, iface_name); + } else { + hddLog(LOG2, + FL("Transaction Id: %d NDP Cmd: %d iface_name: unspecified"), + transaction_id, ndp_cmd_type); } - iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); - - hddLog(LOG2, FL("Transaction Id: %d NDP Cmd: %d iface_name: %s"), - transaction_id, ndp_cmd_type, iface_name); switch (ndp_cmd_type) { case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE: diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.h b/CORE/HDD/src/wlan_hdd_nan_datapath.h index 3a36427f1236..cf72826f0599 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.h +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.h @@ -39,6 +39,7 @@ struct wireless_dev; #define NDP_APP_INFO_LEN 255 #define NDP_QOS_INFO_LEN 255 +#define NDP_NUM_INSTANCE_ID 255 #define HDD_MAX_NUM_NDP_STA (HDD_MAX_NUM_IBSS_STA) @@ -66,13 +67,10 @@ struct wireless_dev; * @QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR: Iface name * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY: Security configuration * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS: Qos configuration - * @QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN: Application info length * @QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO: Application info * @QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID: NDP instance id - * @QCA_WLAN_VENDOR_ATTR_NDP_NUM_INSTANCE_ID: Number of NDP instance ids * @QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY: NDP instance id array * @QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE: Schedule response - * @QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_STATUS_CODE: schedule status * @QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR: NDI mac address * @QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE: Driver return status * @QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE: Driver return value @@ -87,13 +85,10 @@ enum qca_wlan_vendor_attr_ndp_params { QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY, QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS, - QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO_LEN, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, - QCA_WLAN_VENDOR_ATTR_NDP_NUM_INSTANCE_ID, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY, QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, - QCA_WLAN_VENDOR_ATTR_NDP_SCHEDULE_STATUS_CODE, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, @@ -187,17 +182,14 @@ enum nan_datapath_state { * @active_ndp_peers: number of active ndp peers * @ndp_create_transaction_id: transaction id for create req * @ndp_delete_transaction_id: transaction id for delete req - * @wext_state: Wext state variable - * @conn_info: NDP connection info - * @roam_info: NDP roam info - * @gtk_offload_req_params: GTK offload request params * @ndp_key_installed: NDP security key installed * @ndp_enc_key: NDP encryption key info * @ndp_debug_state: debug state info */ struct nan_datapath_ctx { enum nan_datapath_state state; - uint32_t active_ndp_sessions; + /* idx in following array should follow conn_info.peerMacAddress */ + uint32_t active_ndp_sessions[HDD_MAX_NUM_NDP_STA]; uint32_t active_ndp_peers; uint16_t ndp_create_transaction_id; uint16_t ndp_delete_transaction_id; diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c index 66ab1d251c1a..29bdfe094216 100644 --- a/CORE/HDD/src/wlan_hdd_tx_rx.c +++ b/CORE/HDD/src/wlan_hdd_tx_rx.c @@ -774,6 +774,29 @@ VOS_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *sta_ctx, } /** + * hdd_get_peer_idx() - Get the idx for given address in peer table + * @sta_ctx: pointer to HDD Station Context + * @addr: pointer to Peer Mac address + * + * Return: index when success else INVALID_PEER_IDX + */ +int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *addr) +{ + uint8_t idx; + + for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) { + if (sta_ctx->conn_info.staId[idx] == 0) + continue; + if (!vos_mem_compare(&sta_ctx->conn_info.peerMacAddress[idx], + addr, sizeof(v_MACADDR_t))) + continue; + return idx; + } + + return INVALID_PEER_IDX; +} + +/** * wlan_display_tx_timeout_stats() - HDD tx timeout stats display handler * @adapter: hdd adapter * diff --git a/CORE/MAC/inc/qwlan_version.h b/CORE/MAC/inc/qwlan_version.h index 1779243cea57..642e24b03a9f 100644 --- a/CORE/MAC/inc/qwlan_version.h +++ b/CORE/MAC/inc/qwlan_version.h @@ -42,9 +42,9 @@ BRIEF DESCRIPTION: #define QWLAN_VERSION_MINOR 0 #define QWLAN_VERSION_PATCH 11 #define QWLAN_VERSION_EXTRA "" -#define QWLAN_VERSION_BUILD 67 +#define QWLAN_VERSION_BUILD 70 -#define QWLAN_VERSIONSTR "4.0.11.67" +#define QWLAN_VERSIONSTR "4.0.11.70" #define AR6320_REV1_VERSION 0x5000000 diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 7bda8cfa07ce..be2d1fbf71f4 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -6999,6 +6999,32 @@ enum ndp_response_code { }; /** + * enum ndp_end_type - NDP end type + * @NDP_END_TYPE_UNSPECIFIED: type is unspecified + * @NDP_END_TYPE_PEER_UNAVAILABLE: type is peer unavailable + * @NDP_END_TYPE_OTA_FRAME: type OTA frame + * + */ +enum ndp_end_type { + NDP_END_TYPE_UNSPECIFIED = 0x00, + NDP_END_TYPE_PEER_UNAVAILABLE = 0x01, + NDP_END_TYPE_OTA_FRAME = 0x02, +}; + +/** + * enum ndp_end_reason_code - NDP end reason code + * @NDP_END_TYPE_UNSPECIFIED: reason is unspecified + * @NDP_END_TYPE_PEER_UNAVAILABLE: reason is peer inactivity + * @NDP_END_TYPE_OTA_FRAME: reason data end + * + */ +enum ndp_end_reason_code { + NDP_END_REASON_UNSPECIFIED = 0x00, + NDP_END_REASON_INACTIVITY = 0x01, + NDP_END_REASON_PEER_DATA_END = 0x02, +}; + +/** * struct ndp_cfg - ndp configuration * @tag: unique identifier * @ndp_cfg_len: ndp configuration length @@ -7192,7 +7218,6 @@ struct ndp_responder_rsp_event { * @ndp_instance_id: ndp instance id for which confirm is being generated * @peer_ndi_mac_addr: peer NDI mac address * @rsp_code: ndp response code - * @ndp_config: ndp configuration * @ndp_info: ndp application info * */ @@ -7201,23 +7226,20 @@ struct ndp_confirm_event { uint32_t ndp_instance_id; v_MACADDR_t peer_ndi_mac_addr; enum ndp_response_code rsp_code; - struct ndp_cfg ndp_config; struct ndp_app_info ndp_info; }; /** * struct ndp_end_req - ndp end request * @transaction_id: unique transaction identifier - * @vdev_id: session id of the interface over which ndp is being created * @num_ndp_instances: number of ndp instances to be terminated - * @ndp_instances: list of ndp instances to be terminated + * @ndp_ids: pointer to array of ndp_instance_id to be terminated * */ struct ndp_end_req { uint32_t transaction_id; - uint32_t vdev_id; uint32_t num_ndp_instances; - uint32_t ndp_instances[]; + uint32_t *ndp_ids; }; /** @@ -7225,39 +7247,47 @@ struct ndp_end_req { * @vdev_id: session id of the interface over which ndp is being created * @peer_ndi_mac_addr: peer NDI mac address * @num_active_ndp_sessions: number of active NDP sessions on the peer + * @type: NDP end indication type + * @reason_code: NDP end indication reason code + * @ndp_instance_id: NDP instance ID * */ struct peer_ndp_map { uint32_t vdev_id; v_MACADDR_t peer_ndi_mac_addr; uint32_t num_active_ndp_sessions; + enum ndp_end_type type; + enum ndp_end_reason_code reason_code; + uint32_t ndp_instance_id; }; /** * struct ndp_end_rsp_event - firmware response to ndp end request * @transaction_id: unique identifier for the request - * @vdev_id: session id of the interface over which ndp is being created + * @status: status of operation + * @reason: reason(opaque to host driver) + * @num_ndp_terminated: if successful, number of ndp instances terminated + * @num_peers: number of peers in ndp_map * @ndp_map: mapping of NDP instances to peer to VDEV * */ struct ndp_end_rsp_event { uint32_t transaction_id; - uint32_t vdev_id; + uint32_t status; + uint32_t reason; + uint32_t num_ndp_terminated; + uint32_t num_peers; struct peer_ndp_map ndp_map[]; }; /** * struct ndp_end_indication_event - ndp termination notification from FW - * @vdev_id: session id of the interface over which ndp is being created - * @reason: reason code for failure if any - * @status: status of the request - * @ndp_map: mapping of NDP instances to peer to VDEV + * @num_ndp_ids: number of NDP ids + * @ndp_map: mapping of NDP instances to peer and vdev * */ struct ndp_end_indication_event { - uint32_t vdev_id; - uint32_t status; - uint32_t reason; + uint32_t num_ndp_ids; struct peer_ndp_map ndp_map[]; }; diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h index 2a85a40b7e33..9a26f210ab0e 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -414,6 +414,7 @@ enum eWniMsgTypes eWNI_SME_NDP_INDICATION, eWNI_SME_NDP_RESPONDER_REQ, eWNI_SME_NDP_RESPONDER_RSP, + eWNI_SME_NDP_END_REQ, eWNI_SME_NDP_END_RSP, eWNI_SME_NDP_PEER_DEPARTED_IND, eWNI_SME_NDP_END_IND, diff --git a/CORE/MAC/src/dph/dphHashTable.c b/CORE/MAC/src/dph/dphHashTable.c index 5df7f6f11066..ed2c6e06423c 100644 --- a/CORE/MAC/src/dph/dphHashTable.c +++ b/CORE/MAC/src/dph/dphHashTable.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2014, 2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -464,7 +464,8 @@ tSirRetStatus dphDeleteHashEntry(tpAniSirGlobal pMac, tSirMacAddr staAddr, tANI_ void dphPrintMacAddr(tpAniSirGlobal pMac, tANI_U8 addr[], tANI_U32 level) { - limLog(pMac, (tANI_U16) level, FL("MAC ADDR = %d:%d:%d:%d:%d:%d"), + limLog(pMac, (tANI_U16) level, + FL("MAC ADDR = %02x:%02x:%02x:%02x:%02x:%02x"), addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]); } // --------------------------------------------------------------------- diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h index 59fe800d2ec8..19ddfcce691c 100644 --- a/CORE/MAC/src/include/sirParams.h +++ b/CORE/MAC/src/include/sirParams.h @@ -773,8 +773,7 @@ typedef struct sSirMbMsgP2p #define SIR_HAL_NDP_INDICATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 356) #define SIR_HAL_NDP_CONFIRM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 357) #define SIR_HAL_NDP_END_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 358) -#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 359) - +#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 359) #define SIR_BTC_BT_WLAN_INTERVAL_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 360) #define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF) diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c index 3e444a6e349f..1e1843f1e5f4 100644 --- a/CORE/MAC/src/pe/lim/limAssocUtils.c +++ b/CORE/MAC/src/pe/lim/limAssocUtils.c @@ -3501,7 +3501,7 @@ limCheckAndAnnounceJoinSuccess(tpAniSirGlobal pMac, limPostSmeMessage(pMac, LIM_MLM_JOIN_CNF, (tANI_U32 *) &mlmJoinCnf); } // if ((pMac->lim.gLimSystemRole == IBSS.... - if (pBPR->vendor2_ie.VHTCaps.present) { + if (psessionEntry->vhtCapability && pBPR->vendor2_ie.VHTCaps.present) { psessionEntry->is_vendor_specific_vhtcaps = true; psessionEntry->vendor_specific_vht_ie_type = pBPR->vendor2_ie.type; diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index ff93a9ef8002..74ba1148452d 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -1459,6 +1459,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) case eWNI_SME_REGISTER_MGMT_FRAME_CB: case eWNI_SME_NDP_INITIATOR_REQ: case eWNI_SME_NDP_RESPONDER_REQ: + case eWNI_SME_NDP_END_REQ: // These messages are from HDD limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd break; @@ -2209,6 +2210,8 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) case SIR_HAL_NDP_INDICATION: case SIR_HAL_NDP_CONFIRM: case SIR_HAL_NDP_RESPONDER_RSP: + case SIR_HAL_NDP_END_RSP: + case SIR_HAL_NDP_END_IND: lim_handle_ndp_event_message(pMac, limMsg); break; default: diff --git a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c index 6bbf10d8963f..b0f951c96f1c 100644 --- a/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessMlmReqMessages.c @@ -958,7 +958,6 @@ limSendHalStartScanReq(tpAniSirGlobal pMac, tANI_U8 channelNum, tLimLimHalScanSt SET_LIM_PROCESS_DEFD_MESGS(pMac, false); MTRACE(macTraceMsgTx(pMac, NO_SESSION, msg.type)); - limLog(pMac, LOG1, FL("Channel %d"), channelNum); rc = wdaPostCtrlMsg(pMac, &msg); if (rc == eSIR_SUCCESS) { @@ -3776,8 +3775,6 @@ limProcessMinChannelTimeout(tpAniSirGlobal pMac) if (pMac->lim.gLimMlmState == eLIM_MLM_WT_PROBE_RESP_STATE && pMac->lim.gLimHalScanState != eLIM_HAL_FINISH_SCAN_WAIT_STATE) { - PELOG1(limLog(pMac, LOG1, FL("Scanning : min channel timeout occurred"));) - /// Min channel timer timed out pMac->lim.limTimers.gLimPeriodicProbeReqTimer.sessionId = 0xff; limDeactivateAndChangeTimer(pMac, eLIM_MIN_CHANNEL_TIMER); diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c index ec7e2277bcc2..4af824983398 100644 --- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c @@ -2316,15 +2316,26 @@ void limProcessBtAmpApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPES } } +/** + * limProcessMlmDelStaRsp() - Process WDA_DELETE_STA_RSP + * @pMac: Global MAC context + * @limMsgQ: LIM Message pointer + * + * Return: None + */ void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) { - //we need to process the deferred message since the initiating req. there might be nested request. - //in the case of nested request the new request initiated from the response will take care of resetting - //the deffered flag. - tpPESession psessionEntry; tpDeleteStaParams pDeleteStaParams; pDeleteStaParams = (tpDeleteStaParams)limMsgQ->bodyptr; + + /* + * we need to process the message deferred since the initiating req. + * There might be nested request. In the case of nested request, + * the new request initiated from the response will take care of resetting + * the deferred flag. + */ + SET_LIM_PROCESS_DEFD_MESGS(pMac, true); if(NULL == pDeleteStaParams || @@ -2344,6 +2355,11 @@ void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ ) limProcessBtAmpApMlmDelStaRsp(pMac,limMsgQ,psessionEntry); return; } + + if (LIM_IS_NDI_ROLE(psessionEntry)) { + lim_process_ndi_del_sta_rsp(pMac, limMsgQ, psessionEntry); + return; + } limProcessStaMlmDelStaRsp(pMac, limMsgQ,psessionEntry); } @@ -2354,8 +2370,7 @@ void limProcessBtAmpApMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPES tSirResultCodes statusCode = eSIR_SME_SUCCESS; if(limMsgQ->bodyptr == NULL) { - limLog( pMac, LOGE, - FL( "limMsgQ->bodyptry NULL")); + limLog(pMac, LOGE, FL("limMsgQ->bodyptr NULL")); return; } pStaDs = dphGetHashEntry(pMac, pDelStaParams->assocId, &psessionEntry->dph.dphHashTable); diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index c2199a3c491c..72ec883d197d 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -6194,6 +6194,7 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) break; case eWNI_SME_NDP_INITIATOR_REQ: case eWNI_SME_NDP_RESPONDER_REQ: + case eWNI_SME_NDP_END_REQ: lim_handle_ndp_request_message(pMac, pMsg); break; default: diff --git a/CORE/MAC/src/pe/lim/limSendManagementFrames.c b/CORE/MAC/src/pe/lim/limSendManagementFrames.c index 9af329a2d573..74ddb451b621 100644 --- a/CORE/MAC/src/pe/lim/limSendManagementFrames.c +++ b/CORE/MAC/src/pe/lim/limSendManagementFrames.c @@ -2244,8 +2244,8 @@ limSendAssocReqMgmtFrame(tpAniSirGlobal pMac, PopulateDot11fVHTCaps( pMac, psessionEntry, &pFrm->VHTCaps ); isVHTEnabled = eANI_BOOLEAN_TRUE; } - if (!isVHTEnabled && - psessionEntry->is_vendor_specific_vhtcaps) { + if (psessionEntry->vhtCapability && !isVHTEnabled && + psessionEntry->is_vendor_specific_vhtcaps) { limLog(pMac, LOG1, FL("Populate Vendor VHT IEs in Assoc Request")); pFrm->vendor2_ie.present = 1; @@ -2737,7 +2737,8 @@ limSendReassocReqWithFTIEsMgmtFrame(tpAniSirGlobal pMac, if (psessionEntry->is_ext_caps_present) PopulateDot11fExtCap(pMac, isVHTEnabled, &frm.ExtCap, psessionEntry); - if (!isVHTEnabled && psessionEntry->is_vendor_specific_vhtcaps) { + if (psessionEntry->vhtCapability && !isVHTEnabled && + psessionEntry->is_vendor_specific_vhtcaps) { limLog(pMac, LOG1, FL("Populate Vendor VHT IEs in Re-Assoc Request")); frm.vendor2_ie.present = 1; diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c index 3bccdb5371f2..5c7aba25569a 100644 --- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c +++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c @@ -970,9 +970,6 @@ limSendSmeScanRsp(tpAniSirGlobal pMac, tANI_U16 length, vos_mem_copy( (tANI_U8 *) &pDesc->bssId, (tANI_U8 *) &ptemp->bssDescription.bssId, ptemp->bssDescription.length); - limLog(pMac, LOG2, FL("ScanRsp : msgLen %d, bssDescr Len=%d BssID "MAC_ADDRESS_STR), - msgLen, ptemp->bssDescription.length, - MAC_ADDR_ARRAY(ptemp->bssDescription.bssId)); pSirSmeScanRsp->sessionId = smesessionId; pSirSmeScanRsp->transcationId = smetranscationId; diff --git a/CORE/MAC/src/pe/lim/limSession.c b/CORE/MAC/src/pe/lim/limSession.c index d830b091a4a0..60122c056b12 100644 --- a/CORE/MAC/src/pe/lim/limSession.c +++ b/CORE/MAC/src/pe/lim/limSession.c @@ -203,6 +203,7 @@ void pe_reset_protection_callback(void *ptr) pe_session_entry->beaconParams.fRIFSMode; beacon_params.smeSessionId = pe_session_entry->smeSessionId; + beacon_params.paramChangeBitmap |= PARAM_llBCOEXIST_CHANGED; bcn_prms_changed = true; } diff --git a/CORE/MAC/src/pe/nan/nan_datapath.c b/CORE/MAC/src/pe/nan/nan_datapath.c index 91afbe5a6ef3..206140cb46da 100644 --- a/CORE/MAC/src/pe/nan/nan_datapath.c +++ b/CORE/MAC/src/pe/nan/nan_datapath.c @@ -216,6 +216,198 @@ responder_rsp: } /** + * lim_ndp_delete_peers() - Delete NAN data peers + * @mac_ctx: handle to mac context + * @ndp_map: NDP instance/peer map + * @num_peers: number of peers entries in peer_map + * This function deletes a peer if there are no active NDPs left with that peer + * + * Return: None + */ +static void lim_ndp_delete_peers(tpAniSirGlobal mac_ctx, + struct peer_ndp_map *ndp_map, uint8_t num_peers) +{ + tpDphHashNode sta_ds = NULL; + uint16_t deleted_num = 0; + int i, j; + tpPESession session; + v_MACADDR_t *deleted_peers; + uint16_t peer_idx; + bool found; + + deleted_peers = vos_mem_malloc(num_peers * sizeof(*deleted_peers)); + if (!deleted_peers) { + limLog(mac_ctx, LOGE, FL("Memory allocation failed")); + return; + } + + vos_mem_zero(deleted_peers, num_peers * sizeof(*deleted_peers)); + for (i = 0; i < num_peers; i++) { + limLog(mac_ctx, LOG1, + FL("ndp_map[%d]: MAC: " MAC_ADDRESS_STR "num_active %d"), + i, + MAC_ADDR_ARRAY(ndp_map[i].peer_ndi_mac_addr.bytes), + ndp_map[i].num_active_ndp_sessions); + + /* Do not delete a peer with active NDPs */ + if (ndp_map[i].num_active_ndp_sessions > 0) + continue; + + session = pe_find_session_by_sme_session_id(mac_ctx, + ndp_map[i].vdev_id); + if (!session || (session->bssType != eSIR_NDI_MODE)) { + limLog(mac_ctx, LOGE, + FL("PE session is NULL or non-NDI for sme session %d"), + ndp_map[i].vdev_id); + continue; + } + + /* Check if this peer is already in the deleted list */ + found = false; + for (j = 0; j < deleted_num && !found; j++) { + if (vos_mem_compare( + &deleted_peers[j].bytes, + &ndp_map[i].peer_ndi_mac_addr.bytes, + VOS_MAC_ADDR_SIZE)) { + found = true; + break; + } + } + if (found) + continue; + + sta_ds = dphLookupHashEntry(mac_ctx, + ndp_map[i].peer_ndi_mac_addr.bytes, + &peer_idx, &session->dph.dphHashTable); + if (!sta_ds) { + limLog(mac_ctx, LOGE, FL("Unknown NDI Peer")); + continue; + } + if (sta_ds->staType != STA_ENTRY_NDI_PEER) { + limLog(mac_ctx, LOGE, + FL("Non-NDI Peer ignored")); + continue; + } + /* + * Call limDelSta() with response required set true. + * Hence DphHashEntry will be deleted after receiving + * that response. + */ + limDelSta(mac_ctx, sta_ds, true, session); + vos_copy_macaddr(&deleted_peers[deleted_num++], + &ndp_map[i].peer_ndi_mac_addr); + } + vos_mem_free(deleted_peers); +} + +/** + * lim_ndp_end_indication_handler() - Handler for NDP end indication + * @mac_ctx: handle to mac context + * @ind_buf: pointer to indication buffer + * + * It deletes peers from ndp_map. Response of that operation goes + * to LIM and HDD. But peer information does not go to service layer. + * ndp_id_list is sent to service layer; it is not interpreted by the + * driver. + * + * Return: VOS_STATUS_SUCCESS on success; error number otherwise + */ +static VOS_STATUS lim_ndp_end_indication_handler(tpAniSirGlobal mac_ctx, + uint32_t *ind_buf) +{ + + struct ndp_end_indication_event *ndp_event_buf = + (struct ndp_end_indication_event *)ind_buf; + int buf_size; + + if (!ind_buf) { + limLog(mac_ctx, LOGE, FL("NDP end indication buffer is NULL")); + return VOS_STATUS_E_INVAL; + } + lim_ndp_delete_peers(mac_ctx, ndp_event_buf->ndp_map, + ndp_event_buf->num_ndp_ids); + + buf_size = sizeof(*ndp_event_buf) + ndp_event_buf->num_ndp_ids * + sizeof(ndp_event_buf->ndp_map[0]); + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_IND, + ndp_event_buf, buf_size, false); + + return VOS_STATUS_SUCCESS; +} + +/** + * lim_process_ndi_del_sta_rsp() - Handle WDA_DELETE_STA_RSP in eLIM_NDI_ROLE + * @mac_ctx: Global MAC context + * @lim_msg: LIM message + * @pe_session: PE session + * + * Return: None + */ +void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg, + tpPESession pe_session) +{ + tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr; + tpDphHashNode sta_ds; + tSirResultCodes status = eSIR_SME_SUCCESS; + struct sme_ndp_peer_ind peer_ind; + + if (!del_sta_params) { + limLog(mac_ctx, LOGE, + FL("del_sta_params is NULL")); + return; + } + if (!LIM_IS_NDI_ROLE(pe_session)) { + limLog(mac_ctx, LOGE, + FL("Session %d is not NDI role"), del_sta_params->assocId); + status = eSIR_SME_REFUSED; + goto skip_event; + } + + sta_ds = dphGetHashEntry(mac_ctx, del_sta_params->assocId, + &pe_session->dph.dphHashTable); + if (!sta_ds) { + limLog(mac_ctx, LOGE, + FL("DPH Entry for STA %X is missing."), + del_sta_params->assocId); + status = eSIR_SME_REFUSED; + goto skip_event; + } + + if (eHAL_STATUS_SUCCESS != del_sta_params->status) { + limLog(mac_ctx, LOGE, FL("DEL STA failed!")); + status = eSIR_SME_REFUSED; + goto skip_event; + } + limLog(mac_ctx, LOG1, + FL("Deleted STA AssocID %d staId %d MAC " MAC_ADDRESS_STR), + sta_ds->assocId, sta_ds->staIndex, + MAC_ADDR_ARRAY(sta_ds->staAddr)); + + /* + * Copy peer info in del peer indication before + * limDeleteDphHashEntry is called as this will be lost. + */ + peer_ind.msg_len = sizeof(peer_ind); + peer_ind.msg_type = eWNI_SME_NDP_PEER_DEPARTED_IND; + peer_ind.session_id = pe_session->smeSessionId; + peer_ind.sta_id = sta_ds->staIndex; + vos_mem_copy(&peer_ind.peer_mac_addr.bytes, + sta_ds->staAddr, sizeof(tSirMacAddr)); + + limReleasePeerIdx(mac_ctx, sta_ds->assocId, pe_session); + limDeleteDphHashEntry(mac_ctx, sta_ds->staAddr, sta_ds->assocId, + pe_session); + pe_session->limMlmState = eLIM_MLM_IDLE_STATE; + + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_PEER_DEPARTED_IND, + &peer_ind, sizeof(peer_ind), false); + +skip_event: + vos_mem_free(del_sta_params); + lim_msg->bodyptr = NULL; +} + +/** * lim_handle_ndp_event_message() - Handler for NDP events/RSP from WMA * @mac_ctx: handle to mac structure * @msg: pointer to message @@ -237,15 +429,30 @@ VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) msg->bodyptr, sizeof(struct ndp_initiator_rsp), msg->bodyval); break; - case SIR_HAL_NDP_INDICATION: { - struct ndp_indication_event *ndp_ind = msg->bodyptr; - status = lim_handle_ndp_indication_event(mac_ctx, ndp_ind); + case SIR_HAL_NDP_END_RSP: { + struct ndp_end_rsp_event *ndp_end_rsp = msg->bodyptr; + uint32_t rsp_len = sizeof(*ndp_end_rsp); + + if (ndp_end_rsp && ndp_end_rsp->ndp_map) { + lim_ndp_delete_peers(mac_ctx, ndp_end_rsp->ndp_map, + ndp_end_rsp->num_peers); + rsp_len += (ndp_end_rsp->num_peers * + sizeof(struct peer_ndp_map)); + } + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP, + msg->bodyptr, rsp_len, msg->bodyval); break; } + case SIR_HAL_NDP_INDICATION: + status = lim_handle_ndp_indication_event(mac_ctx, msg->bodyptr); + break; case SIR_HAL_NDP_RESPONDER_RSP: status = lim_ndp_responder_rsp_handler(mac_ctx, msg->bodyptr, msg->bodyval); break; + case SIR_HAL_NDP_END_IND: + status = lim_ndp_end_indication_handler(mac_ctx, msg->bodyptr); + break; default: limLog(mac_ctx, LOGE, FL("Unhandled NDP event: %d"), msg->type); status = VOS_STATUS_E_NOSUPPORT; @@ -355,6 +562,55 @@ send_failure_rsp: } /** + * lim_process_sme_ndp_data_end_req() - Handler for eWNI_SME_NDP_END_REQ + * from SME. + * @mac_ctx: handle to mac context + * @sme_msg: ndp data end request msg + * + * Return: Status of operation + */ +VOS_STATUS lim_process_sme_ndp_data_end_req(tpAniSirGlobal mac_ctx, + struct sir_sme_ndp_end_req *sme_msg) +{ + tSirMsgQ msg; + uint32_t len; + VOS_STATUS status = VOS_STATUS_SUCCESS; + + if (NULL == sme_msg) { + limLog(mac_ctx, LOGE, FL("invalid ndp_req")); + /* msg to unblock SME, but not send rsp to HDD */ + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP, NULL, + 0, true); + return VOS_STATUS_E_INVAL; + } + + msg.type = SIR_HAL_NDP_END_REQ; + msg.reserved = 0; + len = sizeof(*sme_msg->req) + (sme_msg->req->num_ndp_instances * + sizeof(uint32_t)); + msg.bodyptr = vos_mem_malloc(len); + if (NULL == msg.bodyptr) { + /* msg to unblock SME, but not send rsp to HDD */ + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP, NULL, + 0, true); + return VOS_STATUS_E_NOMEM; + } + vos_mem_copy(msg.bodyptr, sme_msg->req, len); + msg.bodyval = 0; + + limLog(mac_ctx, LOG1, FL("sending SIR_HAL_NDP_END_REQ to WMA")); + MTRACE(macTraceMsgTx(mac_ctx, NO_SESSION, msg.type)); + + if (eSIR_SUCCESS != wdaPostCtrlMsg(mac_ctx, &msg)) { + limLog(mac_ctx, LOGE, + FL("Post msg failed for SIR_HAL_NDP_END_REQ")); + status = VOS_STATUS_E_FAILURE; + } + + return status; +} + +/** * lim_handle_ndp_request_message() - Handler for NDP req from SME * @mac_ctx: handle to mac structure * @msg: pointer to message @@ -367,6 +623,10 @@ VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx, VOS_STATUS status; switch (msg->type) { + case eWNI_SME_NDP_END_REQ: + status = lim_process_sme_ndp_data_end_req(mac_ctx, + msg->bodyptr); + break; case eWNI_SME_NDP_INITIATOR_REQ: status = lim_process_sme_ndp_initiator_req(mac_ctx, msg->bodyptr); diff --git a/CORE/MAC/src/pe/nan/nan_datapath.h b/CORE/MAC/src/pe/nan/nan_datapath.h index 8c72126e130f..4f247ee30263 100644 --- a/CORE/MAC/src/pe/nan/nan_datapath.h +++ b/CORE/MAC/src/pe/nan/nan_datapath.h @@ -118,6 +118,9 @@ void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx, void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, tpPESession session_entry, tAddStaParams *add_sta_rsp); +void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg, + tpPESession pe_session); + #else /* Function to process NDP requests */ @@ -144,6 +147,10 @@ static inline void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx, void *msg, tpPESession session_entry) { } +static inline void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx, + tpSirMsgQ lim_msg, tpPESession pe_session) +{ +} static inline void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, tpPESession session_entry, @@ -154,4 +161,3 @@ static inline void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __MAC_NAN_DATAPATH_H */ - diff --git a/CORE/SAP/inc/sapApi.h b/CORE/SAP/inc/sapApi.h index 52452d09ea4d..dd37c2ecca1c 100644 --- a/CORE/SAP/inc/sapApi.h +++ b/CORE/SAP/inc/sapApi.h @@ -2394,6 +2394,8 @@ wlansap_get_phymode(v_PVOID_t pctx); VOS_STATUS wlansap_set_tx_leakage_threshold(tHalHandle hal, uint16 tx_leakage_threshold); +VOS_STATUS wlansap_get_chan_width(void *pvosctx, + uint32_t *pchanwidth); #ifdef __cplusplus } diff --git a/CORE/SAP/src/sapModule.c b/CORE/SAP/src/sapModule.c index fe619deb637a..0b369cc52dc8 100644 --- a/CORE/SAP/src/sapModule.c +++ b/CORE/SAP/src/sapModule.c @@ -4007,3 +4007,22 @@ VOS_STATUS wlansap_set_tx_leakage_threshold(tHalHandle hal, return VOS_STATUS_SUCCESS; } +/** + * wlansap_get_chan_width() - get sap channel width. + * @pvosctx: pointer of global vos context + * @pchanwidth: pointer of channel width + * + * This function get channel width of sap. + * + * Return: VOS_STATUS. + */ +VOS_STATUS +wlansap_get_chan_width(void *pvosctx, uint32_t *pchanwidth) +{ + ptSapContext sapcontext; + sapcontext = VOS_GET_SAP_CB(pvosctx); + *pchanwidth = wlan_sap_get_vht_ch_width(sapcontext); + + return VOS_STATUS_SUCCESS; +} + diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 7e3adc3c5d38..d76850401b2a 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -9026,7 +9026,10 @@ VOS_STATUS wma_get_buf_start_scan_cmd(tp_wma_handle wma_handle, cmd->scan_ctrl_flags |= WMI_SCAN_ADD_BCAST_PROBE_REQ; if (scan_req->scanType == eSIR_PASSIVE_SCAN) cmd->scan_ctrl_flags |= WMI_SCAN_FLAG_PASSIVE; + + cmd->scan_ctrl_flags |= WMI_SCAN_ADD_TPC_IE_IN_PROBE_REQ; cmd->scan_ctrl_flags |= WMI_SCAN_FILTER_PROBE_REQ; + /* * Decide burst_duration and dwell_time_active based on * what type of devices are active. @@ -17653,6 +17656,8 @@ static void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) WMA_LOGD("%s: to delete sta for IBSS mode", __func__); } #endif + if (del_sta->staType == STA_ENTRY_NDI_PEER) + oper_mode = BSS_OPERATIONAL_MODE_NDI; switch (oper_mode) { case BSS_OPERATIONAL_MODE_STA: @@ -17665,6 +17670,9 @@ static void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta) case BSS_OPERATIONAL_MODE_AP: wma_delete_sta_req_ap_mode(wma, del_sta); break; + case BSS_OPERATIONAL_MODE_NDI: + wma_delete_sta_req_ndi_mode(wma, del_sta); + break; } #ifdef QCA_IBSS_SUPPORT @@ -27345,6 +27353,11 @@ VOS_STATUS wma_ipa_offload_enable_disable(tp_wma_handle wma, return VOS_STATUS_E_INVAL; } + if (vos_is_load_unload_in_progress(VOS_MODULE_ID_VOSS, NULL)) { + WMA_LOGE("%s: Driver load/unload in progress", __func__); + return VOS_STATUS_E_INVAL; + } + len = sizeof(*cmd); wmi_buf = wmi_buf_alloc(wma->wmi_handle, len); if (!wmi_buf) { @@ -30129,6 +30142,10 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) wma_handle_ndp_responder_req(wma_handle, msg->bodyptr); vos_mem_free(msg->bodyptr); break; + case SIR_HAL_NDP_END_REQ: + wma_handle_ndp_end_req(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; default: WMA_LOGD("unknow msg type %x", msg->type); /* Do Nothing? MSG Body should be freed at here */ diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.c b/CORE/SERVICES/WMA/wma_nan_datapath.c index ee418e8d586c..a9d32137d2ca 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.c +++ b/CORE/SERVICES/WMA/wma_nan_datapath.c @@ -330,14 +330,91 @@ send_ndi_responder_fail: /** * wma_handle_ndp_end_req() - NDP end request handler * @wma_handle: wma handle - * @req_params: request parameters + * @ptr: request parameters * * Return: VOS_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, - struct ndp_end_req *req_params) +VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, void *ptr) { + int ret; + uint16_t len; + uint32_t ndp_end_req_len, i; + wmi_ndp_end_req *ndp_end_req_lst; + wmi_buf_t buf; + vos_msg_t pe_msg = {0}; + wmi_ndp_end_req_fixed_param *cmd; + struct ndp_end_rsp_event *end_rsp = NULL; + struct ndp_end_req *req = ptr; + + if (NULL == req) { + WMA_LOGE(FL("Invalid ndp_end_req")); + goto send_ndp_end_fail; + } + + /* len of tlv following fixed param */ + ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances; + /* above comes out to 4 byte alligned already, no need of padding */ + len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE; + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE(FL("Malloc failed")); + return VOS_STATUS_E_NOMEM; + } + cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf); + + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param, + WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param)); + + cmd->transaction_id = req->transaction_id; + + /* set tlv pointer to end of fixed param */ + WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC, + ndp_end_req_len); + + ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] + + WMI_TLV_HDR_SIZE); + for (i = 0; i < req->num_ndp_instances; i++) { + WMITLV_SET_HDR(&ndp_end_req_lst[i], + WMITLV_TAG_ARRAY_FIXED_STRUC, + (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE)); + + ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i]; + } + + WMA_LOGD(FL("Sending WMI_NDP_END_REQ_CMDID to FW")); + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_NDP_END_REQ_CMDID); + if (ret < 0) { + WMA_LOGE(FL("WMI_NDP_END_REQ_CMDID failed, ret: %d"), ret); + wmi_buf_free(buf); + goto send_ndp_end_fail; + } return VOS_STATUS_SUCCESS; + +send_ndp_end_fail: + pe_msg.type = SIR_HAL_NDP_END_RSP; + if (req) { + end_rsp = vos_mem_malloc(sizeof(*end_rsp)); + if (NULL == end_rsp) { + WMA_LOGE(FL("Malloc failed")); + pe_msg.bodyval = true; + } else { + vos_mem_zero(end_rsp, sizeof(*end_rsp)); + end_rsp->status = NDP_CMD_RSP_STATUS_ERROR; + end_rsp->transaction_id = req->transaction_id; + pe_msg.bodyptr = end_rsp; + } + } else { + pe_msg.bodyval = true; + } + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg)) { + WMA_LOGE("NDP_END_RSP to PE failed"); + vos_mem_free(end_rsp); + } + return VOS_STATUS_E_FAILURE; } /** @@ -375,20 +452,6 @@ static int wma_ndp_indication_event_handler(void *handle, uint8_t *event_info, fixed_params = (wmi_ndp_indication_event_fixed_param *)event->fixed_param; - WMA_LOGD(FL("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d, service_instance %d, ndp_instance %d, role %d, policy %d"), - WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, - fixed_params->service_instance_id, - fixed_params->ndp_instance_id, fixed_params->self_ndp_role, - fixed_params->accept_policy); - - WMA_LOGD(FL("ndp_cfg - %d bytes"), fixed_params->ndp_cfg_len); - VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, - &event->ndp_cfg, fixed_params->ndp_cfg_len); - - WMA_LOGD(FL("ndp_app_info - %d bytes"), fixed_params->ndp_app_info_len); - VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, - &event->ndp_app_info, fixed_params->ndp_app_info_len); - ind_event = vos_mem_malloc(sizeof(*ind_event)); if (!ind_event) { WMA_LOGP(FL("Failed to allocate memory")); @@ -406,6 +469,21 @@ static int wma_ndp_indication_event_handler(void *handle, uint8_t *event_info, WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, ind_event->peer_discovery_mac_addr.bytes); + WMA_LOGD(FL("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d, service_instance %d, ndp_instance %d, role %d, policy %d, peer_mac_addr: %pM, peer_disc_mac_addr: %pM"), + WMI_NDP_INDICATION_EVENTID, fixed_params->vdev_id, + fixed_params->service_instance_id, + fixed_params->ndp_instance_id, fixed_params->self_ndp_role, + fixed_params->accept_policy, + ind_event->peer_mac_addr.bytes, + ind_event->peer_discovery_mac_addr.bytes); + + WMA_LOGD(FL("ndp_cfg - %d bytes"), fixed_params->ndp_cfg_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + &event->ndp_cfg, fixed_params->ndp_cfg_len); + + WMA_LOGD(FL("ndp_app_info - %d bytes"), fixed_params->ndp_app_info_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + &event->ndp_app_info, fixed_params->ndp_app_info_len); ind_event->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; ind_event->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; @@ -524,31 +602,12 @@ static int wma_ndp_confirm_event_handler(void *handle, uint8_t *event_info, WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, ndp_confirm->peer_ndi_mac_addr.bytes); - vos_mem_copy(&ndp_confirm->ndp_config, event->ndp_cfg, - fixed_params->ndp_cfg_len); - - ndp_confirm->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len; ndp_confirm->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len; - - if (ndp_confirm->ndp_config.ndp_cfg_len) { - ndp_confirm->ndp_config.ndp_cfg = - vos_mem_malloc(ndp_confirm->ndp_config.ndp_cfg_len); - if (NULL == ndp_confirm->ndp_config.ndp_cfg) { - WMA_LOGE(FL("malloc failed")); - vos_mem_free(ndp_confirm); - return VOS_STATUS_E_NOMEM; - } - vos_mem_copy(ndp_confirm->ndp_config.ndp_cfg, - event->ndp_cfg, - ndp_confirm->ndp_config.ndp_cfg_len); - } - if (ndp_confirm->ndp_info.ndp_app_info_len) { ndp_confirm->ndp_info.ndp_app_info = vos_mem_malloc(fixed_params->ndp_app_info_len); if (NULL == ndp_confirm->ndp_info.ndp_app_info) { WMA_LOGE(FL("malloc failed")); - vos_mem_free(ndp_confirm->ndp_config.ndp_cfg); vos_mem_free(ndp_confirm); return VOS_STATUS_E_NOMEM; } @@ -563,7 +622,6 @@ static int wma_ndp_confirm_event_handler(void *handle, uint8_t *event_info, status = vos_mq_post_message(VOS_MODULE_ID_PE, &msg); if (!VOS_IS_STATUS_SUCCESS(status)) { WMA_LOGE(FL("fail to post SIR_HAL_NDP_CONFIRM msg to PE")); - vos_mem_free(ndp_confirm->ndp_config.ndp_cfg); vos_mem_free(ndp_confirm->ndp_info.ndp_app_info); vos_mem_free(ndp_confirm); } @@ -583,7 +641,73 @@ static int wma_ndp_confirm_event_handler(void *handle, uint8_t *event_info, static int wma_ndp_end_response_event_handler(void *handle, uint8_t *event_info, uint32_t len) { - return 0; + int ret = 0; + VOS_STATUS status; + vos_msg_t pe_msg = {0}; + struct ndp_end_rsp_event *end_rsp; + WMI_NDP_END_RSP_EVENTID_param_tlvs *event; + wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL; + wmi_ndp_end_rsp_per_ndi *end_rsp_tlv; + uint32_t i; + uint32_t len_end_rsp; + + event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) event_info; + fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param; + WMA_LOGD(FL("WMI_NDP_END_RSP_EVENTID(0x%X) recieved. transaction_id: %d, rsp_status: %d, reason_code: %d"), + WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id, + fixed_params->rsp_status, fixed_params->reason_code); + + len_end_rsp = sizeof(*end_rsp) + (event->num_ndp_end_rsp_per_ndi_list * + sizeof(struct peer_ndp_map)); + end_rsp = vos_mem_malloc(len_end_rsp); + if (NULL == end_rsp) { + WMA_LOGE("malloc failed"); + pe_msg.bodyval = true; + ret = -ENOMEM; + goto send_ndp_end_rsp; + } + pe_msg.bodyptr = end_rsp; + vos_mem_zero(end_rsp, len_end_rsp); + + end_rsp->transaction_id = fixed_params->transaction_id; + end_rsp->reason = fixed_params->reason_code; + end_rsp->status = fixed_params->rsp_status; + + if (end_rsp->status == NDP_CMD_RSP_STATUS_SUCCESS) { + WMA_LOGD(FL("NDP end rsp, num_peers: %d"), + event->num_ndp_end_rsp_per_ndi_list); + end_rsp->num_peers = event->num_ndp_end_rsp_per_ndi_list; + if (end_rsp->num_peers == 0) { + WMA_LOGE(FL("num_peers in NDP rsp should not be 0.")); + end_rsp->status = NDP_CMD_RSP_STATUS_ERROR; + goto send_ndp_end_rsp; + } + /* copy per peer response to return path buffer */ + end_rsp_tlv = event->ndp_end_rsp_per_ndi_list; + for (i = 0; i < end_rsp->num_peers; i++) { + end_rsp->ndp_map[i].vdev_id = end_rsp_tlv[i].vdev_id; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&end_rsp_tlv[i].peer_mac_addr, + end_rsp->ndp_map[i].peer_ndi_mac_addr.bytes); + end_rsp->ndp_map[i].num_active_ndp_sessions = + end_rsp_tlv[i].num_active_ndps_on_ndi; + WMA_LOGD(FL("vdev_id: %d, peer_addr: %pM, active_ndp_left: %d"), + end_rsp->ndp_map[i].vdev_id, + &end_rsp->ndp_map[i].peer_ndi_mac_addr, + end_rsp->ndp_map[i].num_active_ndp_sessions); + } + } + +send_ndp_end_rsp: + pe_msg.type = SIR_HAL_NDP_END_RSP; + WMA_LOGD(FL("Sending SIR_HAL_NDP_END_RSP msg to PE")); + status = vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg); + if (!VOS_IS_STATUS_SUCCESS(status)) { + WMA_LOGE("SIR_HAL_NDP_END_RSP to PE failed"); + vos_mem_free(end_rsp); + ret = -EINVAL; + } + + return ret; } /** @@ -598,7 +722,74 @@ static int wma_ndp_end_response_event_handler(void *handle, static int wma_ndp_end_indication_event_handler(void *handle, uint8_t *event_info, uint32_t len) { - return 0; + WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event; + wmi_ndp_end_indication *ind; + vos_msg_t pe_msg; + struct ndp_end_indication_event *ndp_event_buf; + VOS_STATUS vos_status; + int i; + v_MACADDR_t peer_addr; + int buf_size; + + event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) event_info; + + if (event->num_ndp_end_indication_list == 0) { + WMA_LOGE( + FL("Error: Event ignored, 0 ndp instances")); + return -EINVAL; + } + + WMA_LOGD(FL("number of ndp instances = %d"), + event->num_ndp_end_indication_list); + + buf_size = sizeof(*ndp_event_buf) + event->num_ndp_end_indication_list * + sizeof(ndp_event_buf->ndp_map[0]); + ndp_event_buf = vos_mem_malloc(buf_size); + if (!ndp_event_buf) { + WMA_LOGP(FL("Failed to allocate memory")); + return -ENOMEM; + } + vos_mem_zero(ndp_event_buf, buf_size); + ndp_event_buf->num_ndp_ids = event->num_ndp_end_indication_list; + + ind = event->ndp_end_indication_list; + for (i = 0; i < ndp_event_buf->num_ndp_ids; i++) { + WMI_MAC_ADDR_TO_CHAR_ARRAY( + &ind[i].peer_ndi_mac_addr, + peer_addr.bytes); + WMA_LOGD( + FL("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d MAC: " MAC_ADDRESS_STR), + i, + ind[i].type, + ind[i].reason_code, + ind[i].ndp_instance_id, + ind[i].num_active_ndps_on_peer, + MAC_ADDR_ARRAY(peer_addr.bytes)); + + /* Add each instance entry to the list */ + ndp_event_buf->ndp_map[i].ndp_instance_id = + ind[i].ndp_instance_id; + ndp_event_buf->ndp_map[i].vdev_id = ind[i].vdev_id; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr, + ndp_event_buf->ndp_map[i].peer_ndi_mac_addr.bytes); + ndp_event_buf->ndp_map[i].num_active_ndp_sessions = + ind[i].num_active_ndps_on_peer; + ndp_event_buf->ndp_map[i].type = ind[i].type; + ndp_event_buf->ndp_map[i].reason_code = + ind[i].reason_code; + } + + pe_msg.type = SIR_HAL_NDP_END_IND; + pe_msg.bodyptr = ndp_event_buf; + pe_msg.bodyval = 0; + vos_status = vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg); + if (VOS_IS_STATUS_SUCCESS(vos_status)) { + return 0; + } + + WMA_LOGE(FL("failed to post msg to PE")); + vos_mem_free(ndp_event_buf); + return -EINVAL; } /** @@ -1089,3 +1280,48 @@ send_rsp: add_sta->staMac, add_sta->status); wma_send_msg(wma, WDA_ADD_STA_RSP, (void *)add_sta, 0); } + +/** + * wma_delete_sta_req_ndi_mode() - Process DEL_STA request for NDI data peer + * @wma: WMA context + * @del_sta: DEL_STA parameters from LIM + * + * Removes wma/txrx peer entry for the NDI STA + * + * Return: None + */ +void wma_delete_sta_req_ndi_mode(tp_wma_handle wma, + tpDeleteStaParams del_sta) +{ + ol_txrx_pdev_handle pdev; + struct ol_txrx_peer_t *peer; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (!pdev) { + WMA_LOGE(FL("Failed to get pdev")); + del_sta->status = VOS_STATUS_E_FAILURE; + goto send_del_rsp; + } + + peer = ol_txrx_peer_find_by_local_id(pdev, del_sta->staIdx); + if (!peer) { + WMA_LOGE(FL("Failed to get peer handle using peer id %d"), + del_sta->staIdx); + del_sta->status = VOS_STATUS_E_FAILURE; + goto send_del_rsp; + } + + wma_remove_peer(wma, peer->mac_addr.raw, del_sta->smesessionId, peer, + false); + del_sta->status = VOS_STATUS_SUCCESS; + +send_del_rsp: + if (del_sta->respReqd) { + WMA_LOGD(FL("Sending del rsp to umac (status: %d)"), + del_sta->status); + wma_send_msg(wma, WDA_DELETE_STA_RSP, del_sta, 0); + } +} + + diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.h b/CORE/SERVICES/WMA/wma_nan_datapath.h index a639f394cdfa..ba7874391e21 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.h +++ b/CORE/SERVICES/WMA/wma_nan_datapath.h @@ -58,6 +58,9 @@ void wma_ndp_wow_event_callback(void *handle, void *event, uint32_t len); void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss); void wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta); VOS_STATUS wma_handle_ndp_initiator_req(tp_wma_handle wma_handle, void *req); +VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, void *req); +void wma_delete_sta_req_ndi_mode(tp_wma_handle wma, + tpDeleteStaParams del_sta); #else static inline void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss) {} @@ -85,6 +88,14 @@ static inline VOS_STATUS wma_handle_ndp_responder_req(tp_wma_handle wma_handle, { return VOS_STATUS_SUCCESS; } - +static inline VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, + void *req) +{ + return VOS_STATUS_SUCCESS; +} +static inline void wma_delete_sta_req_ndi_mode(tp_wma_handle wma, + tpDeleteStaParams del_sta) +{ +} #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __WMA_NAN_DATAPATH_H */ diff --git a/CORE/SME/inc/csrApi.h b/CORE/SME/inc/csrApi.h index 02e63d503838..18e13f1a23bb 100644 --- a/CORE/SME/inc/csrApi.h +++ b/CORE/SME/inc/csrApi.h @@ -193,7 +193,7 @@ typedef enum */ typedef enum { - eCSR_SCAN_ABORT_DEFAULT, + eCSR_SCAN_ABORT_DEFAULT = 1, eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE, //Scan aborted due to band change }eCsrAbortReason; @@ -1475,8 +1475,8 @@ typedef struct tagCsrRoamInfo union { struct sme_ndp_peer_ind ndp_peer_ind_params; struct ndp_schedule_update_rsp ndp_sched_upd_rsp_params; - struct ndp_end_indication_event ndp_end_ind_params; - struct ndp_end_rsp_event ndp_end_rsp_params; + struct ndp_end_indication_event *ndp_end_ind_params; + struct ndp_end_rsp_event *ndp_end_rsp_params; struct ndp_confirm_event ndp_confirm_params; struct ndp_responder_rsp_event ndp_responder_rsp_params; struct ndp_indication_event ndp_indication_params; diff --git a/CORE/SME/inc/csrInternal.h b/CORE/SME/inc/csrInternal.h index 5902dce84a22..1f2afe9e95b4 100644 --- a/CORE/SME/inc/csrInternal.h +++ b/CORE/SME/inc/csrInternal.h @@ -45,6 +45,8 @@ #include "wlan_qct_tl.h" #include "vos_utils.h" +#include "csrApi.h" + #ifdef WLAN_FEATURE_NEIGHBOR_ROAMING #include "csrNeighborRoam.h" #endif @@ -403,7 +405,7 @@ typedef struct tagScanCmd tCsrBGScanRequest bgScanRequest; }u; //This flag will be set while aborting the scan due to band change - tANI_BOOLEAN abortScanDueToBandChange; + eCsrAbortReason abort_scan_indication; }tScanCmd; typedef struct tagRoamCmd diff --git a/CORE/SME/inc/smeInside.h b/CORE/SME/inc/smeInside.h index e0de898cc3b1..e8693b6cf406 100644 --- a/CORE/SME/inc/smeInside.h +++ b/CORE/SME/inc/smeInside.h @@ -217,6 +217,7 @@ typedef struct tagSmeCmd #ifdef WLAN_FEATURE_NAN_DATAPATH struct ndp_initiator_req initiator_req; struct ndp_responder_req responder_req; + struct ndp_end_req *data_end_req; #endif }u; }tSmeCmd; diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h index 46e4fab07b2d..edcdd4f450ad 100644 --- a/CORE/SME/inc/smeInternal.h +++ b/CORE/SME/inc/smeInternal.h @@ -100,6 +100,7 @@ typedef enum eSmeCommandType eSmeCommandNoAUpdate, eSmeCommandNdpInitiatorRequest, eSmeCommandNdpResponderRequest, + eSmeCommandNdpDataEndInitiatorRequest, } eSmeCommandType; diff --git a/CORE/SME/inc/sme_nan_datapath.h b/CORE/SME/inc/sme_nan_datapath.h index bec7ed381d62..30b0a00a8516 100644 --- a/CORE/SME/inc/sme_nan_datapath.h +++ b/CORE/SME/inc/sme_nan_datapath.h @@ -63,6 +63,19 @@ struct sir_sme_ndp_responder_req { struct ndp_responder_req req; }; +/** + * struct sir_sme_ndp_end_req - sme request struct for ndp end req + * @msg_type: SME msg type(sir_sme_ndp_initiator_req) + * @msg_len: lenght of message + * @req: actual ndp initiator request + * + */ +struct sir_sme_ndp_end_req { + uint16_t msg_type; + uint16_t msg_len; + struct ndp_end_req *req; +}; + /* NaN initiator request handler */ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, struct ndp_initiator_req *req_params); @@ -72,8 +85,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, struct ndp_responder_req *req_params); /* NaN indication response handler */ -VOS_STATUS sme_ndp_end_req_handler(uint32_t session_id, - struct ndp_end_req *req_params); +VOS_STATUS sme_ndp_end_req_handler(tHalHandle hal, struct ndp_end_req *req); /* NaN schedule update request handler */ VOS_STATUS sme_ndp_sched_req_handler(uint32_t session_id, @@ -106,6 +118,8 @@ void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx, void *roam_info); eHalStatus csr_process_ndp_initiator_request(tpAniSirGlobal mac_ctx, tSmeCmd *cmd); +eHalStatus csr_process_ndp_data_end_request(tpAniSirGlobal mac_ctx, + tSmeCmd *cmd); void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg); @@ -161,6 +175,13 @@ static inline eHalStatus csr_process_ndp_responder_request( { return eHAL_STATUS_SUCCESS; } + +static inline eHalStatus csr_process_ndp_data_end_request( + tpAniSirGlobal mac_ctx, tSmeCmd *cmd) +{ + return eHAL_STATUS_SUCCESS; +} + #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __SME_NAN_DATAPATH_H */ diff --git a/CORE/SME/src/csr/csrApiScan.c b/CORE/SME/src/csr/csrApiScan.c index 669969e3455f..bb73db4ca659 100644 --- a/CORE/SME/src/csr/csrApiScan.c +++ b/CORE/SME/src/csr/csrApiScan.c @@ -1161,9 +1161,7 @@ eHalStatus csrIssueRoamAfterLostlinkScan(tpAniSirGlobal pMac, tANI_U32 sessionId } -eHalStatus csrScanGetScanChnInfo(tpAniSirGlobal pMac, tANI_U8 sessionId, - void *pContext, void *callback, - tANI_U32 scanID) +eHalStatus csrScanGetScanChnInfo(tpAniSirGlobal pMac, tSmeCmd *pCommand) { eHalStatus status = eHAL_STATUS_SUCCESS; tSmeCmd *pScanCmd; @@ -1175,22 +1173,21 @@ eHalStatus csrScanGetScanChnInfo(tpAniSirGlobal pMac, tANI_U8 sessionId, { pScanCmd->command = eSmeCommandScan; vos_mem_set(&pScanCmd->u.scanCmd, sizeof(tScanCmd), 0); - pScanCmd->u.scanCmd.callback = callback; - pScanCmd->u.scanCmd.pContext = pContext; pScanCmd->u.scanCmd.reason = eCsrScanGetScanChnInfo; - if (callback) - { - //use same scanID as maintained in pAdapter - pScanCmd->u.scanCmd.scanID = scanID; + /* Need to make the following atomic */ + pScanCmd->u.scanCmd.scanID = + pMac->scan.nextScanID++; /* let it wrap around */ + pScanCmd->sessionId = pCommand->sessionId; + if (eCsrScanUserRequest == pCommand->u.scanCmd.reason) + { + pScanCmd->u.scanCmd.callback = NULL; + pScanCmd->u.scanCmd.pContext = NULL; + } else { + pScanCmd->u.scanCmd.callback = pCommand->u.scanCmd.callback; + pScanCmd->u.scanCmd.pContext = pCommand->u.scanCmd.pContext; + pScanCmd->u.scanCmd.abort_scan_indication = + pCommand->u.scanCmd.abort_scan_indication; } - else - { - //Need to make the following atomic - pScanCmd->u.scanCmd.scanID = - pMac->scan.nextScanID++; //let it wrap around - } - - pScanCmd->sessionId = sessionId; status = csrQueueSmeCommand(pMac, pScanCmd, eANI_BOOLEAN_FALSE); if( !HAL_STATUS_SUCCESS( status ) ) { @@ -2737,11 +2734,6 @@ eHalStatus csrScanFilterResults(tpAniSirGlobal pMac) csrFreeScanResultEntry( pMac, pBssDesc ); } } - else - { - smsLog( pMac, LOG1, FL("%d is a Valid channel"), - pBssDesc->Result.BssDescriptor.channelId); - } pEntry = pTempEntry; } @@ -4689,7 +4681,8 @@ tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp ) //This check only valid here because csrSaveScanresults is not yet called fSuccess = (!csrLLIsListEmpty(&pMac->scan.tempScanResults, LL_ACCESS_LOCK)); } - if (pCommand->u.scanCmd.abortScanDueToBandChange) + if (pCommand->u.scanCmd.abort_scan_indication & + eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE) { /* * Scan aborted due to band change @@ -4707,8 +4700,6 @@ tANI_BOOLEAN csrScanComplete( tpAniSirGlobal pMac, tSirSmeScanRsp *pScanRsp ) smsLog(pMac, LOG1, FL("11d_scan_done will flush the scan" " results")); } - pCommand->u.scanCmd.abortScanDueToBandChange - = eANI_BOOLEAN_FALSE; } csrSaveScanResults(pMac, pCommand->u.scanCmd.reason, sessionId); @@ -5496,29 +5487,15 @@ eHalStatus csrScanSmeScanResponse( tpAniSirGlobal pMac, void *pMsgBuf ) * wild card scan because it may cause scan results got * aged out incorrectly. */ - if( csrScanIsWildCardScan( pMac, pCommand ) && (!pCommand->u.scanCmd.u.scanRequest.p2pSearch) + if (csrScanIsWildCardScan(pMac, pCommand) && + (!pCommand->u.scanCmd.u.scanRequest.p2pSearch) #ifdef WLAN_FEATURE_ROAM_SCAN_OFFLOAD && (pCommand->u.scanCmd.reason != eCsrScanGetLfrResult) #endif ) - { - //Get the list of channels scanned - if( pCommand->u.scanCmd.reason != eCsrScanUserRequest) - { - csrScanGetScanChnInfo(pMac, pCommand->sessionId, - NULL, NULL, - pCommand->u.scanCmd.scanID); - } - else - { - csrScanGetScanChnInfo(pMac, - pCommand->sessionId, - pCommand->u.scanCmd.pContext, - pCommand->u.scanCmd.callback, - pCommand->u.scanCmd.scanID); - pCommand->u.scanCmd.callback = NULL; - } - } + { + csrScanGetScanChnInfo(pMac, pCommand); + } } break; }//switch @@ -6694,6 +6671,10 @@ void csrScanCallCallback(tpAniSirGlobal pMac, tSmeCmd *pCommand, eCsrScanStatus { if(pCommand->u.scanCmd.callback) { + if (pCommand->u.scanCmd.abort_scan_indication) { + smsLog(pMac, LOG1, FL("scanDone due to abort")); + scanStatus = eCSR_SCAN_ABORT; + } pCommand->u.scanCmd.callback(pMac, pCommand->u.scanCmd.pContext, pCommand->sessionId, pCommand->u.scanCmd.scanID, scanStatus); @@ -8232,10 +8213,11 @@ eHalStatus csrScanAbortMacScan(tpAniSirGlobal pMac, tANI_U8 sessionId, } else { + pCommand->u.scanCmd.abort_scan_indication = eCSR_SCAN_ABORT_DEFAULT; if(reason == eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE) { - pCommand->u.scanCmd.abortScanDueToBandChange - = eANI_BOOLEAN_TRUE; + pCommand->u.scanCmd.abort_scan_indication + = eCSR_SCAN_ABORT_DUE_TO_BAND_CHANGE; } vos_mem_set((void *)pMsg, msgLen, 0); pMsg->type = pal_cpu_to_be16((tANI_U16)eWNI_SME_SCAN_ABORT_IND); diff --git a/CORE/SME/src/nan/nan_datapath_api.c b/CORE/SME/src/nan/nan_datapath_api.c index 0a183c676cdd..aee4c18c3bd3 100644 --- a/CORE/SME/src/nan/nan_datapath_api.c +++ b/CORE/SME/src/nan/nan_datapath_api.c @@ -84,6 +84,7 @@ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, cmd->u.initiator_req.ndp_config.ndp_cfg = vos_mem_malloc(req_params->ndp_config.ndp_cfg_len); if (NULL == cmd->u.initiator_req.ndp_config.ndp_cfg) { + csrReleaseCommandRoam(mac_ctx, cmd); sme_ReleaseGlobalLock(&mac_ctx->sme); vos_mem_free( cmd->u.initiator_req.ndp_info.ndp_app_info); @@ -103,6 +104,7 @@ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, vos_mem_free(cmd->u.initiator_req.ndp_config.ndp_cfg); cmd->u.initiator_req.ndp_info.ndp_app_info_len = 0; cmd->u.initiator_req.ndp_config.ndp_cfg_len = 0; + csrReleaseCommandRoam(mac_ctx, cmd); } sme_ReleaseGlobalLock(&mac_ctx->sme); @@ -156,6 +158,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, cmd->u.responder_req.ndp_info.ndp_app_info = vos_mem_malloc(req_params->ndp_info.ndp_app_info_len); if (NULL == cmd->u.responder_req.ndp_info.ndp_app_info) { + csrReleaseCommandRoam(mac_ctx, cmd); sme_ReleaseGlobalLock(&mac_ctx->sme); return eHAL_STATUS_FAILED_ALLOC; } @@ -168,6 +171,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, cmd->u.responder_req.ndp_config.ndp_cfg = vos_mem_malloc(req_params->ndp_config.ndp_cfg_len); if (NULL == cmd->u.responder_req.ndp_config.ndp_cfg) { + csrReleaseCommandRoam(mac_ctx, cmd); sme_ReleaseGlobalLock(&mac_ctx->sme); vos_mem_free( cmd->u.responder_req.ndp_info.ndp_app_info); @@ -187,6 +191,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, vos_mem_free(cmd->u.responder_req.ndp_config.ndp_cfg); cmd->u.responder_req.ndp_info.ndp_app_info_len = 0; cmd->u.responder_req.ndp_config.ndp_cfg_len = 0; + csrReleaseCommandRoam(mac_ctx, cmd); } sme_ReleaseGlobalLock(&mac_ctx->sme); return status; @@ -194,17 +199,63 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, /** * sme_ndp_end_req_handler() - ndp end request handler - * @session_id: session id over which the ndp is being created - * @req_params: request parameters + * @hal: hal handle + * @req: ndp end request parameters * * Return: VOS_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS sme_ndp_end_req_handler(uint32_t session_id, - struct ndp_end_req *req_params) +VOS_STATUS sme_ndp_end_req_handler(tHalHandle hal, struct ndp_end_req *req) { - return VOS_STATUS_SUCCESS; -} + tSmeCmd *cmd; + VOS_STATUS ret = VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + + if (NULL == req) { + smsLog(mac_ctx, LOGE, FL("Invalid ndp end req")); + return VOS_STATUS_E_INVAL; + } + + status = sme_AcquireGlobalLock(&mac_ctx->sme); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(mac_ctx, LOGE, + FL("SME lock failed, status:%d"), status); + return VOS_STATUS_E_RESOURCES; + } + cmd = csrGetCommandBuffer(mac_ctx); + if (NULL == cmd) { + sme_ReleaseGlobalLock(&mac_ctx->sme); + return VOS_STATUS_E_RESOURCES; + } + + cmd->command = eSmeCommandNdpDataEndInitiatorRequest; + cmd->u.data_end_req = vos_mem_malloc(sizeof(*req) + + (req->num_ndp_instances * sizeof(uint32))); + if (NULL == cmd->u.data_end_req) { + csrReleaseCommandRoam(mac_ctx, cmd); + sme_ReleaseGlobalLock(&mac_ctx->sme); + return VOS_STATUS_E_NOMEM; + } + vos_mem_copy(cmd->u.data_end_req, req, sizeof(*req)); + cmd->u.data_end_req->ndp_ids = + (uint32_t *)((uint8_t *)&cmd->u.data_end_req[1]); + vos_mem_copy(cmd->u.data_end_req->ndp_ids, req->ndp_ids, + sizeof(uint32_t) * req->num_ndp_instances); + + status = csrQueueSmeCommand(mac_ctx, cmd, true); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(mac_ctx, LOGE, FL("SME enqueue failed, status:%d"), + status); + vos_mem_free(cmd->u.data_end_req); + cmd->u.data_end_req = NULL; + ret = VOS_STATUS_E_FAILURE; + csrReleaseCommandRoam(mac_ctx, cmd); + } + + sme_ReleaseGlobalLock(&mac_ctx->sme); + return ret; +} /** * sme_ndp_sched_req_handler() - ndp schedule request handler @@ -493,6 +544,46 @@ free_config: } /** + * csr_process_ndp_data_end_request() - process ndp data end request + * @mac_ctx: Global MAC context + * @cmd: sme command containing ndp initiator request + * + * Return: status of operation + */ +eHalStatus csr_process_ndp_data_end_request(tpAniSirGlobal mac_ctx, + tSmeCmd *cmd) +{ + eHalStatus status; + struct sir_sme_ndp_end_req *lim_msg; + uint16_t msg_len; + + if (NULL == cmd) { + smsLog(mac_ctx, LOGE, FL("NULL sme cmd")); + return eHAL_STATUS_INVALID_PARAMETER; + } + + msg_len = sizeof(*lim_msg); + lim_msg = vos_mem_malloc(msg_len); + if (NULL == lim_msg) { + smsLog(mac_ctx, LOGE, FL("Malloc failed")); + vos_mem_free(cmd->u.data_end_req); + cmd->u.data_end_req = NULL; + return eHAL_STATUS_FAILED_ALLOC; + } + + lim_msg->msg_type = (uint16_t)eWNI_SME_NDP_END_REQ; + lim_msg->msg_len = msg_len; + lim_msg->req = cmd->u.data_end_req; + + status = palSendMBMessage(mac_ctx->hHdd, lim_msg); + if (status != eHAL_STATUS_SUCCESS) { + vos_mem_free(cmd->u.data_end_req); + cmd->u.data_end_req = NULL; + } + return status; +} + +/** * sme_ndp_msg_processor() - message processor for ndp/ndi north-bound SME msg. * @mac_ctx: Global MAC context * @msg: ndp/ndi SME message @@ -514,6 +605,10 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) eSmeCommandType cmd_to_rel = eSmeNoCommand; bool send_to_user = true; + entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, LL_ACCESS_LOCK); + if (entry != NULL) + cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); + switch (msg->type) { case eWNI_SME_NDP_CONFIRM_IND: { result = eCSR_ROAM_RESULT_NDP_CONFIRM_IND; @@ -573,6 +668,52 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) release_active_cmd = true; cmd_to_rel = eSmeCommandNdpResponderRequest; break; + case eWNI_SME_NDP_END_RSP: { + if (true == msg->bodyval) { + /* rsp was locally generated, do not send to HDD */ + send_to_user = false; + } else { + result = eCSR_ROAM_RESULT_NDP_END_RSP; + roam_info.ndp.ndp_end_rsp_params = msg->bodyptr; + /* + * NDP_END_IND is independent of session, but session_id + * is needed for csrRoamCallCallback(). Set it to 0 + * which is a valid session. + */ + session_id = 0; + } + release_active_cmd = true; + cmd_to_rel = eSmeCommandNdpDataEndInitiatorRequest; + /* + * get num of ndp requested to terminated from sme command + * being released + */ + if (cmd != NULL && cmd_to_rel == cmd->command) + roam_info.ndp.ndp_end_rsp_params->num_ndp_terminated = + cmd->u.data_end_req->num_ndp_instances; + break; + } + case eWNI_SME_NDP_END_IND: + result = eCSR_ROAM_RESULT_NDP_END_IND; + roam_info.ndp.ndp_end_ind_params = msg->bodyptr; + /* + * NDP_END_IND is independent of session, but session_id is + * needed for csrRoamCallCallback(). Set it to vdev_id of first + * entry which is a valid session. vdev_id is likely to be same + * for all. + */ + session_id = + roam_info.ndp.ndp_end_ind_params->ndp_map[0].vdev_id; + break; + case eWNI_SME_NDP_PEER_DEPARTED_IND: + result = eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND; + /* copy msg from msg body to roam info passed to callback */ + vos_mem_copy(&roam_info.ndp.ndp_peer_ind_params, + msg->bodyptr, + sizeof(roam_info.ndp.ndp_peer_ind_params)); + session_id = + ((struct sme_ndp_peer_ind *)msg->bodyptr)->session_id; + break; default: smsLog(mac_ctx, LOGE, FL("Unhandled NDP rsp")); vos_mem_free(msg->bodyptr); @@ -584,39 +725,25 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) eCSR_ROAM_NDP_STATUS_UPDATE, result); } + vos_mem_free(msg->bodyptr); + msg->bodyptr = NULL; /* free ndp_cfg and ndp_app_info if required * For some commands this info may be needed in HDD * so free them after roam callback. */ switch (msg->type) { case eWNI_SME_NDP_INITIATOR_RSP: - entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, - LL_ACCESS_LOCK); - if (entry != NULL) { - cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); - if (eSmeCommandNdpInitiatorRequest == cmd->command) { - vos_mem_free( - cmd->u.initiator_req. - ndp_config.ndp_cfg); - vos_mem_free( - cmd->u.initiator_req. - ndp_info.ndp_app_info); - } + if (cmd && eSmeCommandNdpInitiatorRequest == cmd->command) { + vos_mem_free(cmd->u.initiator_req.ndp_config.ndp_cfg); + vos_mem_free( + cmd->u.initiator_req.ndp_info.ndp_app_info); } break; case eWNI_SME_NDP_RESPONDER_RSP: - entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, - LL_ACCESS_LOCK); - if (entry != NULL) { - cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); - if (eSmeCommandNdpResponderRequest == cmd->command) { - vos_mem_free( - cmd->u.responder_req. - ndp_config.ndp_cfg); - vos_mem_free( - cmd->u.responder_req. - ndp_info.ndp_app_info); - } + if (cmd && eSmeCommandNdpResponderRequest == cmd->command) { + vos_mem_free(cmd->u.responder_req.ndp_config.ndp_cfg); + vos_mem_free( + cmd->u.responder_req.ndp_info.ndp_app_info); } break; case eWNI_SME_NDP_INDICATION: @@ -624,21 +751,21 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) roam_info.ndp.ndp_indication_params.ndp_config.ndp_cfg); vos_mem_free( roam_info.ndp.ndp_indication_params. - ndp_info.ndp_app_info); + ndp_info.ndp_app_info); + break; + case eWNI_SME_NDP_END_RSP: + if (cmd && + eSmeCommandNdpDataEndInitiatorRequest == cmd->command) { + vos_mem_free(cmd->u.data_end_req); + cmd->u.data_end_req = NULL; + } + break; + case eWNI_SME_NDP_END_IND: break; default: break; } - vos_mem_free(msg->bodyptr); - if (release_active_cmd == false) - return; - - entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, LL_ACCESS_LOCK); - if (entry == NULL) - return; - - cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); - if (cmd_to_rel == cmd->command) { + if (release_active_cmd && cmd && cmd_to_rel == cmd->command) { /* Now put this cmd back on the avilable command list */ if (csrLLRemoveEntry(&mac_ctx->sme.smeCmdActiveList, entry, LL_ACCESS_LOCK)) diff --git a/CORE/SME/src/pmc/pmcApi.c b/CORE/SME/src/pmc/pmcApi.c index 9d791ec1e29b..dbadeef6216e 100644 --- a/CORE/SME/src/pmc/pmcApi.c +++ b/CORE/SME/src/pmc/pmcApi.c @@ -889,7 +889,8 @@ eHalStatus pmcRequestFullPower (tHalHandle hHal, void (*callbackRoutine) (void * void *callbackContext, tRequestFullPowerReason fullPowerReason) { tpAniSirGlobal pMac = PMAC_STRUCT(hHal); - tpRequestFullPowerEntry pEntry; + tpRequestFullPowerEntry request_full_power_entry; + tListElem *pEntry; #ifdef FEATURE_WLAN_DIAG_SUPPORT WLAN_VOS_DIAG_EVENT_DEF(psRequest, vos_event_wlan_powersave_payload_type); @@ -929,30 +930,41 @@ eHalStatus pmcRequestFullPower (tHalHandle hHal, void (*callbackRoutine) (void * { pmcLog(pMac, LOGE, FL("Cannot cancel IMPS timer")); } - /* Enter Request Full Power State. */ - if (pmcEnterRequestFullPowerState(hHal, fullPowerReason) != eHAL_STATUS_SUCCESS) - return eHAL_STATUS_FAILURE; /* If able to enter Request Full Power State, then request is pending. Allocate entry for request full power callback routine list. */ //If caller doesn't need a callback, simply waits up the chip. - if( callbackRoutine ) - { - pEntry = vos_mem_malloc(sizeof(tRequestFullPowerEntry)); - if ( NULL == pEntry ) - { + if (callbackRoutine) { + request_full_power_entry = vos_mem_malloc(sizeof(tRequestFullPowerEntry)); + if (NULL == request_full_power_entry) { pmcLog(pMac, LOGE, - FL("Cannot allocate memory for request full power routine list entry")); + FL("Cannot allocate memory for request full power routine list entry")); PMC_ABORT; return eHAL_STATUS_FAILURE; } /* Store routine and context in entry. */ - pEntry->callbackRoutine = callbackRoutine; - pEntry->callbackContext = callbackContext; + request_full_power_entry->callbackRoutine = callbackRoutine; + request_full_power_entry->callbackContext = callbackContext; /* Add entry to list. */ - csrLLInsertTail(&pMac->pmc.requestFullPowerList, &pEntry->link, TRUE); + csrLLInsertTail(&pMac->pmc.requestFullPowerList, + &request_full_power_entry->link, TRUE); + } + /* Enter Request Full Power State. */ + if (pmcEnterRequestFullPowerState(hHal, fullPowerReason) != + eHAL_STATUS_SUCCESS) { + /* + * If pmcEnterRequestFullPowerState fails, driver need to + * remove callback from requestFullPowerList + */ + if (callbackRoutine) { + pEntry = csrLLRemoveTail(&pMac->pmc.requestFullPowerList, TRUE); + request_full_power_entry = GET_BASE_ADDR(pEntry, + tRequestFullPowerEntry, link); + vos_mem_free(request_full_power_entry); + } + return eHAL_STATUS_FAILURE; } return eHAL_STATUS_PMC_PENDING; diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index bc5accf79c4b..a33a63ae40a7 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -1053,6 +1053,17 @@ sme_process_cmd: csrReleaseCommand(pMac, pCommand); } break; + case eSmeCommandNdpDataEndInitiatorRequest: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + status = csr_process_ndp_data_end_request(pMac, + pCommand); + if (!HAL_STATUS_SUCCESS(status)) { + if (csrLLRemoveEntry( + &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) + csrReleaseCommand(pMac, pCommand); + } + break; case eSmeCommandDelStaSession: csrLLUnlock( &pMac->sme.smeCmdActiveList ); csrProcessDelStaSessionCommand( pMac, pCommand ); @@ -3381,6 +3392,9 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) case eWNI_SME_NDP_INITIATOR_RSP: case eWNI_SME_NDP_INDICATION: case eWNI_SME_NDP_RESPONDER_RSP: + case eWNI_SME_NDP_END_RSP: + case eWNI_SME_NDP_END_IND: + case eWNI_SME_NDP_PEER_DEPARTED_IND: sme_ndp_msg_processor(pMac, pMsg); break; default: diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h index 89ba9da1eb89..1f9aa6130a63 100644 --- a/CORE/VOSS/inc/vos_api.h +++ b/CORE/VOSS/inc/vos_api.h @@ -375,5 +375,6 @@ void vos_probe_threads(void); void vos_set_fatal_event(bool value); void vos_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, void *data); int vos_get_radio_index(void); +int vos_set_radio_index(int radio_index); #endif // if !defined __VOS_API_H diff --git a/CORE/VOSS/src/vos_api.c b/CORE/VOSS/src/vos_api.c index 4689507a781c..0d14594cc101 100644 --- a/CORE/VOSS/src/vos_api.c +++ b/CORE/VOSS/src/vos_api.c @@ -2971,28 +2971,34 @@ inline void vos_pkt_stats_to_logger_thread(void *pl_hdr, void *pkt_dump, } /** - * * vos_get_radio_index() - get radio index * * Return: radio index otherwise, -EINVAL */ int vos_get_radio_index(void) { - hdd_context_t *hdd_ctx = NULL; - if (gpVosContext == NULL) { VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, FL("global voss context is NULL")); return -EINVAL; } - hdd_ctx = (hdd_context_t *)vos_get_context(VOS_MODULE_ID_HDD, - gpVosContext); + return gpVosContext->radio_index; +} - if (!hdd_ctx) { - VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL, - FL("HDD context is Null")); +/** + * vos_set_radio_index() - set radio index + * @radio_index: the radio index + * + * Return: 0 for success, otherwise -EINVAL + */ +int vos_set_radio_index(int radio_index) +{ + if (gpVosContext == NULL) { + VOS_TRACE(VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_ERROR, + FL("global voss context is NULL")); return -EINVAL; } - return hdd_ctx->radio_index; -} + gpVosContext->radio_index = radio_index; + return 0; +} diff --git a/CORE/VOSS/src/vos_sched.h b/CORE/VOSS/src/vos_sched.h index cdf53cbc0cec..974e2cb0b804 100644 --- a/CORE/VOSS/src/vos_sched.h +++ b/CORE/VOSS/src/vos_sched.h @@ -399,6 +399,9 @@ typedef struct _VosContextType bool crash_indication_pending; bool enable_fatal_event; + + /* radio index per driver */ + int radio_index; } VosContextType, *pVosContextType; |
