From 52a3a3ad051119466d9124308dd47b7284659757 Mon Sep 17 00:00:00 2001 From: Kabilan Kannan Date: Tue, 10 Oct 2017 01:36:39 -0700 Subject: [PATCH] qcacmn: Fix TDLS set state cmd sequence in concurrent TDLS connections TDLS set state cmd to firmware is going out of sequence, if STA is disconnected, when concurrent TDLS connections are active. This out of sequence causes crash in the firmware. Fix the out of sequence issue, by grouping all the TDLS delete peer commands into one single command. Change-Id: Idd315d544c46bcf063881bff5be70cb5d9ad0ea2 CRs-Fixed: 2123838 --- os_if/linux/tdls/inc/wlan_cfg80211_tdls.h | 3 +++ os_if/linux/tdls/src/wlan_cfg80211_tdls.c | 2 ++ umac/tdls/core/src/wlan_tdls_ct.c | 1 - umac/tdls/core/src/wlan_tdls_ct.h | 12 ++++++++++++ umac/tdls/core/src/wlan_tdls_main.c | 7 +++++++ umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h | 1 + umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c | 1 + 7 files changed, 26 insertions(+), 1 deletion(-) diff --git a/os_if/linux/tdls/inc/wlan_cfg80211_tdls.h b/os_if/linux/tdls/inc/wlan_cfg80211_tdls.h index 9dc2da3bfc02..404495cc8141 100644 --- a/os_if/linux/tdls/inc/wlan_cfg80211_tdls.h +++ b/os_if/linux/tdls/inc/wlan_cfg80211_tdls.h @@ -224,6 +224,7 @@ hdd_notify_sta_connect(uint8_t session_id, * hdd_notify_sta_disconnect() - notify sta disconnect to TDLS * @session_id: pointer to soc object * @lfr_roam: indicate, whether disconnect due to lfr roam + * @bool user_disconnect: disconnect from user space * @vdev: vdev object manager * * Notify sta disconnect event to TDLS component @@ -232,6 +233,7 @@ hdd_notify_sta_connect(uint8_t session_id, */ void hdd_notify_sta_disconnect(uint8_t session_id, bool lfr_roam, + bool user_disconnect, struct wlan_objmgr_vdev *vdev); /** @@ -262,6 +264,7 @@ hdd_notify_sta_connect(uint8_t session_id, static inline void hdd_notify_sta_disconnect(uint8_t session_id, bool lfr_roam, + bool user_disconnect, struct wlan_objmgr_vdev *vdev) { diff --git a/os_if/linux/tdls/src/wlan_cfg80211_tdls.c b/os_if/linux/tdls/src/wlan_cfg80211_tdls.c index 08fc91b1bcdc..837c062abfa2 100644 --- a/os_if/linux/tdls/src/wlan_cfg80211_tdls.c +++ b/os_if/linux/tdls/src/wlan_cfg80211_tdls.c @@ -140,6 +140,7 @@ hdd_notify_sta_connect(uint8_t session_id, void hdd_notify_sta_disconnect(uint8_t session_id, bool lfr_roam, + bool user_disconnect, struct wlan_objmgr_vdev *vdev) { struct tdls_sta_notify_params notify_info; @@ -147,6 +148,7 @@ void hdd_notify_sta_disconnect(uint8_t session_id, notify_info.session_id = session_id; notify_info.lfr_roam = lfr_roam; notify_info.vdev = vdev; + notify_info.user_disconnect = user_disconnect; ucfg_tdls_notify_sta_disconnect(¬ify_info); } diff --git a/umac/tdls/core/src/wlan_tdls_ct.c b/umac/tdls/core/src/wlan_tdls_ct.c index 2b676114c892..801044283928 100644 --- a/umac/tdls/core/src/wlan_tdls_ct.c +++ b/umac/tdls/core/src/wlan_tdls_ct.c @@ -1157,7 +1157,6 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, * * Return: QDF_STATUS */ -static QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, struct tdls_soc_priv_obj *tdls_soc) { diff --git a/umac/tdls/core/src/wlan_tdls_ct.h b/umac/tdls/core/src/wlan_tdls_ct.h index 63e306378000..b713c971b4af 100644 --- a/umac/tdls/core/src/wlan_tdls_ct.h +++ b/umac/tdls/core/src/wlan_tdls_ct.h @@ -194,4 +194,16 @@ void tdls_teardown_connections(struct wlan_objmgr_vdev *vdev); void tdls_disable_offchan_and_teardown_links( struct wlan_objmgr_vdev *vdev); +/** + * tdls_delete_all_tdls_peers(): send request to delete tdls peers + * @vdev: vdev object + * @tdls_soc: tdls soc object + * + * This function sends request to lim to delete tdls peers + * + * Return: QDF_STATUS + */ +QDF_STATUS tdls_delete_all_tdls_peers(struct wlan_objmgr_vdev *vdev, + struct tdls_soc_priv_obj *tdls_soc); + #endif diff --git a/umac/tdls/core/src/wlan_tdls_main.c b/umac/tdls/core/src/wlan_tdls_main.c index b66edc02cdbd..53de84207855 100644 --- a/umac/tdls/core/src/wlan_tdls_main.c +++ b/umac/tdls/core/src/wlan_tdls_main.c @@ -915,6 +915,12 @@ tdls_process_sta_disconnect(struct tdls_sta_notify_params *notify) &tdls_soc_obj)) return QDF_STATUS_E_INVAL; + /* if the disconnect comes from user space, we have to delete all the + * tdls peers before sending the set state cmd. + */ + if (notify->user_disconnect) + return tdls_delete_all_tdls_peers(notify->vdev, tdls_soc_obj); + tdls_debug("Check and update TDLS state"); curr_tdls_vdev = tdls_vdev_obj; @@ -1026,6 +1032,7 @@ void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, notify->tdls_prohibited = false; notify->session_id = session_id; notify->vdev = vdev; + notify->user_disconnect = false; tdls_notify_sta_disconnect(notify); } diff --git a/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h index 4691869ffacd..eaed5612c74a 100644 --- a/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/umac/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -1012,6 +1012,7 @@ struct tdls_sta_notify_params { bool tdls_prohibited; bool tdls_chan_swit_prohibited; bool lfr_roam; + bool user_disconnect; uint8_t session_id; }; diff --git a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c index c5bf80475e8e..0d8f34c56aec 100644 --- a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c @@ -642,6 +642,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( notify->tdls_prohibited = false; notify->vdev = notify_info->vdev; notify->lfr_roam = notify_info->lfr_roam; + notify->user_disconnect = notify_info->user_disconnect; msg.bodyptr = notify; msg.callback = tdls_process_cmd;