From da2452fdd79540c098ccd19c55b4b60e1e9aca42 Mon Sep 17 00:00:00 2001 From: Abhishek Ambure Date: Mon, 14 Dec 2020 22:53:55 +0530 Subject: [PATCH] qcacld-3.0: Add lim support for CM disconnect handling Add support to handle disconnect request via connection manager in LIM. Change-Id: I2ead0188368ab75f4862a429d43bf2305ae94abe CRs-Fixed: 2840792 --- .../mlme/dispatcher/inc/wlan_mlme_api.h | 12 ++ .../mlme/dispatcher/src/wlan_mlme_api.c | 14 ++ .../src/pe/lim/lim_process_sme_req_messages.c | 131 ++++++++++++++++++ 3 files changed, 157 insertions(+) diff --git a/components/mlme/dispatcher/inc/wlan_mlme_api.h b/components/mlme/dispatcher/inc/wlan_mlme_api.h index 0ee18479cc..61ecd4df33 100644 --- a/components/mlme/dispatcher/inc/wlan_mlme_api.h +++ b/components/mlme/dispatcher/inc/wlan_mlme_api.h @@ -117,6 +117,18 @@ uint8_t wlan_mlme_get_tx_power(struct wlan_objmgr_psoc *psoc, */ char *wlan_mlme_get_power_usage(struct wlan_objmgr_psoc *psoc); +/** + * wlan_mlme_get_enable_deauth_to_disassoc_map() - Get the deauth to disassoc + * map + * @psoc: pointer to psoc object + * @value: pointer to the value which will be filled for the caller + * + * Return: QDF Status + */ +QDF_STATUS +wlan_mlme_get_enable_deauth_to_disassoc_map(struct wlan_objmgr_psoc *psoc, + bool *value); + /** * wlan_mlme_get_ht_cap_info() - Get the HT cap info config * @psoc: pointer to psoc object diff --git a/components/mlme/dispatcher/src/wlan_mlme_api.c b/components/mlme/dispatcher/src/wlan_mlme_api.c index efc3da0ba1..ba7e173d64 100644 --- a/components/mlme/dispatcher/src/wlan_mlme_api.c +++ b/components/mlme/dispatcher/src/wlan_mlme_api.c @@ -90,6 +90,20 @@ char *wlan_mlme_get_power_usage(struct wlan_objmgr_psoc *psoc) return mlme_obj->cfg.power.power_usage.data; } +QDF_STATUS +wlan_mlme_get_enable_deauth_to_disassoc_map(struct wlan_objmgr_psoc *psoc, + bool *value) +{ + struct wlan_mlme_psoc_ext_obj *mlme_obj; + + mlme_obj = mlme_get_psoc_ext_obj(psoc); + if (!mlme_obj) + return QDF_STATUS_E_INVAL; + + *value = mlme_obj->cfg.gen.enable_deauth_to_disassoc_map; + return QDF_STATUS_SUCCESS; +} + QDF_STATUS wlan_mlme_get_ht_cap_info(struct wlan_objmgr_psoc *psoc, struct mlme_ht_capabilities_info *ht_cap_info) diff --git a/core/mac/src/pe/lim/lim_process_sme_req_messages.c b/core/mac/src/pe/lim/lim_process_sme_req_messages.c index 3a396b112f..18f6141429 100644 --- a/core/mac/src/pe/lim/lim_process_sme_req_messages.c +++ b/core/mac/src/pe/lim/lim_process_sme_req_messages.c @@ -58,12 +58,20 @@ #include "wma.h" #include <../../core/src/wlan_cm_vdev_api.h> #include +#include +#include /* SME REQ processing function templates */ static bool __lim_process_sme_sys_ready_ind(struct mac_context *, uint32_t *); static bool __lim_process_sme_start_bss_req(struct mac_context *, struct scheduler_msg *pMsg); static void __lim_process_sme_disassoc_req(struct mac_context *, uint32_t *); +static void lim_process_sme_disassoc_cnf(struct mac_context *mac_ctx, + struct scheduler_msg *msg); +static void lim_process_sme_deauth_req(struct mac_context *mac_ctx, + struct scheduler_msg *msg); +static void lim_process_sme_disassoc_req(struct mac_context *mac_ctx, + struct scheduler_msg *msg); static void __lim_process_sme_disassoc_cnf(struct mac_context *, uint32_t *); static void __lim_process_sme_deauth_req(struct mac_context *, uint32_t *); static bool __lim_process_sme_stop_bss_req(struct mac_context *, @@ -1487,9 +1495,132 @@ QDF_STATUS cm_process_join_req(struct scheduler_msg *msg) return status; } +static void lim_process_sb_disconnect_req(struct mac_context *mac_ctx, + struct pe_session *pe_session, + struct wlan_cm_vdev_discon_req *req) +{ + struct scheduler_msg msg = {0}; + struct disassoc_cnf disassoc_cnf = {0}; + + if (pe_session->limSmeState == eLIM_SME_WT_DEAUTH_STATE) + disassoc_cnf.messageType = eWNI_SME_DEAUTH_CNF; + else if (pe_session->limSmeState == eLIM_SME_WT_DISASSOC_STATE) + disassoc_cnf.messageType = eWNI_SME_DISASSOC_CNF; + disassoc_cnf.vdev_id = req->req.vdev_id; + disassoc_cnf.bssid = req->req.bssid; + disassoc_cnf.length = sizeof(disassoc_cnf); + disassoc_cnf.peer_macaddr = req->req.bssid; + + msg.bodyptr = &disassoc_cnf; + msg.type = disassoc_cnf.messageType; + lim_process_sme_disassoc_cnf(mac_ctx, &msg); +} + +static void lim_prepare_and_send_disassoc(struct mac_context *mac_ctx, + struct wlan_cm_vdev_discon_req *req) +{ + struct pe_session *pe_session; + struct scheduler_msg msg = {0}; + struct disassoc_req disassoc_req = {0}; + + pe_session = pe_find_session_by_bssid(mac_ctx, req->req.bssid.bytes, + &req->req.vdev_id); + if (!pe_session) + return; + + disassoc_req.messageType = eWNI_SME_DISASSOC_REQ; + disassoc_req.length = sizeof(disassoc_req); + disassoc_req.sessionId = req->req.vdev_id; + disassoc_req.bssid = req->req.bssid; + disassoc_req.peer_macaddr = req->req.bssid; + disassoc_req.reasonCode = req->req.reason_code; + if (req->req.reason_code == REASON_FW_TRIGGERED_ROAM_FAILURE) { + disassoc_req.process_ho_fail = true; + disassoc_req.doNotSendOverTheAir = 1; + } else if (wlan_cm_is_vdev_roaming(pe_session->vdev)) { + disassoc_req.doNotSendOverTheAir = 1; + } + + msg.bodyptr = &disassoc_req; + msg.type = eWNI_SME_DISASSOC_REQ; + lim_process_sme_disassoc_req(mac_ctx, &msg); +} + +static void lim_prepare_and_send_deauth(struct mac_context *mac_ctx, + struct wlan_cm_vdev_discon_req *req) +{ + struct scheduler_msg msg = {0}; + struct deauth_req deauth_req = {0}; + + deauth_req.messageType = eWNI_SME_DEAUTH_REQ; + deauth_req.length = sizeof(deauth_req); + deauth_req.vdev_id = req->req.vdev_id; + deauth_req.bssid = req->req.bssid; + deauth_req.peer_macaddr = req->req.bssid; + deauth_req.reasonCode = req->req.reason_code; + + msg.bodyptr = &deauth_req; + msg.type = eWNI_SME_DEAUTH_REQ; + lim_process_sme_deauth_req(mac_ctx, &msg); +} + +static void lim_process_nb_disconnect_req(struct mac_context *mac_ctx, + struct wlan_cm_vdev_discon_req *req) +{ + enum wlan_reason_code reason_code; + bool enable_deauth_to_disassoc_map = false; + + reason_code = req->req.reason_code; + + switch (reason_code) { + case REASON_PREV_AUTH_NOT_VALID: + case REASON_CLASS2_FRAME_FROM_NON_AUTH_STA: + lim_prepare_and_send_deauth(mac_ctx, req); + break; + case REASON_DEAUTH_NETWORK_LEAVING: + wlan_mlme_get_enable_deauth_to_disassoc_map( + mac_ctx->psoc, + &enable_deauth_to_disassoc_map); + if (enable_deauth_to_disassoc_map) { + req->req.reason_code = REASON_DISASSOC_NETWORK_LEAVING; + return lim_prepare_and_send_disassoc(mac_ctx, req); + } + lim_prepare_and_send_deauth(mac_ctx, req); + break; + default: + lim_prepare_and_send_disassoc(mac_ctx, req); + } +} + static QDF_STATUS lim_cm_handle_disconnect_req(struct wlan_cm_vdev_discon_req *req) { + struct mac_context *mac_ctx; + struct pe_session *pe_session; + + if (!req) + return QDF_STATUS_E_INVAL; + + mac_ctx = cds_get_context(QDF_MODULE_ID_PE); + if (!mac_ctx) + return QDF_STATUS_E_INVAL; + + pe_session = pe_find_session_by_bssid(mac_ctx, req->req.bssid.bytes, + &req->req.vdev_id); + if (!pe_session) { + /* + * TODO: Send disconnect resp from here while adding disconnect + * resp handeling. + */ + return QDF_STATUS_E_INVAL; + } + + if (req->req.source == CM_PEER_DISCONNECT || + req->req.source == CM_SB_DISCONNECT) + lim_process_sb_disconnect_req(mac_ctx, pe_session, req); + else + lim_process_nb_disconnect_req(mac_ctx, req); + return QDF_STATUS_SUCCESS; }