summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNaveen Rawat <nrawat@qca.qualcomm.com>2016-02-29 14:51:43 -0800
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-04-27 14:44:02 +0530
commit65945c65ffd5638fa77d0e648b390ca01b70f098 (patch)
treeffddcbcb4ab0d9b72c1b7ae5d73d16c3ae449b4f
parent5fc3354e215e8de70e187c02eb22616b57ab2d2d (diff)
qcacld-2.0: Add support for NAN Data End Request
Add implementation of NAN Data End request. Change-Id: Iddd22a83b0763dab2e7398f4d2cf5b9ada58225a CRs-Fixed: 962367
-rw-r--r--CORE/HDD/inc/wlan_hdd_assoc.h2
-rw-r--r--CORE/HDD/inc/wlan_hdd_tx_rx.h2
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c4
-rw-r--r--CORE/HDD/src/wlan_hdd_nan_datapath.c181
-rw-r--r--CORE/HDD/src/wlan_hdd_nan_datapath.h8
-rw-r--r--CORE/HDD/src/wlan_hdd_tx_rx.c23
-rw-r--r--CORE/MAC/inc/sirApi.h16
-rw-r--r--CORE/MAC/inc/wniApi.h1
-rw-r--r--CORE/MAC/src/include/sirParams.h3
-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.c86
-rw-r--r--CORE/SERVICES/WMA/wma.c4
-rw-r--r--CORE/SERVICES/WMA/wma_nan_datapath.c180
-rw-r--r--CORE/SERVICES/WMA/wma_nan_datapath.h6
-rw-r--r--CORE/SME/inc/csrApi.h2
-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.h25
-rw-r--r--CORE/SME/src/nan/nan_datapath_api.c186
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c12
21 files changed, 648 insertions, 98 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h
index 5a7f278d1953..6a1c0dacac39 100644
--- a/CORE/HDD/inc/wlan_hdd_assoc.h
+++ b/CORE/HDD/inc/wlan_hdd_assoc.h
@@ -49,6 +49,8 @@
/* Timeout in ms for peer info request completion */
#define IBSS_PEER_INFO_REQ_TIMOEUT 1000
+#define INVALID_PEER_IDX -1
+
/**
* enum eConnectionState - connection state values at HDD
* @eConnectionState_NotConnected: Not associated in Infra or participating in
diff --git a/CORE/HDD/inc/wlan_hdd_tx_rx.h b/CORE/HDD/inc/wlan_hdd_tx_rx.h
index 9e46f119190d..a8d223ed8287 100644
--- a/CORE/HDD/inc/wlan_hdd_tx_rx.h
+++ b/CORE/HDD/inc/wlan_hdd_tx_rx.h
@@ -190,6 +190,8 @@ extern v_BOOL_t hdd_IsEAPOLPacket( vos_pkt_t *pVosPacket );
VOS_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *sta_ctx,
v_MACADDR_t *peer_mac_addr, uint8_t *sta_id);
+int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *addr);
+
/**============================================================================
@brief hdd_flush_ibss_tx_queues() -
Flush tx queues in IBSS mode
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index 99b82ca16c13..df910fbbf867 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -2404,6 +2404,9 @@ bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id,
for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) {
if (0 == sta_ctx->conn_info.staId[idx]) {
+ hddLog(VOS_TRACE_LEVEL_DEBUG,
+ FL("adding peer: %pM, sta_id: %d, at idx: %d"),
+ peer_mac_addr, sta_id, idx);
sta_ctx->conn_info.staId[idx] = sta_id;
vos_copy_macaddr(
&sta_ctx->conn_info.peerMacAddress[idx],
@@ -5395,4 +5398,3 @@ int iw_get_ap_address(struct net_device *dev, struct iw_request_info *info,
return ret;
}
-
diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.c b/CORE/HDD/src/wlan_hdd_nan_datapath.c
index 333a0ebc1d82..cb227e129984 100644
--- a/CORE/HDD/src/wlan_hdd_nan_datapath.c
+++ b/CORE/HDD/src/wlan_hdd_nan_datapath.c
@@ -58,6 +58,8 @@ qca_wlan_vendor_ndp_policy[QCA_WLAN_VENDOR_ATTR_NDP_PARAMS_MAX + 1] = {
[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 },
+ [QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY] = { .type = NLA_BINARY,
+ .len = NDP_NUM_INSTANCE_ID },
};
/**
@@ -424,10 +426,10 @@ static int hdd_ndi_delete_req_handler(hdd_context_t *hdd_ctx,
return -EINVAL;
}
- /* check if there are active NDP sessions on the adapter */
- if (ndp_ctx->active_ndp_sessions > 0) {
- hddLog(LOGE, FL("NDP sessions active %d, cannot delete NDI"),
- ndp_ctx->active_ndp_sessions);
+ /* check if there are active peers on the adapter */
+ if (ndp_ctx->active_ndp_peers > 0) {
+ hddLog(LOGE, FL("NDP peers active: %d, cannot delete NDI"),
+ ndp_ctx->active_ndp_peers);
return -EINVAL;
}
@@ -689,9 +691,51 @@ static int hdd_ndp_responder_req_handler(hdd_context_t *hdd_ctx,
*
* Return: 0 on success or error code on failure
*/
-static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx,
- struct nlattr **tb)
+static int hdd_ndp_end_req_handler(hdd_context_t *hdd_ctx, struct nlattr **tb)
{
+ struct ndp_end_req req = {0};
+ VOS_STATUS status;
+ tHalHandle hal = hdd_ctx->hHal;
+
+ ENTER();
+
+ /* 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;
+ }
+
+ 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_ARRAY]) {
+ hddLog(LOGE, FL("NDP instance ID array is unavailable"));
+ return -EINVAL;
+ }
+
+ req.num_ndp_instances =
+ nla_len(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]) /
+ sizeof(uint32_t);
+ if (0 >= req.num_ndp_instances) {
+ hddLog(LOGE, FL("Num NDP instances is 0"));
+ return -EINVAL;
+ }
+ req.ndp_ids = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY]);
+
+ hddLog(LOG1, FL("sending ndp_end_req to SME, transaction_id: %d"),
+ req.transaction_id);
+
+ status = sme_ndp_end_req_handler(hal, &req);
+ if (status != VOS_STATUS_SUCCESS) {
+ hddLog(LOGE, FL("sme_ndp_end_req_handler failed, status: %d"),
+ status);
+ return -ECOMM;
+ }
+ EXIT();
return 0;
}
@@ -1066,6 +1110,9 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
hddLog(LOGE, FL("Invalid new NDP peer params"));
return;
}
+ hddLog(LOG1, FL("session_id: %d, peer_mac: %pM, sta_id: %d"),
+ new_peer_ind->session_id, new_peer_ind->peer_mac_addr.bytes,
+ new_peer_ind->sta_id);
/* save peer in ndp ctx */
if (false == hdd_save_peer(sta_ctx, new_peer_ind->sta_id,
@@ -1076,6 +1123,8 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
/* this function is called for each new peer */
ndp_ctx->active_ndp_peers++;
+ hddLog(LOG1, FL("vdev_id: %d, num_peers: %d"),
+ adapter->sessionId, ndp_ctx->active_ndp_peers);
hdd_roamRegisterSTA(adapter, &roam_info, new_peer_ind->sta_id,
&new_peer_ind->peer_mac_addr, &tmp_bss_descp);
@@ -1083,7 +1132,7 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
/* perform following steps for first new peer ind */
if (ndp_ctx->active_ndp_peers == 1) {
hdd_ctx->sta_to_adapter[NDP_BROADCAST_STAID] = adapter;
- hdd_save_peer(sta_ctx, new_peer_ind->sta_id, &bc_mac_addr);
+ hdd_save_peer(sta_ctx, NDP_BROADCAST_STAID, &bc_mac_addr);
hdd_roamRegisterSTA(adapter, &roam_info, NDP_BROADCAST_STAID,
&bc_mac_addr, &tmp_bss_descp);
hddLog(LOG1, FL("Set ctx connection state to connected"));
@@ -1118,11 +1167,13 @@ static void hdd_ndp_peer_departed_ind_handler(
static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
void *ind_params)
{
+ int idx;
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);
+ hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
uint32_t data_len;
ENTER();
@@ -1134,8 +1185,14 @@ static void hdd_ndp_confirm_ind_handler(hdd_adapter_t *adapter,
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++;
+ /* ndp_confirm is called each time user generated ndp req succeeds */
+ idx = hdd_get_peer_idx(sta_ctx, &ndp_confirm->peer_ndi_mac_addr);
+ if (idx == INVALID_PEER_IDX)
+ hddLog(LOGE,
+ FL("can't find addr: %pM in vdev_id: %d, peer table."),
+ &ndp_confirm->peer_ndi_mac_addr, adapter->sessionId);
+ else
+ ndp_ctx->active_ndp_sessions[idx]++;
data_len = (4 * sizeof(uint32_t)) + VOS_MAC_ADDR_SIZE + IFNAMSIZ +
sizeof(uint16_t) + NLMSG_HDRLEN + (8 * NLA_HDRLEN) +
@@ -1422,12 +1479,97 @@ ndp_responder_rsp_nla_failed:
* @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_DRV_RETURN_TYPE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VELUE (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID (2 bytes)
+ *
* Return: none
*/
-static void hdd_ndp_end_rsp_handler(hdd_adapter_t *adapter,
- void *rsp_params)
+static void hdd_ndp_end_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_end_rsp_event *rsp = rsp_params;
+ struct nan_datapath_ctx *ndp_ctx;
+ uint32_t data_len, i;
+ int idx;
+ hdd_station_ctx_t *sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+
+ ENTER();
+
+ if (!rsp) {
+ hddLog(LOGE, FL("Invalid ndp end response"));
+ return;
+ }
+
+ if (0 != wlan_hdd_validate_context(hdd_ctx))
+ return;
+
+ /* adjust active ndp instances per peer */
+ if (rsp->status == NDP_CMD_RSP_STATUS_SUCCESS) {
+ for (i = 0; i < rsp->num_peers; i++) {
+ adapter = hdd_get_adapter_by_vdev(hdd_ctx,
+ rsp->ndp_map[i].vdev_id);
+ if (NULL == adapter) {
+ hddLog(LOGE,
+ FL("adapter for vdev_id: %d not found"),
+ rsp->ndp_map[i].vdev_id);
+ continue;
+ }
+ sta_ctx = WLAN_HDD_GET_STATION_CTX_PTR(adapter);
+ ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(adapter);
+ idx = hdd_get_peer_idx(sta_ctx,
+ &rsp->ndp_map[i].peer_ndi_mac_addr);
+ if (idx == INVALID_PEER_IDX)
+ hddLog(LOGE,
+ FL("can't find addr: %pM in vdev_id: %d, peer table."),
+ &rsp->ndp_map[i].peer_ndi_mac_addr,
+ rsp->ndp_map[i].vdev_id);
+ else
+ ndp_ctx->active_ndp_sessions[idx] =
+ rsp->ndp_map[i].num_active_ndp_sessions;
+ }
+ }
+
+ data_len = NLMSG_HDRLEN + (4 * NLA_HDRLEN) + (3 * sizeof(uint32_t)) +
+ sizeof(uint16_t);
+
+ 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_END_RESPONSE))
+ goto ndp_end_rsp_nla_failed;
+
+ if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_TYPE,
+ rsp->status))
+ goto ndp_end_rsp_nla_failed;
+
+ if (nla_put_u32(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_DRV_RETURN_VALUE,
+ rsp->reason))
+ goto ndp_end_rsp_nla_failed;
+
+ if (nla_put_u16(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID,
+ rsp->transaction_id))
+ goto ndp_end_rsp_nla_failed;
+
+ hddLog(LOG1, FL("NDP End rsp sent, transaction id: %d, status: %d, reason: %d"),
+ rsp->transaction_id, rsp->status, rsp->reason);
+ cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+ EXIT();
return;
+
+ndp_end_rsp_nla_failed:
+ hddLog(LOGE, FL("nla_put api failed"));
+ kfree_skb(vendor_event);
+ EXIT();
}
/**
@@ -1506,7 +1648,7 @@ void hdd_ndp_event_handler(hdd_adapter_t *adapter,
break;
case eCSR_ROAM_RESULT_NDP_END_RSP:
hdd_ndp_end_rsp_handler(adapter,
- &roam_info->ndp.ndp_end_rsp_params);
+ roam_info->ndp.ndp_end_rsp_params);
break;
case eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_IND:
hdd_ndp_peer_departed_ind_handler(adapter,
@@ -1581,14 +1723,15 @@ static int __wlan_hdd_cfg80211_process_ndp_cmd(struct wiphy *wiphy,
transaction_id = nla_get_u16(
tb[QCA_WLAN_VENDOR_ATTR_NDP_TRANSACTION_ID]);
- if (!tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
- hddLog(LOGE, FL("Interface name string is unavailable"));
- return -EINVAL;
+ if (tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]) {
+ iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
+ hddLog(LOG2, FL("Transaction Id: %d NDP Cmd: %d iface_name: %s"),
+ transaction_id, ndp_cmd_type, iface_name);
+ } else {
+ hddLog(LOG2,
+ FL("Transaction Id: %d NDP Cmd: %d iface_name: unspecified"),
+ transaction_id, ndp_cmd_type);
}
- iface_name = nla_data(tb[QCA_WLAN_VENDOR_ATTR_NDP_IFACE_STR]);
-
- hddLog(LOG2, FL("Transaction Id: %d NDP Cmd: %d iface_name: %s"),
- transaction_id, ndp_cmd_type, iface_name);
switch (ndp_cmd_type) {
case QCA_WLAN_VENDOR_ATTR_NDP_INTERFACE_CREATE:
diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.h b/CORE/HDD/src/wlan_hdd_nan_datapath.h
index 3a36427f1236..2170d1222af8 100644
--- a/CORE/HDD/src/wlan_hdd_nan_datapath.h
+++ b/CORE/HDD/src/wlan_hdd_nan_datapath.h
@@ -39,6 +39,7 @@ struct wireless_dev;
#define NDP_APP_INFO_LEN 255
#define NDP_QOS_INFO_LEN 255
+#define NDP_NUM_INSTANCE_ID 255
#define HDD_MAX_NUM_NDP_STA (HDD_MAX_NUM_IBSS_STA)
@@ -187,17 +188,14 @@ enum nan_datapath_state {
* @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
- * @conn_info: NDP connection info
- * @roam_info: NDP roam info
- * @gtk_offload_req_params: GTK offload request params
* @ndp_key_installed: NDP security key installed
* @ndp_enc_key: NDP encryption key info
* @ndp_debug_state: debug state info
*/
struct nan_datapath_ctx {
enum nan_datapath_state state;
- uint32_t active_ndp_sessions;
+ /* idx in following array should follow conn_info.peerMacAddress */
+ uint32_t active_ndp_sessions[HDD_MAX_NUM_NDP_STA];
uint32_t active_ndp_peers;
uint16_t ndp_create_transaction_id;
uint16_t ndp_delete_transaction_id;
diff --git a/CORE/HDD/src/wlan_hdd_tx_rx.c b/CORE/HDD/src/wlan_hdd_tx_rx.c
index 66ab1d251c1a..29bdfe094216 100644
--- a/CORE/HDD/src/wlan_hdd_tx_rx.c
+++ b/CORE/HDD/src/wlan_hdd_tx_rx.c
@@ -774,6 +774,29 @@ VOS_STATUS hdd_get_peer_sta_id(hdd_station_ctx_t *sta_ctx,
}
/**
+ * hdd_get_peer_idx() - Get the idx for given address in peer table
+ * @sta_ctx: pointer to HDD Station Context
+ * @addr: pointer to Peer Mac address
+ *
+ * Return: index when success else INVALID_PEER_IDX
+ */
+int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *addr)
+{
+ uint8_t idx;
+
+ for (idx = 0; idx < HDD_MAX_NUM_IBSS_STA; idx++) {
+ if (sta_ctx->conn_info.staId[idx] == 0)
+ continue;
+ if (!vos_mem_compare(&sta_ctx->conn_info.peerMacAddress[idx],
+ addr, sizeof(v_MACADDR_t)))
+ continue;
+ return idx;
+ }
+
+ return INVALID_PEER_IDX;
+}
+
+/**
* wlan_display_tx_timeout_stats() - HDD tx timeout stats display handler
* @adapter: hdd adapter
*
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 7bda8cfa07ce..3d600e757c9e 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -7208,16 +7208,14 @@ struct ndp_confirm_event {
/**
* struct ndp_end_req - ndp end request
* @transaction_id: unique transaction identifier
- * @vdev_id: session id of the interface over which ndp is being created
* @num_ndp_instances: number of ndp instances to be terminated
- * @ndp_instances: list of ndp instances to be terminated
+ * @ndp_ids: pointer to array of ndp_instance_id to be terminated
*
*/
struct ndp_end_req {
uint32_t transaction_id;
- uint32_t vdev_id;
uint32_t num_ndp_instances;
- uint32_t ndp_instances[];
+ uint32_t *ndp_ids;
};
/**
@@ -7236,13 +7234,19 @@ struct peer_ndp_map {
/**
* struct ndp_end_rsp_event - firmware response to ndp end request
* @transaction_id: unique identifier for the request
- * @vdev_id: session id of the interface over which ndp is being created
+ * @status: status of operation
+ * @reason: reason(opaque to host driver)
+ * @num_ndp_terminated: if successful, number of ndp instances terminated
+ * @num_peers: number of peers in ndp_map
* @ndp_map: mapping of NDP instances to peer to VDEV
*
*/
struct ndp_end_rsp_event {
uint32_t transaction_id;
- uint32_t vdev_id;
+ uint32_t status;
+ uint32_t reason;
+ uint32_t num_ndp_terminated;
+ uint32_t num_peers;
struct peer_ndp_map ndp_map[];
};
diff --git a/CORE/MAC/inc/wniApi.h b/CORE/MAC/inc/wniApi.h
index 2a85a40b7e33..9a26f210ab0e 100644
--- a/CORE/MAC/inc/wniApi.h
+++ b/CORE/MAC/inc/wniApi.h
@@ -414,6 +414,7 @@ enum eWniMsgTypes
eWNI_SME_NDP_INDICATION,
eWNI_SME_NDP_RESPONDER_REQ,
eWNI_SME_NDP_RESPONDER_RSP,
+ eWNI_SME_NDP_END_REQ,
eWNI_SME_NDP_END_RSP,
eWNI_SME_NDP_PEER_DEPARTED_IND,
eWNI_SME_NDP_END_IND,
diff --git a/CORE/MAC/src/include/sirParams.h b/CORE/MAC/src/include/sirParams.h
index 59fe800d2ec8..19ddfcce691c 100644
--- a/CORE/MAC/src/include/sirParams.h
+++ b/CORE/MAC/src/include/sirParams.h
@@ -773,8 +773,7 @@ typedef struct sSirMbMsgP2p
#define SIR_HAL_NDP_INDICATION (SIR_HAL_ITC_MSG_TYPES_BEGIN + 356)
#define SIR_HAL_NDP_CONFIRM (SIR_HAL_ITC_MSG_TYPES_BEGIN + 357)
#define SIR_HAL_NDP_END_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 358)
-#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 359)
-
+#define SIR_HAL_SEND_FREQ_RANGE_CONTROL_IND (SIR_HAL_ITC_MSG_TYPES_BEGIN + 359)
#define SIR_BTC_BT_WLAN_INTERVAL_CMD (SIR_HAL_ITC_MSG_TYPES_BEGIN + 360)
#define SIR_HAL_MSG_TYPES_END (SIR_HAL_MSG_TYPES_BEGIN + 0x1FF)
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index ff93a9ef8002..4e4b3cc81620 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -1459,6 +1459,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
case eWNI_SME_REGISTER_MGMT_FRAME_CB:
case eWNI_SME_NDP_INITIATOR_REQ:
case eWNI_SME_NDP_RESPONDER_REQ:
+ case eWNI_SME_NDP_END_REQ:
// These messages are from HDD
limProcessNormalHddMsg(pMac, limMsg, false); //no need to response to hdd
break;
@@ -2209,6 +2210,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
case SIR_HAL_NDP_INDICATION:
case SIR_HAL_NDP_CONFIRM:
case SIR_HAL_NDP_RESPONDER_RSP:
+ case SIR_HAL_NDP_END_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 c2199a3c491c..72ec883d197d 100644
--- a/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessSmeReqMessages.c
@@ -6194,6 +6194,7 @@ limProcessSmeReqMessages(tpAniSirGlobal pMac, tpSirMsgQ pMsg)
break;
case eWNI_SME_NDP_INITIATOR_REQ:
case eWNI_SME_NDP_RESPONDER_REQ:
+ case eWNI_SME_NDP_END_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 91afbe5a6ef3..f90a34dbfa01 100644
--- a/CORE/MAC/src/pe/nan/nan_datapath.c
+++ b/CORE/MAC/src/pe/nan/nan_datapath.c
@@ -216,6 +216,21 @@ responder_rsp:
}
/**
+ * lim_ndp_delete_peers() - Delete peers if needed
+ * @mac_ctx: handle to mac context
+ * @ndp_map: peer map of returning ndp end rsp
+ * @num_peers: number of peers remaining after ndp end
+ * This function deletes a peer if there are no active NDPs left with that peer
+ *
+ * Return: None
+ */
+static void lim_ndp_delete_peers(tpAniSirGlobal mac_ctx,
+ struct peer_ndp_map *ndp_map,
+ uint8_t num_peers)
+{
+}
+
+/**
* lim_handle_ndp_event_message() - Handler for NDP events/RSP from WMA
* @mac_ctx: handle to mac structure
* @msg: pointer to message
@@ -237,11 +252,23 @@ VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
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);
+ case SIR_HAL_NDP_END_RSP: {
+ struct ndp_end_rsp_event *ndp_end_rsp = msg->bodyptr;
+ uint32_t rsp_len = sizeof(*ndp_end_rsp);
+
+ if (ndp_end_rsp && ndp_end_rsp->ndp_map) {
+ lim_ndp_delete_peers(mac_ctx, ndp_end_rsp->ndp_map,
+ ndp_end_rsp->num_peers);
+ rsp_len += (ndp_end_rsp->num_peers *
+ sizeof(struct peer_ndp_map));
+ }
+ lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP,
+ msg->bodyptr, rsp_len, msg->bodyval);
break;
}
+ case SIR_HAL_NDP_INDICATION:
+ status = lim_handle_ndp_indication_event(mac_ctx, msg->bodyptr);
+ break;
case SIR_HAL_NDP_RESPONDER_RSP:
status = lim_ndp_responder_rsp_handler(mac_ctx, msg->bodyptr,
msg->bodyval);
@@ -355,6 +382,55 @@ send_failure_rsp:
}
/**
+ * lim_process_sme_ndp_data_end_req() - Handler for eWNI_SME_NDP_END_REQ
+ * from SME.
+ * @mac_ctx: handle to mac context
+ * @sme_msg: ndp data end request msg
+ *
+ * Return: Status of operation
+ */
+VOS_STATUS lim_process_sme_ndp_data_end_req(tpAniSirGlobal mac_ctx,
+ struct sir_sme_ndp_end_req *sme_msg)
+{
+ tSirMsgQ msg;
+ uint32_t len;
+ VOS_STATUS status = VOS_STATUS_SUCCESS;
+
+ if (NULL == sme_msg) {
+ limLog(mac_ctx, LOGE, FL("invalid ndp_req"));
+ /* msg to unblock SME, but not send rsp to HDD */
+ lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP, NULL,
+ 0, true);
+ return VOS_STATUS_E_INVAL;
+ }
+
+ msg.type = SIR_HAL_NDP_END_REQ;
+ msg.reserved = 0;
+ len = sizeof(*sme_msg->req) + (sme_msg->req->num_ndp_instances *
+ sizeof(uint32_t));
+ msg.bodyptr = vos_mem_malloc(len);
+ if (NULL == msg.bodyptr) {
+ /* msg to unblock SME, but not send rsp to HDD */
+ lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_RSP, NULL,
+ 0, true);
+ return VOS_STATUS_E_NOMEM;
+ }
+ vos_mem_copy(msg.bodyptr, sme_msg->req, len);
+ msg.bodyval = 0;
+
+ limLog(mac_ctx, LOG1, FL("sending SIR_HAL_NDP_END_REQ to WMA"));
+ MTRACE(macTraceMsgTx(mac_ctx, NO_SESSION, msg.type));
+
+ if (eSIR_SUCCESS != wdaPostCtrlMsg(mac_ctx, &msg)) {
+ limLog(mac_ctx, LOGE,
+ FL("Post msg failed for SIR_HAL_NDP_END_REQ"));
+ status = VOS_STATUS_E_FAILURE;
+ }
+
+ return status;
+}
+
+/**
* lim_handle_ndp_request_message() - Handler for NDP req from SME
* @mac_ctx: handle to mac structure
* @msg: pointer to message
@@ -367,6 +443,10 @@ VOS_STATUS lim_handle_ndp_request_message(tpAniSirGlobal mac_ctx,
VOS_STATUS status;
switch (msg->type) {
+ case eWNI_SME_NDP_END_REQ:
+ status = lim_process_sme_ndp_data_end_req(mac_ctx,
+ msg->bodyptr);
+ break;
case eWNI_SME_NDP_INITIATOR_REQ:
status = lim_process_sme_ndp_initiator_req(mac_ctx,
msg->bodyptr);
diff --git a/CORE/SERVICES/WMA/wma.c b/CORE/SERVICES/WMA/wma.c
index 305bebd3d5a0..f218d704c3ee 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -30134,6 +30134,10 @@ VOS_STATUS wma_mc_process_msg(v_VOID_t *vos_context, vos_msg_t *msg)
wma_handle_ndp_responder_req(wma_handle, msg->bodyptr);
vos_mem_free(msg->bodyptr);
break;
+ case SIR_HAL_NDP_END_REQ:
+ wma_handle_ndp_end_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 ee418e8d586c..eec905f3b7bf 100644
--- a/CORE/SERVICES/WMA/wma_nan_datapath.c
+++ b/CORE/SERVICES/WMA/wma_nan_datapath.c
@@ -330,14 +330,91 @@ send_ndi_responder_fail:
/**
* wma_handle_ndp_end_req() - NDP end request handler
* @wma_handle: wma handle
- * @req_params: request parameters
+ * @ptr: request parameters
*
* Return: VOS_STATUS_SUCCESS on success; error number otherwise
*/
-VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle,
- struct ndp_end_req *req_params)
+VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, void *ptr)
{
+ int ret;
+ uint16_t len;
+ uint32_t ndp_end_req_len, i;
+ wmi_ndp_end_req *ndp_end_req_lst;
+ wmi_buf_t buf;
+ vos_msg_t pe_msg = {0};
+ wmi_ndp_end_req_fixed_param *cmd;
+ struct ndp_end_rsp_event *end_rsp = NULL;
+ struct ndp_end_req *req = ptr;
+
+ if (NULL == req) {
+ WMA_LOGE(FL("Invalid ndp_end_req"));
+ goto send_ndp_end_fail;
+ }
+
+ /* len of tlv following fixed param */
+ ndp_end_req_len = sizeof(wmi_ndp_end_req) * req->num_ndp_instances;
+ /* above comes out to 4 byte alligned already, no need of padding */
+ len = sizeof(*cmd) + ndp_end_req_len + WMI_TLV_HDR_SIZE;
+ buf = wmi_buf_alloc(wma_handle->wmi_handle, len);
+ if (!buf) {
+ WMA_LOGE(FL("Malloc failed"));
+ return VOS_STATUS_E_NOMEM;
+ }
+ cmd = (wmi_ndp_end_req_fixed_param *) wmi_buf_data(buf);
+
+ WMITLV_SET_HDR(&cmd->tlv_header,
+ WMITLV_TAG_STRUC_wmi_ndp_end_req_fixed_param,
+ WMITLV_GET_STRUCT_TLVLEN(wmi_ndp_end_req_fixed_param));
+
+ cmd->transaction_id = req->transaction_id;
+
+ /* set tlv pointer to end of fixed param */
+ WMITLV_SET_HDR((uint8_t *)&cmd[1], WMITLV_TAG_ARRAY_STRUC,
+ ndp_end_req_len);
+
+ ndp_end_req_lst = (wmi_ndp_end_req *)((uint8_t *)&cmd[1] +
+ WMI_TLV_HDR_SIZE);
+ for (i = 0; i < req->num_ndp_instances; i++) {
+ WMITLV_SET_HDR(&ndp_end_req_lst[i],
+ WMITLV_TAG_ARRAY_FIXED_STRUC,
+ (sizeof(*ndp_end_req_lst) - WMI_TLV_HDR_SIZE));
+
+ ndp_end_req_lst[i].ndp_instance_id = req->ndp_ids[i];
+ }
+
+ WMA_LOGD(FL("Sending WMI_NDP_END_REQ_CMDID to FW"));
+ ret = wmi_unified_cmd_send(wma_handle->wmi_handle, buf, len,
+ WMI_NDP_END_REQ_CMDID);
+ if (ret < 0) {
+ WMA_LOGE(FL("WMI_NDP_END_REQ_CMDID failed, ret: %d"), ret);
+ wmi_buf_free(buf);
+ goto send_ndp_end_fail;
+ }
return VOS_STATUS_SUCCESS;
+
+send_ndp_end_fail:
+ pe_msg.type = SIR_HAL_NDP_END_RSP;
+ if (req) {
+ end_rsp = vos_mem_malloc(sizeof(*end_rsp));
+ if (NULL == end_rsp) {
+ WMA_LOGE(FL("Malloc failed"));
+ pe_msg.bodyval = true;
+ } else {
+ vos_mem_zero(end_rsp, sizeof(*end_rsp));
+ end_rsp->status = NDP_CMD_RSP_STATUS_ERROR;
+ end_rsp->transaction_id = req->transaction_id;
+ pe_msg.bodyptr = end_rsp;
+ }
+ } else {
+ pe_msg.bodyval = true;
+ }
+
+ if (VOS_STATUS_SUCCESS !=
+ vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg)) {
+ WMA_LOGE("NDP_END_RSP to PE failed");
+ vos_mem_free(end_rsp);
+ }
+ return VOS_STATUS_E_FAILURE;
}
/**
@@ -375,20 +452,6 @@ static int wma_ndp_indication_event_handler(void *handle, uint8_t *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"));
@@ -406,6 +469,21 @@ static int wma_ndp_indication_event_handler(void *handle, uint8_t *event_info,
WMI_MAC_ADDR_TO_CHAR_ARRAY(&fixed_params->peer_discovery_mac_addr,
ind_event->peer_discovery_mac_addr.bytes);
+ WMA_LOGD(FL("WMI_NDP_INDICATION_EVENTID(0x%X) received. vdev %d, service_instance %d, ndp_instance %d, role %d, policy %d, peer_mac_addr: %pM, peer_disc_mac_addr: %pM"),
+ 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,
+ ind_event->peer_mac_addr.bytes,
+ ind_event->peer_discovery_mac_addr.bytes);
+
+ 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->ndp_config.ndp_cfg_len = fixed_params->ndp_cfg_len;
ind_event->ndp_info.ndp_app_info_len = fixed_params->ndp_app_info_len;
@@ -583,7 +661,73 @@ static int wma_ndp_confirm_event_handler(void *handle, uint8_t *event_info,
static int wma_ndp_end_response_event_handler(void *handle,
uint8_t *event_info, uint32_t len)
{
- return 0;
+ int ret = 0;
+ VOS_STATUS status;
+ vos_msg_t pe_msg = {0};
+ struct ndp_end_rsp_event *end_rsp;
+ WMI_NDP_END_RSP_EVENTID_param_tlvs *event;
+ wmi_ndp_end_rsp_event_fixed_param *fixed_params = NULL;
+ wmi_ndp_end_rsp_per_ndi *end_rsp_tlv;
+ uint32_t i;
+ uint32_t len_end_rsp;
+
+ event = (WMI_NDP_END_RSP_EVENTID_param_tlvs *) event_info;
+ fixed_params = (wmi_ndp_end_rsp_event_fixed_param *)event->fixed_param;
+ WMA_LOGD(FL("WMI_NDP_END_RSP_EVENTID(0x%X) recieved. transaction_id: %d, rsp_status: %d, reason_code: %d"),
+ WMI_NDP_END_RSP_EVENTID, fixed_params->transaction_id,
+ fixed_params->rsp_status, fixed_params->reason_code);
+
+ len_end_rsp = sizeof(*end_rsp) + (event->num_ndp_end_rsp_per_ndi_list *
+ sizeof(struct peer_ndp_map));
+ end_rsp = vos_mem_malloc(len_end_rsp);
+ if (NULL == end_rsp) {
+ WMA_LOGE("malloc failed");
+ pe_msg.bodyval = true;
+ ret = -ENOMEM;
+ goto send_ndp_end_rsp;
+ }
+ pe_msg.bodyptr = end_rsp;
+ vos_mem_zero(end_rsp, len_end_rsp);
+
+ end_rsp->transaction_id = fixed_params->transaction_id;
+ end_rsp->reason = fixed_params->reason_code;
+ end_rsp->status = fixed_params->rsp_status;
+
+ if (end_rsp->status == NDP_CMD_RSP_STATUS_SUCCESS) {
+ WMA_LOGD(FL("NDP end rsp, num_peers: %d"),
+ event->num_ndp_end_rsp_per_ndi_list);
+ end_rsp->num_peers = event->num_ndp_end_rsp_per_ndi_list;
+ if (end_rsp->num_peers == 0) {
+ WMA_LOGE(FL("num_peers in NDP rsp should not be 0."));
+ end_rsp->status = NDP_CMD_RSP_STATUS_ERROR;
+ goto send_ndp_end_rsp;
+ }
+ /* copy per peer response to return path buffer */
+ end_rsp_tlv = event->ndp_end_rsp_per_ndi_list;
+ for (i = 0; i < end_rsp->num_peers; i++) {
+ end_rsp->ndp_map[i].vdev_id = end_rsp_tlv[i].vdev_id;
+ WMI_MAC_ADDR_TO_CHAR_ARRAY(&end_rsp_tlv[i].peer_mac_addr,
+ end_rsp->ndp_map[i].peer_ndi_mac_addr.bytes);
+ end_rsp->ndp_map[i].num_active_ndp_sessions =
+ end_rsp_tlv[i].num_active_ndps_on_ndi;
+ WMA_LOGD(FL("vdev_id: %d, peer_addr: %pM, active_ndp_left: %d"),
+ end_rsp->ndp_map[i].vdev_id,
+ &end_rsp->ndp_map[i].peer_ndi_mac_addr,
+ end_rsp->ndp_map[i].num_active_ndp_sessions);
+ }
+ }
+
+send_ndp_end_rsp:
+ pe_msg.type = SIR_HAL_NDP_END_RSP;
+ WMA_LOGD(FL("Sending SIR_HAL_NDP_END_RSP msg to PE"));
+ status = vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg);
+ if (!VOS_IS_STATUS_SUCCESS(status)) {
+ WMA_LOGE("SIR_HAL_NDP_END_RSP to PE failed");
+ vos_mem_free(end_rsp);
+ ret = -EINVAL;
+ }
+
+ return ret;
}
/**
diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.h b/CORE/SERVICES/WMA/wma_nan_datapath.h
index a639f394cdfa..9da9f2eef732 100644
--- a/CORE/SERVICES/WMA/wma_nan_datapath.h
+++ b/CORE/SERVICES/WMA/wma_nan_datapath.h
@@ -58,6 +58,7 @@ 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);
+VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle, void *req);
#else
static inline void wma_add_bss_ndi_mode(tp_wma_handle wma,
tpAddBssParams add_bss) {}
@@ -85,6 +86,11 @@ static inline VOS_STATUS wma_handle_ndp_responder_req(tp_wma_handle wma_handle,
{
return VOS_STATUS_SUCCESS;
}
+static inline VOS_STATUS wma_handle_ndp_end_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 02e63d503838..447f3cf73c90 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1476,7 +1476,7 @@ typedef struct tagCsrRoamInfo
struct sme_ndp_peer_ind ndp_peer_ind_params;
struct ndp_schedule_update_rsp ndp_sched_upd_rsp_params;
struct ndp_end_indication_event ndp_end_ind_params;
- struct ndp_end_rsp_event ndp_end_rsp_params;
+ struct ndp_end_rsp_event *ndp_end_rsp_params;
struct ndp_confirm_event ndp_confirm_params;
struct ndp_responder_rsp_event ndp_responder_rsp_params;
struct ndp_indication_event ndp_indication_params;
diff --git a/CORE/SME/inc/smeInside.h b/CORE/SME/inc/smeInside.h
index e0de898cc3b1..e8693b6cf406 100644
--- a/CORE/SME/inc/smeInside.h
+++ b/CORE/SME/inc/smeInside.h
@@ -217,6 +217,7 @@ typedef struct tagSmeCmd
#ifdef WLAN_FEATURE_NAN_DATAPATH
struct ndp_initiator_req initiator_req;
struct ndp_responder_req responder_req;
+ struct ndp_end_req *data_end_req;
#endif
}u;
}tSmeCmd;
diff --git a/CORE/SME/inc/smeInternal.h b/CORE/SME/inc/smeInternal.h
index 46e4fab07b2d..edcdd4f450ad 100644
--- a/CORE/SME/inc/smeInternal.h
+++ b/CORE/SME/inc/smeInternal.h
@@ -100,6 +100,7 @@ typedef enum eSmeCommandType
eSmeCommandNoAUpdate,
eSmeCommandNdpInitiatorRequest,
eSmeCommandNdpResponderRequest,
+ eSmeCommandNdpDataEndInitiatorRequest,
} eSmeCommandType;
diff --git a/CORE/SME/inc/sme_nan_datapath.h b/CORE/SME/inc/sme_nan_datapath.h
index bec7ed381d62..30b0a00a8516 100644
--- a/CORE/SME/inc/sme_nan_datapath.h
+++ b/CORE/SME/inc/sme_nan_datapath.h
@@ -63,6 +63,19 @@ struct sir_sme_ndp_responder_req {
struct ndp_responder_req req;
};
+/**
+ * struct sir_sme_ndp_end_req - sme request struct for ndp end req
+ * @msg_type: SME msg type(sir_sme_ndp_initiator_req)
+ * @msg_len: lenght of message
+ * @req: actual ndp initiator request
+ *
+ */
+struct sir_sme_ndp_end_req {
+ uint16_t msg_type;
+ uint16_t msg_len;
+ struct ndp_end_req *req;
+};
+
/* NaN initiator request handler */
eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal,
struct ndp_initiator_req *req_params);
@@ -72,8 +85,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal,
struct ndp_responder_req *req_params);
/* NaN indication response handler */
-VOS_STATUS sme_ndp_end_req_handler(uint32_t session_id,
- struct ndp_end_req *req_params);
+VOS_STATUS sme_ndp_end_req_handler(tHalHandle hal, struct ndp_end_req *req);
/* NaN schedule update request handler */
VOS_STATUS sme_ndp_sched_req_handler(uint32_t session_id,
@@ -106,6 +118,8 @@ void csr_roam_update_ndp_return_params(tpAniSirGlobal mac_ctx,
void *roam_info);
eHalStatus csr_process_ndp_initiator_request(tpAniSirGlobal mac_ctx,
tSmeCmd *cmd);
+eHalStatus csr_process_ndp_data_end_request(tpAniSirGlobal mac_ctx,
+ tSmeCmd *cmd);
void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg);
@@ -161,6 +175,13 @@ static inline eHalStatus csr_process_ndp_responder_request(
{
return eHAL_STATUS_SUCCESS;
}
+
+static inline eHalStatus csr_process_ndp_data_end_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 0a183c676cdd..9fbb9660c590 100644
--- a/CORE/SME/src/nan/nan_datapath_api.c
+++ b/CORE/SME/src/nan/nan_datapath_api.c
@@ -84,6 +84,7 @@ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal,
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) {
+ csrReleaseCommandRoam(mac_ctx, cmd);
sme_ReleaseGlobalLock(&mac_ctx->sme);
vos_mem_free(
cmd->u.initiator_req.ndp_info.ndp_app_info);
@@ -103,6 +104,7 @@ eHalStatus sme_ndp_initiator_req_handler(tHalHandle hal,
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;
+ csrReleaseCommandRoam(mac_ctx, cmd);
}
sme_ReleaseGlobalLock(&mac_ctx->sme);
@@ -156,6 +158,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal,
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) {
+ csrReleaseCommandRoam(mac_ctx, cmd);
sme_ReleaseGlobalLock(&mac_ctx->sme);
return eHAL_STATUS_FAILED_ALLOC;
}
@@ -168,6 +171,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal,
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) {
+ csrReleaseCommandRoam(mac_ctx, cmd);
sme_ReleaseGlobalLock(&mac_ctx->sme);
vos_mem_free(
cmd->u.responder_req.ndp_info.ndp_app_info);
@@ -187,6 +191,7 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal,
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;
+ csrReleaseCommandRoam(mac_ctx, cmd);
}
sme_ReleaseGlobalLock(&mac_ctx->sme);
return status;
@@ -194,17 +199,63 @@ eHalStatus sme_ndp_responder_req_handler(tHalHandle hal,
/**
* sme_ndp_end_req_handler() - ndp end request handler
- * @session_id: session id over which the ndp is being created
- * @req_params: request parameters
+ * @hal: hal handle
+ * @req: ndp end request parameters
*
* Return: VOS_STATUS_SUCCESS on success; error number otherwise
*/
-VOS_STATUS sme_ndp_end_req_handler(uint32_t session_id,
- struct ndp_end_req *req_params)
+VOS_STATUS sme_ndp_end_req_handler(tHalHandle hal, struct ndp_end_req *req)
{
- return VOS_STATUS_SUCCESS;
-}
+ tSmeCmd *cmd;
+ VOS_STATUS ret = VOS_STATUS_SUCCESS;
+ eHalStatus status = eHAL_STATUS_SUCCESS;
+ tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+ if (NULL == req) {
+ smsLog(mac_ctx, LOGE, FL("Invalid ndp end req"));
+ return VOS_STATUS_E_INVAL;
+ }
+
+ status = sme_AcquireGlobalLock(&mac_ctx->sme);
+ if (eHAL_STATUS_SUCCESS != status) {
+ smsLog(mac_ctx, LOGE,
+ FL("SME lock failed, status:%d"), status);
+ return VOS_STATUS_E_RESOURCES;
+ }
+ cmd = csrGetCommandBuffer(mac_ctx);
+ if (NULL == cmd) {
+ sme_ReleaseGlobalLock(&mac_ctx->sme);
+ return VOS_STATUS_E_RESOURCES;
+ }
+
+ cmd->command = eSmeCommandNdpDataEndInitiatorRequest;
+ cmd->u.data_end_req = vos_mem_malloc(sizeof(*req) +
+ (req->num_ndp_instances * sizeof(uint32)));
+ if (NULL == cmd->u.data_end_req) {
+ csrReleaseCommandRoam(mac_ctx, cmd);
+ sme_ReleaseGlobalLock(&mac_ctx->sme);
+ return VOS_STATUS_E_NOMEM;
+ }
+
+ vos_mem_copy(cmd->u.data_end_req, req, sizeof(*req));
+ cmd->u.data_end_req->ndp_ids =
+ (uint32_t *)((uint8_t *)&cmd->u.data_end_req[1]);
+ vos_mem_copy(cmd->u.data_end_req->ndp_ids, req->ndp_ids,
+ sizeof(uint32_t) * req->num_ndp_instances);
+
+ 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.data_end_req);
+ cmd->u.data_end_req = NULL;
+ ret = VOS_STATUS_E_FAILURE;
+ csrReleaseCommandRoam(mac_ctx, cmd);
+ }
+
+ sme_ReleaseGlobalLock(&mac_ctx->sme);
+ return ret;
+}
/**
* sme_ndp_sched_req_handler() - ndp schedule request handler
@@ -493,6 +544,46 @@ free_config:
}
/**
+ * csr_process_ndp_data_end_request() - process ndp data end request
+ * @mac_ctx: Global MAC context
+ * @cmd: sme command containing ndp initiator request
+ *
+ * Return: status of operation
+ */
+eHalStatus csr_process_ndp_data_end_request(tpAniSirGlobal mac_ctx,
+ tSmeCmd *cmd)
+{
+ eHalStatus status;
+ struct sir_sme_ndp_end_req *lim_msg;
+ uint16_t msg_len;
+
+ if (NULL == cmd) {
+ smsLog(mac_ctx, LOGE, FL("NULL sme cmd"));
+ return eHAL_STATUS_INVALID_PARAMETER;
+ }
+
+ msg_len = sizeof(*lim_msg);
+ lim_msg = vos_mem_malloc(msg_len);
+ if (NULL == lim_msg) {
+ smsLog(mac_ctx, LOGE, FL("Malloc failed"));
+ vos_mem_free(cmd->u.data_end_req);
+ cmd->u.data_end_req = NULL;
+ return eHAL_STATUS_FAILED_ALLOC;
+ }
+
+ lim_msg->msg_type = (uint16_t)eWNI_SME_NDP_END_REQ;
+ lim_msg->msg_len = msg_len;
+ lim_msg->req = cmd->u.data_end_req;
+
+ status = palSendMBMessage(mac_ctx->hHdd, lim_msg);
+ if (status != eHAL_STATUS_SUCCESS) {
+ vos_mem_free(cmd->u.data_end_req);
+ cmd->u.data_end_req = 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
@@ -514,6 +605,10 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg)
eSmeCommandType cmd_to_rel = eSmeNoCommand;
bool send_to_user = true;
+ entry = csrLLPeekHead(&mac_ctx->sme.smeCmdActiveList, LL_ACCESS_LOCK);
+ if (entry != NULL)
+ cmd = GET_BASE_ADDR(entry, tSmeCmd, Link);
+
switch (msg->type) {
case eWNI_SME_NDP_CONFIRM_IND: {
result = eCSR_ROAM_RESULT_NDP_CONFIRM_IND;
@@ -573,6 +668,31 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg)
release_active_cmd = true;
cmd_to_rel = eSmeCommandNdpResponderRequest;
break;
+ case eWNI_SME_NDP_END_RSP: {
+ if (true == msg->bodyval) {
+ /* rsp was locally generated, do not send to HDD */
+ send_to_user = false;
+ } else {
+ result = eCSR_ROAM_RESULT_NDP_END_RSP;
+ roam_info.ndp.ndp_end_rsp_params = msg->bodyptr;
+ /*
+ * NDP_END_IND is independent of session, but session_id
+ * is needed for csrRoamCallCallback(). Set it to 0
+ * which is a valid session.
+ */
+ session_id = 0;
+ }
+ release_active_cmd = true;
+ cmd_to_rel = eSmeCommandNdpDataEndInitiatorRequest;
+ /*
+ * get num of ndp requested to terminated from sme command
+ * being released
+ */
+ if (cmd != NULL && cmd_to_rel == cmd->command)
+ roam_info.ndp.ndp_end_rsp_params->num_ndp_terminated =
+ cmd->u.data_end_req->num_ndp_instances;
+ break;
+ }
default:
smsLog(mac_ctx, LOGE, FL("Unhandled NDP rsp"));
vos_mem_free(msg->bodyptr);
@@ -584,39 +704,25 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg)
eCSR_ROAM_NDP_STATUS_UPDATE, result);
}
+ vos_mem_free(msg->bodyptr);
+ msg->bodyptr = NULL;
/* 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);
- }
+ if (cmd && 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);
- }
+ if (cmd && 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:
@@ -624,21 +730,19 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg)
roam_info.ndp.ndp_indication_params.ndp_config.ndp_cfg);
vos_mem_free(
roam_info.ndp.ndp_indication_params.
- ndp_info.ndp_app_info);
+ ndp_info.ndp_app_info);
+ break;
+ case eWNI_SME_NDP_END_RSP:
+ if (cmd &&
+ eSmeCommandNdpDataEndInitiatorRequest == cmd->command) {
+ vos_mem_free(cmd->u.data_end_req);
+ cmd->u.data_end_req = NULL;
+ }
break;
default:
break;
}
- 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) {
+ if (release_active_cmd && cmd && 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))
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index bc5accf79c4b..4428ddca9b2c 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -1053,6 +1053,17 @@ sme_process_cmd:
csrReleaseCommand(pMac, pCommand);
}
break;
+ case eSmeCommandNdpDataEndInitiatorRequest:
+ csrLLUnlock(&pMac->sme.smeCmdActiveList);
+ status = csr_process_ndp_data_end_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 );
@@ -3381,6 +3392,7 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg)
case eWNI_SME_NDP_INITIATOR_RSP:
case eWNI_SME_NDP_INDICATION:
case eWNI_SME_NDP_RESPONDER_RSP:
+ case eWNI_SME_NDP_END_RSP:
sme_ndp_msg_processor(pMac, pMsg);
break;
default: