diff options
| author | Naveen Rawat <nrawat@qca.qualcomm.com> | 2016-03-15 13:59:10 -0700 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-13 10:15:35 +0530 |
| commit | 39d331bd32072e59d1697276aacea5094d3b5932 (patch) | |
| tree | 3342ef84ff592444503ffedfcba63f3e2de29d01 | |
| parent | 9d8ea02422acfb169149a9e6c726331e4f7f4e4b (diff) | |
qcacld-2.0: Add support for NDP data initiator request
Add host side changes to handle INITIATOR_REQ, INITIATOR_RSP,
NEW_PEER_IND and NDP_CONFIRM_IND to support NDP data initiator
request.
Change-Id: I10bf88d3fff27e1f842b720a598c923983c06c90
CRs-Fixed: 962367
23 files changed, 1484 insertions, 114 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h index 1c2f01018dbb..5a7f278d1953 100644 --- a/CORE/HDD/inc/wlan_hdd_assoc.h +++ b/CORE/HDD/inc/wlan_hdd_assoc.h @@ -174,4 +174,10 @@ void hdd_indicateEseBcnReportNoResults(const hdd_adapter_t *pAdapter, const tANI_U8 numBss); #endif /* FEATURE_WLAN_ESE && FEATURE_WLAN_ESE_UPLOAD */ +VOS_STATUS hdd_roamRegisterSTA(hdd_adapter_t *adapter, tCsrRoamInfo *roam_info, + uint8_t sta_id, v_MACADDR_t *peer_mac_addr, + tSirBssDescription *bss_desc); + +bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id, + v_MACADDR_t *peer_mac_addr); #endif diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c index c61eb366f1aa..8b7cc0e6e463 100644 --- a/CORE/HDD/src/wlan_hdd_assoc.c +++ b/CORE/HDD/src/wlan_hdd_assoc.c @@ -1190,11 +1190,20 @@ static eHalStatus hdd_DisConnectHandler( hdd_adapter_t *pAdapter, tCsrRoamInfo * complete(&pAdapter->disconnect_comp_var); return( status ); } -static VOS_STATUS hdd_roamRegisterSTA( hdd_adapter_t *pAdapter, - tCsrRoamInfo *pRoamInfo, - v_U8_t staId, - v_MACADDR_t *pPeerMacAddress, - tSirBssDescription *pBssDesc ) + +/** + * hdd_roamRegisterSTA() - Registers new STA to TL module + * @pAdapter: pointer to adapter context + * @pRoamInfo: roam info struct pointer + * @staId: station ID + * @pPeerMacAddress: mac address of new STA + * @pBssDesc: bss descriptor + * + * Return: status of operation + */ +VOS_STATUS hdd_roamRegisterSTA(hdd_adapter_t *pAdapter, tCsrRoamInfo *pRoamInfo, + uint8_t staId, v_MACADDR_t *pPeerMacAddress, + tSirBssDescription *pBssDesc) { VOS_STATUS vosStatus = VOS_STATUS_E_FAILURE; WLAN_STADescType staDesc = {0}; @@ -2359,35 +2368,34 @@ static void hdd_RoamIbssIndicationHandler( hdd_adapter_t *pAdapter, return; } -/**============================================================================ +/** + * hdd_save_peer() - Save peer MAC address in adapter peer table. + * @sta_ctx: pointer to hdd station context + * @sta_id: station ID + * @peer_mac_addr: mac address of new peer * - @brief roamSaveIbssStation() - Save the IBSS peer MAC address in the adapter. - This information is passed to iwconfig later. The peer that joined - last is passed as information to iwconfig. - If we add HDD_MAX_NUM_IBSS_STA or less STA we return success else we - return FALSE. + * This information is passed to iwconfig later. The peer that joined + * last is passed as information to iwconfig. - ===========================================================================*/ -static int roamSaveIbssStation( hdd_station_ctx_t *pHddStaCtx, v_U8_t staId, v_MACADDR_t *peerMacAddress ) + * Return: true if success, false otherwise + */ +bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id, + v_MACADDR_t *peer_mac_addr) { - int fSuccess = FALSE; - int idx = 0; - - for ( idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++ ) - { - if ( 0 == pHddStaCtx->conn_info.staId[ idx ] ) - { - pHddStaCtx->conn_info.staId[ idx ] = staId; - - vos_copy_macaddr( &pHddStaCtx->conn_info.peerMacAddress[ idx ], peerMacAddress ); - - fSuccess = TRUE; - break; - } - } - - return( fSuccess ); + int idx; + + for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) { + if (0 == sta_ctx->conn_info.staId[idx]) { + sta_ctx->conn_info.staId[idx] = sta_id; + vos_copy_macaddr( + &sta_ctx->conn_info.peerMacAddress[idx], + peer_mac_addr); + return true; + } + } + return false; } + /**============================================================================ * @brief roamRemoveIbssStation() - Remove the IBSS peer MAC address in the adapter. @@ -2692,8 +2700,9 @@ static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, t MAC_ADDR_ARRAY(pHddStaCtx->conn_info.bssId), pRoamInfo->staId ); - if ( !roamSaveIbssStation( WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), pRoamInfo->staId, (v_MACADDR_t *)pRoamInfo->peerMac ) ) - { + if (!hdd_save_peer(WLAN_HDD_GET_STATION_CTX_PTR(pAdapter), + pRoamInfo->staId, + (v_MACADDR_t *)pRoamInfo->peerMac)) { VOS_TRACE( VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_WARN, "New IBSS peer but we already have the max we can handle. Can't register this one" ); break; diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.c b/CORE/HDD/src/wlan_hdd_nan_datapath.c index 4ab4a2786a84..f79d7632c77e 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.c +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.c @@ -32,6 +32,8 @@ #include "wlan_hdd_includes.h" #include "wlan_hdd_p2p.h" #include "wma_api.h" +#include "wlan_hdd_assoc.h" +#include "sme_nan_datapath.h" /* NLA policy */ static const struct nla_policy @@ -40,8 +42,8 @@ qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { [QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID] = { .type = NLA_U16 }, [QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR] = { .type = NLA_STRING, .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_SERVICE_INSTANCE_ID] = { .type = NLA_U16 }, + [QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL] = { .type = NLA_U32 }, [QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR] = { .type = NLA_BINARY, .len = VOS_MAC_ADDR_SIZE }, @@ -52,7 +54,7 @@ qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = { [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_SCHEDULE_RESPONSE_CODE] = { .type = NLA_U16 }, + [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 }, @@ -151,6 +153,52 @@ static int hdd_close_ndi(hdd_adapter_t *adapter) } /** + * hdd_is_ndp_allowed() - Indicates if NDP is allowed + * @hdd_ctx: hdd context + * + * NDP is not allowed with any other role active except STA. + * + * Return: true if allowed, false otherwise + */ +static bool hdd_is_ndp_allowed(hdd_context_t *hdd_ctx) +{ + hdd_adapter_t *adapter; + hdd_station_ctx_t *sta_ctx; + VOS_STATUS status; + hdd_adapter_list_node_t *curr = NULL, *next = NULL; + + status = hdd_get_front_adapter(hdd_ctx, &curr); + while (VOS_STATUS_SUCCESS == status) { + adapter = curr->pAdapter; + if (!adapter) + goto next_adapter; + + switch (adapter->device_mode) { + case WLAN_HDD_P2P_GO: + case WLAN_HDD_SOFTAP: + if (test_bit(SOFTAP_BSS_STARTED, + &adapter->event_flags)) + return false; + break; + case WLAN_HDD_P2P_CLIENT: + case WLAN_HDD_IBSS: + sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter); + if (hdd_connIsConnected(sta_ctx) || + hdd_is_connecting(sta_ctx)) + return false; + break; + default: + break; + } +next_adapter: + status = hdd_get_next_adapter(hdd_ctx, curr, &next); + curr = next; + } + + return true; +} + +/** * hdd_ndi_start_bss() - Start BSS on NAN data interface * @adapter: adapter context * @operating_channel: channel on which the BSS to be started @@ -393,7 +441,6 @@ static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx, return ret; } - /** * hdd_ndp_initiator_req_handler() - NDP initiator request handler * @hdd_ctx: hdd context @@ -402,8 +449,117 @@ static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx, * Return: 0 on success or error code on failure */ static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx, - struct nlattr **tb) + struct nlattr **tb) { + hdd_adapter_t *adapter; + char *iface_name; + struct ndp_initiator_req req; + VOS_STATUS status; + uint32_t ndp_qos_cfg; + tHalHandle hal = hdd_ctx->hHal; + struct nan_datapath_ctx *ndp_ctx; + + 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]); + /* Check if an interface with same name exists */ + adapter = hdd_get_adapter_by_name(hdd_ctx, iface_name); + if (!adapter) { + hddLog(LOGE, FL("NAN data interface %s not available"), + iface_name); + return -EINVAL; + } + + /* NAN data path coexists only with STA interface */ + if (false == hdd_is_ndp_allowed(hdd_ctx)) { + hddLog(LOGE, FL("Unsupported concurrency for NAN datapath")); + return -EPERM; + } + + ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + + if (ndp_ctx->state == NAN_DATA_NDI_DELETED_STATE || + ndp_ctx->state == NAN_DATA_NDI_DELETING_STATE || + ndp_ctx->state == NAN_DATA_NDI_CREATING_STATE) { + hddLog(LOGE, + FL("Data request not allowed in NDI current state: %d"), + ndp_ctx->state); + return -EINVAL; + } + + req.vdev_id = adapter->sessionId; + + 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_CHANNEL]) { + hddLog(LOGE, FL("NDP channel is unavailable")); + return -EINVAL; + } + req.channel = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL]); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]) { + hddLog(LOGE, FL("NDP service instance ID is unavailable")); + return -EINVAL; + } + req.service_instance_id = + nla_get_u16(tb[QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID]); + + vos_mem_copy(req.self_ndi_mac_addr.bytes, + adapter->macAddressCurrent.bytes, VOS_MAC_ADDR_SIZE); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR]) { + hddLog(LOGE, FL("NDI peer discovery mac addr is unavailable")); + return -EINVAL; + } + vos_mem_copy(req.peer_discovery_mac_addr.bytes, + 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; + } + 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 */ + req.ndp_config.ndp_cfg_len = 4; + req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg; + ndp_qos_cfg = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); + } + + hddLog(LOG1, FL("vdev_id: %d, transaction_id: %d, channel: %d, service_instance_id: %d, ndp_app_info_len: %d, peer_discovery_mac_addr: %pM"), + req.vdev_id, req.transaction_id, req.channel, + req.service_instance_id, req.ndp_info.ndp_app_info_len, + req.peer_discovery_mac_addr.bytes); + status = sme_ndp_initiator_req_handler(hal, &req); + if (status != VOS_STATUS_SUCCESS) { + hddLog(LOGE, + FL("sme_ndp_initiator_req_handler failed, status: %d"), + status); + return -ECOMM; + } + EXIT(); return 0; } @@ -715,9 +871,63 @@ failure: * Return: none */ static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter, - void *rsp_params) + void *rsp_params) { + struct sk_buff *vendor_event; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct ndp_initiator_rsp *rsp = rsp_params; + uint32_t data_len = (3 * sizeof(uint32_t)) + (2 * sizeof(uint16_t)) + + NLMSG_HDRLEN + (5 * NLA_HDRLEN); + + ENTER(); + + if (!rsp) { + hddLog(LOGE, FL("Invalid NDP Initator response")); + return; + } + + if (0 != wlan_hdd_validate_context(hdd_ctx)) + return; + + 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_INITIATOR_RESPONSE)) + goto ndp_initiator_rsp_nla_failed; + + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + rsp->transaction_id)) + goto ndp_initiator_rsp_nla_failed; + + if (nla_put_u16(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + rsp->ndp_instance_id)) + goto ndp_initiator_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, + rsp->status)) + goto ndp_initiator_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE, + 0)) + goto ndp_initiator_rsp_nla_failed; + + hddLog(LOG1, + FL("NDP Initiator rsp sent, tid:%d, instance id:%d, status:%d"), + rsp->transaction_id, rsp->ndp_instance_id, rsp->status); + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + EXIT(); return; +ndp_initiator_rsp_nla_failed: + hddLog(LOGE, FL("nla_put api failed")); + kfree_skb(vendor_event); + EXIT(); } /** @@ -728,11 +938,44 @@ static void hdd_ndp_initiator_rsp_handler(hdd_adapter_t *adapter, * Return: none */ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter, - void *ind_params) + void *ind_params) { - return; -} + struct sme_ndp_peer_ind *new_peer_ind = ind_params; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + tSirBssDescription tmp_bss_descp = {0}; + tCsrRoamInfo roam_info = {0}; + 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); + + ENTER(); + if (NULL == ind_params) { + hddLog(LOGE, FL("Invalid new NDP peer params")); + return; + } + + /* save peer in ndp ctx */ + if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id, + &new_peer_ind->peer_mac_addr)) { + hddLog(LOGE, FL("Ndp peer table full. cannot save new peer")); + return; + } + + /* this function is called for each new peer */ + ndp_ctx->active_ndp_peers++; + hdd_roamRegisterSTA(adapter, &roam_info, new_peer_ind->sta_id, + &new_peer_ind->peer_mac_addr, &tmp_bss_descp); + hdd_ctx->sta_to_adapter[new_peer_ind->sta_id] = adapter; + /* perform following steps for first new peer ind */ + if (ndp_ctx->active_ndp_peers == 1) { + hddLog(LOG1, FL("Set ctx connection state to connected")); + sta_ctx->conn_info.connState = eConnectionState_NdiConnected; + hdd_wmm_connect(adapter, &roam_info, eCSR_BSS_TYPE_NDI); + netif_carrier_on(adapter->dev); + netif_tx_start_all_queues(adapter->dev); + } + EXIT(); +} /** * hdd_ndp_peer_departed_ind_handler() - NDP peer departed indication handler * @adapter: pointer to adapter context @@ -754,9 +997,95 @@ static void hdd_ndp_peer_departed_ind_handler( * Return: none */ static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter, - void *ind_params) + void *ind_params) { + 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); + uint32_t data_len; + + ENTER(); + if (!ndp_confirm) { + hddLog(LOGE, FL("Invalid NDP Initator response")); + return; + } + + 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++; + + data_len = (4 * sizeof(uint32_t)) + VOS_MAC_ADDR_SIZE + IFNAMSIZ + + sizeof(uint16_t) + NLMSG_HDRLEN + (8 * NLA_HDRLEN) + + ndp_confirm->ndp_info.ndp_app_info_len; + + 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_CONFIRM_IND)) + goto ndp_confirm_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + ndp_confirm->ndp_instance_id)) + goto ndp_confirm_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, + VOS_MAC_ADDR_SIZE, ndp_confirm->peer_ndi_mac_addr.bytes)) + goto ndp_confirm_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + 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)) + goto ndp_confirm_nla_failed; + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + hddLog(LOG1, FL("NDP confim sent, ndp instance id: %d, peer addr: %pM, ndp_cfg: %d, rsp_code: %d"), + ndp_confirm->ndp_instance_id, + ndp_confirm->peer_ndi_mac_addr.bytes, + ndp_qos_config, ndp_confirm->rsp_code); + + hddLog(LOG1, FL("NDP confim, ndp app info dump")); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_DEBUG, + ndp_confirm->ndp_info.ndp_app_info, + ndp_confirm->ndp_info.ndp_app_info_len); + EXIT(); return; +ndp_confirm_nla_failed: + hddLog(LOGE, FL("nla_put api failed")); + kfree_skb(vendor_event); + EXIT(); } /** diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.h b/CORE/HDD/src/wlan_hdd_nan_datapath.h index a74327689e94..5b19484103b5 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.h +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.h @@ -57,7 +57,7 @@ struct wireless_dev; * @QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID: Transaction id reference * @QCA_WLAN_VENDOR_ATTR_NDP_STATUS_ID: NDP status id * @QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID: Service instance id - * @QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_SPEC_CHANNEL: Requested channel + * @QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL: Requested channel * @QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR: Peer discovery mac addr * @QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR: Iface name * @QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY: Security configuration @@ -67,7 +67,7 @@ struct wireless_dev; * @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_SCHEDULE_RESPONSE_CODE: Schedule response + * @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 @@ -78,7 +78,7 @@ enum qca_wlan_vendor_attr_ndp_params { QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, - QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL_SPEC_CHANNEL, + QCA_WLAN_VENDOR_ATTR_NDP_CHANNEL, QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_SECURITY, @@ -88,7 +88,7 @@ enum qca_wlan_vendor_attr_ndp_params { 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_SCHEDULE_RESPONSE_CODE, + 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, @@ -180,6 +180,7 @@ enum nan_datapath_state { * struct nan_datapath_ctx - context for nan data path * @state: Current state of NDP * @active_ndp_sessions: active ndp sessions per adapter + * @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 @@ -193,6 +194,7 @@ enum nan_datapath_state { struct nan_datapath_ctx { enum nan_datapath_state state; uint32_t active_ndp_sessions; + uint32_t active_ndp_peers; uint16_t ndp_create_transaction_id; uint16_t ndp_delete_transaction_id; bool ndp_key_installed; diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 068d33355868..8771929511db 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -7005,7 +7005,7 @@ enum ndp_response_code { struct ndp_cfg { uint32_t tag; uint32_t ndp_cfg_len; - uint8_t ndp_cfg[]; + uint8_t *ndp_cfg; }; /** @@ -7031,7 +7031,7 @@ struct ndp_qos_cfg { struct ndp_app_info { uint32_t tag; uint32_t ndp_app_info_len; - uint8_t ndp_app_info[]; + uint8_t *ndp_app_info; }; /** @@ -7106,7 +7106,7 @@ struct ndp_initiator_req { }; /** - * struct ndp_initiator_rsp_event - response event from FW + * struct ndp_initiator_rsp - response event from FW * @transaction_id: unique identifier * @vdev_id: session id of the interface over which ndp is being created * @ndp_instance_id: locally created NDP instance ID @@ -7114,12 +7114,11 @@ struct ndp_initiator_req { * @reason: reason for failure if any * */ -struct ndp_initiator_rsp_event { +struct ndp_initiator_rsp { uint32_t transaction_id; uint32_t vdev_id; uint32_t ndp_instance_id; uint32_t status; - uint32_t reason; }; /** @@ -7127,6 +7126,7 @@ struct ndp_initiator_rsp_event { * @vdev_id: session id of the interface over which ndp is being created * @service_instance_id: Service identifier * @peer_discovery_mac_addr: Peer's discovery mac address + * @peer_mac_addr: Peer's NDI mac address * @ndp_initiator_mac_addr: NDI mac address of the peer initiating NDP * @ndp_instance_id: locally created NDP instance ID * @role: self role for NDP @@ -7139,7 +7139,7 @@ struct ndp_indication_event { uint32_t vdev_id; uint32_t service_instance_id; v_MACADDR_t peer_discovery_mac_addr; - v_MACADDR_t ndp_initiator_mac_addr; + v_MACADDR_t peer_mac_addr; uint32_t ndp_instance_id; enum ndp_self_role role; enum ndp_accept_policy policy; diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h index e46e4be8ce29..2a85a40b7e33 100644 --- a/CORE/MAC/inc/wniApi.h +++ b/CORE/MAC/inc/wniApi.h @@ -407,6 +407,7 @@ enum eWniMsgTypes eWNI_SME_DEL_ALL_TDLS_PEERS, eWNI_SME_SEND_DISASSOC_FRAME, + eWNI_SME_NDP_INITIATOR_REQ, eWNI_SME_NDP_INITIATOR_RSP, eWNI_SME_NDP_NEW_PEER_IND, eWNI_SME_NDP_CONFIRM_IND, diff --git a/CORE/MAC/src/pe/lim/limAssocUtils.c b/CORE/MAC/src/pe/lim/limAssocUtils.c index efe9c52c6825..0ea96b3645c7 100644 --- a/CORE/MAC/src/pe/lim/limAssocUtils.c +++ b/CORE/MAC/src/pe/lim/limAssocUtils.c @@ -2341,10 +2341,10 @@ limAddSta( #ifdef FEATURE_WLAN_TDLS /* SystemRole shouldn't be matter if staType is TDLS peer */ else if(STA_ENTRY_TDLS_PEER == pStaDs->staType) - { pStaAddr = &pStaDs->staAddr ; - } #endif + else if (STA_ENTRY_NDI_PEER == pStaDs->staType) + pStaAddr = &pStaDs->staAddr; else pStaAddr = &staMac; diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index 994dfbcd9a55..6d221920eb31 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -73,6 +73,7 @@ #include "vos_types.h" #include "vos_packet.h" #include "vos_memory.h" +#include "nan_datapath.h" void limLogSessionStates(tpAniSirGlobal pMac); @@ -1454,6 +1455,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) case eWNI_SME_EXT_CHANGE_CHANNEL: case eWNI_SME_ROAM_RESTART_REQ: case eWNI_SME_REGISTER_MGMT_FRAME_CB: + case eWNI_SME_NDP_INITIATOR_REQ: // These messages are from HDD limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd break; @@ -2195,13 +2197,16 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) lim_sap_offload_del_sta(pMac, limMsg); break; #endif /* SAP_AUTH_OFFLOAD */ - case eWNI_SME_DEL_ALL_TDLS_PEERS: lim_process_sme_del_all_tdls_peers(pMac, limMsg->bodyptr); vos_mem_free((v_VOID_t*)limMsg->bodyptr); limMsg->bodyptr = NULL; break; - + case SIR_HAL_NDP_INITIATOR_RSP: + case SIR_HAL_NDP_INDICATION: + case SIR_HAL_NDP_CONFIRM: + lim_handle_ndp_event_message(pMac, limMsg); + break; default: vos_mem_free((v_VOID_t*)limMsg->bodyptr); limMsg->bodyptr = NULL; diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index fa3c12059f18..8206922f1e1f 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -59,7 +59,7 @@ #include "sirMacProtDef.h" #include "regdomain_common.h" #include "rrmApi.h" - +#include "nan_datapath.h" #include "sapApi.h" @@ -6184,6 +6184,9 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) case eWNI_SME_REGISTER_MGMT_FRAME_CB: lim_register_mgmt_frame_ind_cb(pMac, pMsgBuf); break; + case eWNI_SME_NDP_INITIATOR_REQ: + lim_handle_ndp_request_message(pMac, pMsg); + break; default: vos_mem_free((v_VOID_t*)pMsg->bodyptr); pMsg->bodyptr = NULL; diff --git a/CORE/MAC/src/pe/lim/limUtils.c b/CORE/MAC/src/pe/lim/limUtils.c index f8fad2b4daa8..3aff9ff0476a 100644 --- a/CORE/MAC/src/pe/lim/limUtils.c +++ b/CORE/MAC/src/pe/lim/limUtils.c @@ -68,6 +68,7 @@ #include "limAssocUtils.h" #endif +#include "nan_datapath.h" /* Static global used to mark situations where pMac->lim.gLimTriggerBackgroundScanDuringQuietBss is SET * and limTriggerBackgroundScanDuringQuietBss() returned failure. In this case, we will stop data * traffic instead of going into scan. The recover function limProcessQuietBssTimeout() needs to have @@ -6668,35 +6669,54 @@ tANI_U8 limGetCurrentOperatingChannel(tpAniSirGlobal pMac) return 0; } -void limProcessAddStaRsp(tpAniSirGlobal pMac,tpSirMsgQ limMsgQ) +/** + * limProcessAddStaRsp() - process WDA_ADD_STA_RSP from WMA + * @mac_ctx: Pointer to Global MAC structure + * @msg: msg from WMA + * + * @Return: void + */ +void limProcessAddStaRsp(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) { - tpPESession psessionEntry; - tpAddStaParams pAddStaParams; + tpPESession session; + tpAddStaParams add_sta_params; - pAddStaParams = (tpAddStaParams)limMsgQ->bodyptr; + if (NULL == msg) { + limLog(mac_ctx, LOGE, FL("NULL add_sta_rsp")); + return; + } + + add_sta_params = (tpAddStaParams)msg->bodyptr; + session = peFindSessionBySessionId(mac_ctx, add_sta_params->sessionId); + if (NULL == session) { + limLog(mac_ctx, LOGP, + FL("Session does not exist for given sessionID")); + vos_mem_free(add_sta_params); + return; + } + session->csaOffloadEnable = add_sta_params->csaOffloadEnable; + + if (LIM_IS_IBSS_ROLE(session)) { + limIbssAddStaRsp(mac_ctx, msg->bodyptr, session); + return; + } + + if (LIM_IS_NDI_ROLE(session)) { + lim_ndp_add_sta_rsp(mac_ctx, session, msg->bodyptr); + return; + } - if((psessionEntry = peFindSessionBySessionId(pMac,pAddStaParams->sessionId))==NULL) - { - limLog(pMac, LOGP,FL("Session Does not exist for given sessionID")); - vos_mem_free(pAddStaParams); - return; - } - psessionEntry->csaOffloadEnable = pAddStaParams->csaOffloadEnable; - if (LIM_IS_IBSS_ROLE(psessionEntry)) - (void) limIbssAddStaRsp(pMac, limMsgQ->bodyptr,psessionEntry); #ifdef FEATURE_WLAN_TDLS - else if(pMac->lim.gLimAddStaTdls) - { - limProcessTdlsAddStaRsp(pMac, limMsgQ->bodyptr, psessionEntry) ; - pMac->lim.gLimAddStaTdls = FALSE ; - } + if (mac_ctx->lim.gLimAddStaTdls) { + limProcessTdlsAddStaRsp(mac_ctx, msg->bodyptr, session); + mac_ctx->lim.gLimAddStaTdls = FALSE; + return; + } #endif - else - limProcessMlmAddStaRsp(pMac, limMsgQ,psessionEntry); + limProcessMlmAddStaRsp(mac_ctx, msg, session); } - void limUpdateBeacon(tpAniSirGlobal pMac) { tANI_U8 i; diff --git a/CORE/MAC/src/pe/nan/nan_datapath.c b/CORE/MAC/src/pe/nan/nan_datapath.c index c573e8ef5d18..30eb5bbf08b2 100644 --- a/CORE/MAC/src/pe/nan/nan_datapath.c +++ b/CORE/MAC/src/pe/nan/nan_datapath.c @@ -26,32 +26,230 @@ #include "limUtils.h" #include "limApi.h" +#include "limAssocUtils.h" #include "nan_datapath.h" #include "limTypes.h" #include "limSendMessages.h" +#include "wma_nan_datapath.h" /** - * handle_ndp_request_message() - Function to handle NDP requests from SME + * lim_send_ndp_event_to_sme() - generic function to pepare and send NDP message + * to SME directly. * @mac_ctx: handle to mac structure - * @msg: pointer to message + * @msg_type: sme message type to send + * @body_ptr: buffer + * @len: buffer length + * @body_val: value + * + * Return: Nothing + */ +static void lim_send_ndp_event_to_sme(tpAniSirGlobal mac_ctx, uint32_t msg_type, + void *body_ptr, uint32_t len, uint32_t body_val) +{ + tSirMsgQ mmh_msg = {0}; + + mmh_msg.type = msg_type; + if (len && body_ptr) { + mmh_msg.bodyptr = vos_mem_malloc(len); + if (NULL == mmh_msg.bodyptr) { + limLog(mac_ctx, LOGE, FL("Malloc failed")); + return; + } + vos_mem_copy(mmh_msg.bodyptr, body_ptr, len); + } else { + mmh_msg.bodyval = body_val; + } + limSysProcessMmhMsgApi(mac_ctx, &mmh_msg, ePROT); +} + +/** + * lim_handle_ndp_indication_event() - Function to handle SIR_HAL_NDP_INDICATION + * event from WMA + * @mac_ctx: handle to mac structure + * @ndp_ind: ndp indication event params * * Return: VOS_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS handle_ndp_request_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) +static VOS_STATUS lim_handle_ndp_indication_event(tpAniSirGlobal mac_ctx, + struct ndp_indication_event *ndp_ind) { + tpPESession session; + tpDphHashNode sta_ds; + uint16_t assoc_id, peer_idx; + tSirRetStatus status; + + limLog(mac_ctx, LOG1, + FL("role: %d, vdev: %d, peer_mac_addr "MAC_ADDRESS_STR), + ndp_ind->role, ndp_ind->vdev_id, + MAC_ADDR_ARRAY(ndp_ind->peer_mac_addr.bytes)); + + if (ndp_ind->role == NDP_ROLE_INITIATOR) { + + session = pe_find_session_by_sme_session_id(mac_ctx, + ndp_ind->vdev_id); + if (session == NULL) { + limLog(mac_ctx, LOGE, + FL("Couldn't find session, vdev_id: %d, ndp_role: %d"), + ndp_ind->vdev_id, ndp_ind->role); + goto ndp_indication_failed; + } + sta_ds = dphLookupHashEntry(mac_ctx, + ndp_ind->peer_mac_addr.bytes, + &assoc_id, &session->dph.dphHashTable); + /* peer exists, don't do anything */ + if (sta_ds != NULL) { + limLog(mac_ctx, LOGE, FL("NDI Peer already exists!!")); + return VOS_STATUS_SUCCESS; + } + + /* else create one */ + limLog(mac_ctx, LOG1, FL("Need to create NDI Peer!!")); + peer_idx = limAssignPeerIdx(mac_ctx, session); + sta_ds = dphAddHashEntry(mac_ctx, ndp_ind->peer_mac_addr.bytes, + peer_idx, &session->dph.dphHashTable); + if (sta_ds == NULL) { + limLog(mac_ctx, LOGE, + FL("Couldn't add dph entry, ndp_role: %d"), + ndp_ind->role); + goto ndp_indication_failed; + } + /* wma decides NDI mode from wma->inferface struct */ + sta_ds->staType = STA_ENTRY_NDI_PEER; + status = limAddSta(mac_ctx, sta_ds, false, session); + if (eSIR_SUCCESS != status) { + limLog(mac_ctx, LOGE, + FL("limAddSta failed status: %d, ndp_role: %d"), + status, ndp_ind->role); + goto ndp_indication_failed; + } + } else { + /* Processing for NDP Data Reponder role */ + } + /* + * With NDP indication if peer does not exists already add_sta is + * executed resulting in new peer else no action is taken. Note that + * new_peer event is not necessary event and should not be sent if case + * anything fails in this function. Rather eWNI_SME_NDP_CONFIRM_IND is + * used to indicate success of final operation and abscence of it can be + * used by service layer to identify failure. + */ return VOS_STATUS_SUCCESS; +ndp_indication_failed: + return VOS_STATUS_E_FAILURE; } /** - * handle_ndp_event_message() - Handler for NDP events from WMA + * lim_handle_ndp_event_message() - Handler for NDP events from WMA * @mac_ctx: handle to mac structure * @msg: pointer to message * * Return: VOS_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS handle_ndp_event_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) +VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) { + VOS_STATUS status = VOS_STATUS_SUCCESS; + + switch (msg->type) { + case SIR_HAL_NDP_CONFIRM: + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_CONFIRM_IND, + msg->bodyptr, sizeof(struct ndp_confirm_event), + msg->bodyval); + break; + case SIR_HAL_NDP_INITIATOR_RSP: + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_INITIATOR_RSP, + 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); + vos_mem_free(ndp_ind->ndp_config.ndp_cfg); + vos_mem_free(ndp_ind->ndp_info.ndp_app_info); + break; + } + default: + limLog(mac_ctx, LOGE, FL("Unhandled NDP event: %d"), msg->type); + status = VOS_STATUS_E_NOSUPPORT; + break; + } + vos_mem_free(msg->bodyptr); + return status; +} + +/** + * lim_process_sme_ndp_initiator_req() - Handler for eWNI_SME_NDP_INITIATOR_REQ + * from SME. + * @mac_ctx: handle to mac structure + * @ndp_msg: ndp initiator request msg + * + * Return: Status of operation + */ +VOS_STATUS lim_process_sme_ndp_initiator_req(tpAniSirGlobal mac_ctx, + void *ndp_msg) +{ + tSirMsgQ msg; + VOS_STATUS status; + + struct sir_sme_ndp_initiator_req *sme_req = + (struct sir_sme_ndp_initiator_req *)ndp_msg; + struct ndp_initiator_req *wma_req; + + if (NULL == ndp_msg) { + limLog(mac_ctx, LOGE, FL("invalid ndp_req")); + status = VOS_STATUS_E_INVAL; + goto send_initiator_rsp; + } + wma_req = vos_mem_malloc(sizeof(*wma_req)); + if (wma_req == NULL) { + limLog(mac_ctx, LOGE, FL("malloc failed")); + status = VOS_STATUS_E_NOMEM; + goto send_initiator_rsp; + } + + vos_mem_copy(wma_req, &sme_req->req, sizeof(*wma_req)); + msg.type = SIR_HAL_NDP_INITIATOR_REQ; + msg.reserved = 0; + msg.bodyptr = wma_req; + msg.bodyval = 0; + + limLog(mac_ctx, LOG1, FL("sending WDA_NDP_INITIATOR_REQ to WMA")); + MTRACE(macTraceMsgTx(mac_ctx, NO_SESSION, msg.type)); + + if (eSIR_SUCCESS != wdaPostCtrlMsg(mac_ctx, &msg)) + limLog(mac_ctx, LOGP, FL("wdaPostCtrlMsg failed")); + return VOS_STATUS_SUCCESS; +send_initiator_rsp: + /* msg to unblock SME, but not send rsp to HDD */ + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_INITIATOR_RSP, + NULL, 0, true); + return status; +} + +/** +* lim_handle_ndp_request_message() - Handler for NDP req from SME +* @mac_ctx: handle to mac structure +* @msg: pointer to message +* +* Return: VOS_STATUS_SUCCESS on success; error number otherwise +*/ +VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx, + tpSirMsgQ msg) +{ + VOS_STATUS status; + + switch (msg->type) { + case eWNI_SME_NDP_INITIATOR_REQ: + status = lim_process_sme_ndp_initiator_req(mac_ctx, + msg->bodyptr); + break; + default: + limLog(mac_ctx, LOGE, FL("Unhandled NDP request: %d"), + msg->type); + status = VOS_STATUS_E_NOSUPPORT; + break; + } + return status; } /** @@ -159,3 +357,97 @@ end: session_entry = NULL; } } + +/** + * lim_send_sme_ndp_add_sta_rsp() - prepares and send new peer ind to SME + * @mac_ctx: handle to mac structure + * @session: session pointer + * @add_sta_rsp: add sta response struct + * + * Return: status of operation + */ +static VOS_STATUS lim_send_sme_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, + tpPESession session, + tAddStaParams *add_sta_rsp) +{ + tSirMsgQ mmh_msg = {0}; + struct sme_ndp_peer_ind *new_peer_ind; + + mmh_msg.type = eWNI_SME_NDP_NEW_PEER_IND; + + if (NULL == add_sta_rsp) { + limLog(mac_ctx, LOGE, FL("Invalid add_sta_rsp")); + return VOS_STATUS_E_INVAL; + } + + new_peer_ind = vos_mem_malloc(sizeof(*new_peer_ind)); + if (NULL == new_peer_ind) { + limLog(mac_ctx, LOGE, FL("Failed to allocate memory")); + return VOS_STATUS_E_NOMEM; + } + + /* this message is going to HDD, fill in sme session id */ + new_peer_ind->session_id = add_sta_rsp->smesessionId; + new_peer_ind->msg_len = sizeof(struct sme_ndp_peer_ind); + new_peer_ind->msg_type = eWNI_SME_NDP_NEW_PEER_IND; + vos_mem_copy(new_peer_ind->peer_mac_addr.bytes, add_sta_rsp->staMac, + sizeof(tSirMacAddr)); + new_peer_ind->sta_id = add_sta_rsp->staIdx; + + mmh_msg.bodyptr = new_peer_ind; + mmh_msg.bodyval = 0; + limSysProcessMmhMsgApi(mac_ctx, &mmh_msg, ePROT); + return VOS_STATUS_SUCCESS; +} + +/** + * lim_ndp_add_sta_rsp() - handles add sta rsp for NDP from WMA + * @mac_ctx: handle to mac structure + * @session: session pointer + * @add_sta_rsp: add sta response struct + * + * Return: None + */ +void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, tpPESession session, + tAddStaParams *add_sta_rsp) +{ + tpDphHashNode sta_ds; + uint16_t peer_idx; + + if (NULL == add_sta_rsp) { + limLog(mac_ctx, LOGE, FL("Invalid add_sta_rsp")); + vos_mem_free(add_sta_rsp); + return; + } + + SET_LIM_PROCESS_DEFD_MESGS(mac_ctx, true); + sta_ds = dphLookupHashEntry(mac_ctx, add_sta_rsp->staMac, &peer_idx, + &session->dph.dphHashTable); + if (sta_ds == NULL) { + limLog(mac_ctx, LOGE, + FL("NAN: ADD_STA_RSP for unknown MAC addr " + MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(add_sta_rsp->staMac)); + vos_mem_free(add_sta_rsp); + return; + } + + if (add_sta_rsp->status != eHAL_STATUS_SUCCESS) { + limLog(mac_ctx, LOGE, + FL("NAN: ADD_STA_RSP error %x for MAC addr: %pM"), + add_sta_rsp->status, add_sta_rsp->staMac); + /* delete the sta_ds allocated during ADD STA */ + limDeleteDphHashEntry(mac_ctx, add_sta_rsp->staMac, + peer_idx, session); + vos_mem_free(add_sta_rsp); + return; + } + sta_ds->bssId = add_sta_rsp->bssIdx; + sta_ds->staIndex = add_sta_rsp->staIdx; + sta_ds->ucUcastSig = add_sta_rsp->ucUcastSig; + sta_ds->ucBcastSig = add_sta_rsp->ucBcastSig; + sta_ds->valid = 1; + sta_ds->mlmStaContext.mlmState = eLIM_MLM_LINK_ESTABLISHED_STATE; + lim_send_sme_ndp_add_sta_rsp(mac_ctx, session, add_sta_rsp); + vos_mem_free(add_sta_rsp); +} diff --git a/CORE/MAC/src/pe/nan/nan_datapath.h b/CORE/MAC/src/pe/nan/nan_datapath.h index f8b8b17f8381..8c72126e130f 100644 --- a/CORE/MAC/src/pe/nan/nan_datapath.h +++ b/CORE/MAC/src/pe/nan/nan_datapath.h @@ -105,7 +105,7 @@ VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg); /* Function to process NDP events */ VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, - tpSirMsgQ msg); + tpSirMsgQ msg); void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg_q, @@ -114,19 +114,26 @@ void lim_process_ndi_mlm_add_bss_rsp(tpAniSirGlobal mac_ctx, /* Handler DEL BSS resp for NDI interface */ void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx, void *msg, tpPESession session_entry); + +void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, tpPESession session_entry, + tAddStaParams *add_sta_rsp); + #else + /* Function to process NDP requests */ static inline VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx, - tpSirMsgQ msg) + tpSirMsgQ msg) { return VOS_STATUS_SUCCESS; } + /* Function to process NDP events */ static inline VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, 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, @@ -137,6 +144,13 @@ static inline void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx, void *msg, tpPESession session_entry) { } + +static inline void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, + tpPESession session_entry, + tAddStaParams *add_sta_rsp) +{ +} + #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 65ba52653220..3f6ff1edefa1 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -358,7 +358,7 @@ wma_process_ftm_command(tp_wma_handle wma_handle, struct ar6k_testmode_cmd_data *msg_buffer); #endif -static VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, +VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, ol_txrx_vdev_handle vdev, u8 peer_addr[6], u_int32_t peer_type, u_int8_t vdev_id, v_BOOL_t roam_synch_in_progress); @@ -7716,7 +7716,7 @@ static int wmi_unified_peer_create_send(wmi_unified_t wmi, return 0; } -static VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, +VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, ol_txrx_vdev_handle vdev, u8 peer_addr[6], u_int32_t peer_type, u_int8_t vdev_id, v_BOOL_t roam_synch_in_progress) @@ -16721,7 +16721,8 @@ static void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) #endif } #endif - + if (WMA_IS_VDEV_IN_NDI_MODE(wma->interfaces, add_sta->smesessionId)) + oper_mode = BSS_OPERATIONAL_MODE_NDI; switch (oper_mode) { case BSS_OPERATIONAL_MODE_STA: wma_add_sta_req_sta_mode(wma, add_sta); @@ -16733,6 +16734,9 @@ static void wma_add_sta(tp_wma_handle wma, tpAddStaParams add_sta) case BSS_OPERATIONAL_MODE_AP: wma_add_sta_req_ap_mode(wma, add_sta); break; + case BSS_OPERATIONAL_MODE_NDI: + wma_add_sta_ndi_mode(wma, add_sta); + break; } #ifdef QCA_IBSS_SUPPORT @@ -29886,6 +29890,10 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) wma_enable_disable_caevent_ind(wma_handle, msg->bodyval); break; + case SIR_HAL_NDP_INITIATOR_REQ: + wma_handle_ndp_initiator_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.h b/CORE/SERVICES/WMA/wma.h index b4e061e67d38..3add5cf8275e 100644 --- a/CORE/SERVICES/WMA/wma.h +++ b/CORE/SERVICES/WMA/wma.h @@ -1791,5 +1791,8 @@ void wma_remove_peer(tp_wma_handle wma, u_int8_t *bssid, void wma_add_wow_wakeup_event(tp_wma_handle wma, WOW_WAKE_EVENT_TYPE event, bool enable); - +VOS_STATUS wma_create_peer(tp_wma_handle wma, ol_txrx_pdev_handle pdev, + ol_txrx_vdev_handle vdev, u8 peer_addr[6], + u_int32_t peer_type, u_int8_t vdev_id, + 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 c2cd54c2c268..eb5c1a6e2bac 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.c +++ b/CORE/SERVICES/WMA/wma_nan_datapath.c @@ -34,14 +34,147 @@ /** * wma_handle_ndp_initiator_req() - NDP initiator request handler * @wma_handle: wma handle - * @req_params: request parameters + * @req: request parameters * * Return: VOS_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS wma_handle_ndp_initiator_req(tp_wma_handle wma_handle, - struct ndp_initiator_req *req_params) +VOS_STATUS wma_handle_ndp_initiator_req(tp_wma_handle wma_handle, void *req) { + VOS_STATUS status; + int ret; + uint16_t len; + uint32_t vdev_id, ndp_cfg_len, ndp_app_info_len; + struct ndp_initiator_rsp *rsp = NULL; + uint8_t *cfg_info, *app_info; + ol_txrx_vdev_handle vdev; + wmi_buf_t buf; + wmi_ndp_initiator_req_fixed_param *cmd; + vos_msg_t pe_msg = {0}; + struct ndp_initiator_req *ndp_req = req; + wmi_channel *ch_tlv; + + if (NULL == ndp_req) { + WMA_LOGE(FL("Invalid ndp_req.")); + goto send_ndi_initiator_fail; + } + vdev_id = ndp_req->vdev_id; + vdev = wma_find_vdev_by_id(wma_handle, vdev_id); + if (!vdev) { + WMA_LOGE(FL("vdev not found for vdev id %d."), vdev_id); + goto send_ndi_initiator_fail; + } + + if (!WMA_IS_VDEV_IN_NDI_MODE(wma_handle->interfaces, vdev_id)) { + WMA_LOGE(FL("vdev :%d, not in NDI mode"), vdev_id); + goto send_ndi_initiator_fail; + } + + /* + * WMI command expects 4 byte alligned len: + * round up ndp_cfg_len and ndp_app_info_len to 4 bytes + */ + ndp_cfg_len = roundup(ndp_req->ndp_config.ndp_cfg_len, 4); + ndp_app_info_len = roundup(ndp_req->ndp_info.ndp_app_info_len, 4); + /* allocated memory for fixed params as well as variable size data */ + len = sizeof(*cmd) + ndp_cfg_len + ndp_app_info_len + + (2 * WMI_TLV_HDR_SIZE) + sizeof(*ch_tlv); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE(FL("wmi_buf_alloc failed")); + goto send_ndi_initiator_fail; + } + cmd = (wmi_ndp_initiator_req_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_ndp_initiator_req_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_ndp_initiator_req_fixed_param)); + cmd->vdev_id = ndp_req->vdev_id; + cmd->transaction_id = ndp_req->transaction_id; + cmd->service_instance_id = ndp_req->service_instance_id; + WMI_CHAR_ARRAY_TO_MAC_ADDR(ndp_req->peer_discovery_mac_addr.bytes, + &cmd->peer_discovery_mac_addr); + + cmd->ndp_cfg_len = ndp_req->ndp_config.ndp_cfg_len; + cmd->ndp_app_info_len = ndp_req->ndp_info.ndp_app_info_len; + + ch_tlv = (wmi_channel *)&cmd[1]; + WMITLV_SET_HDR(ch_tlv, WMITLV_TAG_STRUC_wmi_channel, + WMITLV_GET_STRUCT_TLVLEN(wmi_channel)); + ch_tlv->mhz = ndp_req->channel; + ch_tlv->band_center_freq1 = + vos_chan_to_freq(vos_freq_to_chan(ndp_req->channel)); + + cfg_info = (uint8_t *)&ch_tlv[1]; + WMITLV_SET_HDR(cfg_info, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); + vos_mem_copy(&cfg_info[WMI_TLV_HDR_SIZE], ndp_req->ndp_config.ndp_cfg, + cmd->ndp_cfg_len); + + app_info = &cfg_info[WMI_TLV_HDR_SIZE + ndp_cfg_len]; + WMITLV_SET_HDR(app_info, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); + vos_mem_copy(&app_info[WMI_TLV_HDR_SIZE], + ndp_req->ndp_info.ndp_app_info, + cmd->ndp_app_info_len); + + WMA_LOGE(FL("vdev_id = %d, transaction_id: %d, service_instance_id, %d channel: %d"), + cmd->vdev_id, cmd->transaction_id, cmd->service_instance_id, + ch_tlv->mhz); + WMA_LOGE(FL("peer mac addr: mac_addr31to0: 0x%x, mac_addr47to32: 0x%x"), + cmd->peer_discovery_mac_addr.mac_addr31to0, + cmd->peer_discovery_mac_addr.mac_addr47to32); + + WMA_LOGE(FL("ndp_config len: %d"), cmd->ndp_cfg_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + ndp_req->ndp_config.ndp_cfg, + ndp_req->ndp_config.ndp_cfg_len); + + WMA_LOGE(FL("ndp_app_info len: %d"), cmd->ndp_app_info_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + ndp_req->ndp_info.ndp_app_info, + ndp_req->ndp_info.ndp_app_info_len); + + WMA_LOGE(FL("sending WMI_NDP_INITIATOR_REQ_CMDID(0x%X)"), + WMI_NDP_INITIATOR_REQ_CMDID); + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_NDP_INITIATOR_REQ_CMDID); + if (ret < 0) { + WMA_LOGE(FL("WMI_NDP_INITIATOR_REQ_CMDID failed, ret: %d"), + ret); + wmi_buf_free(buf); + goto send_ndi_initiator_fail; + } + return VOS_STATUS_SUCCESS; + +send_ndi_initiator_fail: + status = VOS_STATUS_E_FAILURE; + if (ndp_req) { + rsp = vos_mem_malloc(sizeof(*rsp)); + if (NULL == rsp) { + WMA_LOGE(FL("Memory allocation failure")); + status = VOS_STATUS_E_NOMEM; + /* unblock SME queue, but do not send rsp to HDD */ + pe_msg.bodyval = true; + } else { + rsp->vdev_id = ndp_req->vdev_id; + rsp->transaction_id = ndp_req->transaction_id; + rsp->ndp_instance_id = ndp_req->service_instance_id; + rsp->status = NDP_CMD_RSP_STATUS_ERROR; + } + } else { + /* unblock SME queue, but do not send rsp to HDD */ + pe_msg.bodyval = true; + } + + pe_msg.type = SIR_HAL_NDP_INITIATOR_RSP; + pe_msg.bodyptr = rsp; + + if (VOS_STATUS_SUCCESS != + vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg)) { + WMA_LOGE("SIR_HAL_NDP_INITIATOR_RSP to PE failed"); + vos_mem_free(rsp); + } + + return status; } /** @@ -92,10 +225,92 @@ VOS_STATUS wma_handle_ndp_sched_update_req(tp_wma_handle wma_handle, * Handler for WMI_NDP_INDICATION_EVENTID * Return: 0 on success, negative errno on failure */ -static int wma_ndp_indication_event_handler(void *handle, - uint8_t *event_info, uint32_t len) +static int wma_ndp_indication_event_handler(void *handle, uint8_t *event_info, + uint32_t len) { - return 0; + WMI_NDP_INDICATION_EVENTID_param_tlvs *event; + wmi_ndp_indication_event_fixed_param *fixed_params; + vos_msg_t pe_msg = {0}; + struct ndp_indication_event *ind_event; + VOS_STATUS status; + + event = (WMI_NDP_INDICATION_EVENTID_param_tlvs *)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")); + return VOS_STATUS_E_NOMEM; + } + vos_mem_zero(ind_event, sizeof(*ind_event)); + ind_event->vdev_id = fixed_params->vdev_id; + ind_event->service_instance_id = fixed_params->service_instance_id; + ind_event->ndp_instance_id = fixed_params->ndp_instance_id; + ind_event->role = fixed_params->self_ndp_role; + ind_event->policy = fixed_params->accept_policy; + + WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, + ind_event->peer_mac_addr.bytes); + WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr, + ind_event->peer_discovery_mac_addr.bytes); + + 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; + + if (ind_event->ndp_config.ndp_cfg_len) { + ind_event->ndp_config.ndp_cfg = + vos_mem_malloc(fixed_params->ndp_cfg_len); + if (NULL == ind_event->ndp_config.ndp_cfg) { + WMA_LOGE(FL("malloc failed")); + vos_mem_free(ind_event); + return VOS_STATUS_E_NOMEM; + } + vos_mem_copy(ind_event->ndp_config.ndp_cfg, event->ndp_cfg, + ind_event->ndp_config.ndp_cfg_len); + } + + if (ind_event->ndp_info.ndp_app_info_len) { + ind_event->ndp_info.ndp_app_info = + vos_mem_malloc(ind_event->ndp_info.ndp_app_info_len); + if (NULL == ind_event->ndp_info.ndp_app_info) { + WMA_LOGE(FL("malloc failed")); + vos_mem_free(ind_event->ndp_config.ndp_cfg); + vos_mem_free(ind_event); + return VOS_STATUS_E_NOMEM; + } + vos_mem_copy(ind_event->ndp_info.ndp_app_info, + event->ndp_app_info, + ind_event->ndp_info.ndp_app_info_len); + } + pe_msg.type = SIR_HAL_NDP_INDICATION; + pe_msg.bodyptr = ind_event; + pe_msg.bodyval = 0; + + WMA_LOGE(FL("Sending SIR_HAL_NDP_INDICATION msg to PE")); + status = vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg); + if (!VOS_IS_STATUS_SUCCESS(status)) { + WMA_LOGE(FL("fail to post SIR_HAL_NDP_INDICATION msg to PE")); + vos_mem_free(ind_event->ndp_config.ndp_cfg); + vos_mem_free(ind_event->ndp_info.ndp_app_info); + vos_mem_free(ind_event); + } + + return status; } /** @@ -122,10 +337,88 @@ static int wma_ndp_responder_rsp_event_handler(void *handle, * Handler for WMI_NDP_CONFIRM_EVENTID * Return: 0 on success, negative errno on failure */ -static int wma_ndp_confirm_event_handler(void *handle, - uint8_t *event_info, uint32_t len) +static int wma_ndp_confirm_event_handler(void *handle, uint8_t *event_info, + uint32_t len) { - return 0; + struct ndp_confirm_event *ndp_confirm; + vos_msg_t msg = {0}; + WMI_NDP_CONFIRM_EVENTID_param_tlvs *event; + wmi_ndp_confirm_event_fixed_param *fixed_params; + VOS_STATUS status; + + event = (WMI_NDP_CONFIRM_EVENTID_param_tlvs *) event_info; + fixed_params = (wmi_ndp_confirm_event_fixed_param *)event->fixed_param; + WMA_LOGE(FL("WMI_NDP_CONFIRM_EVENTID(0x%X) recieved. vdev %d, ndp_instance %d, rsp_code %d"), + WMI_NDP_CONFIRM_EVENTID, fixed_params->vdev_id, + fixed_params->ndp_instance_id, fixed_params->rsp_code); + + WMA_LOGE(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_LOGE(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); + + ndp_confirm = vos_mem_malloc(sizeof(*ndp_confirm)); + if (!ndp_confirm) { + WMA_LOGP(FL("Failed to allocate memory")); + return VOS_STATUS_E_NOMEM; + } + vos_mem_zero(ndp_confirm, sizeof(*ndp_confirm)); + + ndp_confirm->vdev_id = fixed_params->vdev_id; + ndp_confirm->ndp_instance_id = fixed_params->ndp_instance_id; + ndp_confirm->rsp_code = fixed_params->rsp_code; + + 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; + } + vos_mem_copy(&ndp_confirm->ndp_info.ndp_app_info, + event->ndp_app_info, + ndp_confirm->ndp_info.ndp_app_info_len); + } + msg.type = SIR_HAL_NDP_CONFIRM; + msg.bodyptr = ndp_confirm; + msg.bodyval = 0; + WMA_LOGE(FL("Sending SIR_HAL_NDP_CONFIRM msg to PE")); + 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); + } + + return VOS_STATUS_SUCCESS; } /** @@ -168,9 +461,38 @@ static int wma_ndp_end_indication_event_handler(void *handle, * Return: 0 on success, negative errno on failure */ static int wma_ndp_initiator_rsp_event_handler(void *handle, - uint8_t *event_info, uint32_t len) + uint8_t *event_info, uint32_t len) { - return 0; + VOS_STATUS status; + vos_msg_t pe_msg = {0}; + WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *event; + wmi_ndp_initiator_rsp_event_fixed_param *fixed_params; + struct ndp_initiator_rsp *rsp; + + rsp = vos_mem_malloc(sizeof(*rsp)); + if (NULL == rsp) { + WMA_LOGE(FL("Invalid rsp_ind")); + return VOS_STATUS_E_INVAL; + } + + event = (WMI_NDP_INITIATOR_RSP_EVENTID_param_tlvs *)event_info; + fixed_params = event->fixed_param; + + rsp->vdev_id = fixed_params->vdev_id; + rsp->transaction_id = fixed_params->transaction_id; + rsp->ndp_instance_id = fixed_params->ndp_instance_id; + rsp->status = fixed_params->rsp_status; + + pe_msg.type = SIR_HAL_NDP_INITIATOR_RSP; + pe_msg.bodyptr = rsp; + status = vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg); + if (!VOS_IS_STATUS_SUCCESS(status)) { + WMA_LOGE("SIR_HAL_NDP_INITIATOR_RSP to PE failed"); + vos_mem_free(rsp); + return status; + } + + return status; } /** @@ -525,3 +847,95 @@ void wma_delete_all_nan_remote_peers(tp_wma_handle wma, uint32_t vdev_id) wma_remove_peer(wma, peer->mac_addr.raw, vdev_id, peer, false); } +/** + * wma_add_sta_ndi_mode() - Process ADD_STA for NaN Data path + * @wma: wma handle + * @add_sta: Parameters of ADD_STA command + * + * Sends CREATE_PEER command to firmware + * Return: void + */ +void wma_add_sta_ndi_mode(tp_wma_handle wma, tpAddStaParams add_sta) +{ + enum ol_txrx_peer_state state = ol_txrx_peer_state_conn; + ol_txrx_pdev_handle pdev; + ol_txrx_vdev_handle vdev; + ol_txrx_peer_handle peer; + u_int8_t peer_id; + VOS_STATUS status; + struct wma_txrx_node *iface; + + pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context); + + if (NULL == pdev) { + WMA_LOGE(FL("Failed to find pdev")); + add_sta->status = VOS_STATUS_E_FAILURE; + goto send_rsp; + } + + vdev = wma_find_vdev_by_id(wma, add_sta->smesessionId); + if (!vdev) { + WMA_LOGE(FL("Failed to find vdev")); + add_sta->status = VOS_STATUS_E_FAILURE; + goto send_rsp; + } + + iface = &wma->interfaces[vdev->vdev_id]; + WMA_LOGD(FL("vdev: %d, peer_mac_addr: "MAC_ADDRESS_STR), + add_sta->smesessionId, MAC_ADDR_ARRAY(add_sta->staMac)); + + peer = ol_txrx_find_peer_by_addr_and_vdev(pdev, vdev, add_sta->staMac, + &peer_id); + if (peer) { + WMA_LOGE(FL("NDI peer already exists, peer_addr %pM"), + add_sta->staMac); + add_sta->status = VOS_STATUS_E_EXISTS; + goto send_rsp; + } + + /* + * The code above only checks the peer existence on its own vdev. + * Need to check whether the peer exists on other vDevs because firmware + * can't create the peer if the peer with same MAC address already + * exists on the pDev. As this peer belongs to other vDevs, just return + * here. + */ + peer = ol_txrx_find_peer_by_addr(pdev, add_sta->staMac, &peer_id); + if (peer) { + WMA_LOGE(FL("vdev:%d, peer exists on other vdev with peer_addr %pM and peer_id %d"), + vdev->vdev_id, add_sta->staMac, peer_id); + add_sta->status = VOS_STATUS_E_EXISTS; + goto send_rsp; + } + + status = wma_create_peer(wma, pdev, vdev, add_sta->staMac, + WMI_PEER_TYPE_NAN_DATA, add_sta->smesessionId, + VOS_FALSE); + if (status != VOS_STATUS_SUCCESS) { + WMA_LOGE(FL("Failed to create peer for %pM"), add_sta->staMac); + add_sta->status = status; + goto send_rsp; + } + + peer = ol_txrx_find_peer_by_addr_and_vdev(pdev, vdev, add_sta->staMac, + &peer_id); + if (!peer) { + WMA_LOGE(FL("Failed to find peer handle using peer mac %pM"), + add_sta->staMac); + add_sta->status = VOS_STATUS_E_FAILURE; + wma_remove_peer(wma, add_sta->staMac, add_sta->smesessionId, + peer, VOS_FALSE); + goto send_rsp; + } + + WMA_LOGD(FL("Moving peer %pM to state %d"), add_sta->staMac, state); + ol_txrx_peer_state_update(pdev, add_sta->staMac, state); + + add_sta->staIdx = ol_txrx_local_peer_id(peer); + add_sta->nss = iface->nss; + add_sta->status = VOS_STATUS_SUCCESS; +send_rsp: + WMA_LOGD(FL("Sending add sta rsp to umac (mac:%pM, status:%d)"), + add_sta->staMac, add_sta->status); + wma_send_msg(wma, WDA_ADD_STA_RSP, (void *)add_sta, 0); +} diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.h b/CORE/SERVICES/WMA/wma_nan_datapath.h index 494aaa032a57..93d25b5e8c1f 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.h +++ b/CORE/SERVICES/WMA/wma_nan_datapath.h @@ -29,13 +29,11 @@ #include "wma.h" #include "sirApi.h" +#include "sme_nan_datapath.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); - /** * wma_update_hdd_cfg_ndp() - Update target device NAN datapath capability * @wma_handle: pointer to WMA context @@ -55,11 +53,12 @@ void wma_ndp_unregister_all_event_handlers(tp_wma_handle wma_handle); void wma_ndp_add_wow_wakeup_event(tp_wma_handle wma_handle, bool enable); 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); #else static inline void wma_add_bss_ndi_mode(tp_wma_handle wma, - tpAddBssParams add_bss) -{ -} + tpAddBssParams add_bss) {} static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle, struct hdd_tgt_cfg *tgt_cfg) {} static inline void wma_ndp_register_all_event_handlers( @@ -72,5 +71,13 @@ static inline void wma_ndp_add_wow_wakeup_event(tp_wma_handle wma_handle, bool enable) {} static inline void wma_ndp_wow_event_callback(void *handle, void *event, uint32_t len) {} +static inline void wma_add_sta_ndi_mode(tp_wma_handle wma, + tpAddStaParams add_sta) {} +static inline VOS_STATUS wma_handle_ndp_initiator_req(tp_wma_handle wma_handle, + void *req) +{ + return VOS_STATUS_SUCCESS; +} + #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 aa413aeabdf8..2a7da87b6733 100644 --- a/CORE/SME/inc/csrApi.h +++ b/CORE/SME/inc/csrApi.h @@ -1454,7 +1454,7 @@ typedef struct tagCsrRoamInfo struct ndp_confirm_event ndp_confirm_params; struct ndp_responder_rsp_event ndp_responder_rsp_params; struct ndp_indication_event ndp_indication_params; - struct ndp_initiator_rsp_event ndp_init_rsp_params; + struct ndp_initiator_rsp ndp_init_rsp_params; struct ndi_create_rsp ndi_create_params; struct ndi_delete_rsp ndi_delete_params; } ndp; diff --git a/CORE/SME/inc/smeInside.h b/CORE/SME/inc/smeInside.h index 90ddd71b549f..7ea674e60b08 100644 --- a/CORE/SME/inc/smeInside.h +++ b/CORE/SME/inc/smeInside.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2015 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2016 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -214,6 +214,9 @@ typedef struct tagSmeCmd tTdlsCmd tdlsCmd; #endif struct s_ani_set_tx_max_pwr set_tx_max_pwr; +#ifdef WLAN_FEATURE_NAN_DATAPATH + struct ndp_initiator_req initiator_req; +#endif }u; }tSmeCmd; diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h index 4f89113b0f1c..89cc6ea54b0e 100644 --- a/CORE/SME/inc/smeInternal.h +++ b/CORE/SME/inc/smeInternal.h @@ -98,6 +98,7 @@ typedef enum eSmeCommandType #endif eSmeCommandRemainOnChannel, eSmeCommandNoAUpdate, + eSmeCommandNdpInitiatorRequest, } eSmeCommandType; diff --git a/CORE/SME/inc/sme_nan_datapath.h b/CORE/SME/inc/sme_nan_datapath.h index 623fec144e81..b04232839ec0 100644 --- a/CORE/SME/inc/sme_nan_datapath.h +++ b/CORE/SME/inc/sme_nan_datapath.h @@ -31,12 +31,26 @@ #include "halTypes.h" #include "sirApi.h" #include "aniGlobal.h" +#include "smeInside.h" #ifdef WLAN_FEATURE_NAN_DATAPATH +/** + * struct sir_sme_ndp_initiator_req - sme request struct for ndp initiator req + * @mesgType: SME msg type(eWNI_SME_NDP_INITIATOR_REQ) + * @mesgLen: lenght of message + * @req: actual ndp initiator request + * + */ +struct sir_sme_ndp_initiator_req { + uint16_t msg_type; + uint16_t msg_len; + struct ndp_initiator_req req; +}; + /* NaN initiator request handler */ -VOS_STATUS sme_ndp_initiator_req_handler(uint32_t session_id, - struct ndp_initiator_req *req_params); +eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, + struct ndp_initiator_req *req_params); /* NaN responder request handler */ VOS_STATUS sme_ndp_responder_req_handler(uint32_t session_id, @@ -75,6 +89,11 @@ void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx, uint32_t *roam_status, uint32_t *roam_result, void *roam_info); +eHalStatus csr_process_ndp_initiator_request(tpAniSirGlobal mac_ctx, + tSmeCmd *cmd); + +void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg); + #else /* Start NDI BSS */ @@ -110,6 +129,16 @@ static inline void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx, { } +static inline eHalStatus csr_process_ndp_initiator_request( + tpAniSirGlobal mac_ctx, tSmeCmd *cmd) +{ + return eHAL_STATUS_SUCCESS; +} + +static inline void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) +{ +} + #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __SME_NAN_DATAPATH_H */ diff --git a/CORE/SME/src/nan/nan_datapath_api.c b/CORE/SME/src/nan/nan_datapath_api.c index 3aa34f3b64f9..66bff0fd8082 100644 --- a/CORE/SME/src/nan/nan_datapath_api.c +++ b/CORE/SME/src/nan/nan_datapath_api.c @@ -32,15 +32,82 @@ /** * sme_ndp_initiator_req_handler() - ndp initiator req handler - * @session_id: session id over which the ndp is being created + * @hal: hal handle * @req_params: request parameters * * Return: VOS_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS sme_ndp_initiator_req_handler(uint32_t session_id, - struct ndp_initiator_req *req_params) +eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, + struct ndp_initiator_req *req_params) { - return VOS_STATUS_SUCCESS; + eHalStatus status = eHAL_STATUS_SUCCESS; + tSmeCmd *cmd; + tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal); + + if (NULL == req_params) { + smsLog(mac_ctx, LOGE, FL("Invalid req_params")); + return eHAL_STATUS_INVALID_PARAMETER; + } + + status = sme_AcquireGlobalLock(&mac_ctx->sme); + if (eHAL_STATUS_SUCCESS != status) { + smsLog(mac_ctx, LOGE, + FL("SME lock failed, status:%d"), status); + return status; + } + cmd = csrGetCommandBuffer(mac_ctx); + if (NULL == cmd) { + sme_ReleaseGlobalLock(&mac_ctx->sme); + return eHAL_STATUS_RESOURCES; + } + + cmd->command = eSmeCommandNdpInitiatorRequest; + cmd->sessionId = (tANI_U8)req_params->vdev_id; + vos_mem_copy(&cmd->u.initiator_req, req_params, + sizeof(struct ndp_initiator_req)); + /* pointers copied as part of above operation are to be overwritten */ + cmd->u.initiator_req.ndp_info.ndp_app_info = NULL; + cmd->u.initiator_req.ndp_config.ndp_cfg = NULL; + + if (req_params->ndp_info.ndp_app_info_len) { + cmd->u.initiator_req.ndp_info.ndp_app_info = + vos_mem_malloc(req_params->ndp_info.ndp_app_info_len); + if (NULL == cmd->u.initiator_req.ndp_info.ndp_app_info) { + sme_ReleaseGlobalLock(&mac_ctx->sme); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_copy(cmd->u.initiator_req.ndp_info.ndp_app_info, + req_params->ndp_info.ndp_app_info, + req_params->ndp_info.ndp_app_info_len); + } + + if (req_params->ndp_config.ndp_cfg_len) { + 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) { + sme_ReleaseGlobalLock(&mac_ctx->sme); + vos_mem_free( + cmd->u.initiator_req.ndp_info.ndp_app_info); + cmd->u.initiator_req.ndp_info.ndp_app_info_len = 0; + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_copy(cmd->u.initiator_req.ndp_config.ndp_cfg, + req_params->ndp_config.ndp_cfg, + req_params->ndp_config.ndp_cfg_len); + } + + 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.initiator_req.ndp_info.ndp_app_info); + 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; + } + + sme_ReleaseGlobalLock(&mac_ctx->sme); + return status; } /** @@ -246,3 +313,142 @@ void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx, break; } } + +/** + * csr_process_ndp_initiator_request() - process ndp initiator request + * @mac_ctx: Global MAC context + * @cmd: ndp initiator sme cmd + * + * Return: status of operation + */ +eHalStatus csr_process_ndp_initiator_request(tpAniSirGlobal mac_ctx, + tSmeCmd *cmd) +{ + struct sir_sme_ndp_initiator_req *lim_msg; + uint16_t msg_len; + uint8_t *self_mac_addr = NULL; + struct ndp_initiator_req *req; + + if (NULL == cmd) { + smsLog(mac_ctx, LOGE, FL("Invalid req_params")); + return eHAL_STATUS_INVALID_PARAMETER; + } + req = &cmd->u.initiator_req; + + msg_len = sizeof(*lim_msg); + lim_msg = vos_mem_malloc(msg_len); + if (NULL == lim_msg) + return eHAL_STATUS_FAILED_ALLOC; + + vos_mem_set(lim_msg, msg_len, 0); + lim_msg->msg_type = + pal_cpu_to_be16((uint16_t)eWNI_SME_NDP_INITIATOR_REQ); + lim_msg->msg_len = pal_cpu_to_be16(msg_len); + /* + * following is being copied from p_cmd->u.initiator_req, + * no need to perform deep copy, as we are going to use memory + * allocated at SME in p_cmd->u.initiator_req and pass it all the way + * to WMA. + */ + vos_mem_copy(&lim_msg->req, req, sizeof(struct ndp_initiator_req)); + + self_mac_addr = lim_msg->req.self_ndi_mac_addr.bytes; + smsLog(mac_ctx, LOG1, FL("selfMac = "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(self_mac_addr)); + + return palSendMBMessage(mac_ctx->hHdd, lim_msg); +} + +/** + * sme_ndp_msg_processor() - message processor for ndp/ndi north-bound SME msg. + * @mac_ctx: Global MAC context + * @msg: ndp/ndi SME message + * + * This function will further call csrRoamCallCallback with appropriate + * roam_status and roam_result thus allowing hdd to correctly identify NDP/NDI + * response. + * + * Return: nothing + */ +void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) +{ + tCsrRoamInfo roam_info = {0}; + eCsrRoamResult result; + uint32_t session_id; + tListElem *entry = NULL; + tSmeCmd *cmd = NULL; + bool release_active_cmd = false; + eSmeCommandType cmd_to_rel = eSmeNoCommand; + bool send_to_user = true; + + switch (msg->type) { + case eWNI_SME_NDP_CONFIRM_IND: { + result = eCSR_ROAM_RESULT_NDP_CONFIRM_IND; + /* copy msg from msg body to roam info passed to callback */ + vos_mem_copy(&roam_info.ndp.ndp_confirm_params, msg->bodyptr, + sizeof(roam_info.ndp.ndp_confirm_params)); + session_id = roam_info.ndp.ndp_confirm_params.vdev_id; + break; + } + case eWNI_SME_NDP_INITIATOR_RSP: { + if (true == msg->bodyval) { + /* rsp was locally generated, do not send to HDD */ + send_to_user = false; + } else { + result = eCSR_ROAM_RESULT_NDP_INITIATOR_RSP; + vos_mem_copy(&roam_info.ndp.ndp_init_rsp_params, + msg->bodyptr, + sizeof(roam_info.ndp.ndp_init_rsp_params)); + session_id = roam_info.ndp.ndp_init_rsp_params.vdev_id; + } + release_active_cmd = true; + cmd_to_rel = eSmeCommandNdpInitiatorRequest; + entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, + LL_ACCESS_LOCK); + if (entry != NULL) { + cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); + if (cmd_to_rel == 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_NEW_PEER_IND: { + result = eCSR_ROAM_RESULT_NDP_NEW_PEER_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 = roam_info.ndp.ndp_peer_ind_params.session_id; + break; + } + default: + smsLog(mac_ctx, LOGE, FL("Unhandled NDP rsp")); + vos_mem_free(msg->bodyptr); + return; + } + + if (true == send_to_user) { + csrRoamCallCallback(mac_ctx, session_id, &roam_info, 0, + eCSR_ROAM_NDP_STATUS_UPDATE, result); + } + 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) { + /* Now put this cmd back on the avilable command list */ + if (csrLLRemoveEntry(&mac_ctx->sme.smeCmdActiveList, + entry, LL_ACCESS_LOCK)) + smeReleaseCommand(mac_ctx, cmd); + smeProcessPendingQueue(mac_ctx); + } +} diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 044ac94fecde..83e46d7c9b38 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -74,6 +74,7 @@ #endif #include "regdomain_common.h" #include "schApi.h" +#include "sme_nan_datapath.h" extern tSirRetStatus uMacPostCtrlMsg(void* pSirGlobal, tSirMbMsg* pMb); @@ -1028,6 +1029,17 @@ sme_process_cmd: csrLLUnlock( &pMac->sme.smeCmdActiveList ); csrProcessAddStaSessionCommand( pMac, pCommand ); break; + case eSmeCommandNdpInitiatorRequest: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + if (csr_process_ndp_initiator_request(pMac, + pCommand) != eHAL_STATUS_SUCCESS) { + if (csrLLRemoveEntry( + &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) { + csrReleaseCommand(pMac, pCommand); + } + } + break; case eSmeCommandDelStaSession: csrLLUnlock( &pMac->sme.smeCmdActiveList ); csrProcessDelStaSessionCommand( pMac, pCommand ); @@ -3351,6 +3363,11 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) pMsg->bodyptr); vos_mem_free(pMsg->bodyptr); break; + case eWNI_SME_NDP_CONFIRM_IND: + case eWNI_SME_NDP_NEW_PEER_IND: + case eWNI_SME_NDP_INITIATOR_RSP: + sme_ndp_msg_processor(pMac, pMsg); + break; default: if ( ( pMsg->type >= eWNI_SME_MSG_TYPES_BEGIN ) diff --git a/CORE/WDA/inc/legacy/halMsgApi.h b/CORE/WDA/inc/legacy/halMsgApi.h index ad3e66726674..84b8412aabdf 100644 --- a/CORE/WDA/inc/legacy/halMsgApi.h +++ b/CORE/WDA/inc/legacy/halMsgApi.h @@ -49,6 +49,7 @@ #ifdef FEATURE_WLAN_TDLS #define STA_ENTRY_TDLS_PEER 4 #endif /* FEATURE_WLAN_TDLS */ +#define STA_ENTRY_NDI_PEER 5 #define STA_ENTRY_TRANSMITTER STA_ENTRY_SELF #define STA_ENTRY_RECEIVER STA_ENTRY_OTHER |
