From 3ea99d7b087f7ed262e6e793e95db2a706a1c975 Mon Sep 17 00:00:00 2001 From: Rachit Kankane Date: Wed, 7 Jul 2021 17:01:39 +0530 Subject: [PATCH] qcacld-3.0: Add support for silent deauth Add support to facilitate silent deauthentication to peer stations in master mode. Change-Id: I8c92d68d7ae94d1d425bfcb6744bed84b67f1f3b CRs-Fixed: 3070885 --- core/hdd/src/wlan_hdd_son.c | 24 ++++++++++++++ .../src/pe/lim/lim_send_management_frames.c | 33 +++++++++++++------ os_if/son/inc/os_if_son.h | 16 +++++++++ os_if/son/src/os_if_son.c | 14 ++++++++ 4 files changed, 77 insertions(+), 10 deletions(-) diff --git a/core/hdd/src/wlan_hdd_son.c b/core/hdd/src/wlan_hdd_son.c index cc6ae6cb5a..8b4d23b712 100644 --- a/core/hdd/src/wlan_hdd_son.c +++ b/core/hdd/src/wlan_hdd_son.c @@ -1254,6 +1254,29 @@ static uint8_t hdd_son_get_rx_nss(struct wlan_objmgr_vdev *vdev) return rx_nss; } +static void hdd_son_deauth_sta(struct wlan_objmgr_vdev *vdev, + uint8_t *peer_mac, + bool ignore_frame) +{ + struct hdd_adapter *adapter = wlan_hdd_get_adapter_from_objmgr(vdev); + struct csr_del_sta_params param; + + if (!adapter) { + hdd_err("null adapter"); + return; + } + + qdf_mem_copy(param.peerMacAddr.bytes, peer_mac, QDF_MAC_ADDR_SIZE); + param.subtype = SIR_MAC_MGMT_DEAUTH; + param.reason_code = ignore_frame ? REASON_HOST_TRIGGERED_SILENT_DEAUTH + : REASON_UNSPEC_FAILURE; + hdd_debug("Peer - "QDF_MAC_ADDR_FMT" Ignore Frame - %u", + QDF_FULL_MAC_REF(peer_mac), ignore_frame); + + if (hdd_softap_sta_deauth(adapter, ¶m) != QDF_STATUS_SUCCESS) + hdd_err("Error in deauthenticating peer"); +} + void hdd_son_register_callbacks(struct hdd_context *hdd_ctx) { struct son_callbacks cb_obj = {0}; @@ -1277,6 +1300,7 @@ void hdd_son_register_callbacks(struct hdd_context *hdd_ctx) cb_obj.os_if_get_rx_nss = hdd_son_get_rx_nss; cb_obj.os_if_set_chwidth = hdd_son_set_chwidth; cb_obj.os_if_get_chwidth = hdd_son_get_chwidth; + cb_obj.os_if_deauth_sta = hdd_son_deauth_sta; os_if_son_register_hdd_callbacks(hdd_ctx->psoc, &cb_obj); } diff --git a/core/mac/src/pe/lim/lim_send_management_frames.c b/core/mac/src/pe/lim/lim_send_management_frames.c index e4802bd409..c674e204ec 100644 --- a/core/mac/src/pe/lim/lim_send_management_frames.c +++ b/core/mac/src/pe/lim/lim_send_management_frames.c @@ -3901,24 +3901,37 @@ lim_send_deauth_mgmt_frame(struct mac_context *mac, #endif uint8_t smeSessionId = 0; struct element_info *discon_ie; + bool drop_deauth = false; if (!pe_session) { return; } /* - * In case when cac timer is running for this SAP session then - * avoid deauth frame out. It is violation of dfs specification. + * Avoid sending deauth frame out when + * 1. CAC timer is running for this SAP session, + * It is avoid violation of dfs specification. + * 2. Silent deauth is requested for a particular peer */ - if (((pe_session->opmode == QDF_SAP_MODE) || - (pe_session->opmode == QDF_P2P_GO_MODE)) && - (true == mac->sap.SapDfsInfo.is_dfs_cac_timer_running)) { - QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, - FL + if ((pe_session->opmode == QDF_SAP_MODE) || + (pe_session->opmode == QDF_P2P_GO_MODE)) { + if (mac->sap.SapDfsInfo.is_dfs_cac_timer_running) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, + FL ("CAC timer is running, drop the deauth from going out")); - if (waitForAck) - lim_send_deauth_cnf(mac); - return; + drop_deauth = true; + } + if (nReason == REASON_HOST_TRIGGERED_SILENT_DEAUTH) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO, + FL + ("Silent deauth, remove the peer")); + drop_deauth = true; + } + if (drop_deauth) { + if (waitForAck) + lim_send_deauth_cnf(mac); + return; + } } smeSessionId = pe_session->smeSessionId; diff --git a/os_if/son/inc/os_if_son.h b/os_if/son/inc/os_if_son.h index 08298c4438..85a8cd3eb8 100644 --- a/os_if/son/inc/os_if_son.h +++ b/os_if/son/inc/os_if_son.h @@ -53,6 +53,7 @@ * @os_if_kickout_mac: kickout sta with given mac * @os_if_set_chwidth: set chan width * @os_if_get_chwidth: get chan width + * @os_if_deauth_sta: Deauths the target peer */ struct son_callbacks { uint32_t (*os_if_is_acs_in_progress)(struct wlan_objmgr_vdev *vdev); @@ -91,6 +92,9 @@ struct son_callbacks { enum ieee80211_cwm_width son_chwidth); enum ieee80211_cwm_width (*os_if_get_chwidth)( struct wlan_objmgr_vdev *vdev); + void (*os_if_deauth_sta)(struct wlan_objmgr_vdev *vdev, + uint8_t *peer_mac, + bool ignore_frame); }; /** @@ -465,4 +469,16 @@ int os_if_son_set_chwidth(struct wlan_objmgr_vdev *vdev, * Return: son chan width */ enum ieee80211_cwm_width os_if_son_get_chwidth(struct wlan_objmgr_vdev *vdev); + +/** + * os_if_son_deauth_peer_sta - Deauths specified STA + * @vdev: vdev + * @peer_mac: Target peer MAC address + * @ignore_frame: True to silently deauth the peer + * + * Return: void + */ +void os_if_son_deauth_peer_sta(struct wlan_objmgr_vdev *vdev, + uint8_t *peer_mac, + bool ignore_frame); #endif diff --git a/os_if/son/src/os_if_son.c b/os_if/son/src/os_if_son.c index 21ccd6a462..a422f5728c 100644 --- a/os_if/son/src/os_if_son.c +++ b/os_if/son/src/os_if_son.c @@ -911,3 +911,17 @@ bool os_if_son_vdev_is_wds(struct wlan_objmgr_vdev *vdev) } qdf_export_symbol(os_if_son_vdev_is_wds); + +void os_if_son_deauth_peer_sta(struct wlan_objmgr_vdev *vdev, + uint8_t *peer_mac, + bool ignore_frame) +{ + if (!vdev || !peer_mac) { + osif_err("null vdev / peer_mac"); + return; + } + if (g_son_os_if_cb.os_if_deauth_sta) + g_son_os_if_cb.os_if_deauth_sta(vdev, peer_mac, ignore_frame); +} + +qdf_export_symbol(os_if_son_deauth_peer_sta);