From c8bbb0058de14932d504858614f5e30b14606fba Mon Sep 17 00:00:00 2001 From: Bala Venkatesh Date: Tue, 18 Dec 2018 19:55:48 +0530 Subject: [PATCH] qcacld-3.0: Enable TDLS in FW in standalone STA and P2P client TDLS is not supported in concurrency. As part of second interface creation, TDLS is disabled in both host and FW. But after the second interface is deleted, TDLS is not enabled in FW and host even for Standalone STA and P2P client cases. Change-Id: I362c22a79e171f9779393b1b893b5bfd14ff562a CRs-Fixed: 2367083 --- components/tdls/core/src/wlan_tdls_main.c | 65 +++++++++++++++++------ components/tdls/core/src/wlan_tdls_main.h | 9 ++++ core/hdd/src/wlan_hdd_cfg80211.c | 12 ----- 3 files changed, 58 insertions(+), 28 deletions(-) diff --git a/components/tdls/core/src/wlan_tdls_main.c b/components/tdls/core/src/wlan_tdls_main.c index 7295adda9689..9df012ee3b2f 100644 --- a/components/tdls/core/src/wlan_tdls_main.c +++ b/components/tdls/core/src/wlan_tdls_main.c @@ -510,8 +510,10 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_CMD_SET_TDLS_MODE: tdls_set_operation_mode(msg->bodyptr); break; - case TDLS_CMD_SESSION_INCREMENT: case TDLS_CMD_SESSION_DECREMENT: + tdls_process_decrement_active_session(msg->bodyptr); + /*Fall through to take decision on connection tracker.*/ + case TDLS_CMD_SESSION_INCREMENT: tdls_process_policy_mgr_notification(msg->bodyptr); break; case TDLS_CMD_TEARDOWN_LINKS: @@ -845,16 +847,55 @@ set_state: QDF_STATUS tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) { + struct tdls_vdev_priv_obj *tdls_priv_vdev; + struct wlan_objmgr_vdev *tdls_obj_vdev; + struct tdls_soc_priv_obj *tdls_priv_soc; + if (!psoc) { tdls_err("psoc: %pK", psoc); return QDF_STATUS_E_NULL_VALUE; } + tdls_obj_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); tdls_debug("enter "); tdls_set_ct_mode(psoc); + if (tdls_obj_vdev && (tdls_get_vdev_objects(tdls_obj_vdev, + &tdls_priv_vdev, &tdls_priv_soc) == QDF_STATUS_SUCCESS) && + tdls_priv_soc->enable_tdls_connection_tracker) + tdls_implicit_enable(tdls_priv_vdev); + + if (tdls_obj_vdev) + wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID); + tdls_debug("exit "); return QDF_STATUS_SUCCESS; } +QDF_STATUS +tdls_process_decrement_active_session(struct wlan_objmgr_psoc *psoc) +{ + struct tdls_soc_priv_obj *tdls_priv_soc; + struct tdls_vdev_priv_obj *tdls_priv_vdev; + struct wlan_objmgr_vdev *tdls_obj_vdev; + uint8_t vdev_id; + + tdls_debug("Enter"); + if (!psoc) + return QDF_STATUS_E_NULL_VALUE; + + tdls_obj_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); + if (tdls_obj_vdev) { + tdls_debug("Enable TDLS in FW and host as only one active sta/p2p_cli interface is present"); + vdev_id = wlan_vdev_get_id(tdls_obj_vdev); + if (tdls_get_vdev_objects(tdls_obj_vdev, &tdls_priv_vdev, + &tdls_priv_soc) == QDF_STATUS_SUCCESS) + tdls_send_update_to_fw(tdls_priv_vdev, tdls_priv_soc, + false, false, true, vdev_id); + wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID); + } + + return QDF_STATUS_SUCCESS; +} + /** * tdls_get_vdev() - Get tdls specific vdev object manager * @psoc: wlan psoc object manager @@ -965,15 +1006,19 @@ void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, struct tdls_config_params *threshold_params; uint32_t tdls_feature_flags; QDF_STATUS status; + uint8_t set_state_cnt; + tdls_debug("Enter"); 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; } - if (tdls_soc_obj->set_state_info.set_state_cnt == 0 && - !sta_connect_event) { + set_state_cnt = tdls_soc_obj->set_state_info.set_state_cnt; + if ((set_state_cnt == 0 && !sta_connect_event) || + (set_state_cnt && sta_connect_event)) { + tdls_debug("FW TDLS state is already in requested state"); return; } @@ -1020,19 +1065,7 @@ void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_info_to_fw->rssi_teardown_threshold = threshold_params->rssi_teardown_threshold; tdls_info_to_fw->rssi_delta = threshold_params->rssi_delta; - - if (tdls_soc_obj->set_state_info.set_state_cnt == 1 && - sta_connect_event) { - tdls_warn("Concurrency not allowed in TDLS! set state cnt %d", - tdls_soc_obj->set_state_info.set_state_cnt); - /* disable off channel and teardown links */ - /* Go through the peer list and delete them */ - tdls_disable_offchan_and_teardown_links(tdls_vdev_obj->vdev); - tdls_soc_obj->tdls_current_mode = TDLS_SUPPORT_DISABLED; - tdls_info_to_fw->vdev_id = tdls_soc_obj->set_state_info.vdev_id; - } else { - tdls_info_to_fw->vdev_id = session_id; - } + tdls_info_to_fw->vdev_id = session_id; /* record the session id in vdev context */ tdls_vdev_obj->session_id = session_id; diff --git a/components/tdls/core/src/wlan_tdls_main.h b/components/tdls/core/src/wlan_tdls_main.h index ed5c1ab2cd82..c038edd767bc 100644 --- a/components/tdls/core/src/wlan_tdls_main.h +++ b/components/tdls/core/src/wlan_tdls_main.h @@ -678,6 +678,15 @@ struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc, QDF_STATUS tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc); +/** + * tdls_process_decrement_active_session() - process policy manager decrement + * sessions. + * @psoc: soc object manager + * + * Return: QDF_STATUS + */ +QDF_STATUS +tdls_process_decrement_active_session(struct wlan_objmgr_psoc *psoc); /** * tdls_scan_complete_event_handler() - scan complete event handler for tdls * @vdev: vdev object diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 1d3fb5bb5773..b14ee6269109 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -13454,18 +13454,6 @@ static int __wlan_hdd_cfg80211_change_iface(struct wiphy *wiphy, /* Reset the current device mode bit mask */ policy_mgr_clear_concurrency_mode(hdd_ctx->psoc, adapter->device_mode); - /* TDLS ignores p2p-device mode for concurrency considerations */ - if (new_mode != QDF_P2P_DEVICE_MODE) { - struct wlan_objmgr_vdev *vdev; - - vdev = hdd_objmgr_get_vdev(adapter); - if (vdev) { - hdd_debug("Disable tdls; new interface is coming up"); - hdd_notify_teardown_tdls_links(vdev); - hdd_objmgr_put_vdev(adapter); - } - } - if (hdd_is_client_mode(adapter->device_mode)) { if (hdd_is_client_mode(new_mode)) { if (new_mode == QDF_IBSS_MODE)