From 57692441c83de35d2b9f4636bc98dcc1369c325c Mon Sep 17 00:00:00 2001 From: Jianmin Zhu Date: Fri, 3 Jan 2020 11:43:09 +0800 Subject: [PATCH] qcacld-3.0: LFR2 failed for deleting wrong pe session During LFR2, new pe session is created before old pe session deleted, the 2 pe sessions have different pe session id, but same vdev id. After change-Id: Ib2e7c72e0636765341792a79aa12968a84ed4879, When delete old pe session DPH Entry, get pe session by vdev id instead of pe session id, since both new and old session have same vdev id, so there is 50% chance to get wrong pe session. then DPH Entry for STA 1 missing issue happens, then no reassoc happens. Fix: When delete old pe session DPH Entry, get pe session by both vdev id and PE mlm state: eLIM_MLM_WT_DEL_BSS_RSP_STATE. Change-Id: I207a4291cd26175ea7013fb2f2a0c27865304db2 CRs-Fixed: 2593194 --- core/mac/src/pe/include/lim_session.h | 20 +++++++++++++++++- .../src/pe/lim/lim_send_sme_rsp_messages.c | 6 +++--- core/mac/src/pe/lim/lim_session.c | 21 ++++++++++++++++++- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/core/mac/src/pe/include/lim_session.h b/core/mac/src/pe/include/lim_session.h index 014fff54a405..f7171fb29289 100644 --- a/core/mac/src/pe/include/lim_session.h +++ b/core/mac/src/pe/include/lim_session.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -652,6 +652,24 @@ struct pe_session *pe_find_session_by_bssid(struct mac_context *mac, uint8_t *bs struct pe_session *pe_find_session_by_vdev_id(struct mac_context *mac, uint8_t vdev_id); +/** + * pe_find_session_by_vdev_id_and_state() - Find PE session by vdev_id and + * mlm state. + * @mac: pointer to global adapter context + * @vdev_id: vdev id the session + * @vdev_id: vdev id the session + * + * During LFR2 roaming, new pe session is created before old pe session + * deleted, the 2 pe sessions have different pe session id, but same vdev id, + * can't get correct pe session by vdev id at this time. + * + * Return: pointer to the session context or NULL if session is not found. + */ +struct pe_session +*pe_find_session_by_vdev_id_and_state(struct mac_context *mac, + uint8_t vdev_id, + enum eLimMlmStates lim_state); + /** * pe_find_session_by_peer_sta() - looks up the PE session given the Peer * Station Address. diff --git a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c index 5bb756e9ac70..a33e448b9b44 100644 --- a/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c +++ b/core/mac/src/pe/lim/lim_send_sme_rsp_messages.c @@ -1850,10 +1850,10 @@ void lim_handle_delete_bss_rsp(struct mac_context *mac, struct pe_session *pe_session; pe_session = - pe_find_session_by_vdev_id(mac, del_bss_rsp->vdev_id); + pe_find_session_by_vdev_id_and_state(mac, + del_bss_rsp->vdev_id, + eLIM_MLM_WT_DEL_BSS_RSP_STATE); if (!pe_session) { - pe_err("Session Does not exist for vdev id: %d", - del_bss_rsp->vdev_id); qdf_mem_free(del_bss_rsp); return; } diff --git a/core/mac/src/pe/lim/lim_session.c b/core/mac/src/pe/lim/lim_session.c index c427343e2f39..2b0320582c39 100644 --- a/core/mac/src/pe/lim/lim_session.c +++ b/core/mac/src/pe/lim/lim_session.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2020 The Linux Foundation. All rights reserved. * * Permission to use, copy, modify, and/or distribute this software for * any purpose with or without fee is hereby granted, provided that the @@ -754,6 +754,25 @@ struct pe_session *pe_find_session_by_vdev_id(struct mac_context *mac, return NULL; } +struct pe_session +*pe_find_session_by_vdev_id_and_state(struct mac_context *mac, + uint8_t vdev_id, + enum eLimMlmStates lim_state) +{ + uint8_t i; + + for (i = 0; i < mac->lim.maxBssId; i++) { + if (mac->lim.gpSession[i].valid && + mac->lim.gpSession[i].vdev_id == vdev_id && + mac->lim.gpSession[i].limMlmState == lim_state) + return &mac->lim.gpSession[i]; + } + pe_debug("Session lookup fails for vdev_id: %d, mlm state: %d", + vdev_id, lim_state); + + return NULL; +} + /*-------------------------------------------------------------------------- \brief pe_find_session_by_session_id() - looks up the PE session given the session ID.