diff --git a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h index a732c5706fab..9331776c4a01 100644 --- a/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h +++ b/umac/cmn_services/obj_mgr/inc/wlan_objmgr_vdev_obj.h @@ -199,6 +199,9 @@ /* CAPABILITY: bg scanning */ #define WLAN_VDEV_C_BGSCAN 0x00000100 +/* Invalid VDEV identifier */ +#define WLAN_INVALID_VDEV_ID 255 + /** * enum wlan_vdev_state - VDEV state * @WLAN_VDEV_S_INIT: Default state, IDLE state diff --git a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 53cf435021fb..9853383b3f54 100644 --- a/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/umac/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -1331,6 +1331,19 @@ void policy_mgr_checkn_update_hw_mode_single_mac_mode( */ void policy_mgr_dump_connection_status_info(struct wlan_objmgr_psoc *psoc); +/** + * policy_mgr_mode_specific_vdev_id() - provides the + * vdev id of the pecific mode + * @psoc: PSOC object information + * @mode: type of connection + * + * This function provides vdev id for the given mode + * + * Return: vdev id + */ +uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode); + /** * policy_mgr_mode_specific_connection_count() - provides the * count of connections of specific mode diff --git a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index a9885f68a7cc..873e1d2eb8b1 100644 --- a/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/umac/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -788,6 +788,36 @@ uint32_t policy_mgr_get_connection_count(struct wlan_objmgr_psoc *psoc) return count; } +uint32_t policy_mgr_mode_specific_vdev_id(struct wlan_objmgr_psoc *psoc, + enum policy_mgr_con_mode mode) +{ + uint32_t conn_index = 0; + uint32_t vdev_id = WLAN_INVALID_VDEV_ID; + struct policy_mgr_psoc_priv_obj *pm_ctx; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return vdev_id; + } + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + /* + * Note: This gives you the first vdev id of the mode type in a + * sta+sta or sap+sap or p2p + p2p case + */ + for (conn_index = 0; conn_index < MAX_NUMBER_OF_CONC_CONNECTIONS; + conn_index++) { + if ((pm_conc_connection_list[conn_index].mode == mode) && + pm_conc_connection_list[conn_index].in_use) { + vdev_id = pm_conc_connection_list[conn_index].vdev_id; + break; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return vdev_id; +} + uint32_t policy_mgr_mode_specific_connection_count( struct wlan_objmgr_psoc *psoc, enum policy_mgr_con_mode mode, diff --git a/umac/tdls/core/src/wlan_tdls_main.c b/umac/tdls/core/src/wlan_tdls_main.c index 5e2bdbf79a20..437b51f5fc8d 100644 --- a/umac/tdls/core/src/wlan_tdls_main.c +++ b/umac/tdls/core/src/wlan_tdls_main.c @@ -623,20 +623,25 @@ tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, wlan_objmgr_ref_dbgid dbg_id) { + uint32_t vdev_id; + if (policy_mgr_get_connection_count(psoc) > 1) return NULL; - if (policy_mgr_mode_specific_connection_count(psoc, - PM_STA_MODE, - NULL) == 1) - return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_STA_MODE, - dbg_id); - if (policy_mgr_mode_specific_connection_count(psoc, - PM_P2P_CLIENT_MODE, - NULL) == 1) - return wlan_objmgr_get_vdev_by_opmode_from_psoc(psoc, - QDF_P2P_CLIENT_MODE, - dbg_id); + + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_STA_MODE); + + if (WLAN_INVALID_VDEV_ID != vdev_id) + return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + dbg_id); + + vdev_id = policy_mgr_mode_specific_vdev_id(psoc, PM_P2P_CLIENT_MODE); + + if (WLAN_INVALID_VDEV_ID != vdev_id) + return wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + vdev_id, + dbg_id); + return NULL; } @@ -705,10 +710,9 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, uint32_t tdls_feature_flags; QDF_STATUS status; - - /* If TDLS support is disabled then no need to update target */ - if (tdls_soc_obj->tdls_current_mode <= TDLS_SUPPORT_SUSPENDED) { - tdls_err("TDLS not enabled or suspended"); + tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; + if (!TDLS_IS_ENABLED(tdls_feature_flags)) { + tdls_debug("TDLS mode is not enabled"); return; } @@ -717,23 +721,28 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, return; } - tdls_feature_flags = tdls_soc_obj->tdls_configs.tdls_feature_flags; - /* If AP or caller indicated TDLS Prohibited then disable tdls mode */ - if (tdls_prohibited) { - tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; - } else { - tdls_debug("TDLS feature flags from ini %d ", + if (sta_connect_event) { + if (tdls_prohibited) { + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_DISABLED; + } else { + tdls_debug("TDLS feature flags from ini %d ", tdls_feature_flags); - if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_EXP_TRIG_ONLY; - else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED(tdls_feature_flags)) - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_EXT_CONTROL; - else - tdls_soc_obj->tdls_current_mode = - TDLS_SUPPORT_IMP_MODE; + if (!TDLS_IS_IMPLICIT_TRIG_ENABLED(tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXP_TRIG_ONLY; + else if (TDLS_IS_EXTERNAL_CONTROL_ENABLED( + tdls_feature_flags)) + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_EXT_CONTROL; + else + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_IMP_MODE; + } + } else { + tdls_soc_obj->tdls_current_mode = + TDLS_SUPPORT_DISABLED; } tdls_info_to_fw = qdf_mem_malloc(sizeof(struct tdls_info)); @@ -827,8 +836,6 @@ static void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, done: qdf_mem_free(tdls_info_to_fw); - tdls_process_session_update(tdls_soc_obj->soc, - TDLS_CMD_SESSION_INCREMENT); return; } @@ -846,6 +853,11 @@ tdls_process_sta_connect(struct tdls_sta_notify_params *notify) tdls_debug("Check and update TDLS state"); + if (policy_mgr_get_connection_count(tdls_soc_obj->soc) > 1) { + tdls_debug("Concurrent sessions exist, TDLS can't be enabled"); + return QDF_STATUS_SUCCESS; + } + /* Association event */ if (!tdls_soc_obj->tdls_disable_in_progress) { tdls_send_update_to_fw(tdls_vdev_obj, @@ -872,8 +884,10 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify) return QDF_STATUS_E_INVAL; if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) + WLAN_TDLS_NB_ID)) { + qdf_mem_free(notify); return QDF_STATUS_E_INVAL; + } status = tdls_process_sta_connect(notify); @@ -956,8 +970,10 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) return QDF_STATUS_E_INVAL; if (QDF_STATUS_SUCCESS != wlan_objmgr_vdev_try_get_ref(notify->vdev, - WLAN_TDLS_NB_ID)) + WLAN_TDLS_NB_ID)) { + qdf_mem_free(notify); return QDF_STATUS_E_INVAL; + } status = tdls_process_sta_disconnect(notify); @@ -968,6 +984,26 @@ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify) return status; } +void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, + uint32_t session_id) +{ + struct tdls_sta_notify_params *notify; + + notify = qdf_mem_malloc(sizeof(*notify)); + if (!notify) { + tdls_err("memory allocation failed !!!"); + return; + } + + notify->lfr_roam = true; + notify->tdls_chan_swit_prohibited = false; + notify->tdls_prohibited = false; + notify->session_id = session_id; + notify->vdev = vdev; + + tdls_notify_sta_disconnect(notify); +} + /** * tdls_set_mode_in_vdev() - set TDLS mode * @tdls_vdev: tdls vdev object diff --git a/umac/tdls/core/src/wlan_tdls_main.h b/umac/tdls/core/src/wlan_tdls_main.h index b250c4d3d8b3..a518ceaa7aad 100644 --- a/umac/tdls/core/src/wlan_tdls_main.h +++ b/umac/tdls/core/src/wlan_tdls_main.h @@ -583,6 +583,20 @@ QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify); */ QDF_STATUS tdls_notify_sta_disconnect(struct tdls_sta_notify_params *notify); +/** + * tdls_peers_deleted_notification() - peer delete notification + * @vdev: vdev object + * @session_id: session id + * + * Legacy lim layer will delete tdls peers for roaming and heart beat failures + * and notify the component about the delete event to update the tdls. + * state. + * + * Return: None + */ +void tdls_peers_deleted_notification(struct wlan_objmgr_vdev *vdev, + uint32_t session_id); + /** * tdls_notify_decrement_session() - Notify the session decrement * @psoc: psoc object manager diff --git a/umac/tdls/dispatcher/inc/wlan_tdls_tgt_api.h b/umac/tdls/dispatcher/inc/wlan_tdls_tgt_api.h index 4357241a4eee..4b1e99c4a302 100644 --- a/umac/tdls/dispatcher/inc/wlan_tdls_tgt_api.h +++ b/umac/tdls/dispatcher/inc/wlan_tdls_tgt_api.h @@ -146,4 +146,16 @@ QDF_STATUS tgt_tdls_mgmt_frame_rx_cb(struct wlan_objmgr_psoc *psoc, struct mgmt_rx_event_params *mgmt_rx_params, enum mgmt_frame_type frm_type); +/** + * tgt_tdls_peers_deleted_notification()- notification from legacy lim + * @psoc: soc object + * @session_id: session id + * + * This function called from legacy lim to notify tdls peer deletion + * + * Return: None + */ +void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint32_t session_id); + #endif diff --git a/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c b/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c index cd097dbf86f6..c292ac1fea0c 100644 --- a/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c +++ b/umac/tdls/dispatcher/src/wlan_tdls_tgt_api.c @@ -334,3 +334,24 @@ release_nbuf: return status; } +void tgt_tdls_peers_deleted_notification(struct wlan_objmgr_psoc *psoc, + uint32_t session_id) +{ + struct wlan_objmgr_vdev *vdev; + + vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, + session_id, + WLAN_TDLS_SB_ID); + + if (!vdev) { + tdls_err("vdev not exist for the session id %d", + session_id); + return; + } + + tdls_peers_deleted_notification(vdev, session_id); + + wlan_objmgr_vdev_release_ref(vdev, + WLAN_TDLS_SB_ID); +} + diff --git a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c index 427c183ae420..9bb85352bcea 100644 --- a/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c +++ b/umac/tdls/dispatcher/src/wlan_tdls_ucfg_api.c @@ -623,6 +623,7 @@ QDF_STATUS ucfg_tdls_notify_sta_disconnect( notify->tdls_chan_swit_prohibited = false; notify->tdls_prohibited = false; notify->vdev = notify_info->vdev; + notify->lfr_roam = notify_info->lfr_roam; msg.bodyptr = notify; msg.callback = tdls_process_cmd;