From 49f4bf7e0d40139d1faf9dadc5dbe8e21b02ebb0 Mon Sep 17 00:00:00 2001 From: Lincoln Tran Date: Thu, 20 Aug 2020 16:03:24 -0700 Subject: [PATCH] qcacld-3.0: Add disconnect changes to interface mgr Add disconnect start and disconnect complete event handlers to the interface manager. Add disable roaming, enable roaming on connnected STA, and enable roaming after P2P disconnect APIs. This change is part of the connection manager effort. Change-Id: Ib68b9ef9ff5b6541d7393bfbe6332a68b17bd587 CRs-fixed: 2760090 --- .../interface_mgr/inc/wlan_if_mgr_roam.h | 47 +++++++ .../interface_mgr/src/wlan_if_mgr_roam.c | 127 +++++++++++++++++- .../interface_mgr/src/wlan_if_mgr_sta.c | 54 ++++++++ core/hdd/src/wlan_hdd_assoc.c | 27 ++++ core/hdd/src/wlan_hdd_cfg80211.c | 13 ++ 5 files changed, 267 insertions(+), 1 deletion(-) 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 38c7d4643ff4..71920261d890 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 @@ -27,6 +27,19 @@ #include "wlan_policy_mgr_api.h" #include "wlan_if_mgr_roam.h" +/** + * struct change_roam_state_arg - Contains roam state arguments + * @requestor: Driver disabled roaming requestor + * @curr_vdev_id: Pointer to current vdev objmgr + * + * This structure is used to pass the roam state change information to the + * callback + */ +struct change_roam_state_arg { + enum wlan_cm_rso_control_requestor requestor; + uint8_t curr_vdev_id; +}; + /** * if_mgr_enable_roaming() - interface manager enable roaming * @vdev: vdev object @@ -59,4 +72,38 @@ QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_pdev *pdev, 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 + * + * Loops through connected vdevs and disables roaming if it is STA + * + * Context: It should run in thread context + * + * 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_after_p2p_disconnect() - interface manager enable + * roaming after p2p disconnect + * @vdev: vdev object + * @pdev: pdev object + * @requestor: RSO disable requestor + * + * Disables roaming on p2p vdevs if the state is disconnected + * + * Context: It should run in thread context + * + * Return: QDF_STATUS + */ +QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect( + struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_pdev *pdev, + enum wlan_cm_rso_control_requestor requestor); + #endif 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 899b0dce4136..f97064967680 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 @@ -26,16 +26,141 @@ #include "wlan_if_mgr_main.h" #include "wlan_p2p_ucfg_api.h" +static void if_mgr_enable_roaming_on_vdev(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; + struct change_roam_state_arg *roam_arg = arg; + uint8_t vdev_id, curr_vdev_id; + + vdev_id = wlan_vdev_get_id(vdev); + curr_vdev_id = roam_arg->curr_vdev_id; + + if (curr_vdev_id != vdev_id && + vdev->vdev_mlme.vdev_opmode == QDF_STA_MODE && + vdev->vdev_mlme.mlme_state == WLAN_VDEV_S_UP) { + wlan_cm_enable_rso(pdev, vdev_id, roam_arg->requestor, + REASON_DRIVER_ENABLED); + } +} + QDF_STATUS if_mgr_enable_roaming(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_pdev *pdev, enum wlan_cm_rso_control_requestor requestor) { - return QDF_STATUS_SUCCESS; + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct change_roam_state_arg roam_arg; + uint8_t vdev_id; + + vdev_id = wlan_vdev_get_id(vdev); + + roam_arg.requestor = requestor; + roam_arg.curr_vdev_id = vdev_id; + + status = wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + if_mgr_enable_roaming_on_vdev, + &roam_arg, 0, + WLAN_IF_MGR_ID); + + return status; +} + +static void if_mgr_disable_roaming_on_vdev(struct wlan_objmgr_pdev *pdev, + void *object, void *arg) +{ + struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object; + struct change_roam_state_arg *roam_arg = arg; + uint8_t vdev_id, curr_vdev_id; + + vdev_id = wlan_vdev_get_id(vdev); + curr_vdev_id = roam_arg->curr_vdev_id; + + if (curr_vdev_id != vdev_id && + wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE && + vdev->vdev_mlme.mlme_state == WLAN_VDEV_S_UP) { + wlan_cm_disable_rso(pdev, vdev_id, roam_arg->requestor, + REASON_DRIVER_DISABLED); + } } QDF_STATUS if_mgr_disable_roaming(struct wlan_objmgr_vdev *vdev, struct wlan_objmgr_pdev *pdev, enum wlan_cm_rso_control_requestor requestor) { + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct change_roam_state_arg roam_arg; + uint8_t vdev_id; + + vdev_id = wlan_vdev_get_id(vdev); + + roam_arg.requestor = requestor; + roam_arg.curr_vdev_id = vdev_id; + + status = wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + if_mgr_disable_roaming_on_vdev, + &roam_arg, 0, + WLAN_IF_MGR_ID); + + return status; +} + +QDF_STATUS +if_mgr_enable_roaming_on_connected_sta(struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_pdev *pdev) +{ + struct wlan_objmgr_psoc *psoc; + uint8_t vdev_id; + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) + return QDF_STATUS_E_FAILURE; + + vdev_id = wlan_vdev_get_id(vdev); + + if (policy_mgr_is_sta_active_connection_exists(psoc) && + wlan_vdev_mlme_get_opmode(vdev) == QDF_STA_MODE) { + wlan_cm_enable_roaming_on_connected_sta(pdev, vdev_id); + policy_mgr_clear_and_set_pcl_for_connected_vdev(psoc, vdev_id, + true); + } + return QDF_STATUS_SUCCESS; } + +QDF_STATUS if_mgr_enable_roaming_after_p2p_disconnect( + struct wlan_objmgr_vdev *vdev, + struct wlan_objmgr_pdev *pdev, + enum wlan_cm_rso_control_requestor requestor) +{ + QDF_STATUS status = QDF_STATUS_SUCCESS; + struct wlan_objmgr_psoc *psoc; + struct change_roam_state_arg roam_arg; + uint8_t vdev_id; + + psoc = wlan_vdev_get_psoc(vdev); + if (!psoc) + return QDF_STATUS_E_FAILURE; + + vdev_id = wlan_vdev_get_id(vdev); + + roam_arg.requestor = requestor; + roam_arg.curr_vdev_id = vdev_id; + + /* + * Due to audio share glitch with P2P clients due + * to roam scan on concurrent interface, disable + * roaming if "p2p_disable_roam" ini is enabled. + * Re-enable roaming again once the p2p client + * gets disconnected. + */ + if (ucfg_p2p_is_roam_config_disabled(psoc) && + wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_CLIENT_MODE) { + ifmgr_debug("P2P client disconnected, enable roam"); + status = wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP, + if_mgr_enable_roaming_on_vdev, + &roam_arg, 0, + WLAN_IF_MGR_ID); + } + + return status; +} 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 8ed63b9a9e00..e4487bf985c5 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 @@ -21,6 +21,8 @@ #include "wlan_objmgr_vdev_obj.h" #include "wlan_if_mgr_public_struct.h" #include "wlan_if_mgr_sta.h" +#include "wlan_if_mgr_roam.h" +#include "wlan_if_mgr_main.h" #include "nan_ucfg_api.h" #include "wlan_policy_mgr_api.h" @@ -72,3 +74,55 @@ QDF_STATUS if_mgr_connect_complete(struct wlan_objmgr_vdev *vdev, { return QDF_STATUS_SUCCESS; } + +QDF_STATUS if_mgr_disconnect_start(struct wlan_objmgr_vdev *vdev, + void *event_data) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + + 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; + + /* Leaving as stub to fill in later */ + + return QDF_STATUS_SUCCESS; +} + +QDF_STATUS if_mgr_disconnect_complete(struct wlan_objmgr_vdev *vdev, + void *event_data) +{ + struct wlan_objmgr_psoc *psoc; + struct wlan_objmgr_pdev *pdev; + QDF_STATUS status; + + 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; + + status = if_mgr_enable_roaming_after_p2p_disconnect(vdev, pdev, + RSO_INVALID_REQUESTOR); + if (status) { + ifmgr_err("Failed to enable roaming after p2p disconnect"); + return status; + } + + policy_mgr_check_concurrent_intf_and_restart_sap(psoc); + + status = if_mgr_enable_roaming_on_connected_sta(vdev, pdev); + if (status) { + ifmgr_err("Failed to enable roaming on connected sta"); + return status; + } + + return QDF_STATUS_SUCCESS; +} diff --git a/core/hdd/src/wlan_hdd_assoc.c b/core/hdd/src/wlan_hdd_assoc.c index 51bf97a3f3e6..78e2c5d9261a 100644 --- a/core/hdd/src/wlan_hdd_assoc.c +++ b/core/hdd/src/wlan_hdd_assoc.c @@ -78,6 +78,11 @@ #include #include "wlan_pkt_capture_ucfg_api.h" +#ifdef WLAN_FEATURE_INTERFACE_MGR +#include "wlan_if_mgr_api.h" +#include "wlan_if_mgr_public_struct.h" +#endif + /* These are needed to recognize WPA and RSN suite types */ #define HDD_WPA_OUI_SIZE 4 #define HDD_RSN_OUI_SIZE 4 @@ -1880,6 +1885,11 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, /* indicate 'disconnect' status to wpa_supplicant... */ hdd_send_association_event(dev, roam_info); + /* + * Following code will be cleaned once the interface manager + * module is enabled. + */ +#ifndef WLAN_FEATURE_INTERFACE_MGR /* * Due to audio share glitch with P2P clients due * to roam scan on concurrent interface, disable @@ -1892,6 +1902,7 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, hdd_debug("P2P client disconnected, enable roam"); wlan_hdd_enable_roaming(adapter, RSO_CONNECT_START); } +#endif /* indicate disconnected event to nl80211 */ /* @@ -1985,7 +1996,14 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, } wlan_hdd_clear_link_layer_stats(adapter); + /* + * Following code will be cleaned once the interface manager + * module is enabled. + */ +#ifndef WLAN_FEATURE_INTERFACE_MGR policy_mgr_check_concurrent_intf_and_restart_sap(hdd_ctx->psoc); +#endif + adapter->hdd_stats.tx_rx_stats.cont_txtimeout_cnt = 0; /* @@ -2007,6 +2025,14 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, hdd_print_bss_info(sta_ctx); + /* + * Following code will be cleaned once the interface manager + * module is enabled. + */ +#ifdef WLAN_FEATURE_INTERFACE_MGR + ucfg_if_mgr_deliver_event(adapter->vdev, + WLAN_IF_MGR_EV_DISCONNECT_COMPLETE, NULL); +#else if (policy_mgr_is_sta_active_connection_exists(hdd_ctx->psoc) && QDF_STA_MODE == adapter->device_mode) { sme_enable_roaming_on_connected_sta(mac_handle, @@ -2014,6 +2040,7 @@ static QDF_STATUS hdd_dis_connect_handler(struct hdd_adapter *adapter, sme_clear_and_set_pcl_for_connected_vdev(mac_handle, adapter->vdev_id); } +#endif return status; } diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index da38474bb8d0..12a789710503 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -162,6 +162,11 @@ #define TWT_FLOW_TYPE_ANNOUNCED 0 #define TWT_FLOW_TYPE_UNANNOUNCED 1 +#ifdef WLAN_FEATURE_INTERFACE_MGR +#include "wlan_if_mgr_api.h" +#include "wlan_if_mgr_public_struct.h" +#endif + #define g_mode_rates_size (12) #define a_mode_rates_size (8) @@ -20264,6 +20269,14 @@ static void wlan_hdd_wait_for_roaming(mac_handle_t mac_handle, if (sta_ctx->conn_info.conn_state != eConnectionState_Associated) return; + /* + * Following code will be cleaned once the interface manager + * module is enabled. + */ +#ifdef WLAN_FEATURE_INTERFACE_MGR + ucfg_if_mgr_deliver_event(adapter->vdev, + WLAN_IF_MGR_EV_DISCONNECT_START, NULL); +#endif /* * If firmware has already started roaming process, driver * needs to wait for processing of this disconnect request.