From a266ccd8f0c74bce46343351735206f123512b53 Mon Sep 17 00:00:00 2001 From: Gururaj Pandurangi Date: Wed, 30 Sep 2020 12:31:01 -0700 Subject: [PATCH] qcacld-3.0: Modify connect start code in if mgr Modify connect start code in interface manager by moving disable roam and tdls link teardown notify APIs from HDD to if mgr. Alongside, move tdls link teardown notify API from HDD to if mgr in start bss API. Also, move the tdls link teardown API to TDLS module from HDD module as TDLS should manage the wait logic. Change-Id: I09fa31878563a3daaa7c5fde46327475829317b3 CRs-Fixed: 2811807 --- Kbuild | 1 + .../interface_mgr/inc/wlan_if_mgr_roam.h | 22 ++-- .../interface_mgr/src/wlan_if_mgr_roam.c | 14 +-- .../interface_mgr/src/wlan_if_mgr_sap.c | 9 +- .../interface_mgr/src/wlan_if_mgr_sta.c | 26 +++- components/tdls/core/src/wlan_tdls_ct.c | 29 ++--- components/tdls/core/src/wlan_tdls_ct.h | 12 +- components/tdls/core/src/wlan_tdls_main.c | 33 ++++-- components/tdls/core/src/wlan_tdls_main.h | 2 + .../tdls/dispatcher/inc/wlan_tdls_api.h | 42 +++++++ .../dispatcher/inc/wlan_tdls_public_structs.h | 8 ++ .../tdls/dispatcher/inc/wlan_tdls_ucfg_api.h | 17 ++- .../tdls/dispatcher/src/wlan_tdls_api.c | 111 ++++++++++++++++++ .../tdls/dispatcher/src/wlan_tdls_ucfg_api.c | 23 ++-- core/hdd/src/wlan_hdd_cfg80211.c | 23 +++- core/hdd/src/wlan_hdd_hostapd.c | 10 +- os_if/tdls/inc/wlan_cfg80211_tdls.h | 13 +- os_if/tdls/src/wlan_cfg80211_tdls.c | 49 -------- 18 files changed, 300 insertions(+), 144 deletions(-) create mode 100644 components/tdls/dispatcher/inc/wlan_tdls_api.h create mode 100644 components/tdls/dispatcher/src/wlan_tdls_api.c diff --git a/Kbuild b/Kbuild index 3955984360fd..ad7cb6c050af 100644 --- a/Kbuild +++ b/Kbuild @@ -1414,6 +1414,7 @@ TDLS_OBJS := $(TDLS_DIR)/core/src/wlan_tdls_main.o \ $(TDLS_DIR)/dispatcher/src/wlan_tdls_ucfg_api.o \ $(TDLS_DIR)/dispatcher/src/wlan_tdls_utils_api.o \ $(TDLS_DIR)/dispatcher/src/wlan_tdls_cfg.o \ + $(TDLS_DIR)/dispatcher/src/wlan_tdls_api.o \ $(TDLS_OS_IF_SRC)/wlan_cfg80211_tdls.o \ $(TDLS_TARGET_IF_SRC)/target_if_tdls.o endif diff --git a/components/cmn_services/interface_mgr/inc/wlan_if_mgr_roam.h b/components/cmn_services/interface_mgr/inc/wlan_if_mgr_roam.h index 486e69a882a2..0f2977cbe7ef 100644 --- a/components/cmn_services/interface_mgr/inc/wlan_if_mgr_roam.h +++ b/components/cmn_services/interface_mgr/inc/wlan_if_mgr_roam.h @@ -56,8 +56,8 @@ struct bssid_search_arg { /** * if_mgr_enable_roaming() - interface manager enable roaming - * @vdev: vdev object * @pdev: pdev object + * @vdev: vdev object * @requestor: RSO enable requestor * * Interface manager api to enable roaming for all other active vdev id's @@ -66,14 +66,14 @@ struct bssid_search_arg { * * Return: QDF_STATUS */ -QDF_STATUS if_mgr_enable_roaming(struct wlan_objmgr_vdev *vdev, - struct wlan_objmgr_pdev *pdev, +QDF_STATUS if_mgr_enable_roaming(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, enum wlan_cm_rso_control_requestor requestor); /** * if_mgr_disable_roaming() - interface manager disable roaming - * @vdev: vdev object * @pdev: pdev object + * @vdev: vdev object * @requestor: RSO disable requestor * * Interface manager api to disable roaming for all other active vdev id's @@ -82,15 +82,15 @@ QDF_STATUS if_mgr_enable_roaming(struct wlan_objmgr_vdev *vdev, * * Return: QDF_STATUS */ -QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_vdev *vdev, - struct wlan_objmgr_pdev *pdev, +QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, enum wlan_cm_rso_control_requestor requestor); /** * if_mgr_enable_roaming_on_connected_sta() - interface manager disable roaming * on connected STA - * @vdev: vdev object * @pdev: pdev object + * @vdev: vdev object * * Loops through connected vdevs and disables roaming if it is STA * @@ -99,14 +99,14 @@ QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_vdev *vdev, * Return: QDF_STATUS */ QDF_STATUS -if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_vdev *vdev, - struct wlan_objmgr_pdev *pdev); +if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev); /** * if_mgr_enable_roaming_after_p2p_disconnect() - interface manager enable * roaming after p2p disconnect - * @vdev: vdev object * @pdev: pdev object + * @vdev: vdev object * @requestor: RSO enable requestor * * Disables roaming on p2p vdevs if the state is disconnected @@ -116,8 +116,8 @@ if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_vdev *vdev, * Return: QDF_STATUS */ QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect( - struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, enum wlan_cm_rso_control_requestor requestor); /** diff --git a/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c b/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c index afb63a4b395e..72c7ba78a078 100644 --- a/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c +++ b/components/cmn_services/interface_mgr/src/wlan_if_mgr_roam.c @@ -50,8 +50,8 @@ static void if_mgr_enable_roaming_on_vdev(struct wlan_objmgr_pdev *pdev, } } -QDF_STATUS if_mgr_enable_roaming(struct wlan_objmgr_vdev *vdev, - struct wlan_objmgr_pdev *pdev, +QDF_STATUS if_mgr_enable_roaming(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, enum wlan_cm_rso_control_requestor requestor) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -95,8 +95,8 @@ static void if_mgr_disable_roaming_on_vdev(struct wlan_objmgr_pdev *pdev, } } -QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_vdev *vdev, - struct wlan_objmgr_pdev *pdev, +QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, enum wlan_cm_rso_control_requestor requestor) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -117,8 +117,8 @@ QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_vdev *vdev, } QDF_STATUS -if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_vdev *vdev, - struct wlan_objmgr_pdev *pdev) +if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev) { struct wlan_objmgr_psoc *psoc; uint8_t vdev_id; @@ -140,8 +140,8 @@ if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_vdev *vdev, } QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect( - struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_pdev *pdev, + struct wlan_objmgr_vdev *vdev, enum wlan_cm_rso_control_requestor requestor) { QDF_STATUS status = QDF_STATUS_SUCCESS; diff --git a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c index d2aed42bb005..3e3ec38b6222 100644 --- a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c +++ b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sap.c @@ -25,6 +25,7 @@ #include "wlan_policy_mgr_api.h" #include "wlan_if_mgr_main.h" #include "wlan_p2p_cfg_api.h" +#include "wlan_tdls_api.h" QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev, struct if_mgr_event_data *event_data) @@ -40,6 +41,8 @@ QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev, if (!psoc) return QDF_STATUS_E_FAILURE; + wlan_tdls_teardown_links_sync(psoc); + if (policy_mgr_is_hw_mode_change_in_progress(psoc)) { if (!QDF_IS_STATUS_SUCCESS( policy_mgr_wait_for_connection_update(psoc))) { @@ -50,7 +53,7 @@ QDF_STATUS if_mgr_ap_start_bss(struct wlan_objmgr_vdev *vdev, if (policy_mgr_is_sta_active_connection_exists(psoc)) /* Disable Roaming on all vdev's before starting bss */ - if_mgr_disable_roaming(vdev, pdev, RSO_START_BSS); + if_mgr_disable_roaming(pdev, vdev, RSO_START_BSS); return QDF_STATUS_SUCCESS; } @@ -82,7 +85,7 @@ if_mgr_ap_start_bss_complete(struct wlan_objmgr_vdev *vdev, ifmgr_debug("p2p go mode, keep roam disabled"); } else { /* Enable Roaming after start bss in case of failure/success */ - if_mgr_enable_roaming(vdev, pdev, RSO_START_BSS); + if_mgr_enable_roaming(pdev, vdev, RSO_START_BSS); } return QDF_STATUS_SUCCESS; @@ -119,7 +122,7 @@ if_mgr_ap_stop_bss_complete(struct wlan_objmgr_vdev *vdev, if (cfg_p2p_is_roam_config_disabled(psoc) && wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) { ifmgr_debug("p2p go disconnected enable roam"); - if_mgr_enable_roaming(vdev, pdev, RSO_START_BSS); + if_mgr_enable_roaming(pdev, vdev, RSO_START_BSS); } return QDF_STATUS_SUCCESS; diff --git a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c index b2a14af54f43..abdc582b1bbb 100644 --- a/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c +++ b/components/cmn_services/interface_mgr/src/wlan_if_mgr_sta.c @@ -27,15 +27,21 @@ #include "wlan_policy_mgr_api.h" #include "wlan_p2p_ucfg_api.h" #include "wlan_tdls_ucfg_api.h" +#include "wlan_tdls_api.h" QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev, struct if_mgr_event_data *event_data) { uint8_t sta_cnt, sap_cnt; + struct wlan_objmgr_pdev *pdev; struct wlan_objmgr_psoc *psoc; enum QDF_OPMODE op_mode; - psoc = wlan_vdev_get_psoc(vdev); + pdev = wlan_vdev_get_pdev(vdev); + if (!pdev) + return QDF_STATUS_E_FAILURE; + + psoc = wlan_pdev_get_psoc(pdev); if (!psoc) return QDF_STATUS_E_FAILURE; @@ -68,6 +74,16 @@ QDF_STATUS if_mgr_connect_start(struct wlan_objmgr_vdev *vdev, ucfg_nan_check_and_disable_unsupported_ndi(psoc, false); + /* + * In case of STA+STA concurrency, firmware might try to roam + * to same AP where host is trying to do association on the other + * STA iface. Roaming is disabled on all the ifaces to avoid + * this scenario. + */ + if_mgr_disable_roaming(pdev, vdev, RSO_CONNECT_START); + + wlan_tdls_teardown_links_sync(psoc); + return QDF_STATUS_SUCCESS; } @@ -106,7 +122,7 @@ QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev, * Firmware doesn't support connection on one STA iface * while roaming on other STA iface. */ - if_mgr_enable_roaming(vdev, pdev, RSO_CONNECT_START); + if_mgr_enable_roaming(pdev, vdev, RSO_CONNECT_START); } } else { /* notify connect failure on final failure */ @@ -117,7 +133,7 @@ QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev, * Firmware doesn't support connection on one STA iface * while roaming on other STA iface. */ - if_mgr_enable_roaming(vdev, pdev, RSO_CONNECT_START); + if_mgr_enable_roaming(pdev, vdev, RSO_CONNECT_START); } policy_mgr_check_n_start_opportunistic_timer(psoc); @@ -161,7 +177,7 @@ QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev, if (!psoc) return QDF_STATUS_E_FAILURE; - status = if_mgr_enable_roaming_after_p2p_disconnect(vdev, pdev, + status = if_mgr_enable_roaming_after_p2p_disconnect(pdev, vdev, RSO_INVALID_REQUESTOR); if (status) { ifmgr_err("Failed to enable roaming after p2p disconnect"); @@ -170,7 +186,7 @@ QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev, policy_mgr_check_concurrent_intf_and_restart_sap(psoc); - status = if_mgr_enable_roaming_on_connected_sta(vdev, pdev); + status = if_mgr_enable_roaming_on_connected_sta(pdev, vdev); if (status) { ifmgr_err("Failed to enable roaming on connected sta"); return status; diff --git a/components/tdls/core/src/wlan_tdls_ct.c b/components/tdls/core/src/wlan_tdls_ct.c index 8ead54eddb72..29a60701e8c6 100644 --- a/components/tdls/core/src/wlan_tdls_ct.c +++ b/components/tdls/core/src/wlan_tdls_ct.c @@ -1315,30 +1315,27 @@ void tdls_disable_offchan_and_teardown_links( } } -void tdls_teardown_connections(struct wlan_objmgr_psoc *psoc) +void tdls_teardown_connections(struct tdls_link_teardown *tdls_teardown) { - struct tdls_osif_indication indication; - struct tdls_soc_priv_obj *tdls_soc; + struct tdls_vdev_priv_obj *tdls_vdev_obj; struct wlan_objmgr_vdev *tdls_vdev; - - tdls_soc = wlan_psoc_get_tdls_soc_obj(psoc); - if (!tdls_soc) - return; - /* Get the tdls specific vdev and clear the links */ - tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_SB_ID); + tdls_vdev = tdls_get_vdev(tdls_teardown->psoc, WLAN_TDLS_SB_ID); if (!tdls_vdev) { tdls_err("Unable get the vdev"); return; } + + tdls_vdev_obj = wlan_vdev_get_tdls_vdev_obj(tdls_vdev); + if (!tdls_vdev_obj) { + tdls_err("vdev priv is NULL"); + return; + } + tdls_disable_offchan_and_teardown_links(tdls_vdev); - - indication.vdev = tdls_vdev; - - if (tdls_soc->tdls_event_cb) - tdls_soc->tdls_event_cb(tdls_soc->tdls_evt_cb_data, - TDLS_EVENT_TEARDOWN_LINKS_DONE, - &indication); + qdf_event_set(&tdls_vdev_obj->tdls_teardown_comp); wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_SB_ID); + wlan_objmgr_psoc_release_ref(tdls_teardown->psoc, WLAN_TDLS_SB_ID); + qdf_mem_free(tdls_teardown); } diff --git a/components/tdls/core/src/wlan_tdls_ct.h b/components/tdls/core/src/wlan_tdls_ct.h index 48718e628f97..f99c9d7c5c02 100644 --- a/components/tdls/core/src/wlan_tdls_ct.h +++ b/components/tdls/core/src/wlan_tdls_ct.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-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 @@ -152,7 +152,7 @@ void tdls_discovery_timeout_peer_cb(void *user_data); void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev); /** - * tdls_is_vdev_authenticated() -check the vdev authentication state + * tdls_is_vdev_authenticated() - check the vdev authentication state * @vdev: vdev oobject * * Return: true or false @@ -160,12 +160,12 @@ void tdls_implicit_disable(struct tdls_vdev_priv_obj *tdls_vdev); bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev); /** - * tdls_teardown_connections() -teardown and delete all the tdls peers - * @psoc: psoc object + * tdls_teardown_connections() - teardown and delete all the tdls peers + * @tdls_teardown: tdls teardown struct * * Return: true or false */ -void tdls_teardown_connections(struct wlan_objmgr_psoc *psoc); +void tdls_teardown_connections(struct tdls_link_teardown *tdls_teardown); /** * tdls_disable_offchan_and_teardown_links - Disable offchannel @@ -178,7 +178,7 @@ void tdls_disable_offchan_and_teardown_links( struct wlan_objmgr_vdev *vdev); /** - * tdls_delete_all_tdls_peers(): send request to delete tdls peers + * tdls_delete_all_tdls_peers() - send request to delete tdls peers * @vdev: vdev object * @tdls_soc: tdls soc object * diff --git a/components/tdls/core/src/wlan_tdls_main.c b/components/tdls/core/src/wlan_tdls_main.c index ec418679d65e..57e5fe5da468 100644 --- a/components/tdls/core/src/wlan_tdls_main.c +++ b/components/tdls/core/src/wlan_tdls_main.c @@ -271,7 +271,7 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, tdls_vdev_obj = qdf_mem_malloc(sizeof(*tdls_vdev_obj)); if (!tdls_vdev_obj) { status = QDF_STATUS_E_NOMEM; - goto err; + goto err_attach; } status = wlan_objmgr_vdev_component_obj_attach(vdev, @@ -280,12 +280,16 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, QDF_STATUS_SUCCESS); if (QDF_IS_STATUS_ERROR(status)) { tdls_err("Failed to attach vdev tdls component"); - goto err; + goto err_attach; } tdls_vdev_obj->vdev = vdev; status = tdls_vdev_init(tdls_vdev_obj); if (QDF_IS_STATUS_ERROR(status)) - goto err; + goto err_vdev_init; + + status = qdf_event_create(&tdls_vdev_obj->tdls_teardown_comp); + if (QDF_IS_STATUS_ERROR(status)) + goto err_event_create; pdev = wlan_vdev_get_pdev(vdev); @@ -295,19 +299,28 @@ QDF_STATUS tdls_vdev_obj_create_notification(struct wlan_objmgr_vdev *vdev, if (QDF_STATUS_SUCCESS != status) { tdls_err("scan event register failed "); - tdls_vdev_deinit(tdls_vdev_obj); - goto err; + goto err_register; } tdls_debug("tdls object attach to vdev successfully"); return status; -err: + +err_register: + qdf_event_destroy(&tdls_vdev_obj->tdls_teardown_comp); +err_event_create: + tdls_vdev_deinit(tdls_vdev_obj); +err_vdev_init: + wlan_objmgr_vdev_component_obj_detach(vdev, + WLAN_UMAC_COMP_TDLS, + (void *)tdls_vdev_obj); +err_attach: if (tdls_soc_obj->tdls_osif_deinit_cb) tdls_soc_obj->tdls_osif_deinit_cb(vdev); if (tdls_vdev_obj) { qdf_mem_free(tdls_vdev_obj); tdls_vdev_obj = NULL; } + return status; } @@ -315,7 +328,7 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, void *arg) { QDF_STATUS status; - void *tdls_vdev_obj; + struct tdls_vdev_priv_obj *tdls_vdev_obj; struct tdls_soc_priv_obj *tdls_soc_obj; uint32_t tdls_feature_flags; @@ -343,16 +356,18 @@ QDF_STATUS tdls_vdev_obj_destroy_notification(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_FAILURE; } + qdf_event_destroy(&tdls_vdev_obj->tdls_teardown_comp); + tdls_vdev_deinit(tdls_vdev_obj); + status = wlan_objmgr_vdev_component_obj_detach(vdev, WLAN_UMAC_COMP_TDLS, tdls_vdev_obj); if (QDF_IS_STATUS_ERROR(status)) tdls_err("Failed to detach vdev tdls component"); - tdls_vdev_deinit(tdls_vdev_obj); - qdf_mem_free(tdls_vdev_obj); if (tdls_soc_obj->tdls_osif_deinit_cb) tdls_soc_obj->tdls_osif_deinit_cb(vdev); + qdf_mem_free(tdls_vdev_obj); return status; } diff --git a/components/tdls/core/src/wlan_tdls_main.h b/components/tdls/core/src/wlan_tdls_main.h index b854fe10a741..bf3c7d3e0eed 100644 --- a/components/tdls/core/src/wlan_tdls_main.h +++ b/components/tdls/core/src/wlan_tdls_main.h @@ -255,6 +255,7 @@ struct tdls_soc_priv_obj { * @valid_mac_entries: number of valid mac entry in @ct_peer_mac_table * @magic: magic * @tx_queue: tx frame queue + * @tdls_teardown_comp: tdls teardown completion */ struct tdls_vdev_priv_obj { struct wlan_objmgr_vdev *vdev; @@ -271,6 +272,7 @@ struct tdls_vdev_priv_obj { uint32_t magic; uint8_t session_id; qdf_list_t tx_queue; + qdf_event_t tdls_teardown_comp; }; /** diff --git a/components/tdls/dispatcher/inc/wlan_tdls_api.h b/components/tdls/dispatcher/inc/wlan_tdls_api.h new file mode 100644 index 000000000000..67ef3fd67bdd --- /dev/null +++ b/components/tdls/dispatcher/inc/wlan_tdls_api.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 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 above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * DOC: contains tdls link teardown declarations + */ + #ifndef _WLAN_TDLS_API_H_ + #define _WLAN_TDLS_API_H_ + +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_objmgr_pdev_obj.h" +#include "wlan_objmgr_vdev_obj.h" + +/** + * wlan_tdls_teardown_links() - notify TDLS module to teardown all TDLS links + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS wlan_tdls_teardown_links(struct wlan_objmgr_psoc *psoc); + +/** + * wlan_tdls_teardown_links_sync() - teardown all the TDLS links + * @psoc: psoc object + * + * Return: None + */ +void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc); +#endif diff --git a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h index b73866b415cb..4ae3784b58de 100644 --- a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -1337,4 +1337,12 @@ struct tdls_del_sta_req { struct qdf_mac_addr peermac; }; +/** + * struct tdls_link_teardown - TDLS link teardown struct + * @psoc: soc object + */ +struct tdls_link_teardown { + struct wlan_objmgr_psoc *psoc; +}; + #endif diff --git a/components/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h b/components/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h index 7033beca04e7..11d24dfdd7ec 100644 --- a/components/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h +++ b/components/tdls/dispatcher/inc/wlan_tdls_ucfg_api.h @@ -152,12 +152,20 @@ QDF_STATUS ucfg_tdls_send_mgmt_frame( QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *msg_req); /** - * ucfg_tdls_teardown_links() - teardown all TDLS links + * ucfg_tdls_teardown_links() - notify TDLS modules to teardown all TDLS links. + * @psoc: psoc object + * + * Return: QDF_STATUS + */ +QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_psoc *psoc); + +/** + * ucfg_tdls_teardown_links_sync() - teardown all TDLS links. * @psoc: psoc object * * Return: None */ -QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_psoc *psoc); +void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc); /** * ucfg_tdls_notify_reset_adapter() - notify reset adapter @@ -350,6 +358,11 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_psoc *psoc) return QDF_STATUS_SUCCESS; } +static inline +void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc) +{ +} + static inline QDF_STATUS ucfg_tdls_set_rssi(struct wlan_objmgr_vdev *vdev, uint8_t *mac, int8_t rssi) diff --git a/components/tdls/dispatcher/src/wlan_tdls_api.c b/components/tdls/dispatcher/src/wlan_tdls_api.c new file mode 100644 index 000000000000..d0ac6b51b49b --- /dev/null +++ b/components/tdls/dispatcher/src/wlan_tdls_api.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 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 above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * DOC: contains tdls link teardown definitions + */ + +#include "wlan_objmgr_psoc_obj.h" +#include "wlan_objmgr_pdev_obj.h" +#include "wlan_objmgr_vdev_obj.h" +#include "wlan_tdls_api.h" +#include "../../core/src/wlan_tdls_main.h" +#include "../../core/src/wlan_tdls_ct.h" +#include "../../core/src/wlan_tdls_mgmt.h" +#include +#include + +static QDF_STATUS tdls_teardown_flush_cb(struct scheduler_msg *msg) +{ + struct tdls_link_teardown *tdls_teardown = msg->bodyptr; + struct wlan_objmgr_psoc *psoc = tdls_teardown->psoc; + + wlan_objmgr_psoc_release_ref(psoc, WLAN_TDLS_SB_ID); + qdf_mem_free(tdls_teardown); + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS wlan_tdls_teardown_links(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct scheduler_msg msg = {0, }; + struct tdls_link_teardown *link_teardown; + + link_teardown = qdf_mem_malloc(sizeof(*link_teardown)); + if (!link_teardown) + return QDF_STATUS_E_NOMEM; + + wlan_objmgr_psoc_get_ref(psoc, WLAN_TDLS_SB_ID); + link_teardown->psoc = psoc; + msg.bodyptr = link_teardown; + msg.callback = tdls_process_cmd; + msg.flush_callback = tdls_teardown_flush_cb; + msg.type = TDLS_CMD_TEARDOWN_LINKS; + + status = scheduler_post_message(QDF_MODULE_ID_HDD, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_OS_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post msg fail, %d", status); + wlan_objmgr_psoc_release_ref(psoc, WLAN_TDLS_SB_ID); + qdf_mem_free(link_teardown); + } + + return status; +} + +void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc) +{ + struct tdls_vdev_priv_obj *vdev_priv_obj; + QDF_STATUS status; + struct wlan_objmgr_vdev *vdev; + + vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); + if (!vdev) + return; + + vdev_priv_obj = wlan_vdev_get_tdls_vdev_obj(vdev); + if (!vdev_priv_obj) { + tdls_err("vdev priv is NULL"); + goto release_ref; + } + + qdf_event_reset(&vdev_priv_obj->tdls_teardown_comp); + + status = wlan_tdls_teardown_links(psoc); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("wlan_tdls_teardown_links failed err %d", status); + goto release_ref; + } + + tdls_debug("Wait for tdls teardown completion. Timeout %u ms", + WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS); + + status = qdf_wait_for_event_completion( + &vdev_priv_obj->tdls_teardown_comp, + WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err(" Teardown Completion timed out %d", status); + goto release_ref; + } + + tdls_debug("TDLS teardown completion status %d ", status); + +release_ref: + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_NB_ID); +} diff --git a/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c b/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c index 9cdff05b7c26..0838f81bcfde 100644 --- a/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/components/tdls/dispatcher/src/wlan_tdls_ucfg_api.c @@ -34,6 +34,7 @@ #include "wlan_scan_ucfg_api.h" #include "wlan_tdls_cfg.h" #include "cfg_ucfg_api.h" +#include "wlan_tdls_api.h" QDF_STATUS ucfg_tdls_init(void) { @@ -487,7 +488,6 @@ static QDF_STATUS ucfg_tdls_post_msg_flush_cb(struct scheduler_msg *msg) struct wlan_objmgr_vdev *vdev = NULL; switch (msg->type) { - case TDLS_CMD_TEARDOWN_LINKS: case TDLS_NOTIFY_RESET_ADAPTERS: ptr = NULL; break; @@ -826,23 +826,14 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req) return status; } +void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc) +{ + return wlan_tdls_teardown_links_sync(psoc); +} + QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_psoc *psoc) { - QDF_STATUS status; - struct scheduler_msg msg = {0, }; - - tdls_debug("Enter "); - - msg.bodyptr = psoc; - msg.callback = tdls_process_cmd; - msg.flush_callback = ucfg_tdls_post_msg_flush_cb; - msg.type = TDLS_CMD_TEARDOWN_LINKS; - status = scheduler_post_message(QDF_MODULE_ID_HDD, - QDF_MODULE_ID_TDLS, - QDF_MODULE_ID_OS_IF, &msg); - - tdls_debug("Exit "); - return status; + return wlan_tdls_teardown_links(psoc); } QDF_STATUS ucfg_tdls_notify_reset_adapter(struct wlan_objmgr_vdev *vdev) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 6f83123b0f39..c84ab53496ad 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -110,6 +110,7 @@ #include #include #include "wlan_tdls_cfg_api.h" +#include "wlan_tdls_ucfg_api.h" #include #include #include @@ -18757,11 +18758,24 @@ static int wlan_hdd_cfg80211_connect_start(struct hdd_adapter *adapter, goto ret_status; } + /** + * Following code will be cleaned once the interface manager + * module is enabled. + */ +#ifdef WLAN_FEATURE_INTERFACE_MGR + vdev = hdd_objmgr_get_vdev(adapter); + if (!vdev) + return -EINVAL; + + ucfg_if_mgr_deliver_event(vdev, WLAN_IF_MGR_EV_CONNECT_START, NULL); + + hdd_objmgr_put_vdev(vdev); +#else /* Disable roaming on all other adapters before connect start */ wlan_hdd_disable_roaming(adapter, RSO_CONNECT_START); - hdd_notify_teardown_tdls_links(hdd_ctx->psoc); - + ucfg_tdls_teardown_links_sync(hdd_ctx->psoc); +#endif qdf_mem_zero(&hdd_sta_ctx->conn_info.conn_flag, sizeof(hdd_sta_ctx->conn_info.conn_flag)); @@ -20785,10 +20799,7 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, * Following code will be cleaned up once the interface manager * module is enabled */ -#ifdef WLAN_FEATURE_INTERFACE_MGR - ucfg_if_mgr_deliver_event(adapter->vdev, WLAN_IF_MGR_EV_CONNECT_START, - NULL); -#else +#ifndef WLAN_FEATURE_INTERFACE_MGR /* * Disable NAN Discovery if incoming connection is P2P or if a STA * connection already exists and if this is a case of STA+STA diff --git a/core/hdd/src/wlan_hdd_hostapd.c b/core/hdd/src/wlan_hdd_hostapd.c index d499449dcbd7..fdb8f51f87fa 100644 --- a/core/hdd/src/wlan_hdd_hostapd.c +++ b/core/hdd/src/wlan_hdd_hostapd.c @@ -94,6 +94,7 @@ #include "wlan_hdd_sta_info.h" #include "ftm_time_sync_ucfg_api.h" #include +#include "wlan_tdls_ucfg_api.h" #ifdef WLAN_FEATURE_INTERFACE_MGR #include "wlan_if_mgr_ucfg_api.h" #include "wlan_if_mgr_public_struct.h" @@ -5138,8 +5139,13 @@ int wlan_hdd_cfg80211_start_bss(struct hdd_adapter *adapter, if (policy_mgr_is_sta_mon_concurrency(hdd_ctx->psoc)) return -EINVAL; - hdd_notify_teardown_tdls_links(hdd_ctx->psoc); - + /** + * Following code will be cleaned once the interface manager + * module is enabled. + */ +#ifndef WLAN_FEATURE_INTERFACE_MGR + ucfg_tdls_teardown_links_sync(hdd_ctx->psoc); +#endif ucfg_mlme_get_sap_force_11n_for_11ac(hdd_ctx->psoc, &sap_force_11n_for_11ac); ucfg_mlme_get_go_force_11n_for_11ac(hdd_ctx->psoc, diff --git a/os_if/tdls/inc/wlan_cfg80211_tdls.h b/os_if/tdls/inc/wlan_cfg80211_tdls.h index 29059b5bd26f..bde9a56fe889 100644 --- a/os_if/tdls/inc/wlan_cfg80211_tdls.h +++ b/os_if/tdls/inc/wlan_cfg80211_tdls.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 The Linux Foundation. All rights reserved. + * Copyright (c) 2017-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 @@ -259,17 +259,6 @@ void hdd_notify_sta_disconnect(uint8_t session_id, bool user_disconnect, struct wlan_objmgr_vdev *vdev); -/** - * hdd_notify_teardown_tdls_links() - notify TDLS to teardown links - * @psoc: psoc object - * - * Notify tdls to teardown all the links, due to certain events - * in the system - * - * Return: None - */ -void hdd_notify_teardown_tdls_links(struct wlan_objmgr_psoc *psoc); - #else /* FEATURE_WLAN_TDLS */ static inline QDF_STATUS wlan_cfg80211_tdls_osif_priv_init(struct wlan_objmgr_vdev *vdev) diff --git a/os_if/tdls/src/wlan_cfg80211_tdls.c b/os_if/tdls/src/wlan_cfg80211_tdls.c index ec6bf3529b3b..b2991a4340ad 100644 --- a/os_if/tdls/src/wlan_cfg80211_tdls.c +++ b/os_if/tdls/src/wlan_cfg80211_tdls.c @@ -98,52 +98,6 @@ void wlan_cfg80211_tdls_osif_priv_deinit(struct wlan_objmgr_vdev *vdev) osif_priv->osif_tdls = NULL; } -void hdd_notify_teardown_tdls_links(struct wlan_objmgr_psoc *psoc) -{ - struct vdev_osif_priv *osif_priv; - struct osif_tdls_vdev *tdls_priv; - QDF_STATUS status; - unsigned long rc; - struct wlan_objmgr_vdev *vdev; - - vdev = ucfg_get_tdls_vdev(psoc, WLAN_OSIF_ID); - if (!vdev) - return; - - osif_priv = wlan_vdev_get_ospriv(vdev); - - if (!osif_priv || !osif_priv->osif_tdls) { - osif_err("osif priv or tdls priv is NULL"); - goto release_ref; - } - tdls_priv = osif_priv->osif_tdls; - - reinit_completion(&tdls_priv->tdls_teardown_comp); - status = ucfg_tdls_teardown_links(psoc); - if (QDF_IS_STATUS_ERROR(status)) { - osif_err("ucfg_tdls_teardown_links failed err %d", status); - goto release_ref; - } - - osif_debug("Wait for tdls teardown completion. Timeout %u ms", - WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS); - - rc = wait_for_completion_timeout( - &tdls_priv->tdls_teardown_comp, - msecs_to_jiffies(WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS)); - - if (0 == rc) { - osif_err(" Teardown Completion timed out rc: %ld", rc); - goto release_ref; - } - - osif_debug("TDLS teardown completion status %ld ", rc); - -release_ref: - wlan_objmgr_vdev_release_ref(vdev, - WLAN_OSIF_ID); -} - void hdd_notify_tdls_reset_adapter(struct wlan_objmgr_vdev *vdev) { ucfg_tdls_notify_reset_adapter(vdev); @@ -972,9 +926,6 @@ void wlan_cfg80211_tdls_event_callback(void *user_data, case TDLS_EVENT_SETUP_REQ: wlan_cfg80211_tdls_indicate_setup(ind); break; - case TDLS_EVENT_TEARDOWN_LINKS_DONE: - complete(&tdls_priv->tdls_teardown_comp); - break; case TDLS_EVENT_USER_CMD: tdls_priv->tdls_user_cmd_len = ind->status; complete(&tdls_priv->tdls_user_cmd_comp);