summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNitesh Shah <niteshs@codeaurora.org>2017-03-20 19:27:47 +0530
committerNitesh Shah <niteshs@codeaurora.org>2017-03-23 11:00:14 +0530
commit1ca8f290b3d43d4474885d978c0f337acbe2e194 (patch)
treee21e871899d756967c9b3cc69acdc71ad890d367
parent94906065213808b173bb0f7dc7849e6e527d80ca (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.h2
-rw-r--r--core/hdd/src/wlan_hdd_assoc.c9
-rw-r--r--core/hdd/src/wlan_hdd_tdls.c57
-rw-r--r--core/mac/inc/sir_api.h12
-rw-r--r--core/mac/inc/wni_api.h1
-rw-r--r--core/mac/src/pe/lim/lim_process_message_queue.c5
-rw-r--r--core/mac/src/pe/lim/lim_process_tdls.c115
-rw-r--r--core/mac/src/pe/lim/lim_types.h3
-rw-r--r--core/sme/inc/sme_api.h3
-rw-r--r--core/sme/src/common/sme_api.c41
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;
+}