summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbhishek Singh <absingh@qti.qualcomm.com>2016-02-29 15:13:39 +0530
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-04-17 21:56:25 +0530
commit5d5b53ea92f660e01b4d66c03441a368acbc01ed (patch)
tree745c8132ea2a75df0c727173f3c4c42b01e710c7
parent78620e81228f9768eb695c6b8cfa8d7bb4adbf9f (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.c289
-rw-r--r--CORE/MAC/inc/sirApi.h2
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMessageQueue.c2
-rw-r--r--CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c1
-rw-r--r--CORE/MAC/src/pe/nan/nan_datapath.c234
-rw-r--r--CORE/SERVICES/WMA/wma.c4
-rw-r--r--CORE/SERVICES/WMA/wma_nan_datapath.c158
-rw-r--r--CORE/SERVICES/WMA/wma_nan_datapath.h7
-rw-r--r--CORE/SME/inc/smeInside.h1
-rw-r--r--CORE/SME/inc/smeInternal.h1
-rw-r--r--CORE/SME/inc/sme_nan_datapath.h24
-rw-r--r--CORE/SME/src/nan/nan_datapath_api.c226
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c14
-rw-r--r--CORE/VOSS/inc/vos_api.h2
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
------------------------------------------------------------------------*/