summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaveen Rawat <nrawat@qca.qualcomm.com>2016-03-15 13:59:10 -0700
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-04-13 10:15:35 +0530
commit39d331bd32072e59d1697276aacea5094d3b5932 (patch)
tree3342ef84ff592444503ffedfcba63f3e2de29d01
parent9d8ea02422acfb169149a9e6c726331e4f7f4e4b (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
-rw-r--r--CORE/HDD/inc/wlan_hdd_assoc.h6
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c73
-rw-r--r--CORE/HDD/src/wlan_hdd_nan_datapath.c349
-rw-r--r--CORE/HDD/src/wlan_hdd_nan_datapath.h10
-rw-r--r--CORE/MAC/inc/sirApi.h12
-rw-r--r--CORE/MAC/inc/wniApi.h1
-rw-r--r--CORE/MAC/src/pe/lim/limAssocUtils.c4
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMessageQueue.c9
-rw-r--r--CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c5
-rw-r--r--CORE/MAC/src/pe/lim/limUtils.c62
-rw-r--r--CORE/MAC/src/pe/nan/nan_datapath.c302
-rw-r--r--CORE/MAC/src/pe/nan/nan_datapath.h18
-rw-r--r--CORE/SERVICES/WMA/wma.c14
-rw-r--r--CORE/SERVICES/WMA/wma.h5
-rw-r--r--CORE/SERVICES/WMA/wma_nan_datapath.c436
-rw-r--r--CORE/SERVICES/WMA/wma_nan_datapath.h19
-rw-r--r--CORE/SME/inc/csrApi.h2
-rw-r--r--CORE/SME/inc/smeInside.h5
-rw-r--r--CORE/SME/inc/smeInternal.h1
-rw-r--r--CORE/SME/inc/sme_nan_datapath.h33
-rw-r--r--CORE/SME/src/nan/nan_datapath_api.c214
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c17
-rw-r--r--CORE/WDA/inc/legacy/halMsgApi.h1
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