diff options
| author | Nitesh Shah <niteshs@codeaurora.org> | 2017-03-20 19:27:47 +0530 |
|---|---|---|
| committer | Nitesh Shah <niteshs@codeaurora.org> | 2017-03-23 11:00:14 +0530 |
| commit | 1ca8f290b3d43d4474885d978c0f337acbe2e194 (patch) | |
| tree | e21e871899d756967c9b3cc69acdc71ad890d367 | |
| parent | 94906065213808b173bb0f7dc7849e6e527d80ca (diff) | |
qcacld-3.0: Send Deauth and delete all TDLS stations
This change addresses sending Deauth to TDLS peers,
delete TDLS stations and clear hdd structures if
concurrency is detected.
Change-Id: Ia9f6724a9db20c6d9ebfc2fa735569305f35f084
CRs-Fixed: 2022489
| -rw-r--r-- | core/hdd/inc/wlan_hdd_assoc.h | 2 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_assoc.c | 9 | ||||
| -rw-r--r-- | core/hdd/src/wlan_hdd_tdls.c | 57 | ||||
| -rw-r--r-- | core/mac/inc/sir_api.h | 12 | ||||
| -rw-r--r-- | core/mac/inc/wni_api.h | 1 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_process_message_queue.c | 5 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_process_tdls.c | 115 | ||||
| -rw-r--r-- | core/mac/src/pe/lim/lim_types.h | 3 | ||||
| -rw-r--r-- | core/sme/inc/sme_api.h | 3 | ||||
| -rw-r--r-- | core/sme/src/common/sme_api.c | 41 |
10 files changed, 181 insertions, 67 deletions
diff --git a/core/hdd/inc/wlan_hdd_assoc.h b/core/hdd/inc/wlan_hdd_assoc.h index 7f28c069e74e..ffa475016095 100644 --- a/core/hdd/inc/wlan_hdd_assoc.h +++ b/core/hdd/inc/wlan_hdd_assoc.h @@ -290,6 +290,8 @@ QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter, uint8_t ucastSig, uint8_t qos); #endif +QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter, uint8_t staId); + /** * hdd_perform_roam_set_key_complete() - perform set key complete * @pAdapter: pointer to adapter diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 3b48dded2a56..c9604d800ca5 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -3473,8 +3473,7 @@ QDF_STATUS hdd_roam_register_tdlssta(hdd_adapter_t *pAdapter, * * Return: QDF_STATUS enumeration */ -static QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter, - uint8_t staId) +QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter, uint8_t staId) { QDF_STATUS qdf_status; qdf_status = ol_txrx_clear_peer(staId); @@ -3731,9 +3730,11 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, } else mutex_unlock(&pHddCtx->tdls_lock); + mutex_lock(&pHddCtx->tdls_lock); wlan_hdd_tdls_reset_peer(pAdapter, pRoamInfo-> peerMac.bytes); + mutex_unlock(&pHddCtx->tdls_lock); pHddCtx->tdlsConnInfo[staIdx].staId = 0; pHddCtx->tdlsConnInfo[staIdx]. @@ -3783,11 +3784,13 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, [staIdx]. peerMac. bytes)); + mutex_lock(&pHddCtx->tdls_lock); wlan_hdd_tdls_reset_peer(pAdapter, pHddCtx-> tdlsConnInfo [staIdx]. peerMac.bytes); + mutex_unlock(&pHddCtx->tdls_lock); hdd_roam_deregister_tdlssta(pAdapter, pHddCtx-> tdlsConnInfo @@ -4054,7 +4057,7 @@ hdd_roam_tdls_status_update_handler(hdd_adapter_t *pAdapter, } #else -static inline QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter, +inline QDF_STATUS hdd_roam_deregister_tdlssta(hdd_adapter_t *pAdapter, uint8_t staId) { return QDF_STATUS_SUCCESS; diff --git a/core/hdd/src/wlan_hdd_tdls.c b/core/hdd/src/wlan_hdd_tdls.c index 0a7142944aa5..34f7c03df054 100644 --- a/core/hdd/src/wlan_hdd_tdls.c +++ b/core/hdd/src/wlan_hdd_tdls.c @@ -43,6 +43,8 @@ #include <net/ieee80211_radiotap.h> #include "wlan_hdd_tdls.h" #include "wlan_hdd_cfg80211.h" +#include "wlan_hdd_assoc.h" +#include "sme_api.h" #include "cds_sched.h" #include "wma_types.h" #include "cds_concurrency.h" @@ -233,8 +235,10 @@ void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx) connected_tdls_peers = wlan_hdd_tdls_connected_peers(adapter); - if (!connected_tdls_peers) - return ; + if (!connected_tdls_peers) { + hdd_notice("No TDLS connected peers to delete"); + return; + } /* TDLS is not supported in case of concurrency. * Disable TDLS Offchannel in FW to avoid more @@ -253,6 +257,9 @@ void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx) TDLS_SEC_OFFCHAN_OFFSET_40PLUS); hdd_set_tdls_offchannelmode(adapter, DISABLE_CHANSWITCH); + /* Send Msg to PE for deleting all the TDLS peers */ + sme_delete_all_tdls_peers(hddctx->hHal, adapter->sessionId); + for (staidx = 0; staidx < hddctx->max_num_tdls_sta; staidx++) { if (!hddctx->tdlsConnInfo[staidx].staId) @@ -261,20 +268,35 @@ void wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_context_t *hddctx) mutex_lock(&hddctx->tdls_lock); curr_peer = wlan_hdd_tdls_find_all_peer(hddctx, hddctx->tdlsConnInfo[staidx].peerMac.bytes); - if (!curr_peer) continue; hdd_notice("indicate TDLS teardown (staId %d)", curr_peer->staId); + /* Indicate teardown to supplicant */ wlan_hdd_tdls_indicate_teardown( curr_peer->pHddTdlsCtx->pAdapter, curr_peer, eSIR_MAC_TDLS_TEARDOWN_UNSPEC_REASON); + + /* + * Del Sta happened already as part of sme_delete_all_tdls_peers + * Hence clear hdd data structure. + */ + wlan_hdd_tdls_reset_peer(adapter, curr_peer->peerMac); hdd_send_wlan_tdls_teardown_event(eTDLS_TEARDOWN_CONCURRENCY, curr_peer->peerMac); mutex_unlock(&hddctx->tdls_lock); + + hdd_roam_deregister_tdlssta(adapter, + hddctx->tdlsConnInfo[staidx].staId); + wlan_hdd_tdls_decrement_peer_count(adapter); + hddctx->tdlsConnInfo[staidx].staId = 0; + hddctx->tdlsConnInfo[staidx].sessionId = 255; + + qdf_mem_zero(&hddctx->tdlsConnInfo[staidx].peerMac, + sizeof(struct qdf_mac_addr)); } } @@ -1913,7 +1935,6 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, tdlsCtx_t *hdd_tdls_ctx; tdlsInfo_t *tdls_param; QDF_STATUS qdf_ret_status = QDF_STATUS_E_FAILURE; - uint16_t staIdx; /* If TDLS support is disabled then no need to update target */ if (false == hdd_ctx->config->fEnableTDLSSupport) { @@ -1981,29 +2002,6 @@ void wlan_hdd_update_tdls_info(hdd_adapter_t *adapter, bool tdls_prohibited, hdd_warn("Concurrency not allowed in TDLS! set state cnt %d", hdd_ctx->set_state_info.set_state_cnt); wlan_hdd_tdls_disable_offchan_and_teardown_links(hdd_ctx); - if (hdd_ctx->connected_peer_count >= 1) { - /* clean up the tdls peers if any */ - for (staIdx = 0; staIdx < hdd_ctx->max_num_tdls_sta; - staIdx++) { - if ((hdd_ctx->tdlsConnInfo[staIdx].sessionId == - adapter->sessionId) - && (hdd_ctx->tdlsConnInfo[staIdx].staId)) { - uint8_t *mac; - mac = hdd_ctx->tdlsConnInfo[staIdx]. - peerMac.bytes; - hdd_notice("call sme_delete_tdls_peer_" - "sta staId %d sessionId %d " - MAC_ADDRESS_STR, - hdd_ctx->tdlsConnInfo - [staIdx].staId, - adapter->sessionId, - MAC_ADDR_ARRAY(mac)); - sme_delete_tdls_peer_sta( - WLAN_HDD_GET_HAL_CTX(adapter), - adapter->sessionId, mac); - } - } - } tdls_prohibited = true; hdd_ctx->tdls_mode = eTDLS_SUPPORT_NOT_ENABLED; tdls_param->vdev_id = hdd_ctx->set_state_info.vdev_id; @@ -2358,12 +2356,11 @@ int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, const uint8_t *mac) goto ret_status; } - mutex_lock(&pHddCtx->tdls_lock); curr_peer = wlan_hdd_tdls_get_peer(pAdapter, mac); if (curr_peer == NULL) { hdd_err("curr_peer is NULL"); status = -EINVAL; - goto rel_lock; + goto ret_status; } /* @@ -2386,8 +2383,6 @@ int wlan_hdd_tdls_reset_peer(hdd_adapter_t *pAdapter, const uint8_t *mac) eTDLS_LINK_IDLE, eTDLS_LINK_UNSPECIFIED); curr_peer->staId = 0; -rel_lock: - mutex_unlock(&pHddCtx->tdls_lock); ret_status: return status; } diff --git a/core/mac/inc/sir_api.h b/core/mac/inc/sir_api.h index 356dadcb1403..300f80f48c45 100644 --- a/core/mac/inc/sir_api.h +++ b/core/mac/inc/sir_api.h @@ -7139,4 +7139,16 @@ struct get_arp_stats_params { uint8_t pkt_type; uint32_t vdev_id; }; + +/** + * struct sir_del_all_tdls_peers - delete all tdls peers + * @msg_type: type of message + * @msg_len: length of message + * @bssid: bssid of peer device + */ +struct sir_del_all_tdls_peers { + uint16_t msg_type; + uint16_t msg_len; + struct qdf_mac_addr bssid; +}; #endif /* __SIR_API_H */ diff --git a/core/mac/inc/wni_api.h b/core/mac/inc/wni_api.h index a21fb2bfac88..22d20bc9d1de 100644 --- a/core/mac/inc/wni_api.h +++ b/core/mac/inc/wni_api.h @@ -267,6 +267,7 @@ enum eWniMsgTypes { eWNI_SME_RSO_CMD_STATUS_IND, eWMI_SME_LL_STATS_IND, eWNI_SME_BT_ACTIVITY_INFO_IND, + eWNI_SME_DEL_ALL_TDLS_PEERS, eWNI_SME_MSG_TYPES_END }; diff --git a/core/mac/src/pe/lim/lim_process_message_queue.c b/core/mac/src/pe/lim/lim_process_message_queue.c index 54effd2cea1b..d2d606e15049 100644 --- a/core/mac/src/pe/lim/lim_process_message_queue.c +++ b/core/mac/src/pe/lim/lim_process_message_queue.c @@ -1964,6 +1964,11 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx, tpSirMsgQ msg) qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; break; + case eWNI_SME_DEL_ALL_TDLS_PEERS: + lim_process_sme_del_all_tdls_peers(mac_ctx, msg->bodyptr); + qdf_mem_free((void *)msg->bodyptr); + msg->bodyptr = NULL; + break; default: qdf_mem_free((void *)msg->bodyptr); msg->bodyptr = NULL; diff --git a/core/mac/src/pe/lim/lim_process_tdls.c b/core/mac/src/pe/lim/lim_process_tdls.c index 84ee26bf9778..550f596fa04c 100644 --- a/core/mac/src/pe/lim/lim_process_tdls.c +++ b/core/mac/src/pe/lim/lim_process_tdls.c @@ -3350,68 +3350,85 @@ lim_tdls_link_establish_error: } /** - * lim_delete_tdls_peers() - delete tdls peers - * - * @mac_ctx - global MAC context - * @session_entry - PE session entry + * lim_check_aid_and_delete_peer() - Funtion to check aid and delete peer + * @p_mac: pointer to mac context + * @session_entry: pointer to PE session * - * Delete all the TDLS peer connected before leaving the BSS + * This function verifies aid and delete's peer with that aid from hash table * - * Return: eSIR_SUCCESS on success, error code otherwise + * Return: None */ -tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx, - tpPESession session_entry) +static void lim_check_aid_and_delete_peer(tpAniSirGlobal p_mac, + tpPESession session_entry) { tpDphHashNode stads = NULL; int i, aid; size_t aid_bitmap_size = sizeof(session_entry->peerAIDBitmap); struct qdf_mac_addr mac_addr; - if (NULL == session_entry) { - lim_log(mac_ctx, LOGE, FL("NULL session_entry")); - return eSIR_FAILURE; - } - /* * Check all the set bit in peerAIDBitmap and delete the peer * (with that aid) entry from the hash table and add the aid * in free pool */ - lim_log(mac_ctx, LOGD, FL("Delete all the TDLS peer connected")); + lim_log(p_mac, LOGD, FL("Delete all the TDLS peer connected")); for (i = 0; i < aid_bitmap_size / sizeof(uint32_t); i++) { for (aid = 0; aid < (sizeof(uint32_t) << 3); aid++) { if (!CHECK_BIT(session_entry->peerAIDBitmap[i], aid)) continue; - stads = dph_get_hash_entry(mac_ctx, + stads = dph_get_hash_entry(p_mac, (aid + i * (sizeof(uint32_t) << 3)), &session_entry->dph.dphHashTable); - if (NULL != stads) { - lim_log(mac_ctx, LOGE, - FL("Deleting "MAC_ADDRESS_STR), - MAC_ADDR_ARRAY(stads->staAddr)); + if (NULL == stads) + goto skip; - lim_send_deauth_mgmt_frame(mac_ctx, - eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, - stads->staAddr, session_entry, false); + lim_log(p_mac, LOG1, + FL("Deleting "MAC_ADDRESS_STR), + MAC_ADDR_ARRAY(stads->staAddr)); - /* Delete TDLS peer */ - qdf_mem_copy(mac_addr.bytes, stads->staAddr, - QDF_MAC_ADDR_SIZE); + lim_send_deauth_mgmt_frame(p_mac, + eSIR_MAC_DEAUTH_LEAVING_BSS_REASON, + stads->staAddr, session_entry, false); - lim_tdls_del_sta(mac_ctx, mac_addr, - session_entry, false); + /* Delete TDLS peer */ + qdf_mem_copy(mac_addr.bytes, stads->staAddr, + QDF_MAC_ADDR_SIZE); - dph_delete_hash_entry(mac_ctx, - stads->staAddr, stads->assocId, - &session_entry->dph.dphHashTable); - } - lim_release_peer_idx(mac_ctx, + lim_tdls_del_sta(p_mac, mac_addr, + session_entry, false); + + dph_delete_hash_entry(p_mac, + stads->staAddr, stads->assocId, + &session_entry->dph.dphHashTable); +skip: + lim_release_peer_idx(p_mac, (aid + i * (sizeof(uint32_t) << 3)), session_entry); CLEAR_BIT(session_entry->peerAIDBitmap[i], aid); } } +} + +/** + * lim_delete_tdls_peers() - delete tdls peers + * + * @mac_ctx - global MAC context + * @session_entry - PE session entry + * + * Delete all the TDLS peer connected before leaving the BSS + * + * Return: eSIR_SUCCESS on success, error code otherwise + */ +tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx, + tpPESession session_entry) +{ + if (NULL == session_entry) { + lim_log(mac_ctx, LOGE, FL("NULL session_entry")); + return eSIR_FAILURE; + } + + lim_check_aid_and_delete_peer(mac_ctx, session_entry); if (lim_is_roam_synch_in_progress(session_entry)) return eSIR_SUCCESS; lim_send_sme_tdls_delete_all_peer_ind(mac_ctx, session_entry); @@ -3420,6 +3437,40 @@ tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx, } /** + * lim_process_sme_del_all_tdls_peers(): process delete tdls peers + * @p_mac: pointer to mac context + * @msg_buf: message buffer + * + * This function processes request to delete tdls peers + * + * Return: Success: eSIR_SUCCESS Failure: Error value + */ +tSirRetStatus lim_process_sme_del_all_tdls_peers(tpAniSirGlobal p_mac, + uint32_t *msg_buf) +{ + struct sir_del_all_tdls_peers *msg; + tpPESession session_entry; + uint8_t session_id; + + msg = (struct sir_del_all_tdls_peers *)msg_buf; + if (msg == NULL) { + lim_log(p_mac, LOGE, FL("NULL msg")); + return eSIR_FAILURE; + } + + session_entry = pe_find_session_by_bssid(p_mac, + msg->bssid.bytes, &session_id); + if (NULL == session_entry) { + lim_log(p_mac, LOGE, FL("NULL psessionEntry")); + return eSIR_FAILURE; + } + + lim_check_aid_and_delete_peer(p_mac, session_entry); + + return eSIR_SUCCESS; +} + +/** * lim_process_tdls_del_sta_rsp() - Handle WDA_DELETE_STA_RSP for TDLS * @mac_ctx: Global MAC context * @lim_msg: LIM message diff --git a/core/mac/src/pe/lim/lim_types.h b/core/mac/src/pe/lim/lim_types.h index cfbe70823874..85a5d1d8ea1f 100644 --- a/core/mac/src/pe/lim/lim_types.h +++ b/core/mac/src/pe/lim/lim_types.h @@ -867,7 +867,8 @@ int lim_process_remain_on_chnl_req(tpAniSirGlobal pMac, uint32_t *pMsg); void lim_remain_on_chn_rsp(tpAniSirGlobal pMac, QDF_STATUS status, uint32_t *data); void lim_send_sme_disassoc_deauth_ntf(tpAniSirGlobal mac_ctx, QDF_STATUS status, uint32_t *ctx); - +tSirRetStatus lim_process_sme_del_all_tdls_peers(tpAniSirGlobal p_mac, + uint32_t *msg_buf); /* / Bit value data structure */ typedef enum sHalBitVal /* For Bit operations */ { diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 2ba2bfc14105..add07344d121 100644 --- a/core/sme/inc/sme_api.h +++ b/core/sme/inc/sme_api.h @@ -1550,4 +1550,7 @@ QDF_STATUS sme_set_bt_activity_info_cb(tHalHandle hal, */ tCsrScanResultInfo *sme_scan_get_result_for_bssid(tHalHandle hal_handle, struct qdf_mac_addr *bssid); + +QDF_STATUS sme_delete_all_tdls_peers(tHalHandle hal, uint8_t session_id); + #endif /* #if !defined( __SME_API_H ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 63cc4c2c2aee..d74637c31cc4 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -17497,3 +17497,44 @@ QDF_STATUS sme_set_bt_activity_info_cb(tHalHandle hal, return status; } + +/** + * sme_delete_all_tdls_peers(): send request to delete tdls peers + * @hal: handler for HAL + * @session_id: session id + * + * This function sends request to lim to delete tdls peers + * + * Return: QDF_STATUS + */ +QDF_STATUS sme_delete_all_tdls_peers(tHalHandle hal, uint8_t session_id) +{ + struct sir_del_all_tdls_peers *msg; + QDF_STATUS status = QDF_STATUS_SUCCESS; + tpAniSirGlobal p_mac = PMAC_STRUCT(hal); + tCsrRoamSession *session = CSR_GET_SESSION(p_mac, session_id); + + msg = qdf_mem_malloc(sizeof(*msg)); + if (NULL == msg) { + sme_err("memory alloc failed"); + return QDF_STATUS_E_FAILURE; + } + + qdf_mem_zero(msg, sizeof(*msg)); + + msg->msg_type = eWNI_SME_DEL_ALL_TDLS_PEERS; + msg->msg_len = (uint16_t) sizeof(*msg); + + qdf_mem_copy(msg->bssid.bytes, session->connectedProfile.bssid.bytes, + sizeof(struct qdf_mac_addr)); + + status = cds_send_mb_message_to_mac(msg); + + if (status != QDF_STATUS_SUCCESS) { + QDF_TRACE(QDF_MODULE_ID_SME, QDF_TRACE_LEVEL_ERROR, + FL("cds_send_mb_message_to_mac Failed")); + status = QDF_STATUS_E_FAILURE; + } + + return status; +} |
