diff options
| author | Abhishek Singh <absingh@qti.qualcomm.com> | 2016-02-29 15:13:39 +0530 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-17 21:56:25 +0530 |
| commit | 5d5b53ea92f660e01b4d66c03441a368acbc01ed (patch) | |
| tree | 745c8132ea2a75df0c727173f3c4c42b01e710c7 | |
| parent | 78620e81228f9768eb695c6b8cfa8d7bb4adbf9f (diff) | |
qcacld-2.0: Add support for NDP Responder Request
Add implementation for non-auto accept NDP responder request.
Change-Id: I2ced33cfa0faf487d8e31275493e8d85251e8c59
CRs-Fixed: 962367
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_nan_datapath.c | 289 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 2 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessMessageQueue.c | 2 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c | 1 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/nan/nan_datapath.c | 234 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 4 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma_nan_datapath.c | 158 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma_nan_datapath.h | 7 | ||||
| -rw-r--r-- | CORE/SME/inc/smeInside.h | 1 | ||||
| -rw-r--r-- | CORE/SME/inc/smeInternal.h | 1 | ||||
| -rw-r--r-- | CORE/SME/inc/sme_nan_datapath.h | 24 | ||||
| -rw-r--r-- | CORE/SME/src/nan/nan_datapath_api.c | 226 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 14 | ||||
| -rw-r--r-- | CORE/VOSS/inc/vos_api.h | 2 |
14 files changed, 891 insertions, 74 deletions
diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.c b/CORE/HDD/src/wlan_hdd_nan_datapath.c index 48d9070a0080..d38708058a1e 100644 --- a/CORE/HDD/src/wlan_hdd_nan_datapath.c +++ b/CORE/HDD/src/wlan_hdd_nan_datapath.c @@ -575,7 +575,110 @@ static int hdd_ndp_initiator_req_handler(hdd_context_t *hdd_ctx, static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb) { - return 0; + hdd_adapter_t *adapter; + char *iface_name; + struct ndp_responder_req req = {0}; + eHalStatus status; + int ret = 0; + struct nan_datapath_ctx *ndp_ctx; + uint32_t ndp_qos_cfg; + + 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 there is already an existing interface with the same name */ + 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; + } + + if (WLAN_HDD_NDI != adapter->device_mode) { + hddLog(LOGE, + FL("Interface %s not in NDI mode"), iface_name); + return -EINVAL; + } + + /* NAN data path coexists only with STA interface */ + if (!hdd_is_ndp_allowed(hdd_ctx)) { + hddLog(LOGE, FL("Unsupported concurrency for NAN datapath")); + return -EINVAL; + } + + 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 current NDI state: %d"), + ndp_ctx->state); + return -EAGAIN; + } + + 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_INSTANCE_ID]) { + hddLog(LOGE, FL("Instance ID is unavailable")); + return -EINVAL; + } + req.ndp_instance_id = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID]); + + if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]) { + hddLog(LOGE, FL("ndp_rsp is unavailable")); + return -EINVAL; + } + req.ndp_rsp = nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE]); + + if (tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]) { + req.ndp_info.ndp_app_info_len = + nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + if (req.ndp_info.ndp_app_info_len) { + req.ndp_info.ndp_app_info = + nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO]); + } + } else { + hddLog(LOG1, FL("NDP app info is unavailable")); + } + 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; + ndp_qos_cfg = + nla_get_u32(tb[QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS]); + req.ndp_config.ndp_cfg = (uint8_t *)&ndp_qos_cfg; + } else { + hddLog(LOG1, FL("NDP config data is unavailable")); + } + + hddLog(LOG1, + FL("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d"), + req.vdev_id, req.transaction_id, req.ndp_rsp, + req.ndp_instance_id, req.ndp_info.ndp_app_info_len); + + status = sme_ndp_responder_req_handler(hdd_ctx->hHal, &req); + if (status != eHAL_STATUS_SUCCESS) { + hddLog(LOGE, + FL("sme_ndp_initiator_req_handler failed, status: %d"), + status); + ret = -EINVAL; + } + + EXIT(); + return ret; } /** @@ -1104,12 +1207,135 @@ ndp_confirm_nla_failed: * @adapter: pointer to adapter context * @ind_params: indication parameters * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR (IFNAMSIZ) + * QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID (2 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR (6 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR (6 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO (ndp_app_info_len size) + * QCA_WLAN_VENDOR_ATTR_NDP_CONFIG_QOS (4 bytes) + * * Return: none */ static void hdd_ndp_indication_handler(hdd_adapter_t *adapter, void *ind_params) { + struct sk_buff *vendor_event; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct ndp_indication_event *event = ind_params; + uint32_t ndp_qos_config; + struct nan_datapath_ctx *ndp_ctx; + uint16_t data_len; + + ENTER(); + if (!ind_params) { + hddLog(LOGE, FL("Invalid NDP Indication")); + return; + } + + if (0 != 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; + } + + hddLog(LOG1, + FL("NDP Indication, policy: %d"), event->policy); + + /* Policy check */ + if (!WLAN_HDD_IS_NDP_ENABLED(hdd_ctx)) { + hddLog(LOGE, FL("NAN datapath is not suported")); + return; + } + + /* NAN data path coexists only with STA interface */ + if (!hdd_is_ndp_allowed(hdd_ctx)) { + hddLog(LOGE, FL("Unsupported concurrency for NAN datapath")); + return; + } + + ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter); + + /* check if we are in middle of deleting/creating the interface */ + 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 current NDI state: %d"), + ndp_ctx->state); + return; + } + + data_len = 3 * sizeof(uint32_t) + 2 * sizeof(uint16_t) + + 2 * VOS_MAC_ADDR_SIZE + IFNAMSIZ + + event->ndp_info.ndp_app_info_len + 9 * NLA_HDRLEN + + NLMSG_HDRLEN; + + /* 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; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_REQUEST_IND)) + goto ndp_indication_nla_failed; + + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR, + IFNAMSIZ, adapter->dev->name)) + goto ndp_indication_nla_failed; + + if (nla_put_u16(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_SERVICE_INSTANCE_ID, + event->service_instance_id)) + goto ndp_indication_nla_failed; + + if (nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_NDI_MAC_ADDR, + VOS_MAC_ADDR_SIZE, event->peer_mac_addr.bytes)) + goto ndp_indication_nla_failed; + + if (nla_put(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_PEER_DISCOVERY_MAC_ADDR , + VOS_MAC_ADDR_SIZE, event->peer_discovery_mac_addr.bytes)) + goto ndp_indication_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID, + event->ndp_instance_id)) + goto ndp_indication_nla_failed; + + if (event->ndp_info.ndp_app_info_len) + if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_APP_INFO, + event->ndp_info.ndp_app_info_len, + event->ndp_info.ndp_app_info)) + goto ndp_indication_nla_failed; + + if (event->ndp_config.ndp_cfg_len) { + ndp_qos_config = *((uint32_t *)event->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_indication_nla_failed; + } + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + EXIT(); return; +ndp_indication_nla_failed: + hddLog(LOGE, FL("nla_put api failed")); + kfree_skb(vendor_event); + EXIT(); } /** @@ -1117,12 +1343,73 @@ static void hdd_ndp_indication_handler(hdd_adapter_t *adapter, * @adapter: pointer to adapter context * @rsp_params: response parameters * + * Following vendor event is sent to cfg80211: + * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = + * QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE (4 bytes) + * QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE (4 bytes) + * * Return: none */ static void hdd_ndp_responder_rsp_handler(hdd_adapter_t *adapter, void *rsp_params) { + struct sk_buff *vendor_event; + hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter); + struct ndp_responder_rsp_event *rsp = rsp_params; + uint16_t data_len; + + ENTER(); + if (!rsp) { + hddLog(LOGE, FL("Invalid NDP Responder response")); + return; + } + + if (0 != wlan_hdd_validate_context(hdd_ctx)) + return; + + hddLog(LOG1, + FL("NDP Responder,vdev id %d transaction_id %d status code: %d reason %d"), + rsp->vdev_id, rsp->transaction_id, + rsp->status, rsp->reason); + + data_len = 3 * sizeof(uint32_t) + sizeof(uint16_t) + + 4 * NLA_HDRLEN + NLMSG_HDRLEN; + /* 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; + } + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD, + QCA_WLAN_VENDOR_ATTR_NDP_RESPONDER_RESPONSE)) + goto ndp_responder_rsp_nla_failed; + + if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID, + rsp->transaction_id)) + goto ndp_responder_rsp_nla_failed; + + if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE, + rsp->status)) + goto ndp_responder_rsp_nla_failed; + + if (nla_put_u32(vendor_event, + QCA_WLAN_VENDOR_ATTR_NDP_RESPONSE_CODE, + rsp->reason)) + goto ndp_responder_rsp_nla_failed; + + cfg80211_vendor_event(vendor_event, GFP_KERNEL); + EXIT(); return; +ndp_responder_rsp_nla_failed: + hddLog(LOGE, FL("nla_put api failed")); + kfree_skb(vendor_event); + EXIT(); } /** diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h index 2852e00e9179..936b68ad0ef0 100644 --- a/CORE/MAC/inc/sirApi.h +++ b/CORE/MAC/inc/sirApi.h @@ -7175,6 +7175,7 @@ struct ndp_responder_req { * @vdev_id: session id of the interface over which ndp is being created * @status: command status * @reason: reason for failure if any + * @peer_mac_addr: Peer's mac address * */ struct ndp_responder_rsp_event { @@ -7182,6 +7183,7 @@ struct ndp_responder_rsp_event { uint32_t vdev_id; uint32_t status; uint32_t reason; + v_MACADDR_t peer_mac_addr; }; /** diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c index 6d221920eb31..e1c7fe424a62 100644 --- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c +++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c @@ -1456,6 +1456,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) case eWNI_SME_ROAM_RESTART_REQ: case eWNI_SME_REGISTER_MGMT_FRAME_CB: case eWNI_SME_NDP_INITIATOR_REQ: + case eWNI_SME_NDP_RESPONDER_REQ: // These messages are from HDD limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd break; @@ -2205,6 +2206,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg) case SIR_HAL_NDP_INITIATOR_RSP: case SIR_HAL_NDP_INDICATION: case SIR_HAL_NDP_CONFIRM: + case SIR_HAL_NDP_RESPONDER_RSP: lim_handle_ndp_event_message(pMac, limMsg); break; default: diff --git a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c index 74ef4c369234..1ac85b4c134f 100644 --- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c +++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c @@ -6187,6 +6187,7 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg) lim_register_mgmt_frame_ind_cb(pMac, pMsgBuf); break; case eWNI_SME_NDP_INITIATOR_REQ: + case eWNI_SME_NDP_RESPONDER_REQ: lim_handle_ndp_request_message(pMac, pMsg); break; default: diff --git a/CORE/MAC/src/pe/nan/nan_datapath.c b/CORE/MAC/src/pe/nan/nan_datapath.c index 30eb5bbf08b2..850cd837fb53 100644 --- a/CORE/MAC/src/pe/nan/nan_datapath.c +++ b/CORE/MAC/src/pe/nan/nan_datapath.c @@ -33,15 +33,15 @@ #include "wma_nan_datapath.h" /** - * lim_send_ndp_event_to_sme() - generic function to pepare and send NDP message - * to SME directly. - * @mac_ctx: handle to mac structure + * lim_send_ndp_event_to_sme() - generic function to prepare and send NDP + * message to SME. + * @mac_ctx: handle to mac context structure * @msg_type: sme message type to send * @body_ptr: buffer * @len: buffer length * @body_val: value * - * Return: Nothing + * Return: None */ 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) @@ -63,6 +63,61 @@ static void lim_send_ndp_event_to_sme(tpAniSirGlobal mac_ctx, uint32_t msg_type, } /** + * lim_add_ndi_peer() - Function to add ndi peer + * @mac_ctx: handle to mac structure + * @vdev_id: vdev id on which peer is added + * @peer_mac_addr: peer to be added + * + * Return: VOS_STATUS_SUCCESS on success; error number otherwise + */ +static VOS_STATUS lim_add_ndi_peer(tpAniSirGlobal mac_ctx, + uint32_t vdev_id, v_MACADDR_t peer_mac_addr) +{ + tpPESession session; + tpDphHashNode sta_ds; + uint16_t assoc_id, peer_idx; + tSirRetStatus status; + + session = pe_find_session_by_sme_session_id(mac_ctx, + vdev_id); + if (session == NULL) { + /* couldn't find session */ + return VOS_STATUS_E_FAILURE; + } + sta_ds = dphLookupHashEntry(mac_ctx, + 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; + } + limLog(mac_ctx, LOG1, + FL("Need to create NDI Peer :" MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(peer_mac_addr.bytes)); + peer_idx = limAssignPeerIdx(mac_ctx, session); + sta_ds = dphAddHashEntry(mac_ctx, peer_mac_addr.bytes, peer_idx, + &session->dph.dphHashTable); + if (sta_ds == NULL) { + limLog(mac_ctx, LOGE, + FL("Couldn't add dph entry")); + /* couldn't add dph entry */ + return VOS_STATUS_E_FAILURE; + } + /* 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) { + /* couldn't add peer */ + limLog(mac_ctx, LOGE, + FL("limAddSta failed status: %d"), + status); + return VOS_STATUS_E_FAILURE; + } + return VOS_STATUS_SUCCESS; +} + +/** * lim_handle_ndp_indication_event() - Function to handle SIR_HAL_NDP_INDICATION * event from WMA * @mac_ctx: handle to mac structure @@ -73,10 +128,7 @@ static void lim_send_ndp_event_to_sme(tpAniSirGlobal mac_ctx, uint32_t msg_type, 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; + VOS_STATUS status; limLog(mac_ctx, LOG1, FL("role: %d, vdev: %d, peer_mac_addr "MAC_ADDRESS_STR), @@ -84,47 +136,30 @@ static VOS_STATUS lim_handle_ndp_indication_event(tpAniSirGlobal mac_ctx, MAC_ADDR_ARRAY(ndp_ind->peer_mac_addr.bytes)); if (ndp_ind->role == NDP_ROLE_INITIATOR) { + /* Free config only for INITIATOR role */ + vos_mem_free(ndp_ind->ndp_config.ndp_cfg); + vos_mem_free(ndp_ind->ndp_info.ndp_app_info); - 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) { + status = lim_add_ndi_peer(mac_ctx, ndp_ind->vdev_id, + ndp_ind->peer_mac_addr); + if (VOS_STATUS_SUCCESS != status) { limLog(mac_ctx, LOGE, - FL("Couldn't add dph entry, ndp_role: %d"), - ndp_ind->role); + FL("Couldn't add ndi peer, 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 if (NDP_ROLE_RESPONDER == ndp_ind->role) { + /* + * For RESPONDER role ndp_cfg and app_info sent till HDD + * will be freed in sme. + */ + if (NDP_ACCEPT_POLICY_ALL != ndp_ind->policy) { + lim_send_ndp_event_to_sme(mac_ctx, + eWNI_SME_NDP_INDICATION, + ndp_ind, sizeof(*ndp_ind), 0); } - } 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 @@ -139,7 +174,47 @@ ndp_indication_failed: } /** - * lim_handle_ndp_event_message() - Handler for NDP events from WMA + * lim_ndp_responder_rsp_handler() - Handler for NDP responder rsp + * @mac_ctx: handle to mac structure + * @ndp_rsp: pointer to rsp message + * @bodyval: value + * + * Return: VOS_STATUS_SUCCESS on success; error number otherwise + */ +static VOS_STATUS lim_ndp_responder_rsp_handler(tpAniSirGlobal mac_ctx, + struct ndp_responder_rsp_event *rsp_ind, uint32_t bodyval) +{ + VOS_STATUS ret_val = VOS_STATUS_SUCCESS; + + if ((NULL == rsp_ind) || bodyval) { + limLog(mac_ctx, LOGE, + FL("rsp_ind is NULL or bodyval %d"), bodyval); + /* msg to unblock SME, but not send rsp to HDD */ + bodyval = true; + ret_val = VOS_STATUS_E_INVAL; + goto responder_rsp; + } + + if (VOS_STATUS_SUCCESS == rsp_ind->status) { + ret_val = lim_add_ndi_peer(mac_ctx, rsp_ind->vdev_id, + rsp_ind->peer_mac_addr); + if (VOS_STATUS_SUCCESS != ret_val) { + limLog(mac_ctx, LOGE, + FL("Couldn't add ndi peer")); + rsp_ind->status = VOS_STATUS_E_FAILURE; + } + } + +responder_rsp: + /* send eWNI_SME_NDP_RESPONDER_RSP */ + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_RESPONDER_RSP, + bodyval ? NULL : rsp_ind, + bodyval ? 0 : sizeof(*rsp_ind), bodyval); + return ret_val; +} + +/** + * lim_handle_ndp_event_message() - Handler for NDP events/RSP from WMA * @mac_ctx: handle to mac structure * @msg: pointer to message * @@ -163,10 +238,12 @@ VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) 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; } + case SIR_HAL_NDP_RESPONDER_RSP: + status = lim_ndp_responder_rsp_handler(mac_ctx, msg->bodyptr, + msg->bodyval); + break; default: limLog(mac_ctx, LOGE, FL("Unhandled NDP event: %d"), msg->type); status = VOS_STATUS_E_NOSUPPORT; @@ -227,12 +304,61 @@ send_initiator_rsp: } /** -* 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 -*/ + * lim_process_sme_ndp_responder_req() - Handler for NDP responder req + * @mac_ctx: handle to mac structure + * @ndp_msg: pointer to message + * + * Return: VOS_STATUS_SUCCESS on success or failure code in case of failure + */ +static VOS_STATUS lim_process_sme_ndp_responder_req(tpAniSirGlobal mac_ctx, + struct sir_sme_ndp_responder_req *lim_msg) +{ + tSirMsgQ msg; + VOS_STATUS status = VOS_STATUS_SUCCESS; + struct ndp_responder_req *responder_req; + + if (NULL == lim_msg) { + limLog(mac_ctx, LOGE, FL("ndp_msg is NULL")); + status = VOS_STATUS_E_INVAL; + goto send_failure_rsp; + } + responder_req = vos_mem_malloc(sizeof(*responder_req)); + if (NULL == responder_req) { + limLog(mac_ctx, LOGE, + FL("Unable to allocate memory for responder_req")); + status = VOS_STATUS_E_NOMEM; + goto send_failure_rsp; + } + vos_mem_copy(responder_req, &lim_msg->req, sizeof(*responder_req)); + msg.type = SIR_HAL_NDP_RESPONDER_REQ; + msg.reserved = 0; + msg.bodyptr = responder_req; + msg.bodyval = 0; + + limLog(mac_ctx, LOG1, FL("sending SIR_HAL_NDP_RESPONDER_REQ to WMA")); + MTRACE(macTraceMsgTx(mac_ctx, NO_SESSION, msg.type)); + + if (eSIR_SUCCESS != wdaPostCtrlMsg(mac_ctx, &msg)) { + limLog(mac_ctx, LOGE, FL("wdaPostCtrlMsg failed")); + status = VOS_STATUS_E_FAILURE; + vos_mem_free(responder_req); + goto send_failure_rsp; + } + return status; +send_failure_rsp: + /* msg to unblock SME, but not send rsp to HDD */ + lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_RESPONDER_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) { @@ -243,6 +369,10 @@ VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx, status = lim_process_sme_ndp_initiator_req(mac_ctx, msg->bodyptr); break; + case eWNI_SME_NDP_RESPONDER_REQ: + status = lim_process_sme_ndp_responder_req(mac_ctx, + msg->bodyptr); + break; default: limLog(mac_ctx, LOGE, FL("Unhandled NDP request: %d"), msg->type); diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c index 10f9b2106dd6..448700e47d1a 100644 --- a/CORE/SERVICES/WMA/wma.c +++ b/CORE/SERVICES/WMA/wma.c @@ -30103,6 +30103,10 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg) wma_handle_ndp_initiator_req(wma_handle, msg->bodyptr); vos_mem_free(msg->bodyptr); break; + case SIR_HAL_NDP_RESPONDER_REQ: + wma_handle_ndp_responder_req(wma_handle, msg->bodyptr); + vos_mem_free(msg->bodyptr); + break; default: WMA_LOGD("unknow msg type %x", msg->type); /* Do Nothing? MSG Body should be freed at here */ diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.c b/CORE/SERVICES/WMA/wma_nan_datapath.c index eb5c1a6e2bac..ee418e8d586c 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.c +++ b/CORE/SERVICES/WMA/wma_nan_datapath.c @@ -73,8 +73,8 @@ VOS_STATUS wma_handle_ndp_initiator_req(tp_wma_handle wma_handle, void *req) * 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); + ndp_cfg_len = vos_roundup(ndp_req->ndp_config.ndp_cfg_len, 4); + ndp_app_info_len = vos_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); @@ -178,6 +178,45 @@ send_ndi_initiator_fail: } /** + * wma_send_ndp_responder_rsp() - NDP responder request handler + * @rsp_ind: rsp parameters + * + * Return: VOS_STATUS_SUCCESS on success; error number otherwise + */ +static VOS_STATUS wma_send_ndp_responder_rsp + (struct ndp_responder_rsp_event *rsp_ind) +{ + VOS_STATUS status; + vos_msg_t pe_msg = {0}; + uint8_t len = sizeof(*rsp_ind); + + if (NULL == rsp_ind) { + WMA_LOGE(FL("Invalid rsp_ind")); + /* msg to unblock SME, but not send rsp to HDD */ + pe_msg.bodyptr = NULL; + pe_msg.bodyval = true; + goto send_rsp; + } + pe_msg.bodyptr = vos_mem_malloc(len); + if (NULL == pe_msg.bodyptr) { + WMA_LOGE(FL("Memory allocation failure")); + /* msg to unblock SME, but not send rsp to HDD */ + pe_msg.bodyval = true; + } else { + vos_mem_copy(pe_msg.bodyptr, rsp_ind, len); + pe_msg.bodyval = 0; + } +send_rsp: + pe_msg.type = SIR_HAL_NDP_RESPONDER_RSP; + status = vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg); + if (!VOS_IS_STATUS_SUCCESS(status)) { + WMA_LOGE(FL("fail to post msg to PE")); + vos_mem_free(pe_msg.bodyptr); + } + return status; +} + +/** * wma_handle_ndp_responder_req() - NDP responder request handler * @wma_handle: wma handle * @req_params: request parameters @@ -187,7 +226,105 @@ send_ndi_initiator_fail: VOS_STATUS wma_handle_ndp_responder_req(tp_wma_handle wma_handle, struct ndp_responder_req *req_params) { + wmi_buf_t buf; + ol_txrx_vdev_handle vdev; + uint32_t vdev_id = 0, ndp_cfg_len, ndp_app_info_len; + uint8_t *cfg_info, *app_info; + int ret; + wmi_ndp_responder_req_fixed_param *cmd; + uint16_t len; + struct ndp_responder_rsp_event rsp; + + if (NULL == req_params) { + WMA_LOGE(FL("Invalid req_params.")); + return VOS_STATUS_E_INVAL; + } + + vdev_id = req_params->vdev_id; + WMA_LOGD(FL("vdev_id: %d, transaction_id: %d, ndp_rsp %d, ndp_instance_id: %d, ndp_app_info_len: %d"), + req_params->vdev_id, req_params->transaction_id, + req_params->ndp_rsp, + req_params->ndp_instance_id, + req_params->ndp_info.ndp_app_info_len); + 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_responder_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_responder_fail; + } + + /* + * WMI command expects 4 byte alligned len: + * round up ndp_cfg_len and ndp_app_info_len to 4 bytes + */ + ndp_cfg_len = vos_roundup(req_params->ndp_config.ndp_cfg_len, 4); + ndp_app_info_len = vos_roundup(req_params->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); + buf = wmi_buf_alloc(wma_handle->wmi_handle, len); + if (!buf) { + WMA_LOGE(FL("wmi_buf_alloc failed")); + goto send_ndi_responder_fail; + } + cmd = (wmi_ndp_responder_req_fixed_param *) wmi_buf_data(buf); + WMITLV_SET_HDR(&cmd->tlv_header, + WMITLV_TAG_STRUC_wmi_ndp_responder_req_fixed_param, + WMITLV_GET_STRUCT_TLVLEN( + wmi_ndp_responder_req_fixed_param)); + cmd->vdev_id = req_params->vdev_id; + cmd->transaction_id = req_params->transaction_id; + cmd->ndp_instance_id = req_params->ndp_instance_id; + cmd->rsp_code = req_params->ndp_rsp; + + cmd->ndp_cfg_len = req_params->ndp_config.ndp_cfg_len; + cmd->ndp_app_info_len = req_params->ndp_info.ndp_app_info_len; + + cfg_info = (uint8_t *)&cmd[1]; + /* WMI command expects 4 byte alligned len */ + WMITLV_SET_HDR(cfg_info, WMITLV_TAG_ARRAY_BYTE, ndp_cfg_len); + vos_mem_copy(&cfg_info[WMI_TLV_HDR_SIZE], + req_params->ndp_config.ndp_cfg, cmd->ndp_cfg_len); + + app_info = &cfg_info[WMI_TLV_HDR_SIZE + ndp_cfg_len]; + /* WMI command expects 4 byte alligned len */ + WMITLV_SET_HDR(app_info, WMITLV_TAG_ARRAY_BYTE, ndp_app_info_len); + vos_mem_copy(&app_info[WMI_TLV_HDR_SIZE], + req_params->ndp_info.ndp_app_info, + req_params->ndp_info.ndp_app_info_len); + + WMA_LOGD(FL("ndp_config len: %d"), + req_params->ndp_config.ndp_cfg_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + req_params->ndp_config.ndp_cfg, + req_params->ndp_config.ndp_cfg_len); + + WMA_LOGD(FL("ndp_app_info len: %d"), + req_params->ndp_info.ndp_app_info_len); + VOS_TRACE_HEX_DUMP(VOS_MODULE_ID_WDA, VOS_TRACE_LEVEL_DEBUG, + req_params->ndp_info.ndp_app_info, + req_params->ndp_info.ndp_app_info_len); + + ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len, + WMI_NDP_RESPONDER_REQ_CMDID); + if (ret < 0) { + WMA_LOGE(FL("WMI_NDP_RESPONDER_REQ_CMDID failed, ret: %d"), + ret); + wmi_buf_free(buf); + goto send_ndi_responder_fail; + } return VOS_STATUS_SUCCESS; +send_ndi_responder_fail: + vos_mem_zero(&rsp, sizeof(rsp)); + rsp.vdev_id = req_params->vdev_id; + rsp.transaction_id = req_params->transaction_id; + rsp.status = VOS_STATUS_E_FAILURE; + wma_send_ndp_responder_rsp(&rsp); + return VOS_STATUS_E_FAILURE; } /** @@ -323,9 +460,22 @@ static int wma_ndp_indication_event_handler(void *handle, uint8_t *event_info, * Return: 0 on success, negative errno on failure */ static int wma_ndp_responder_rsp_event_handler(void *handle, - uint8_t *event_info, uint32_t len) + uint8_t *event_info, uint32_t len) { - return 0; + WMI_NDP_RESPONDER_RSP_EVENTID_param_tlvs *event; + wmi_ndp_responder_rsp_event_fixed_param *fixed_params; + struct ndp_responder_rsp_event rsp; + + event = (WMI_NDP_RESPONDER_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.reason = fixed_params->reason_code; + rsp.status = fixed_params->rsp_status; + WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_ndi_mac_addr, + rsp.peer_mac_addr.bytes); + return wma_send_ndp_responder_rsp(&rsp); } /** diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.h b/CORE/SERVICES/WMA/wma_nan_datapath.h index 93d25b5e8c1f..a639f394cdfa 100644 --- a/CORE/SERVICES/WMA/wma_nan_datapath.h +++ b/CORE/SERVICES/WMA/wma_nan_datapath.h @@ -46,6 +46,8 @@ static inline void wma_update_hdd_cfg_ndp(tp_wma_handle wma_handle, { tgt_cfg->nan_datapath_enabled = wma_handle->nan_datapath_enabled; } +VOS_STATUS wma_handle_ndp_responder_req(tp_wma_handle wma_handle, + struct ndp_responder_req *req_params); void wma_delete_all_nan_remote_peers(tp_wma_handle wma, uint32_t vdev_id); void wma_ndp_register_all_event_handlers(tp_wma_handle wma_handle); @@ -78,6 +80,11 @@ static inline VOS_STATUS wma_handle_ndp_initiator_req(tp_wma_handle wma_handle, { return VOS_STATUS_SUCCESS; } +static inline VOS_STATUS wma_handle_ndp_responder_req(tp_wma_handle wma_handle, + void *req_params) +{ + return VOS_STATUS_SUCCESS; +} #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __WMA_NAN_DATAPATH_H */ diff --git a/CORE/SME/inc/smeInside.h b/CORE/SME/inc/smeInside.h index 7ea674e60b08..e0de898cc3b1 100644 --- a/CORE/SME/inc/smeInside.h +++ b/CORE/SME/inc/smeInside.h @@ -216,6 +216,7 @@ typedef struct tagSmeCmd struct s_ani_set_tx_max_pwr set_tx_max_pwr; #ifdef WLAN_FEATURE_NAN_DATAPATH struct ndp_initiator_req initiator_req; + struct ndp_responder_req responder_req; #endif }u; }tSmeCmd; diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h index 89cc6ea54b0e..46e4fab07b2d 100644 --- a/CORE/SME/inc/smeInternal.h +++ b/CORE/SME/inc/smeInternal.h @@ -99,6 +99,7 @@ typedef enum eSmeCommandType eSmeCommandRemainOnChannel, eSmeCommandNoAUpdate, eSmeCommandNdpInitiatorRequest, + eSmeCommandNdpResponderRequest, } eSmeCommandType; diff --git a/CORE/SME/inc/sme_nan_datapath.h b/CORE/SME/inc/sme_nan_datapath.h index b04232839ec0..bec7ed381d62 100644 --- a/CORE/SME/inc/sme_nan_datapath.h +++ b/CORE/SME/inc/sme_nan_datapath.h @@ -30,6 +30,7 @@ #include "vos_types.h" #include "halTypes.h" #include "sirApi.h" +#include "csrInsideApi.h" #include "aniGlobal.h" #include "smeInside.h" @@ -48,12 +49,26 @@ struct sir_sme_ndp_initiator_req { struct ndp_initiator_req req; }; +/** + * struct sir_sme_ndp_responder_req - Wraper of responder's response + * to ndp create request + * @msg_type: SME msg type + * @msg_len: Length of msg + * @req: responder's response to ndp create request + * + */ +struct sir_sme_ndp_responder_req { + uint16_t msg_type; + uint16_t msg_len; + struct ndp_responder_req req; +}; + /* NaN initiator request handler */ 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, +eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, struct ndp_responder_req *req_params); /* NaN indication response handler */ @@ -94,6 +109,8 @@ eHalStatus csr_process_ndp_initiator_request(tpAniSirGlobal mac_ctx, void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg); +eHalStatus csr_process_ndp_responder_request(tpAniSirGlobal mac_ctx, + tSmeCmd *cmd); #else /* Start NDI BSS */ @@ -139,6 +156,11 @@ static inline void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) { } +static inline eHalStatus csr_process_ndp_responder_request( + tpAniSirGlobal mac_ctx, tSmeCmd *cmd) +{ + return eHAL_STATUS_SUCCESS; +} #endif /* WLAN_FEATURE_NAN_DATAPATH */ #endif /* __SME_NAN_DATAPATH_H */ diff --git a/CORE/SME/src/nan/nan_datapath_api.c b/CORE/SME/src/nan/nan_datapath_api.c index 66bff0fd8082..0a183c676cdd 100644 --- a/CORE/SME/src/nan/nan_datapath_api.c +++ b/CORE/SME/src/nan/nan_datapath_api.c @@ -25,7 +25,6 @@ */ #include "smsDebug.h" #include "sme_Api.h" -#include "csrInsideApi.h" #include "smeInside.h" #include "csrInternal.h" #include "sme_nan_datapath.h" @@ -112,15 +111,85 @@ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal, /** * sme_ndp_responder_req_handler() - ndp responder request 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 + * Return: eHAL_STATUS_SUCCESS on success; error number otherwise */ -VOS_STATUS sme_ndp_responder_req_handler(uint32_t session_id, +eHalStatus sme_ndp_responder_req_handler(tHalHandle hal, struct ndp_responder_req *req_params) { - return VOS_STATUS_SUCCESS; + eHalStatus status; + 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 = eSmeCommandNdpResponderRequest; + cmd->sessionId = (tANI_U8)req_params->vdev_id; + vos_mem_copy(&cmd->u.responder_req, req_params, + sizeof(*req_params)); + + /* + * Pointers copied as part of above operation are + * to be overwritten + */ + cmd->u.responder_req.ndp_info.ndp_app_info = NULL; + cmd->u.responder_req.ndp_config.ndp_cfg = NULL; + + if (req_params->ndp_info.ndp_app_info_len) { + cmd->u.responder_req.ndp_info.ndp_app_info = + vos_mem_malloc(req_params->ndp_info.ndp_app_info_len); + if (NULL == cmd->u.responder_req.ndp_info.ndp_app_info) { + sme_ReleaseGlobalLock(&mac_ctx->sme); + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_copy(cmd->u.responder_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.responder_req.ndp_config.ndp_cfg = + vos_mem_malloc(req_params->ndp_config.ndp_cfg_len); + if (NULL == cmd->u.responder_req.ndp_config.ndp_cfg) { + sme_ReleaseGlobalLock(&mac_ctx->sme); + vos_mem_free( + cmd->u.responder_req.ndp_info.ndp_app_info); + cmd->u.responder_req.ndp_info.ndp_app_info_len = 0; + return eHAL_STATUS_FAILED_ALLOC; + } + vos_mem_copy(cmd->u.responder_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.responder_req.ndp_info.ndp_app_info); + vos_mem_free(cmd->u.responder_req.ndp_config.ndp_cfg); + cmd->u.responder_req.ndp_info.ndp_app_info_len = 0; + cmd->u.responder_req.ndp_config.ndp_cfg_len = 0; + } + sme_ReleaseGlobalLock(&mac_ctx->sme); + return status; } /** @@ -360,6 +429,70 @@ eHalStatus csr_process_ndp_initiator_request(tpAniSirGlobal mac_ctx, } /** + * csr_process_ndp_responder_request() - ndp responder req + * @mac_ctx: Global MAC context + * @cmd: Cmd sent to SME + * + * Return: Success or failure code + */ +eHalStatus csr_process_ndp_responder_request(tpAniSirGlobal mac_ctx, + tSmeCmd *cmd) +{ + struct sir_sme_ndp_responder_req *lim_msg; + uint16_t msg_len; + eHalStatus status; + + if (!cmd) { + smsLog(mac_ctx, LOGE, FL("Invalid req_params")); + return eHAL_STATUS_INVALID_PARAMETER; + } + + msg_len = sizeof(*lim_msg); + lim_msg = vos_mem_malloc(msg_len); + if (!lim_msg) { + smsLog(mac_ctx, LOGE, FL("Mem alloc fail")); + status = eHAL_STATUS_FAILED_ALLOC; + goto free_config; + } + + vos_mem_set(lim_msg, msg_len, 0); + lim_msg->msg_type = + pal_cpu_to_be16((uint16_t)eWNI_SME_NDP_RESPONDER_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, &cmd->u.responder_req, + sizeof(struct ndp_responder_req)); + + smsLog(mac_ctx, LOG1, + FL("vdev_id %d ndp_rsp = %d Instance id %d"), + lim_msg->req.vdev_id, + lim_msg->req.ndp_rsp, + lim_msg->req.ndp_instance_id); + + status = palSendMBMessage(mac_ctx->hHdd, lim_msg); + +free_config: + if (!HAL_STATUS_SUCCESS(status)) { + /* + * If fail, free up the ndp_cfg and ndp_app_info + * allocated in sme. + */ + vos_mem_free(cmd->u.responder_req.ndp_info.ndp_app_info); + vos_mem_free(cmd->u.responder_req.ndp_config.ndp_cfg); + cmd->u.responder_req.ndp_info.ndp_app_info_len = 0; + cmd->u.responder_req.ndp_config.ndp_cfg_len = 0; + cmd->u.responder_req.ndp_config.ndp_cfg = NULL; + cmd->u.responder_req.ndp_info.ndp_app_info = NULL; + } + return status; +} + +/** * sme_ndp_msg_processor() - message processor for ndp/ndi north-bound SME msg. * @mac_ctx: Global MAC context * @msg: ndp/ndi SME message @@ -403,17 +536,6 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) } 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: { @@ -425,6 +547,32 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) session_id = roam_info.ndp.ndp_peer_ind_params.session_id; break; } + case eWNI_SME_NDP_INDICATION: + result = eCSR_ROAM_RESULT_NDP_INDICATION; + /* copy msg from msg body to roam info passed to callback */ + vos_mem_copy(&roam_info.ndp.ndp_indication_params, + msg->bodyptr, sizeof(struct ndp_indication_event)); + session_id = roam_info.ndp.ndp_indication_params.vdev_id; + break; + case eWNI_SME_NDP_RESPONDER_RSP: + if (true == msg->bodyval) { + /* rsp was locally generated, do not send to HDD */ + send_to_user = false; + } else { + result = eCSR_ROAM_RESULT_NDP_RESPONDER_RSP; + /* + * Copy msg from msg body to roam info passed to + * callback + */ + vos_mem_copy(&roam_info.ndp.ndp_responder_rsp_params, + msg->bodyptr, + sizeof(struct ndp_responder_rsp_event)); + session_id = + roam_info.ndp.ndp_responder_rsp_params.vdev_id; + } + release_active_cmd = true; + cmd_to_rel = eSmeCommandNdpResponderRequest; + break; default: smsLog(mac_ctx, LOGE, FL("Unhandled NDP rsp")); vos_mem_free(msg->bodyptr); @@ -435,6 +583,52 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg) csrRoamCallCallback(mac_ctx, session_id, &roam_info, 0, eCSR_ROAM_NDP_STATUS_UPDATE, result); } + + /* free ndp_cfg and ndp_app_info if required + * For some commands this info may be needed in HDD + * so free them after roam callback. + */ + switch (msg->type) { + case eWNI_SME_NDP_INITIATOR_RSP: + entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, + LL_ACCESS_LOCK); + if (entry != NULL) { + cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); + if (eSmeCommandNdpInitiatorRequest == cmd->command) { + vos_mem_free( + cmd->u.initiator_req. + ndp_config.ndp_cfg); + vos_mem_free( + cmd->u.initiator_req. + ndp_info.ndp_app_info); + } + } + break; + case eWNI_SME_NDP_RESPONDER_RSP: + entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, + LL_ACCESS_LOCK); + if (entry != NULL) { + cmd = GET_BASE_ADDR(entry, tSmeCmd, Link); + if (eSmeCommandNdpResponderRequest == cmd->command) { + vos_mem_free( + cmd->u.responder_req. + ndp_config.ndp_cfg); + vos_mem_free( + cmd->u.responder_req. + ndp_info.ndp_app_info); + } + } + break; + case eWNI_SME_NDP_INDICATION: + vos_mem_free( + roam_info.ndp.ndp_indication_params.ndp_config.ndp_cfg); + vos_mem_free( + roam_info.ndp.ndp_indication_params. + ndp_info.ndp_app_info); + break; + default: + break; + } vos_mem_free(msg->bodyptr); if (release_active_cmd == false) return; diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c index 83e46d7c9b38..f94fcdb125fb 100644 --- a/CORE/SME/src/sme_common/sme_Api.c +++ b/CORE/SME/src/sme_common/sme_Api.c @@ -1040,6 +1040,18 @@ sme_process_cmd: } } break; + case eSmeCommandNdpResponderRequest: + csrLLUnlock(&pMac->sme.smeCmdActiveList); + status = + csr_process_ndp_responder_request(pMac, + pCommand); + if (!HAL_STATUS_SUCCESS(status)) { + if (csrLLRemoveEntry( + &pMac->sme.smeCmdActiveList, + &pCommand->Link, LL_ACCESS_LOCK)) + csrReleaseCommand(pMac, pCommand); + } + break; case eSmeCommandDelStaSession: csrLLUnlock( &pMac->sme.smeCmdActiveList ); csrProcessDelStaSessionCommand( pMac, pCommand ); @@ -3366,6 +3378,8 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg) case eWNI_SME_NDP_CONFIRM_IND: case eWNI_SME_NDP_NEW_PEER_IND: case eWNI_SME_NDP_INITIATOR_RSP: + case eWNI_SME_NDP_INDICATION: + case eWNI_SME_NDP_RESPONDER_RSP: sme_ndp_msg_processor(pMac, pMsg); break; default: diff --git a/CORE/VOSS/inc/vos_api.h b/CORE/VOSS/inc/vos_api.h index e9ee25e740c9..dce0a458e29b 100644 --- a/CORE/VOSS/inc/vos_api.h +++ b/CORE/VOSS/inc/vos_api.h @@ -75,6 +75,8 @@ #define VOS_WDA_TIMEOUT 15000 +#define vos_roundup(x, y) roundup(x, y); + /*------------------------------------------------------------------------- Function declarations and documenation ------------------------------------------------------------------------*/ |
