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.