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);