Merge "qcacld-3.0: Send Deauth and delete all TDLS stations" into wlan-cld3.driver.lnx.2.0-dev

This commit is contained in:
Service qcabuildsw 2017-03-21 18:48:33 -07:00 • committed by Gerrit - the friendly Code Review server
commit 25b3ed108f
10 changed files with 179 additions and 68 deletions

View file

@ -289,6 +289,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

View file

@ -3565,8 +3565,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 = cdp_clear_peer(cds_get_context(QDF_MODULE_ID_SOC),
@ -3826,9 +3825,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].
@ -3878,11 +3879,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
@ -4148,7 +4151,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;

View file

@ -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"
@ -234,8 +236,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
@ -254,6 +258,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)
@ -262,20 +269,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));
}
}
@ -1918,7 +1940,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) {
@ -1986,29 +2007,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;
@ -2364,12 +2362,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;
}
/*
@ -2392,8 +2389,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;
}

View file

@ -6900,4 +6900,15 @@ struct wow_enable_params {
#endif
/**
* 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 */

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2012-2016 The Linux Foundation. All rights reserved.
* Copyright (c) 2012-2017 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@ -263,6 +263,7 @@ enum eWniMsgTypes {
eWNI_SME_DEFAULT_SCAN_IE,
eWNI_SME_ROAM_SCAN_OFFLOAD_REQ,
eWNI_SME_LOST_LINK_INFO_IND,
eWNI_SME_DEL_ALL_TDLS_PEERS,
eWNI_SME_MSG_TYPES_END
};

View file

@ -1964,6 +1964,11 @@ static void lim_process_messages(tpAniSirGlobal mac_ctx,
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;

View file

@ -3367,6 +3367,67 @@ lim_tdls_link_establish_error:
return eSIR_SUCCESS;
}
/**
* 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
*
* This function verifies aid and delete's peer with that aid from hash table
*
* Return: None
*/
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;
/*
* 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(p_mac, LOG1, 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(p_mac,
(aid + i * (sizeof(uint32_t) << 3)),
&session_entry->dph.dphHashTable);
if (NULL == stads)
goto skip;
lim_log(p_mac, LOG1,
FL("Deleting "MAC_ADDRESS_STR),
MAC_ADDR_ARRAY(stads->staAddr));
lim_send_deauth_mgmt_frame(p_mac,
eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
stads->staAddr, session_entry, false);
/* Delete TDLS peer */
qdf_mem_copy(mac_addr.bytes, stads->staAddr,
QDF_MAC_ADDR_SIZE);
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
*
@ -3380,56 +3441,12 @@ lim_tdls_link_establish_error:
tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
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, LOGE, 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,
(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));
lim_send_deauth_mgmt_frame(mac_ctx,
eSIR_MAC_DEAUTH_LEAVING_BSS_REASON,
stads->staAddr, session_entry, false);
/* Delete TDLS peer */
qdf_mem_copy(mac_addr.bytes, stads->staAddr,
QDF_MAC_ADDR_SIZE);
lim_tdls_del_sta(mac_ctx, mac_addr,
session_entry, false);
dph_delete_hash_entry(mac_ctx,
stads->staAddr, stads->assocId,
&session_entry->dph.dphHashTable);
}
lim_release_peer_idx(mac_ctx,
(aid + i * (sizeof(uint32_t) << 3)),
session_entry);
CLEAR_BIT(session_entry->peerAIDBitmap[i], aid);
}
}
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);
@ -3437,6 +3454,40 @@ tSirRetStatus lim_delete_tdls_peers(tpAniSirGlobal mac_ctx,
return eSIR_SUCCESS;
}
/**
* 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

View file

@ -910,7 +910,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 */
{

View file

@ -1435,4 +1435,6 @@ QDF_STATUS sme_get_beacon_frm(tHalHandle hal, tCsrRoamProfile *profile,
const tSirMacAddr bssid,
uint8_t **frame_buf, uint32_t *frame_len);
QDF_STATUS sme_delete_all_tdls_peers(tHalHandle hal, uint8_t session_id);
#endif /* #if !defined( __SME_API_H ) */

View file

@ -16458,3 +16458,43 @@ free_scan_flter:
return QDF_STATUS_SUCCESS;
}
/**
* 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) {
sms_log(p_mac, LOGE, FL("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 = umac_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;
}