diff options
| author | Deepak Dhamdhere <ddhamdhe@qca.qualcomm.com> | 2016-03-07 00:14:47 -0800 |
|---|---|---|
| committer | Anjaneedevi Kapparapu <akappa@codeaurora.org> | 2016-04-28 16:45:21 +0530 |
| commit | 9141bca8871acf737251e31ab220e19221bca72c (patch) | |
| tree | e28f002c3403c142c6754a9a72fc13d72c9ae380 | |
| parent | 8ef2ea33ad2b624a653838ba84a9b79305ccd4c3 (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.h | 5 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_assoc.c | 32 | ||||
| -rw-r--r-- | CORE/HDD/src/wlan_hdd_nan_datapath.c | 109 | ||||
| -rw-r--r-- | CORE/MAC/inc/sirApi.h | 42 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessMessageQueue.c | 1 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/lim/limProcessMlmRspMessages.c | 27 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/nan/nan_datapath.c | 190 | ||||
| -rw-r--r-- | CORE/MAC/src/pe/nan/nan_datapath.h | 8 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma.c | 5 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma_nan_datapath.c | 114 | ||||
| -rw-r--r-- | CORE/SERVICES/WMA/wma_nan_datapath.h | 7 | ||||
| -rw-r--r-- | CORE/SME/inc/csrApi.h | 2 | ||||
| -rw-r--r-- | CORE/SME/src/nan/nan_datapath_api.c | 23 | ||||
| -rw-r--r-- | CORE/SME/src/sme_common/sme_Api.c | 2 |
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: |
