diff options
| author | Abhishek Singh <absingh@qti.qualcomm.com> | 2016-01-29 15:49:58 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-03-09 18:09:24 +0530 |
| commit | 309e7ac4d46f4e4bd2e1fb5f286e4e9c6c048fb9 (patch) | |
| tree | 0a2cda586aa8cc561bfc6e14776ffb42a1ab820c | |
| parent | d1916cbd501e55cdd77bd38220d941b6e135cafc (diff) | |
qcacld-2.0: Handle request to delete NAN Data Interface (NDI)
Add changes to handle request to delete NAN Data Interface.
Change-Id: I3efef6adf6c7a974d3e344a7609f8517cd1aa752
CRs-Fixed: 962367
| -rw-r--r-- | CORE/HDD/inc/wlan_hdd_main.h | 2 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_assoc.c | 1 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg.c | 1 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_cfg80211.c | 11 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_main.c | 26 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_nan_datapath.c | 204 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_nan_datapath.h | 4 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c | 39 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limSendSmeRspMessages.c | 9 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/nan/nan_datapath.c | 64 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/nan/nan_datapath.h | 12 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 15 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.h | 3 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma_nan_datapath.c | 47 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma_nan_datapath.h | 8 | ||||
| -rw-r--r-- | CORE/SME/inc/csrApi.h | 1 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_nan_datapath.h | 6 | ||||
| -rw-r--r-- | CORE/SME/src/csr/csrApiRoam.c | 44 | ||||
| -rw-r--r-- | CORE/SME/src/csr/csrInsideApi.h | 3 | ||||
| -rw-r--r-- | CORE/SME/src/nan/nan_datapath_api.c | 16 |
20 files changed, 457 insertions, 59 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h index 81144222e5d2..827b0c29ed31 100644 --- a/CORE/HDD/inc/wlan_hdd_main.h +++ b/CORE/HDD/inc/wlan_hdd_main.h @@ -60,9 +60,7 @@ #ifdef WLAN_FEATURE_MBSSID #include "sapApi.h" #endif -#ifdef WLAN_FEATURE_NAN_DATAPATH #include "wlan_hdd_nan_datapath.h" -#endif /*--------------------------------------------------------------------------- Preprocessor definitions and constants diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index 70d9d2fee800..5011a13cdd8f 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -70,7 +70,6 @@ #endif #include <vos_sched.h> #include <wlan_logging_sock_svc.h> -#include "wlan_hdd_nan_datapath.h" struct ether_addr { diff --git a/CORE/HDD/src/wlan_hdd_cfg.c b/CORE/HDD/src/wlan_hdd_cfg.c index 633d79b8c55d..f6b36fd6c269 100644 --- a/CORE/HDD/src/wlan_hdd_cfg.c +++ b/CORE/HDD/src/wlan_hdd_cfg.c @@ -59,7 +59,6 @@ #include <csrApi.h> #include <pmcApi.h> #include <wlan_hdd_misc.h> -#include "wlan_hdd_nan_datapath.h" #if defined (WLAN_FEATURE_VOWIFI_11R) || defined (FEATURE_WLAN_ESE) || defined(FEATURE_WLAN_LFR) static void diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c index 946807eef702..9958a7571817 100644 --- a/CORE/HDD/src/wlan_hdd_cfg80211.c +++ b/CORE/HDD/src/wlan_hdd_cfg80211.c @@ -109,7 +109,6 @@ #include "wlan_hdd_memdump.h" #include "wlan_logging_sock_svc.h" -#include "wlan_hdd_nan_datapath.h" #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -1306,11 +1305,11 @@ static const struct nl80211_vendor_cmd_info wlan_hdd_cfg80211_vendor_events[] = .subcmd = QCA_NL80211_VENDOR_SUBCMD_EXTSCAN_HOTLIST_AP_LOST }, #endif /* FEATURE_WLAN_EXTSCAN */ - /* OCB events */ - [QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX] = { - .vendor_id = QCA_NL80211_VENDOR_ID, - .subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT - }, + /* OCB events */ + [QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT_INDEX] = { + .vendor_id = QCA_NL80211_VENDOR_ID, + .subcmd = QCA_NL80211_VENDOR_SUBCMD_DCC_STATS_EVENT + }, #ifdef WLAN_FEATURE_MEMDUMP [QCA_NL80211_VENDOR_SUBCMD_WIFI_LOGGER_MEMORY_DUMP_INDEX] = { .vendor_id = QCA_NL80211_VENDOR_ID, diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c index 66790887c0cc..746b701c1fc2 100644 --- a/CORE/HDD/src/wlan_hdd_main.c +++ b/CORE/HDD/src/wlan_hdd_main.c @@ -115,7 +115,6 @@ void hdd_ch_avoid_cb(void *hdd_context,void *indi_param); #ifdef WLAN_FEATURE_NAN #include "wlan_hdd_nan.h" -#include "wlan_hdd_nan_datapath.h" #endif /* WLAN_FEATURE_NAN */ #include "wlan_hdd_debugfs.h" @@ -135,7 +134,6 @@ void hdd_ch_avoid_cb(void *hdd_context,void *indi_param); #include "wlan_hdd_ocb.h" #include "wlan_hdd_tsf.h" #include "tl_shim.h" -#include "wlan_hdd_nan_datapath.h" #if defined(LINUX_QCMBR) #define SIOCIOCTLTX99 (SIOCDEVPRIVATE+13) @@ -10082,6 +10080,12 @@ eHalStatus hdd_smeCloseSessionCallback(void *pContext) return eHAL_STATUS_NOT_INITIALIZED; } + /* + * For NAN Data interface, the close session results in the final + * indication to the userspace + */ + hdd_ndp_session_end_handler(pAdapter); + clear_bit(SME_SESSION_OPENED, &pAdapter->event_flags); #if !defined (CONFIG_CNSS) && \ @@ -11223,10 +11227,20 @@ VOS_STATUS hdd_stop_adapter( hdd_context_t *pHddCtx, hdd_adapter_t *pAdapter, case WLAN_HDD_IBSS: case WLAN_HDD_P2P_CLIENT: case WLAN_HDD_P2P_DEVICE: - if (hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)) || - hdd_is_connecting(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) - { - if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS) + case WLAN_HDD_NDI: + if ((WLAN_HDD_NDI == pAdapter->device_mode) || + hdd_connIsConnected(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter)) || + hdd_is_connecting(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter))) { + INIT_COMPLETION(pAdapter->disconnect_comp_var); + /* + * For NDI do not use pWextState from sta_ctx, if needed + * extract from ndi_ctx. + */ + if (WLAN_HDD_NDI == pAdapter->device_mode) + halStatus = sme_RoamDisconnect(pHddCtx->hHal, + pAdapter->sessionId, + eCSR_DISCONNECT_REASON_NDI_DELETE); + else if (pWextState->roamProfile.BSSType == eCSR_BSS_TYPE_START_IBSS) halStatus = sme_RoamDisconnect(pHddCtx->hHal, pAdapter->sessionId, eCSR_DISCONNECT_REASON_IBSS_LEAVE); diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.c b/CORE/HDD/src/wlan_hdd_nan_datapath.c index f7becb286a25..1526dd0bfc79 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.c +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.c @@ -30,7 +30,6 @@ #include "vos_trace.h" #include "vos_sched.h" #include "wlan_hdd_includes.h" -#include "wlan_hdd_nan_datapath.h" #include "wlan_hdd_p2p.h" #include "wma_api.h" @@ -43,7 +42,8 @@ qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { .len = IFNAMSIZ }, [QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID] = { .type = NLA_U32 }, [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_SPEC_CHANNEL] = { .type = NLA_U32 }, - [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = { .type = NLA_BINARY, + [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = { + .type = NLA_BINARY, .len = VOS_MAC_ADDR_SIZE }, [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY] = { .type = NLA_U16 }, [QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS] = { .type = NLA_BINARY, @@ -174,7 +174,6 @@ static int hdd_ndi_start_bss(hdd_adapter_t *adapter, return ret; } - /** * hdd_ndi_create_req_handler() - NDI create request handler * @hdd_ctx: hdd context @@ -236,6 +235,7 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx, */ ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); ndp_ctx->ndp_create_transaction_id = transaction_id; + ndp_ctx->state = NAN_DATA_NDI_CREATING_STATE; /* * The NAN data interface has been created at this point. @@ -268,7 +268,68 @@ static int hdd_ndi_create_req_handler(hdd_context_t *hdd_ctx, static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb) { - return 0; + hdd_adapter_t *adapter; + char *iface_name; + uint16_t transaction_id; + struct nan_datapath_ctx *ndp_ctx; + int ret; + + ENTER(); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) { + hddLog(LOGE, FL("Interface name string is unavailable")); + return -EINVAL; + } + + iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]) { + hddLog(LOGE, FL("Transaction id is unavailable")); + return -EINVAL; + } + + transaction_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]); + + /* Check if there is already an existing inteface with the same name */ + adapter = hdd_get_adapter_by_name(hdd_ctx, iface_name); + if (!adapter) { + hddLog(LOGE, FL("NAN data interface %s is not available"), + iface_name); + return -EINVAL; + } + + /* check if adapter is in NDI mode */ + if (WLAN_HDD_NDI != adapter->device_mode) { + hddLog(LOGE, FL("Interface %s is not in NDI mode"), + iface_name); + return -EINVAL; + } + + ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + if (!ndp_ctx) { + hddLog(LOGE, FL("ndp_ctx is NULL")); + 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); + return -EINVAL; + } + + ndp_ctx->ndp_delete_transaction_id = transaction_id; + ndp_ctx->state = NAN_DATA_NDI_DELETING_STATE; + + /* Delete the interface */ + ret = __wlan_hdd_del_virtual_intf(hdd_ctx->wiphy, &adapter->wdev); + if (ret < 0) + hddLog(LOGE, FL("NDI delete request failed")); + else + hddLog(LOGE, FL("NDI delete request successfully issued")); + + return ret; } @@ -352,6 +413,11 @@ static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter, return; } + if (!ndp_ctx) { + hddLog(LOGE, FL("ndp_ctx is NULL")); + return; + } + /* notify response to the upper layer */ vendor_event = cfg80211_vendor_event_alloc(hdd_ctx->wiphy, NULL, @@ -406,6 +472,7 @@ static void hdd_ndp_iface_create_rsp_handler(hdd_adapter_t *adapter, cfg80211_vendor_event(vendor_event, GFP_KERNEL); ndp_ctx->ndp_create_transaction_id = 0; + ndp_ctx->state = NAN_DATA_NDI_CREATED_STATE; if (ndi_rsp->status == VOS_STATUS_SUCCESS) { hddLog(LOGE, FL("NDI interface successfully created")); @@ -432,9 +499,135 @@ nla_put_failure: static void hdd_ndp_iface_delete_rsp_handler(hdd_adapter_t *adapter, void *rsp_params) { + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct ndi_delete_rsp *ndi_rsp = rsp_params; + + if (wlan_hdd_validate_context(hdd_ctx)) + return; + + if (!ndi_rsp) { + hddLog(LOGE, FL("Invalid ndi delete response")); + return; + } + + if (ndi_rsp->status == VOS_STATUS_SUCCESS) + hddLog(LOGE, FL("NDI BSS successfully stopped")); + else + hddLog(LOGE, + FL("NDI BSS stop failed with reason %d"), + ndi_rsp->reason); + + complete(&adapter->disconnect_comp_var); + return; +} + +/** + * hdd_ndp_session_end_handler() - NDI session termination handler + * @adapter: pointer to adapter context + * + * Return: none + */ +void hdd_ndp_session_end_handler(hdd_adapter_t *adapter) +{ + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct sk_buff *vendor_event; + struct nan_datapath_ctx *ndp_ctx; + uint32_t data_len = sizeof(uint32_t) * 2 + sizeof(uint16_t) + + NLA_HDRLEN * 3 + NLMSG_HDRLEN; + + ENTER(); + + if (wlan_hdd_validate_context(hdd_ctx)) + return; + + /* Handle only if adapter is in NDI mode */ + if (WLAN_HDD_NDI != adapter->device_mode) { + hddLog(LOGE, FL("Adapter is not in NDI mode")); + return; + } + + ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + if (!ndp_ctx) { + hddLog(LOGE, FL("ndp context is NULL")); + return; + } + + /* + * The virtual adapters are stopped and closed even during + * driver unload or stop, the service layer is not required + * to be informed in that case (response is not expected) + */ + if (NAN_DATA_NDI_DELETING_STATE != ndp_ctx->state) { + hddLog(LOGE, FL("NDI interface %s deleted"), + adapter->dev->name); + return; + } + + /* notify response to the upper layer */ + 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; + } + + /* Sub vendor command goes first */ + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE)) { + hddLog(LOGE, FL("VENDOR_ATTR_NDP_SUBCMD put fail")); + goto failure; + } + + /* Transaction id */ + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + ndp_ctx->ndp_delete_transaction_id)) { + hddLog(LOGE, FL("VENDOR_ATTR_NDP_TRANSACTION_ID put fail")); + goto failure; + } + + /* Status code */ + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, 0x0)) { + hddLog(LOGE, FL("VENDOR_ATTR_NDP_DRV_RETURN_TYPE put fail")); + goto failure; + } + + /* Status return value */ + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0x0)) { + hddLog(LOGE, FL("VENDOR_ATTR_NDP_DRV_RETURN_VALUE put fail")); + goto failure; + } + + hddLog(LOG2, FL("sub command: %d, value: %d"), + QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_DELETE); + hddLog(LOG2, FL("delete transaction id: %d, value: %d"), + QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + ndp_ctx->ndp_delete_transaction_id); + hddLog(LOG2, FL("status code: %d, value: %d"), + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, + true); + hddLog(LOG2, FL("Return value: %d, value: %d"), + QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, 0x5A); + + ndp_ctx->ndp_delete_transaction_id = 0; + ndp_ctx->state = NAN_DATA_NDI_DELETED_STATE; + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + + EXIT(); return; + +failure: + kfree_skb(vendor_event); } + /** * hdd_ndp_initiator_rsp_handler() - NDP initiator response handler * @adapter: pointer to adapter context @@ -789,7 +982,8 @@ int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter) } /* Register wireless extensions */ - if (eHAL_STATUS_SUCCESS != (hal_status = hdd_register_wext(wlan_dev))) { + hal_status = hdd_register_wext(wlan_dev); + if (eHAL_STATUS_SUCCESS != hal_status) { hddLog(LOGE, FL("Wext registration failed with status code %d"), hal_status); ret_val = -EAGAIN; diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.h b/CORE/HDD/src/wlan_hdd_nan_datapath.h index 23fb9ab7375b..97158a1c85ea 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.h +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.h @@ -215,6 +215,7 @@ void hdd_ndp_event_handler(struct hdd_adapter_s *adapter, int wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy, struct wireless_dev *wdev, const void *data, int data_len); int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter); +void hdd_ndp_session_end_handler(hdd_adapter_t *adapter); #else static inline void hdd_ndp_print_ini_config(struct hdd_context_s *hdd_ctx) { @@ -237,6 +238,9 @@ static inline int hdd_init_nan_data_mode(struct hdd_adapter_s *adapter) { return 0; } +static inline void hdd_ndp_session_end_handler(hdd_adapter_t *adapter) +{ +} #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __WLAN_HDD_NAN_DATAPATH_H */ diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index 592224bc593d..4ee8f6e51e6e 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -3964,33 +3964,40 @@ __limHandleSmeStopBssRequest(tpAniSirGlobal pMac, tANI_U32 *pMsgBuf) psessionEntry->smeSessionId = smesessionId; psessionEntry->transactionId = smetransactionId; - /* BTAMP_STA and STA_IN_IBSS should NOT send Disassoc frame */ + /* BTAMP_STA, STA_IN_IBSS and NDI should NOT send Disassoc frame */ if (!LIM_IS_IBSS_ROLE(psessionEntry) && - !LIM_IS_BT_AMP_STA_ROLE(psessionEntry)) { + !LIM_IS_BT_AMP_STA_ROLE(psessionEntry) && + !LIM_IS_NDI_ROLE(psessionEntry)) { tSirMacAddr bcAddr = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; if ((stopBssReq.reasonCode == eSIR_SME_MIC_COUNTER_MEASURES)) // Send disassoc all stations associated thru TKIP __limCounterMeasures(pMac,psessionEntry); else - limSendDisassocMgmtFrame(pMac, eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, bcAddr, psessionEntry, FALSE); + limSendDisassocMgmtFrame(pMac, + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, + bcAddr, psessionEntry, FALSE); } - /* Free the buffer allocated in START_BSS_REQ */ - vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); - psessionEntry->addIeParams.probeRespDataLen = 0; - psessionEntry->addIeParams.probeRespData_buff = NULL; - - vos_mem_free(psessionEntry->addIeParams.assocRespData_buff); - psessionEntry->addIeParams.assocRespDataLen = 0; - psessionEntry->addIeParams.assocRespData_buff = NULL; + if (!LIM_IS_NDI_ROLE(psessionEntry)) { + /* Free the buffer allocated in START_BSS_REQ */ + vos_mem_free(psessionEntry->addIeParams.probeRespData_buff); + psessionEntry->addIeParams.probeRespDataLen = 0; + psessionEntry->addIeParams.probeRespData_buff = NULL; - vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff); - psessionEntry->addIeParams.probeRespBCNDataLen = 0; - psessionEntry->addIeParams.probeRespBCNData_buff = NULL; + vos_mem_free(psessionEntry->addIeParams.assocRespData_buff); + psessionEntry->addIeParams.assocRespDataLen = 0; + psessionEntry->addIeParams.assocRespData_buff = NULL; - //limDelBss is also called as part of coalescing, when we send DEL BSS followed by Add Bss msg. - pMac->lim.gLimIbssCoalescingHappened = false; + vos_mem_free(psessionEntry->addIeParams.probeRespBCNData_buff); + psessionEntry->addIeParams.probeRespBCNDataLen = 0; + psessionEntry->addIeParams.probeRespBCNData_buff = NULL; + /* + * limDelBss is also called as part of coalescing, + * when we send DEL BSS followed by Add Bss msg. + */ + pMac->lim.gLimIbssCoalescingHappened = false; + } for(i = 1 ; i < pMac->lim.gLimAssocStaLimit ; i++) { pStaDs = dphGetHashEntry(pMac, i, &psessionEntry->dph.dphHashTable); diff --git a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c index 7160bb72dfa7..89f98c9e5ae0 100644 --- a/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c +++ b/CORE/MAC/src/pe/lim/limSendSmeRspMessages.c @@ -55,6 +55,7 @@ #include "limIbssPeerMgmt.h" #include "limSessionUtils.h" #include "regdomain_common.h" +#include "nan_datapath.h" #include "sirApi.h" @@ -3018,11 +3019,13 @@ void limHandleDeleteBssRsp(tpAniSirGlobal pMac,tpSirMsgQ MsgQ) pDelBss->sessionId); return; } - if (LIM_IS_IBSS_ROLE(psessionEntry)) { + if (LIM_IS_IBSS_ROLE(psessionEntry)) limIbssDelBssRsp(pMac, MsgQ->bodyptr, psessionEntry); - } else if(LIM_IS_UNKNOWN_ROLE(psessionEntry)) { + else if(LIM_IS_UNKNOWN_ROLE(psessionEntry)) limProcessSmeDelBssRsp(pMac, MsgQ->bodyval,psessionEntry); - } else + else if (LIM_IS_NDI_ROLE(psessionEntry)) + lim_ndi_del_bss_rsp(pMac, MsgQ->bodyptr, psessionEntry); + else limProcessMlmDelBssRsp(pMac,MsgQ,psessionEntry); } diff --git a/CORE/MAC/src/pe/nan/nan_datapath.c b/CORE/MAC/src/pe/nan/nan_datapath.c index 1e9bd97ad636..c573e8ef5d18 100644 --- a/CORE/MAC/src/pe/nan/nan_datapath.c +++ b/CORE/MAC/src/pe/nan/nan_datapath.c @@ -27,6 +27,8 @@ #include "limUtils.h" #include "limApi.h" #include "nan_datapath.h" +#include "limTypes.h" +#include "limSendMessages.h" /** * handle_ndp_request_message() - Function to handle NDP requests from SME @@ -61,7 +63,7 @@ VOS_STATUS handle_ndp_event_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) * Return: None */ void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msgq, - tpPESession session_entry) + tpPESession session_entry) { tLimMlmStartCnf mlm_start_cnf; tpAddBssParams add_bss_params = (tpAddBssParams) lim_msgq->bodyptr; @@ -97,3 +99,63 @@ end: vos_mem_free(lim_msgq->bodyptr); lim_msgq->bodyptr = NULL; } + +/** + * lim_ndi_del_bss_rsp() - Handler DEL BSS resp for NDI interface + * @mac_ctx: handle to mac structure + * @msg: pointer to message + * @session_entry: session entry + * + * Return: void + */ +void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx, + void *msg, tpPESession session_entry) +{ + tSirResultCodes rc = eSIR_SME_SUCCESS; + tpDeleteBssParams del_bss = (tpDeleteBssParams) msg; + + SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); + if (del_bss == NULL) { + limLog(mac_ctx, LOGE, + FL("NDI: DEL_BSS_RSP with no body!")); + rc = eSIR_SME_STOP_BSS_FAILURE; + goto end; + } + session_entry = + peFindSessionBySessionId(mac_ctx, del_bss->sessionId); + if (!session_entry) { + limLog(mac_ctx, LOGE, + FL("Session Does not exist for given sessionID")); + goto end; + } + + if (del_bss->status != eHAL_STATUS_SUCCESS) { + limLog(mac_ctx, LOGE, FL("NDI: DEL_BSS_RSP error (%x) Bss %d "), + del_bss->status, del_bss->bssIdx); + rc = eSIR_SME_STOP_BSS_FAILURE; + goto end; + } + + if (limSetLinkState(mac_ctx, eSIR_LINK_IDLE_STATE, + session_entry->selfMacAddr, + session_entry->selfMacAddr, NULL, NULL) + != eSIR_SUCCESS) { + limLog(mac_ctx, LOGE, + FL("NDI: DEL_BSS_RSP setLinkState failed")); + goto end; + } + + session_entry->limMlmState = eLIM_MLM_IDLE_STATE; + +end: + if (del_bss) + vos_mem_free(del_bss); + /* Delete PE session once BSS is deleted */ + if (NULL != session_entry) { + limSendSmeRsp(mac_ctx, eWNI_SME_STOP_BSS_RSP, + rc, session_entry->smeSessionId, + session_entry->transactionId); + peDeleteSession(mac_ctx, session_entry); + session_entry = NULL; + } +} diff --git a/CORE/MAC/src/pe/nan/nan_datapath.h b/CORE/MAC/src/pe/nan/nan_datapath.h index d079e42126e1..f8b8b17f8381 100644 --- a/CORE/MAC/src/pe/nan/nan_datapath.h +++ b/CORE/MAC/src/pe/nan/nan_datapath.h @@ -110,6 +110,10 @@ VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg_q, tpPESession session_entry); + +/* Handler DEL BSS resp for NDI interface */ +void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx, + void *msg, tpPESession session_entry); #else /* Function to process NDP requests */ static inline VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx, @@ -119,18 +123,20 @@ static inline VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx, } /* Function to process NDP events */ static inline VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, - tpSirMsgQ msg) + tpSirMsgQ msg) { return VOS_STATUS_SUCCESS; } - /* Function to process NDP events */ static inline void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg_q, tpPESession session_entry) { } - +static inline void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx, + void *msg, tpPESession session_entry) +{ +} #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __MAC_NAN_DATAPATH_H */ diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 26dc2e0283f3..ee6c4bcb107a 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -1621,7 +1621,7 @@ static int32_t wmi_unified_peer_flush_tids_send(wmi_unified_t wmi, return 0; } -static void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid, +void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid, u_int8_t vdev_id, ol_txrx_peer_handle peer, v_BOOL_t roam_synch_in_progress) { @@ -2198,7 +2198,11 @@ static int wma_vdev_stop_ind(tp_wma_handle wma, u_int8_t *buf) wma_delete_all_ibss_peers(wma, resp_event->vdev_id); else #endif - { + if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, + resp_event->vdev_id)) { + wma_delete_all_nan_remote_peers(wma, + resp_event->vdev_id); + } else { if (wma_is_vdev_in_ap_mode(wma, resp_event->vdev_id)) { wma_delete_all_ap_remote_peers(wma, resp_event->vdev_id); @@ -17449,6 +17453,13 @@ static void wma_delete_bss(tp_wma_handle wma, tpDeleteBssParams params) &peer_id); else #endif + if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, + params->smesessionId)) + /* In ndi case, self mac is used to create the self peer */ + peer = ol_txrx_find_peer_by_addr(pdev, + wma->interfaces[params->smesessionId].addr, + &peer_id); + else peer = ol_txrx_find_peer_by_addr(pdev, params->bssid, &peer_id); diff --git a/CORE/SERVICES/WMA/wma.h b/CORE/SERVICES/WMA/wma.h index e1e869ff4377..649fcf0143e7 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -1776,4 +1776,7 @@ struct wma_version_info { u_int32_t revision; }; +void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid, + u_int8_t vdev_id, ol_txrx_peer_handle peer, + v_BOOL_t roam_synch_in_progress); #endif diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.c b/CORE/SERVICES/WMA/wma_nan_datapath.c index 7528c75470bf..68e52dc09f98 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.c +++ b/CORE/SERVICES/WMA/wma_nan_datapath.c @@ -253,3 +253,50 @@ send_fail_resp: wma_send_msg(wma, WDA_ADD_BSS_RSP, (void *)add_bss, 0); } +/** + * wma_delete_all_nan_remote_peers() - Delete all nan peer + * @wma: wma handle + * @vdev_id: vdev id + * + * Return: void + */ +void wma_delete_all_nan_remote_peers(tp_wma_handle wma, uint32_t vdev_id) +{ + ol_txrx_vdev_handle vdev; + ol_txrx_peer_handle peer, temp; + + if (!wma || vdev_id > wma->max_bssid) + return; + + vdev = wma->interfaces[vdev_id].handle; + if (!vdev) + return; + + /* remove all remote peers of ndi*/ + adf_os_spin_lock_bh(&vdev->pdev->peer_ref_mutex); + + temp = NULL; + TAILQ_FOREACH_REVERSE(peer, &vdev->peer_list, + peer_list_t, peer_list_elem) { + if (temp) { + adf_os_spin_unlock_bh(&vdev->pdev->peer_ref_mutex); + if (adf_os_atomic_read( + &temp->delete_in_progress) == 0) + wma_remove_peer(wma, temp->mac_addr.raw, + vdev_id, temp, VOS_FALSE); + adf_os_spin_lock_bh(&vdev->pdev->peer_ref_mutex); + } + /* self peer is deleted last */ + if (peer == TAILQ_FIRST(&vdev->peer_list)) { + WMA_LOGE("%s: self peer removed", __func__); + break; + } else + temp = peer; + } + adf_os_spin_unlock_bh(&vdev->pdev->peer_ref_mutex); + + /* remove ndi self peer last */ + peer = TAILQ_FIRST(&vdev->peer_list); + wma_remove_peer(wma, peer->mac_addr.raw, vdev_id, peer, + false); +} diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.h b/CORE/SERVICES/WMA/wma_nan_datapath.h index ed807e334ccc..46e54a0a4cfe 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.h +++ b/CORE/SERVICES/WMA/wma_nan_datapath.h @@ -31,6 +31,8 @@ #include "sirApi.h" #ifdef WLAN_FEATURE_NAN_DATAPATH +#define WMA_IS_VDEV_IN_NDI_MODE(intf, vdev_id) \ + (WMI_VDEV_TYPE_NDI == intf[vdev_id].type) void wma_add_bss_ndi_mode(tp_wma_handle wma, tpAddBssParams add_bss); @@ -46,12 +48,14 @@ static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle, { tgt_cfg->nan_datapath_enabled = wma_handle->nan_datapath_enabled; } - +void wma_delete_all_nan_remote_peers(tp_wma_handle wma, + uint32_t vdev_id); #else #define wma_add_bss_ndi_mode(x, y) ((void)0) #define wma_update_hdd_cfg_ndp(x, y) ((void)0) +#define WMA_IS_VDEV_IN_NDI_MODE(intf, vdev_id) (false) +#define wma_delete_all_nan_remote_peers(x, y) ((void)0) #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 a5d2177e21e5..5c5dd9dc777b 100644 --- a/CORE/SME/inc/csrApi.h +++ b/CORE/SME/inc/csrApi.h @@ -685,6 +685,7 @@ typedef enum eCSR_DISCONNECT_REASON_IBSS_JOIN_FAILURE, eCSR_DISCONNECT_REASON_IBSS_LEAVE, eCSR_DISCONNECT_REASON_STA_HAS_LEFT, + eCSR_DISCONNECT_REASON_NDI_DELETE, }eCsrRoamDisconnectReason; typedef enum diff --git a/CORE/SME/inc/sme_nan_datapath.h b/CORE/SME/inc/sme_nan_datapath.h index 71d09671e83a..623fec144e81 100644 --- a/CORE/SME/inc/sme_nan_datapath.h +++ b/CORE/SME/inc/sme_nan_datapath.h @@ -73,7 +73,8 @@ void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx, void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx, uint32_t result, uint32_t *roam_status, - uint32_t *roam_result); + uint32_t *roam_result, + void *roam_info); #else /* Start NDI BSS */ @@ -104,7 +105,8 @@ static inline void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx, static inline void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx, uint32_t result, uint32_t *roam_status, - uint32_t *roam_result) + uint32_t *roam_result, + void *roam_info) { } diff --git a/CORE/SME/src/csr/csrApiRoam.c b/CORE/SME/src/csr/csrApiRoam.c index 1fe570c03dab..d40336f6338c 100644 --- a/CORE/SME/src/csr/csrApiRoam.c +++ b/CORE/SME/src/csr/csrApiRoam.c @@ -6286,7 +6286,7 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman } if (CSR_IS_NDI(pProfile)) { csr_roam_update_ndp_return_params(pMac, Result, - &roamStatus, &roamResult); + &roamStatus, &roamResult, &roamInfo); csr_roam_fill_roaminfo_ndp(pMac, &roamInfo, roamResult, pSmeStartBssRsp->statusCode, 0, 0); @@ -6379,7 +6379,7 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman } if (CSR_IS_NDI(pProfile)) { csr_roam_update_ndp_return_params(pMac, Result, - &roamStatus, &roamResult); + &roamStatus, &roamResult, &roamInfo); csr_roam_fill_roaminfo_ndp(pMac, &roamInfo, roamResult, (pSmeStartBssRsp) ? pSmeStartBssRsp->statusCode : eHAL_STATUS_FAILURE, 0, 0); @@ -6463,6 +6463,24 @@ static tANI_BOOLEAN csrRoamProcessResults( tpAniSirGlobal pMac, tSmeCmd *pComman eCSR_ROAM_RESULT_WDS_NOT_ASSOCIATED); //Need to issue stop_bss break; + case eCsrStopBssSuccess: + if (CSR_IS_NDI(pProfile)) { + csr_roam_update_ndp_return_params(pMac, Result, &roamStatus, + &roamResult, &roamInfo); + csrRoamCallCallback(pMac, sessionId, &roamInfo, + pCommand->u.roamCmd.roamId, + roamStatus, roamResult); + } + break; + case eCsrStopBssFailure: + if (CSR_IS_NDI(pProfile)) { + csr_roam_update_ndp_return_params(pMac, Result, &roamStatus, + &roamResult, &roamInfo); + csrRoamCallCallback(pMac, sessionId, &roamInfo, + pCommand->u.roamCmd.roamId, + roamStatus, roamResult); + } + break; case eCsrJoinFailure: case eCsrNothingToJoin: case eCsrJoinFailureDueToConcurrency: @@ -7784,6 +7802,9 @@ eHalStatus csrRoamIssueDisassociateCmd( tpAniSirGlobal pMac, tANI_U32 sessionId, VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_INFO, FL("SME convert to internal reason code eCsrStaHasLeft")); break; + case eCSR_DISCONNECT_REASON_NDI_DELETE: + pCommand->u.roamCmd.roamReason = eCsrStopBss; + pCommand->u.roamCmd.roamProfile.BSSType = eCSR_BSS_TYPE_NDI; default: break; } @@ -7841,9 +7862,11 @@ eHalStatus csrRoamDisconnectInternal(tpAniSirGlobal pMac, tANI_U32 sessionId, eC //Not to call cancel roaming here //Only issue disconnect when necessary - if(csrIsConnStateConnected(pMac, sessionId) || csrIsBssTypeIBSS(pSession->connectedProfile.BSSType) - || csrIsBssTypeWDS(pSession->connectedProfile.BSSType) - || csrIsRoamCommandWaitingForSession(pMac, sessionId) ) + if (csrIsConnStateConnected(pMac, sessionId) + || csrIsBssTypeIBSS(pSession->connectedProfile.BSSType) + || csrIsBssTypeWDS(pSession->connectedProfile.BSSType) + || csrIsRoamCommandWaitingForSession(pMac, sessionId) + || CSR_IS_CONN_NDI(&pSession->connectedProfile)) { smsLog(pMac, LOG2, FL("called")); @@ -8732,6 +8755,8 @@ static void csrRoamRoamingStateReassocRspProcessor( tpAniSirGlobal pMac, tpSirSm static void csrRoamRoamingStateStopBssRspProcessor(tpAniSirGlobal pMac, tSirSmeRsp *pSmeRsp) { + eCsrRoamCompleteResult result_code = eCsrNothingToJoin ; + #ifdef FEATURE_WLAN_DIAG_SUPPORT_CSR { vos_log_ibss_pkt_type *pIbssLog; @@ -8750,7 +8775,12 @@ static void csrRoamRoamingStateStopBssRspProcessor(tpAniSirGlobal pMac, tSirSmeR pMac->roam.roamSession[pSmeRsp->sessionId].connectState = eCSR_ASSOC_STATE_TYPE_NOT_CONNECTED; if(CSR_IS_ROAM_SUBSTATE_STOP_BSS_REQ( pMac, pSmeRsp->sessionId)) { - csrRoamComplete( pMac, eCsrNothingToJoin, NULL ); + if (CSR_IS_CONN_NDI(pMac->roam.roamSession[pSmeRsp->sessionId].pCurRoamProfile)) { + result_code = eCsrStopBssSuccess; + if (pSmeRsp->statusCode != eSIR_SME_SUCCESS) + result_code = eCsrStopBssFailure; + } + csrRoamComplete(pMac, result_code, NULL); } else if(CSR_IS_ROAM_SUBSTATE_DISCONNECT_CONTINUE( pMac, pSmeRsp->sessionId)) { @@ -8829,7 +8859,7 @@ void csrRoamRoamingStateDisassocRspProcessor( tpAniSirGlobal pMac, tSirSmeDisass if(HAL_STATUS_SUCCESS(status)) { vos_mem_set(pScanFilter, sizeof(tCsrScanResultFilter), 0); - pScanFilter->scan_filter_for_roam = 1; + pScanFilter->scan_filter_for_roam = 1; status = csrRoamPrepareFilterFromProfile(pMac, &pNeighborRoamInfo->csrNeighborRoamProfile, pScanFilter); diff --git a/CORE/SME/src/csr/csrInsideApi.h b/CORE/SME/src/csr/csrInsideApi.h index 2fc4a2482228..9cf60d4a105c 100644 --- a/CORE/SME/src/csr/csrInsideApi.h +++ b/CORE/SME/src/csr/csrInsideApi.h @@ -157,7 +157,8 @@ typedef enum eCsrSilentlyStopRoamingSaveState, eCsrJoinWdsFailure, eCsrJoinFailureDueToConcurrency, - + eCsrStopBssSuccess, + eCsrStopBssFailure, }eCsrRoamCompleteResult; typedef struct tagScanReqParam diff --git a/CORE/SME/src/nan/nan_datapath_api.c b/CORE/SME/src/nan/nan_datapath_api.c index ef46a1719151..3aa34f3b64f9 100644 --- a/CORE/SME/src/nan/nan_datapath_api.c +++ b/CORE/SME/src/nan/nan_datapath_api.c @@ -212,20 +212,34 @@ void csr_roam_save_ndi_connected_info(tpAniSirGlobal mac_ctx, * @result: result of the roaming command * @roam_status: roam status returned to the roam command initiator * @roam_result: roam result returned to the roam command initiator + * @rinfo: Roam info context * * Results: None */ void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx, uint32_t result, uint32_t *roam_status, - uint32_t *roam_result) + uint32_t *roam_result, + void *rinfo) { + tCsrRoamInfo *roam_info = (tCsrRoamInfo *)rinfo; + switch (result) { case eCsrStartBssSuccess: case eCsrStartBssFailure: *roam_status = eCSR_ROAM_NDP_STATUS_UPDATE; *roam_result = eCSR_ROAM_RESULT_NDP_CREATE_RSP; break; + case eCsrStopBssSuccess: + *roam_status = eCSR_ROAM_NDP_STATUS_UPDATE; + *roam_result = eCSR_ROAM_RESULT_NDP_DELETE_RSP; + roam_info->ndp.ndi_delete_params.status = VOS_STATUS_SUCCESS; + break; + case eCsrStopBssFailure: + *roam_status = eCSR_ROAM_NDP_STATUS_UPDATE; + *roam_result = eCSR_ROAM_RESULT_NDP_DELETE_RSP; + roam_info->ndp.ndi_delete_params.status = VOS_STATUS_E_FAILURE; + break; default: smsLog(mac_ctx, LOGE, FL("Invalid CSR Roam result code: %d"), result); |
