summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDeepak Dhamdhere <ddhamdhe@qca.qualcomm.com>2016-03-07 00:14:47 -0800
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-04-28 16:45:21 +0530
commit9141bca8871acf737251e31ab220e19221bca72c (patch)
treee28f002c3403c142c6754a9a72fc13d72c9ae380
parent8ef2ea33ad2b624a653838ba84a9b79305ccd4c3 (diff)
qcacld-2.0: Process NDP data end indication
Firmware sends an array of: {ndp instance id, vdev id, active ndp num, peer mac address} for the NDP instances that are to be terminated. Host driver deletes the peers that have 0 active ndp instances and sends the entire list of ndp instance id's to the service layer. Change-Id: I325843ce7fb8198466cb66ce66710cef999d4581 CRs-Fixed: 962367
-rw-r--r--CORE/HDD/inc/wlan_hdd_assoc.h5
-rw-r--r--CORE/HDD/src/wlan_hdd_assoc.c32
-rw-r--r--CORE/HDD/src/wlan_hdd_nan_datapath.c109
-rw-r--r--CORE/MAC/inc/sirApi.h42
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMessageQueue.c1
-rw-r--r--CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c27
-rw-r--r--CORE/MAC/src/pe/nan/nan_datapath.c190
-rw-r--r--CORE/MAC/src/pe/nan/nan_datapath.h8
-rw-r--r--CORE/SERVICES/WMA/wma.c5
-rw-r--r--CORE/SERVICES/WMA/wma_nan_datapath.c114
-rw-r--r--CORE/SERVICES/WMA/wma_nan_datapath.h7
-rw-r--r--CORE/SME/inc/csrApi.h2
-rw-r--r--CORE/SME/src/nan/nan_datapath_api.c23
-rw-r--r--CORE/SME/src/sme_common/sme_Api.c2
14 files changed, 538 insertions, 29 deletions
diff --git a/CORE/HDD/inc/wlan_hdd_assoc.h b/CORE/HDD/inc/wlan_hdd_assoc.h
index 6a1c0dacac39..26feb4442270 100644
--- a/CORE/HDD/inc/wlan_hdd_assoc.h
+++ b/CORE/HDD/inc/wlan_hdd_assoc.h
@@ -182,4 +182,9 @@ VOS_STATUS hdd_roamRegisterSTA(hdd_adapter_t *adapter, tCsrRoamInfo *roam_info,
bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id,
v_MACADDR_t *peer_mac_addr);
+void hdd_delete_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id);
+
+int hdd_get_peer_idx(hdd_station_ctx_t *sta_ctx, v_MACADDR_t *addr);
+VOS_STATUS hdd_roamDeregisterSTA(hdd_adapter_t *adapter, uint8_t sta_id);
+
#endif
diff --git a/CORE/HDD/src/wlan_hdd_assoc.c b/CORE/HDD/src/wlan_hdd_assoc.c
index df910fbbf867..e2d0c41bb86d 100644
--- a/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/CORE/HDD/src/wlan_hdd_assoc.c
@@ -895,8 +895,15 @@ static void hdd_connRemoveConnectInfo(hdd_station_ctx_t *pHddStaCtx)
vos_mem_zero( &pHddStaCtx->conn_info.SSID, sizeof( tCsrSSIDInfo ) );
}
-/* TODO Revisit this function. and data path */
-static VOS_STATUS hdd_roamDeregisterSTA( hdd_adapter_t *pAdapter, tANI_U8 staId )
+
+/**
+ * hdd_roamDeregisterSTA() - Deregister STA from data path
+ * @pAdapter - HDD context
+ * @staId - Station ID
+ *
+ * Return: 0 or VOS_STATUS error code
+ */
+VOS_STATUS hdd_roamDeregisterSTA(hdd_adapter_t *pAdapter, tANI_U8 staId)
{
VOS_STATUS vosStatus;
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
@@ -2417,6 +2424,27 @@ bool hdd_save_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id,
return false;
}
+/**
+ * hdd_delete_peer() - removes peer from hdd station context peer table
+ * @sta_ctx: pointer to hdd station context
+ * @sta_id: station ID
+ *
+ * Return: none
+ */
+void hdd_delete_peer(hdd_station_ctx_t *sta_ctx, uint8_t sta_id)
+{
+ int i;
+
+ for (i = 0; i < HDD_MAX_NUM_IBSS_STA; i++) {
+ if (sta_id == sta_ctx->conn_info.staId[i]) {
+ sta_ctx->conn_info.staId[i] = 0;
+ return;
+ }
+ }
+
+ hddLog(LOGE, FL("sta_id %d is not present in peer table"), sta_id);
+}
+
/**============================================================================
*
@brief roamRemoveIbssStation() - Remove the IBSS peer MAC address in the adapter.
diff --git a/CORE/HDD/src/wlan_hdd_nan_datapath.c b/CORE/HDD/src/wlan_hdd_nan_datapath.c
index cb227e129984..68374125de09 100644
--- a/CORE/HDD/src/wlan_hdd_nan_datapath.c
+++ b/CORE/HDD/src/wlan_hdd_nan_datapath.c
@@ -1145,16 +1145,32 @@ static void hdd_ndp_new_peer_ind_handler(hdd_adapter_t *adapter,
EXIT();
}
/**
- * hdd_ndp_peer_departed_ind_handler() - NDP peer departed indication handler
+ * hdd_ndp_peer_departed_ind_handler() - Handle NDP peer departed indication
* @adapter: pointer to adapter context
* @ind_params: indication parameters
*
* Return: none
*/
-static void hdd_ndp_peer_departed_ind_handler(
- hdd_adapter_t *adapter, void *ind_params)
+static void hdd_ndp_peer_departed_ind_handler(hdd_adapter_t *adapter,
+ void *ind_params)
{
- return;
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ struct sme_ndp_peer_ind *peer_ind = ind_params;
+ 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);
+
+ hdd_roamDeregisterSTA(adapter, peer_ind->sta_id);
+ hdd_delete_peer(sta_ctx, peer_ind->sta_id);
+ hdd_ctx->sta_to_adapter[peer_ind->sta_id] = 0;
+
+ if (--ndp_ctx->active_ndp_peers == 0) {
+ hddLog(LOG1, FL("No more ndp peers."));
+ sta_ctx->conn_info.connState = eConnectionState_NdiDisconnected;
+ hdd_connSetConnectionState(adapter,
+ eConnectionState_NdiDisconnected);
+ hddLog(LOG1, FL("Stop netif tx queues."));
+ netif_tx_stop_all_queues(adapter->dev);
+ }
}
/**
@@ -1577,12 +1593,95 @@ ndp_end_rsp_nla_failed:
* @adapter: pointer to adapter context
* @ind_params: indication parameters
*
+ * Following vendor event is sent to cfg80211:
+ * QCA_WLAN_VENDOR_ATTR_NDP_SUBCMD = QCA_WLAN_VENDOR_ATTR_NDP_END_IND (4 bytes)
+ * QCA_WLAN_VENDOR_ATTR_NDP_NUM_INSTANCE_ID (1 byte)
+ * QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY (4 * NUM_INSTANCE_ID bytes)
+ *
* Return: none
*/
static void hdd_ndp_end_ind_handler(hdd_adapter_t *adapter,
void *ind_params)
{
+ struct sk_buff *vendor_event;
+ hdd_context_t *hdd_ctx = WLAN_HDD_GET_CTX(adapter);
+ struct ndp_end_indication_event *end_ind = ind_params;
+ uint32_t data_len, i;
+ 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 *ndp_instance_array;
+
+ ENTER();
+
+ if (!end_ind) {
+ hddLog(LOGE, FL("Invalid ndp end indication"));
+ return;
+ }
+
+ if (0 != wlan_hdd_validate_context(hdd_ctx))
+ return;
+
+ ndp_instance_array = vos_mem_malloc(end_ind->num_ndp_ids *
+ sizeof(*ndp_instance_array));
+ if (!ndp_instance_array) {
+ hddLog(LOGE, "Failed to allocate ndp_instance_array");
+ return;
+ }
+ for (i = 0; i < end_ind->num_ndp_ids; i++) {
+ int idx;
+
+ ndp_instance_array[i] = end_ind->ndp_map[i].ndp_instance_id;
+ ndp_ctx = WLAN_HDD_GET_NDP_CTX_PTR(
+ hdd_get_adapter_by_vdev(hdd_ctx,
+ end_ind->ndp_map[i].vdev_id));
+ idx = hdd_get_peer_idx(sta_ctx,
+ &end_ind->ndp_map[i].peer_ndi_mac_addr);
+ if (idx == INVALID_PEER_IDX) {
+ hddLog(LOGE,
+ FL("can't find addr: %pM in sta_ctx."),
+ &end_ind->ndp_map[i].peer_ndi_mac_addr);
+ continue;
+ }
+ /* save the value of active sessions on each peer */
+ ndp_ctx->active_ndp_sessions[idx] =
+ end_ind->ndp_map[i].num_active_ndp_sessions;
+ }
+
+ data_len = (sizeof(uint32_t)) +
+ sizeof(uint8_t) + NLMSG_HDRLEN + (2 * NLA_HDRLEN) +
+ end_ind->num_ndp_ids * sizeof(*ndp_instance_array);
+
+ 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_IND))
+ goto ndp_end_ind_nla_failed;
+
+ if (nla_put_u8(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_NUM_INSTANCE_ID,
+ end_ind->num_ndp_ids))
+ goto ndp_end_ind_nla_failed;
+
+ if (nla_put(vendor_event, QCA_WLAN_VENDOR_ATTR_NDP_INSTANCE_ID_ARRAY,
+ end_ind->num_ndp_ids * sizeof(*ndp_instance_array),
+ ndp_instance_array))
+ goto ndp_end_ind_nla_failed;
+
+ cfg80211_vendor_event(vendor_event, GFP_KERNEL);
+ vos_mem_free(ndp_instance_array);
+ EXIT();
return;
+
+ndp_end_ind_nla_failed:
+ hddLog(LOGE, FL("nla_put api failed"));
+ kfree_skb(vendor_event);
+ vos_mem_free(ndp_instance_array);
+ EXIT();
}
/**
@@ -1656,7 +1755,7 @@ void hdd_ndp_event_handler(hdd_adapter_t *adapter,
break;
case eCSR_ROAM_RESULT_NDP_END_IND:
hdd_ndp_end_ind_handler(adapter,
- &roam_info->ndp.ndp_end_ind_params);
+ roam_info->ndp.ndp_end_ind_params);
break;
default:
hddLog(LOGE,
diff --git a/CORE/MAC/inc/sirApi.h b/CORE/MAC/inc/sirApi.h
index 3d600e757c9e..acf99ee728d8 100644
--- a/CORE/MAC/inc/sirApi.h
+++ b/CORE/MAC/inc/sirApi.h
@@ -6999,6 +6999,32 @@ enum ndp_response_code {
};
/**
+ * enum ndp_end_type - NDP end type
+ * @NDP_END_TYPE_UNSPECIFIED: type is unspecified
+ * @NDP_END_TYPE_PEER_UNAVAILABLE: type is peer unavailable
+ * @NDP_END_TYPE_OTA_FRAME: type OTA frame
+ *
+ */
+enum ndp_end_type {
+ NDP_END_TYPE_UNSPECIFIED = 0x00,
+ NDP_END_TYPE_PEER_UNAVAILABLE = 0x01,
+ NDP_END_TYPE_OTA_FRAME = 0x02,
+};
+
+/**
+ * enum ndp_end_reason_code - NDP end reason code
+ * @NDP_END_TYPE_UNSPECIFIED: reason is unspecified
+ * @NDP_END_TYPE_PEER_UNAVAILABLE: reason is peer inactivity
+ * @NDP_END_TYPE_OTA_FRAME: reason data end
+ *
+ */
+enum ndp_end_reason_code {
+ NDP_END_REASON_UNSPECIFIED = 0x00,
+ NDP_END_REASON_INACTIVITY = 0x01,
+ NDP_END_REASON_PEER_DATA_END = 0x02,
+};
+
+/**
* struct ndp_cfg - ndp configuration
* @tag: unique identifier
* @ndp_cfg_len: ndp configuration length
@@ -7223,12 +7249,18 @@ struct ndp_end_req {
* @vdev_id: session id of the interface over which ndp is being created
* @peer_ndi_mac_addr: peer NDI mac address
* @num_active_ndp_sessions: number of active NDP sessions on the peer
+ * @type: NDP end indication type
+ * @reason_code: NDP end indication reason code
+ * @ndp_instance_id: NDP instance ID
*
*/
struct peer_ndp_map {
uint32_t vdev_id;
v_MACADDR_t peer_ndi_mac_addr;
uint32_t num_active_ndp_sessions;
+ enum ndp_end_type type;
+ enum ndp_end_reason_code reason_code;
+ uint32_t ndp_instance_id;
};
/**
@@ -7252,16 +7284,12 @@ struct ndp_end_rsp_event {
/**
* struct ndp_end_indication_event - ndp termination notification from FW
- * @vdev_id: session id of the interface over which ndp is being created
- * @reason: reason code for failure if any
- * @status: status of the request
- * @ndp_map: mapping of NDP instances to peer to VDEV
+ * @num_ndp_ids: number of NDP ids
+ * @ndp_map: mapping of NDP instances to peer and vdev
*
*/
struct ndp_end_indication_event {
- uint32_t vdev_id;
- uint32_t status;
- uint32_t reason;
+ uint32_t num_ndp_ids;
struct peer_ndp_map ndp_map[];
};
diff --git a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
index 4e4b3cc81620..74ba1148452d 100644
--- a/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
+++ b/CORE/MAC/src/pe/lim/limProcessMessageQueue.c
@@ -2211,6 +2211,7 @@ limProcessMessages(tpAniSirGlobal pMac, tpSirMsgQ limMsg)
case SIR_HAL_NDP_CONFIRM:
case SIR_HAL_NDP_RESPONDER_RSP:
case SIR_HAL_NDP_END_RSP:
+ case SIR_HAL_NDP_END_IND:
lim_handle_ndp_event_message(pMac, limMsg);
break;
default:
diff --git a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
index ec7e2277bcc2..4af824983398 100644
--- a/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
+++ b/CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c
@@ -2316,15 +2316,26 @@ void limProcessBtAmpApMlmDelBssRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPES
}
}
+/**
+ * limProcessMlmDelStaRsp() - Process WDA_DELETE_STA_RSP
+ * @pMac: Global MAC context
+ * @limMsgQ: LIM Message pointer
+ *
+ * Return: None
+ */
void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
{
- //we need to process the deferred message since the initiating req. there might be nested request.
- //in the case of nested request the new request initiated from the response will take care of resetting
- //the deffered flag.
-
tpPESession psessionEntry;
tpDeleteStaParams pDeleteStaParams;
pDeleteStaParams = (tpDeleteStaParams)limMsgQ->bodyptr;
+
+ /*
+ * we need to process the message deferred since the initiating req.
+ * There might be nested request. In the case of nested request,
+ * the new request initiated from the response will take care of resetting
+ * the deferred flag.
+ */
+
SET_LIM_PROCESS_DEFD_MESGS(pMac, true);
if(NULL == pDeleteStaParams ||
@@ -2344,6 +2355,11 @@ void limProcessMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ )
limProcessBtAmpApMlmDelStaRsp(pMac,limMsgQ,psessionEntry);
return;
}
+
+ if (LIM_IS_NDI_ROLE(psessionEntry)) {
+ lim_process_ndi_del_sta_rsp(pMac, limMsgQ, psessionEntry);
+ return;
+ }
limProcessStaMlmDelStaRsp(pMac, limMsgQ,psessionEntry);
}
@@ -2354,8 +2370,7 @@ void limProcessBtAmpApMlmDelStaRsp( tpAniSirGlobal pMac, tpSirMsgQ limMsgQ,tpPES
tSirResultCodes statusCode = eSIR_SME_SUCCESS;
if(limMsgQ->bodyptr == NULL)
{
- limLog( pMac, LOGE,
- FL( "limMsgQ->bodyptry NULL"));
+ limLog(pMac, LOGE, FL("limMsgQ->bodyptr NULL"));
return;
}
pStaDs = dphGetHashEntry(pMac, pDelStaParams->assocId, &psessionEntry->dph.dphHashTable);
diff --git a/CORE/MAC/src/pe/nan/nan_datapath.c b/CORE/MAC/src/pe/nan/nan_datapath.c
index f90a34dbfa01..206140cb46da 100644
--- a/CORE/MAC/src/pe/nan/nan_datapath.c
+++ b/CORE/MAC/src/pe/nan/nan_datapath.c
@@ -216,18 +216,195 @@ responder_rsp:
}
/**
- * lim_ndp_delete_peers() - Delete peers if needed
+ * lim_ndp_delete_peers() - Delete NAN data peers
* @mac_ctx: handle to mac context
- * @ndp_map: peer map of returning ndp end rsp
- * @num_peers: number of peers remaining after ndp end
+ * @ndp_map: NDP instance/peer map
+ * @num_peers: number of peers entries in peer_map
* 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)
+ struct peer_ndp_map *ndp_map, uint8_t num_peers)
{
+ tpDphHashNode sta_ds = NULL;
+ uint16_t deleted_num = 0;
+ int i, j;
+ tpPESession session;
+ v_MACADDR_t *deleted_peers;
+ uint16_t peer_idx;
+ bool found;
+
+ deleted_peers = vos_mem_malloc(num_peers * sizeof(*deleted_peers));
+ if (!deleted_peers) {
+ limLog(mac_ctx, LOGE, FL("Memory allocation failed"));
+ return;
+ }
+
+ vos_mem_zero(deleted_peers, num_peers * sizeof(*deleted_peers));
+ for (i = 0; i < num_peers; i++) {
+ limLog(mac_ctx, LOG1,
+ FL("ndp_map[%d]: MAC: " MAC_ADDRESS_STR "num_active %d"),
+ i,
+ MAC_ADDR_ARRAY(ndp_map[i].peer_ndi_mac_addr.bytes),
+ ndp_map[i].num_active_ndp_sessions);
+
+ /* Do not delete a peer with active NDPs */
+ if (ndp_map[i].num_active_ndp_sessions > 0)
+ continue;
+
+ session = pe_find_session_by_sme_session_id(mac_ctx,
+ ndp_map[i].vdev_id);
+ if (!session || (session->bssType != eSIR_NDI_MODE)) {
+ limLog(mac_ctx, LOGE,
+ FL("PE session is NULL or non-NDI for sme session %d"),
+ ndp_map[i].vdev_id);
+ continue;
+ }
+
+ /* Check if this peer is already in the deleted list */
+ found = false;
+ for (j = 0; j < deleted_num && !found; j++) {
+ if (vos_mem_compare(
+ &deleted_peers[j].bytes,
+ &ndp_map[i].peer_ndi_mac_addr.bytes,
+ VOS_MAC_ADDR_SIZE)) {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ continue;
+
+ sta_ds = dphLookupHashEntry(mac_ctx,
+ ndp_map[i].peer_ndi_mac_addr.bytes,
+ &peer_idx, &session->dph.dphHashTable);
+ if (!sta_ds) {
+ limLog(mac_ctx, LOGE, FL("Unknown NDI Peer"));
+ continue;
+ }
+ if (sta_ds->staType != STA_ENTRY_NDI_PEER) {
+ limLog(mac_ctx, LOGE,
+ FL("Non-NDI Peer ignored"));
+ continue;
+ }
+ /*
+ * Call limDelSta() with response required set true.
+ * Hence DphHashEntry will be deleted after receiving
+ * that response.
+ */
+ limDelSta(mac_ctx, sta_ds, true, session);
+ vos_copy_macaddr(&deleted_peers[deleted_num++],
+ &ndp_map[i].peer_ndi_mac_addr);
+ }
+ vos_mem_free(deleted_peers);
+}
+
+/**
+ * lim_ndp_end_indication_handler() - Handler for NDP end indication
+ * @mac_ctx: handle to mac context
+ * @ind_buf: pointer to indication buffer
+ *
+ * It deletes peers from ndp_map. Response of that operation goes
+ * to LIM and HDD. But peer information does not go to service layer.
+ * ndp_id_list is sent to service layer; it is not interpreted by the
+ * driver.
+ *
+ * Return: VOS_STATUS_SUCCESS on success; error number otherwise
+ */
+static VOS_STATUS lim_ndp_end_indication_handler(tpAniSirGlobal mac_ctx,
+ uint32_t *ind_buf)
+{
+
+ struct ndp_end_indication_event *ndp_event_buf =
+ (struct ndp_end_indication_event *)ind_buf;
+ int buf_size;
+
+ if (!ind_buf) {
+ limLog(mac_ctx, LOGE, FL("NDP end indication buffer is NULL"));
+ return VOS_STATUS_E_INVAL;
+ }
+ lim_ndp_delete_peers(mac_ctx, ndp_event_buf->ndp_map,
+ ndp_event_buf->num_ndp_ids);
+
+ buf_size = sizeof(*ndp_event_buf) + ndp_event_buf->num_ndp_ids *
+ sizeof(ndp_event_buf->ndp_map[0]);
+ lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_END_IND,
+ ndp_event_buf, buf_size, false);
+
+ return VOS_STATUS_SUCCESS;
+}
+
+/**
+ * lim_process_ndi_del_sta_rsp() - Handle WDA_DELETE_STA_RSP in eLIM_NDI_ROLE
+ * @mac_ctx: Global MAC context
+ * @lim_msg: LIM message
+ * @pe_session: PE session
+ *
+ * Return: None
+ */
+void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg,
+ tpPESession pe_session)
+{
+ tpDeleteStaParams del_sta_params = (tpDeleteStaParams) lim_msg->bodyptr;
+ tpDphHashNode sta_ds;
+ tSirResultCodes status = eSIR_SME_SUCCESS;
+ struct sme_ndp_peer_ind peer_ind;
+
+ if (!del_sta_params) {
+ limLog(mac_ctx, LOGE,
+ FL("del_sta_params is NULL"));
+ return;
+ }
+ if (!LIM_IS_NDI_ROLE(pe_session)) {
+ limLog(mac_ctx, LOGE,
+ FL("Session %d is not NDI role"), del_sta_params->assocId);
+ status = eSIR_SME_REFUSED;
+ goto skip_event;
+ }
+
+ sta_ds = dphGetHashEntry(mac_ctx, del_sta_params->assocId,
+ &pe_session->dph.dphHashTable);
+ if (!sta_ds) {
+ limLog(mac_ctx, LOGE,
+ FL("DPH Entry for STA %X is missing."),
+ del_sta_params->assocId);
+ status = eSIR_SME_REFUSED;
+ goto skip_event;
+ }
+
+ if (eHAL_STATUS_SUCCESS != del_sta_params->status) {
+ limLog(mac_ctx, LOGE, FL("DEL STA failed!"));
+ status = eSIR_SME_REFUSED;
+ goto skip_event;
+ }
+ limLog(mac_ctx, LOG1,
+ FL("Deleted STA AssocID %d staId %d MAC " MAC_ADDRESS_STR),
+ sta_ds->assocId, sta_ds->staIndex,
+ MAC_ADDR_ARRAY(sta_ds->staAddr));
+
+ /*
+ * Copy peer info in del peer indication before
+ * limDeleteDphHashEntry is called as this will be lost.
+ */
+ peer_ind.msg_len = sizeof(peer_ind);
+ peer_ind.msg_type = eWNI_SME_NDP_PEER_DEPARTED_IND;
+ peer_ind.session_id = pe_session->smeSessionId;
+ peer_ind.sta_id = sta_ds->staIndex;
+ vos_mem_copy(&peer_ind.peer_mac_addr.bytes,
+ sta_ds->staAddr, sizeof(tSirMacAddr));
+
+ limReleasePeerIdx(mac_ctx, sta_ds->assocId, pe_session);
+ limDeleteDphHashEntry(mac_ctx, sta_ds->staAddr, sta_ds->assocId,
+ pe_session);
+ pe_session->limMlmState = eLIM_MLM_IDLE_STATE;
+
+ lim_send_ndp_event_to_sme(mac_ctx, eWNI_SME_NDP_PEER_DEPARTED_IND,
+ &peer_ind, sizeof(peer_ind), false);
+
+skip_event:
+ vos_mem_free(del_sta_params);
+ lim_msg->bodyptr = NULL;
}
/**
@@ -273,6 +450,9 @@ VOS_STATUS lim_handle_ndp_event_message(tpAniSirGlobal mac_ctx, tpSirMsgQ msg)
status = lim_ndp_responder_rsp_handler(mac_ctx, msg->bodyptr,
msg->bodyval);
break;
+ case SIR_HAL_NDP_END_IND:
+ status = lim_ndp_end_indication_handler(mac_ctx, msg->bodyptr);
+ break;
default:
limLog(mac_ctx, LOGE, FL("Unhandled NDP event: %d"), msg->type);
status = VOS_STATUS_E_NOSUPPORT;
diff --git a/CORE/MAC/src/pe/nan/nan_datapath.h b/CORE/MAC/src/pe/nan/nan_datapath.h
index 8c72126e130f..4f247ee30263 100644
--- a/CORE/MAC/src/pe/nan/nan_datapath.h
+++ b/CORE/MAC/src/pe/nan/nan_datapath.h
@@ -118,6 +118,9 @@ void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx,
void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx, tpPESession session_entry,
tAddStaParams *add_sta_rsp);
+void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx, tpSirMsgQ lim_msg,
+ tpPESession pe_session);
+
#else
/* Function to process NDP requests */
@@ -144,6 +147,10 @@ static inline void lim_ndi_del_bss_rsp(tpAniSirGlobal mac_ctx,
void *msg, tpPESession session_entry)
{
}
+static inline void lim_process_ndi_del_sta_rsp(tpAniSirGlobal mac_ctx,
+ tpSirMsgQ lim_msg, tpPESession pe_session)
+{
+}
static inline void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx,
tpPESession session_entry,
@@ -154,4 +161,3 @@ static inline void lim_ndp_add_sta_rsp(tpAniSirGlobal mac_ctx,
#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 f218d704c3ee..5753d04576eb 100644
--- a/CORE/SERVICES/WMA/wma.c
+++ b/CORE/SERVICES/WMA/wma.c
@@ -17653,6 +17653,8 @@ static void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
WMA_LOGD("%s: to delete sta for IBSS mode", __func__);
}
#endif
+ if (del_sta->staType == STA_ENTRY_NDI_PEER)
+ oper_mode = BSS_OPERATIONAL_MODE_NDI;
switch (oper_mode) {
case BSS_OPERATIONAL_MODE_STA:
@@ -17665,6 +17667,9 @@ static void wma_delete_sta(tp_wma_handle wma, tpDeleteStaParams del_sta)
case BSS_OPERATIONAL_MODE_AP:
wma_delete_sta_req_ap_mode(wma, del_sta);
break;
+ case BSS_OPERATIONAL_MODE_NDI:
+ wma_delete_sta_req_ndi_mode(wma, del_sta);
+ break;
}
#ifdef QCA_IBSS_SUPPORT
diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.c b/CORE/SERVICES/WMA/wma_nan_datapath.c
index eec905f3b7bf..abbfdf054e7d 100644
--- a/CORE/SERVICES/WMA/wma_nan_datapath.c
+++ b/CORE/SERVICES/WMA/wma_nan_datapath.c
@@ -742,7 +742,74 @@ send_ndp_end_rsp:
static int wma_ndp_end_indication_event_handler(void *handle,
uint8_t *event_info, uint32_t len)
{
- return 0;
+ WMI_NDP_END_INDICATION_EVENTID_param_tlvs *event;
+ wmi_ndp_end_indication *ind;
+ vos_msg_t pe_msg;
+ struct ndp_end_indication_event *ndp_event_buf;
+ VOS_STATUS vos_status;
+ int i;
+ v_MACADDR_t peer_addr;
+ int buf_size;
+
+ event = (WMI_NDP_END_INDICATION_EVENTID_param_tlvs *) event_info;
+
+ if (event->num_ndp_end_indication_list == 0) {
+ WMA_LOGE(
+ FL("Error: Event ignored, 0 ndp instances"));
+ return -EINVAL;
+ }
+
+ WMA_LOGD(FL("number of ndp instances = %d"),
+ event->num_ndp_end_indication_list);
+
+ buf_size = sizeof(*ndp_event_buf) + event->num_ndp_end_indication_list *
+ sizeof(ndp_event_buf->ndp_map[0]);
+ ndp_event_buf = vos_mem_malloc(buf_size);
+ if (!ndp_event_buf) {
+ WMA_LOGP(FL("Failed to allocate memory"));
+ return -ENOMEM;
+ }
+ vos_mem_zero(ndp_event_buf, buf_size);
+ ndp_event_buf->num_ndp_ids = event->num_ndp_end_indication_list;
+
+ ind = event->ndp_end_indication_list;
+ for (i = 0; i < ndp_event_buf->num_ndp_ids; i++) {
+ WMI_MAC_ADDR_TO_CHAR_ARRAY(
+ &ind[i].peer_ndi_mac_addr,
+ peer_addr.bytes);
+ WMA_LOGD(
+ FL("ind[%d]: type %d, reason_code %d, instance_id %d num_active %d MAC: " MAC_ADDRESS_STR),
+ i,
+ ind[i].type,
+ ind[i].reason_code,
+ ind[i].ndp_instance_id,
+ ind[i].num_active_ndps_on_peer,
+ MAC_ADDR_ARRAY(peer_addr.bytes));
+
+ /* Add each instance entry to the list */
+ ndp_event_buf->ndp_map[i].ndp_instance_id =
+ ind[i].ndp_instance_id;
+ ndp_event_buf->ndp_map[i].vdev_id = ind[i].vdev_id;
+ WMI_MAC_ADDR_TO_CHAR_ARRAY(&ind[i].peer_ndi_mac_addr,
+ ndp_event_buf->ndp_map[i].peer_ndi_mac_addr.bytes);
+ ndp_event_buf->ndp_map[i].num_active_ndp_sessions =
+ ind[i].num_active_ndps_on_peer;
+ ndp_event_buf->ndp_map[i].type = ind[i].type;
+ ndp_event_buf->ndp_map[i].reason_code =
+ ind[i].reason_code;
+ }
+
+ pe_msg.type = SIR_HAL_NDP_END_IND;
+ pe_msg.bodyptr = ndp_event_buf;
+ pe_msg.bodyval = 0;
+ vos_status = vos_mq_post_message(VOS_MODULE_ID_PE, &pe_msg);
+ if (VOS_IS_STATUS_SUCCESS(vos_status)) {
+ return 0;
+ }
+
+ WMA_LOGE(FL("failed to post msg to PE"));
+ vos_mem_free(ndp_event_buf);
+ return -EINVAL;
}
/**
@@ -1233,3 +1300,48 @@ send_rsp:
add_sta->staMac, add_sta->status);
wma_send_msg(wma, WDA_ADD_STA_RSP, (void *)add_sta, 0);
}
+
+/**
+ * wma_delete_sta_req_ndi_mode() - Process DEL_STA request for NDI data peer
+ * @wma: WMA context
+ * @del_sta: DEL_STA parameters from LIM
+ *
+ * Removes wma/txrx peer entry for the NDI STA
+ *
+ * Return: None
+ */
+void wma_delete_sta_req_ndi_mode(tp_wma_handle wma,
+ tpDeleteStaParams del_sta)
+{
+ ol_txrx_pdev_handle pdev;
+ struct ol_txrx_peer_t *peer;
+
+ pdev = vos_get_context(VOS_MODULE_ID_TXRX, wma->vos_context);
+
+ if (!pdev) {
+ WMA_LOGE(FL("Failed to get pdev"));
+ del_sta->status = VOS_STATUS_E_FAILURE;
+ goto send_del_rsp;
+ }
+
+ peer = ol_txrx_peer_find_by_local_id(pdev, del_sta->staIdx);
+ if (!peer) {
+ WMA_LOGE(FL("Failed to get peer handle using peer id %d"),
+ del_sta->staIdx);
+ del_sta->status = VOS_STATUS_E_FAILURE;
+ goto send_del_rsp;
+ }
+
+ wma_remove_peer(wma, peer->mac_addr.raw, del_sta->smesessionId, peer,
+ false);
+ del_sta->status = VOS_STATUS_SUCCESS;
+
+send_del_rsp:
+ if (del_sta->respReqd) {
+ WMA_LOGD(FL("Sending del rsp to umac (status: %d)"),
+ del_sta->status);
+ wma_send_msg(wma, WDA_DELETE_STA_RSP, del_sta, 0);
+ }
+}
+
+
diff --git a/CORE/SERVICES/WMA/wma_nan_datapath.h b/CORE/SERVICES/WMA/wma_nan_datapath.h
index 9da9f2eef732..ba7874391e21 100644
--- a/CORE/SERVICES/WMA/wma_nan_datapath.h
+++ b/CORE/SERVICES/WMA/wma_nan_datapath.h
@@ -59,6 +59,8 @@ 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);
+void wma_delete_sta_req_ndi_mode(tp_wma_handle wma,
+ tpDeleteStaParams del_sta);
#else
static inline void wma_add_bss_ndi_mode(tp_wma_handle wma,
tpAddBssParams add_bss) {}
@@ -91,6 +93,9 @@ static inline VOS_STATUS wma_handle_ndp_end_req(tp_wma_handle wma_handle,
{
return VOS_STATUS_SUCCESS;
}
-
+static inline void wma_delete_sta_req_ndi_mode(tp_wma_handle wma,
+ tpDeleteStaParams del_sta)
+{
+}
#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 447f3cf73c90..c9acd06b2039 100644
--- a/CORE/SME/inc/csrApi.h
+++ b/CORE/SME/inc/csrApi.h
@@ -1475,7 +1475,7 @@ typedef struct tagCsrRoamInfo
union {
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_indication_event *ndp_end_ind_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;
diff --git a/CORE/SME/src/nan/nan_datapath_api.c b/CORE/SME/src/nan/nan_datapath_api.c
index 9fbb9660c590..aee4c18c3bd3 100644
--- a/CORE/SME/src/nan/nan_datapath_api.c
+++ b/CORE/SME/src/nan/nan_datapath_api.c
@@ -693,6 +693,27 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg)
cmd->u.data_end_req->num_ndp_instances;
break;
}
+ case eWNI_SME_NDP_END_IND:
+ result = eCSR_ROAM_RESULT_NDP_END_IND;
+ roam_info.ndp.ndp_end_ind_params = msg->bodyptr;
+ /*
+ * NDP_END_IND is independent of session, but session_id is
+ * needed for csrRoamCallCallback(). Set it to vdev_id of first
+ * entry which is a valid session. vdev_id is likely to be same
+ * for all.
+ */
+ session_id =
+ roam_info.ndp.ndp_end_ind_params->ndp_map[0].vdev_id;
+ break;
+ case eWNI_SME_NDP_PEER_DEPARTED_IND:
+ result = eCSR_ROAM_RESULT_NDP_PEER_DEPARTED_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 =
+ ((struct sme_ndp_peer_ind *)msg->bodyptr)->session_id;
+ break;
default:
smsLog(mac_ctx, LOGE, FL("Unhandled NDP rsp"));
vos_mem_free(msg->bodyptr);
@@ -739,6 +760,8 @@ void sme_ndp_msg_processor(tpAniSirGlobal mac_ctx, vos_msg_t *msg)
cmd->u.data_end_req = NULL;
}
break;
+ case eWNI_SME_NDP_END_IND:
+ break;
default:
break;
}
diff --git a/CORE/SME/src/sme_common/sme_Api.c b/CORE/SME/src/sme_common/sme_Api.c
index 4428ddca9b2c..a33a63ae40a7 100644
--- a/CORE/SME/src/sme_common/sme_Api.c
+++ b/CORE/SME/src/sme_common/sme_Api.c
@@ -3393,6 +3393,8 @@ eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg)
case eWNI_SME_NDP_INDICATION:
case eWNI_SME_NDP_RESPONDER_RSP:
case eWNI_SME_NDP_END_RSP:
+ case eWNI_SME_NDP_END_IND:
+ case eWNI_SME_NDP_PEER_DEPARTED_IND:
sme_ndp_msg_processor(pMac, pMsg);
break;
default: