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 06f30c1244..0b6efe278c 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 @@ -47,7 +47,7 @@ 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); + wlan_tdls_notify_start_bss(psoc); if (wlan_vdev_mlme_get_opmode(vdev) == QDF_SAP_MODE || wlan_vdev_mlme_get_opmode(vdev) == QDF_P2P_GO_MODE) diff --git a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h index 132493a708..e693efa7a5 100644 --- a/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h +++ b/components/cmn_services/policy_mgr/inc/wlan_policy_mgr_api.h @@ -2185,6 +2185,26 @@ void policy_mgr_set_dual_mac_fw_mode_config(struct wlan_objmgr_psoc *psoc, bool policy_mgr_is_scc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id); +/** + * policy_mgr_is_mcc_with_this_vdev_id() - Is current vdev having MCC + * with any other vdev. + * @psoc: Pointer to PSOC object + * @vdev_id: vdev id + * @mcc_vdev_id: Concurrent MCC vdev id + * + * Return: true if MCC exists, false otherwise + */ +bool policy_mgr_is_mcc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t *mcc_vdev_id); + +/** + * policy_mgr_is_mcc_on_any_sta_vdev() - Check if any sta vdev is in MCC + * @psoc: Pointer to PSOC object + * + * Return: true if STA vdev is in MCC false otherwise + */ +bool policy_mgr_is_mcc_on_any_sta_vdev(struct wlan_objmgr_psoc *psoc); + /** * policy_mgr_soc_set_dual_mac_cfg_cb() - Callback for set dual mac config * @status: Status of set dual mac config @@ -2652,21 +2672,6 @@ bool policy_mgr_is_sta_gc_active_on_mac(struct wlan_objmgr_psoc *psoc, QDF_STATUS policy_mgr_get_mac_id_by_session_id(struct wlan_objmgr_psoc *psoc, uint8_t session_id, uint8_t *mac_id); -/** - * policy_mgr_get_mcc_session_id_on_mac() - Get MCC session's ID - * @psoc: PSOC object information - * @mac_id: MAC ID on which MCC session needs to be found - * @session_id: Session with which MCC combination needs to be found - * @mcc_session_id: Pointer to the MCC session ID - * - * Get the session ID of the MCC interface - * - * Return: QDF_STATUS - */ -QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, - uint8_t mac_id, uint8_t session_id, - uint8_t *mcc_session_id); - /** * policy_mgr_get_mcc_operating_channel() - Get the MCC channel * @psoc: PSOC object information diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c index 4ffb7ea4c0..bf633b8943 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c @@ -3818,7 +3818,7 @@ policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc, return true; } else if (sta_vdev_id == info[j].vdev_id) { - *ch_freq = info[j].ch_freq; + *ch_freq = info[i].ch_freq; return true; } } diff --git a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c index 60f2f16a7c..b7eb2053e7 100644 --- a/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c +++ b/components/cmn_services/policy_mgr/src/wlan_policy_mgr_get_set_utils.c @@ -3145,6 +3145,73 @@ bool policy_mgr_is_scc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc, return false; } +bool policy_mgr_is_mcc_with_this_vdev_id(struct wlan_objmgr_psoc *psoc, + uint8_t vdev_id, uint8_t *mcc_vdev_id) +{ + struct policy_mgr_psoc_priv_obj *pm_ctx; + uint32_t i, ch_freq; + QDF_STATUS status = QDF_STATUS_E_FAILURE; + + if (mcc_vdev_id) + *mcc_vdev_id = WLAN_INVALID_VDEV_ID; + + pm_ctx = policy_mgr_get_context(psoc); + if (!pm_ctx) { + policy_mgr_err("Invalid Context"); + return false; + } + + /* Get the channel freq for a given vdev_id */ + status = policy_mgr_get_chan_by_session_id(psoc, vdev_id, &ch_freq); + if (QDF_IS_STATUS_ERROR(status)) { + policy_mgr_err("Failed to get channel for vdev:%d", vdev_id); + return false; + } + + /* Compare given vdev_id freq against other vdev_id's */ + qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); + for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { + if (pm_conc_connection_list[i].vdev_id == vdev_id) + continue; + + if (!pm_conc_connection_list[i].in_use) + continue; + + if (pm_conc_connection_list[i].freq != ch_freq && + policy_mgr_are_2_freq_on_same_mac(psoc, + pm_conc_connection_list[i].freq, + ch_freq)) { + if (mcc_vdev_id) + *mcc_vdev_id = pm_conc_connection_list[i].vdev_id; + + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + return true; + } + } + qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); + + return false; +} + +bool policy_mgr_is_mcc_on_any_sta_vdev(struct wlan_objmgr_psoc *psoc) +{ + uint8_t connection_count, i; + uint8_t vdev_id_list[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0}; + + connection_count = + policy_mgr_get_mode_specific_conn_info(psoc, NULL, vdev_id_list, + PM_STA_MODE); + if (!connection_count) + return false; + + for (i = 0; i < connection_count; i++) + if (policy_mgr_is_mcc_with_this_vdev_id(psoc, vdev_id_list[i], + NULL)) + return true; + + return false; +} + bool policy_mgr_current_concurrency_is_scc(struct wlan_objmgr_psoc *psoc) { uint32_t num_connections = 0; @@ -8397,78 +8464,22 @@ uint32_t policy_mgr_get_sap_go_count_on_mac(struct wlan_objmgr_psoc *psoc, return count; } -QDF_STATUS policy_mgr_get_mcc_session_id_on_mac(struct wlan_objmgr_psoc *psoc, - uint8_t mac_id, uint8_t session_id, - uint8_t *mcc_session_id) -{ - uint32_t i, ch_freq; - QDF_STATUS status; - struct policy_mgr_psoc_priv_obj *pm_ctx; - - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid Context"); - return QDF_STATUS_E_FAILURE; - } - - status = policy_mgr_get_chan_by_session_id(psoc, session_id, &ch_freq); - if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("Failed to get channel for session id:%d", - session_id); - return QDF_STATUS_E_FAILURE; - } - - qdf_mutex_acquire(&pm_ctx->qdf_conc_list_lock); - for (i = 0; i < MAX_NUMBER_OF_CONC_CONNECTIONS; i++) { - if (pm_conc_connection_list[i].mac != mac_id) - continue; - if (pm_conc_connection_list[i].vdev_id == session_id) - continue; - /* Inter band or intra band MCC */ - if (pm_conc_connection_list[i].freq != ch_freq && - pm_conc_connection_list[i].in_use) { - *mcc_session_id = pm_conc_connection_list[i].vdev_id; - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - return QDF_STATUS_SUCCESS; - } - } - qdf_mutex_release(&pm_ctx->qdf_conc_list_lock); - - return QDF_STATUS_E_FAILURE; -} - uint32_t policy_mgr_get_mcc_operating_channel(struct wlan_objmgr_psoc *psoc, - uint8_t session_id) + uint8_t vdev_id) { - uint8_t mac_id, mcc_session_id; + uint8_t mcc_vdev_id; QDF_STATUS status; uint32_t ch_freq; - struct policy_mgr_psoc_priv_obj *pm_ctx; - pm_ctx = policy_mgr_get_context(psoc); - if (!pm_ctx) { - policy_mgr_err("Invalid Context"); + if (!policy_mgr_is_mcc_with_this_vdev_id(psoc, vdev_id, &mcc_vdev_id)) { + policy_mgr_debug("No concurrent MCC vdev for id:%d", vdev_id); return INVALID_CHANNEL_ID; } - status = policy_mgr_get_mac_id_by_session_id(psoc, session_id, &mac_id); + status = policy_mgr_get_chan_by_session_id(psoc, mcc_vdev_id, &ch_freq); if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("failed to get MAC ID"); - return INVALID_CHANNEL_ID; - } - - status = policy_mgr_get_mcc_session_id_on_mac(psoc, mac_id, session_id, - &mcc_session_id); - if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("failed to get MCC session ID"); - return INVALID_CHANNEL_ID; - } - - status = policy_mgr_get_chan_by_session_id(psoc, mcc_session_id, - &ch_freq); - if (QDF_IS_STATUS_ERROR(status)) { - policy_mgr_err("Failed to get channel for MCC session ID:%d", - mcc_session_id); + policy_mgr_err("Failed to get channel for MCC vdev:%d", + mcc_vdev_id); return INVALID_CHANNEL_ID; } diff --git a/components/tdls/core/src/wlan_tdls_ct.c b/components/tdls/core/src/wlan_tdls_ct.c index 141b8b74f8..1d70448cd1 100644 --- a/components/tdls/core/src/wlan_tdls_ct.c +++ b/components/tdls/core/src/wlan_tdls_ct.c @@ -1080,11 +1080,11 @@ tdls_update_peer_off_channel_list(struct wlan_objmgr_pdev *pdev, if (!wlan_psoc_nif_fw_ext2_cap_get(psoc, WLAN_TDLS_CONCURRENCIES_SUPPORT)) - return false; + return QDF_STATUS_SUCCESS; if (!policy_mgr_get_allowed_tdls_offchannel_freq(psoc, vdev, &freq)) { tdls_debug("off channel not allowed for current concurrency"); - return false; + return QDF_STATUS_E_NOSUPPORT; } /* @@ -1129,7 +1129,8 @@ tdls_update_peer_off_channel_list(struct wlan_objmgr_pdev *pdev, (!wlan_reg_is_24ghz_ch_freq(peer_freq) || (wlan_reg_is_6ghz_chan_freq(peer_freq) && tdls_is_6g_freq_allowed(vdev, peer_freq)))) { - off_channels[i] = peer_info->peer_cap.peer_chan[i]; + off_channels[params->num_off_channels] = + peer_info->peer_cap.peer_chan[i]; params->num_off_channels++; } } @@ -1244,9 +1245,17 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev, conn_peer->op_class_for_pref_off_chan = chan_switch_params->oper_class; - tdls_update_peer_off_channel_list(pdev, tdls_soc, vdev, - conn_peer, - chan_switch_params); + /* + * Don't enable TDLS off channel if concurrency is not allowed + */ + status = tdls_update_peer_off_channel_list(pdev, tdls_soc, vdev, + conn_peer, + chan_switch_params); + if (QDF_IS_STATUS_ERROR(status)) { + qdf_mem_free(chan_switch_params); + return -EINVAL; + } + break; case DISABLE_CHANSWITCH: case DISABLE_ACTIVE_CHANSWITCH: diff --git a/components/tdls/core/src/wlan_tdls_main.c b/components/tdls/core/src/wlan_tdls_main.c index e3c5806ebe..94eeddb19b 100644 --- a/components/tdls/core/src/wlan_tdls_main.c +++ b/components/tdls/core/src/wlan_tdls_main.c @@ -93,7 +93,8 @@ static char *tdls_get_cmd_type_str(enum tdls_command_type cmd_type) return "TDLS_NOTIFY_RESET_ADAPTERS"; case TDLS_CMD_ANTENNA_SWITCH: return "TDLS_CMD_ANTENNA_SWITCH"; - + case TDLS_CMD_START_BSS: + return "TDLS_CMD_START_BSS"; default: return "Invalid TDLS command"; } @@ -571,6 +572,24 @@ static QDF_STATUS tdls_reset_all_peers( return status; } +#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES +QDF_STATUS tdls_handle_start_bss(struct wlan_objmgr_psoc *psoc) +{ + struct wlan_objmgr_vdev *tdls_vdev; + + tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID); + if (!tdls_vdev) { + tdls_err("Unable get the tdls vdev"); + return QDF_STATUS_E_FAILURE; + } + + tdls_set_tdls_offchannelmode(tdls_vdev, DISABLE_ACTIVE_CHANSWITCH); + wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID); + + return QDF_STATUS_SUCCESS; +} +#endif + QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) { QDF_STATUS status = QDF_STATUS_SUCCESS; @@ -655,6 +674,9 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg) case TDLS_DELETE_ALL_PEERS_INDICATION: tdls_reset_all_peers(msg->bodyptr); break; + case TDLS_CMD_START_BSS: + tdls_handle_start_bss(msg->bodyptr); + break; default: break; } @@ -959,6 +981,7 @@ bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev) qdf_freq_t ch_freq; QDF_STATUS status; uint32_t connection_count; + uint8_t sta_count, p2p_cli_count; status = wlan_objmgr_vdev_try_get_ref(vdev, WLAN_TDLS_NB_ID); if (QDF_IS_STATUS_ERROR(status)) @@ -981,7 +1004,14 @@ bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev) } connection_count = policy_mgr_get_connection_count(tdls_soc_obj->soc); - if (connection_count == 1 || + sta_count = + policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc, + PM_STA_MODE, NULL); + p2p_cli_count = + policy_mgr_mode_specific_connection_count(tdls_soc_obj->soc, + PM_P2P_CLIENT_MODE, + NULL); + if ((connection_count == 1 && (sta_count || p2p_cli_count)) || (connection_count > 1 && tdls_is_concurrency_allowed(tdls_soc_obj->soc))) { state = true; @@ -1020,7 +1050,7 @@ bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc) return false; } - if (policy_mgr_current_concurrency_is_mcc(psoc)) { + if (policy_mgr_is_mcc_on_any_sta_vdev(psoc)) { tdls_debug("Base channel MCC. Don't allow TDLS"); return false; } @@ -1115,10 +1145,13 @@ tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc) } if (!tdls_check_is_tdls_allowed(tdls_obj_vdev)) { + tdls_disable_offchan_and_teardown_links(tdls_obj_vdev); wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID); return QDF_STATUS_E_NULL_VALUE; } + tdls_set_tdls_offchannelmode(tdls_obj_vdev, ENABLE_CHANSWITCH); + tdls_debug("enter "); tdls_set_ct_mode(psoc, tdls_obj_vdev); @@ -1139,24 +1172,41 @@ tdls_process_decrement_active_session(struct wlan_objmgr_psoc *psoc) tdls_debug("Enter"); if (!psoc) return QDF_STATUS_E_NULL_VALUE; + if(!policy_mgr_is_hw_dbs_2x2_capable(psoc) && - !policy_mgr_is_hw_dbs_required_for_band( - psoc, HW_MODE_MAC_BAND_2G) && + !policy_mgr_is_hw_dbs_required_for_band(psoc, HW_MODE_MAC_BAND_2G) && policy_mgr_is_current_hwmode_dbs(psoc)) { tdls_debug("Current HW mode is 1*1 DBS. Wait for Opportunistic timer to expire to enable TDLS in FW"); return QDF_STATUS_SUCCESS; } + 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); + if (!tdls_obj_vdev) + return QDF_STATUS_E_FAILURE; + + if (!tdls_check_is_tdls_allowed(tdls_obj_vdev)) + goto release_ref; + + /* + * 2 Port MCC -> 1 port scenario or + * 3 Port MCC -> 2 port SCC scenario or + * 4 Port -> 3 Port SCC scenario + * So enable TDLS in firmware + */ + tdls_debug("Enable TDLS in FW and host as 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); + if (tdls_priv_soc->connected_peer_count == 1) + tdls_set_tdls_offchannelmode(tdls_obj_vdev, + ENABLE_CHANSWITCH); } +release_ref: + wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID); + return QDF_STATUS_SUCCESS; } @@ -1331,11 +1381,12 @@ void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj, tdls_info_to_fw->tdls_state = tdls_soc_obj->tdls_current_mode; tdls_info_to_fw->tdls_options = 0; - /* Do not enable TDLS offchannel, if AP prohibited TDLS + /* + * Do not enable TDLS offchannel, if AP prohibited TDLS * channel switch */ if (TDLS_IS_OFF_CHANNEL_ENABLED(tdls_feature_flags) && - (!tdls_chan_swit_prohibited)) + !tdls_chan_swit_prohibited) tdls_info_to_fw->tdls_options = ENA_TDLS_OFFCHAN; if (TDLS_IS_BUFFER_STA_ENABLED(tdls_feature_flags)) diff --git a/components/tdls/core/src/wlan_tdls_main.h b/components/tdls/core/src/wlan_tdls_main.h index ad12b9b4ed..8296080302 100644 --- a/components/tdls/core/src/wlan_tdls_main.h +++ b/components/tdls/core/src/wlan_tdls_main.h @@ -829,6 +829,15 @@ uint8_t tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev *vdev, uint8_t *reg_bw_offset); #ifdef WLAN_FEATURE_TDLS_CONCURRENCIES +/** + * tdls_handle_start_bss() - Handle start BSS event to act on concurrent + * session offchannel mode + * @psoc: Pointer to PSOC object + * + * Return: None + */ +QDF_STATUS tdls_handle_start_bss(struct wlan_objmgr_psoc *psoc); + /** * tdls_is_concurrency_allowed() - Is TDLS allowed with the current concurrency * @psoc: Pointer to PSOC @@ -837,10 +846,17 @@ uint8_t tdls_get_opclass_from_bandwidth(struct wlan_objmgr_vdev *vdev, */ bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc); #else +static inline +QDF_STATUS tdls_handle_start_bss(struct wlan_objmgr_psoc *psoc) +{ + return QDF_STATUS_SUCCESS; +} + static inline bool tdls_is_concurrency_allowed(struct wlan_objmgr_psoc *psoc) { return false; } + #endif /* WLAN_FEATURE_TDLS_CONCURRENCIES */ #endif diff --git a/components/tdls/dispatcher/inc/wlan_tdls_api.h b/components/tdls/dispatcher/inc/wlan_tdls_api.h index 200b3149c0..80bc046928 100644 --- a/components/tdls/dispatcher/inc/wlan_tdls_api.h +++ b/components/tdls/dispatcher/inc/wlan_tdls_api.h @@ -1,6 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. 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 @@ -110,6 +110,13 @@ void wlan_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, struct qdf_mac_addr *mac_addr, struct qdf_mac_addr *dest_mac_addr); +/** + * wlan_tdls_notify_start_bss() - Notify TDLS module on start bss + * @psoc: Pointer to PSOC object + * + * Return: None + */ +void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc); #else #ifdef FEATURE_SET @@ -153,5 +160,8 @@ void wlan_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev, { } +static inline +void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc) +{} #endif #endif diff --git a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h index 305042af38..37612d265a 100644 --- a/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h +++ b/components/tdls/dispatcher/inc/wlan_tdls_public_structs.h @@ -46,8 +46,20 @@ #define WLAN_MAC_MAX_SUPP_RATES 32 #define WLAN_CHANNEL_14 14 +/* Enable TDLS off-channel switch */ #define ENABLE_CHANSWITCH 1 + +/* + * Passive(peer requested) responder mode off-channel switch. + * If peer initiates off channel request, that will be honored in + * this mode + */ #define DISABLE_CHANSWITCH 2 + +/* + * Disable TDLS off-channel operation completely. + * Peer initiated requests will also be discarded. + */ #define DISABLE_ACTIVE_CHANSWITCH 3 #define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1 @@ -228,6 +240,7 @@ enum tdls_feature_mode { * @TDLS_CMD_SET_OFFCHANMODE: tdls offchannel mode * @TDLS_CMD_SET_SECOFFCHANOFFSET: tdls secondary offchannel offset * @TDLS_DELETE_ALL_PEERS_INDICATION: tdls delete all peers indication + * @TDLS_CMD_START_BSS: SAP start indication to tdls module */ enum tdls_command_type { TDLS_CMD_TX_ACTION = 1, @@ -253,7 +266,8 @@ enum tdls_command_type { TDLS_CMD_SET_OFFCHANNEL, TDLS_CMD_SET_OFFCHANMODE, TDLS_CMD_SET_SECOFFCHANOFFSET, - TDLS_DELETE_ALL_PEERS_INDICATION + TDLS_DELETE_ALL_PEERS_INDICATION, + TDLS_CMD_START_BSS }; /** diff --git a/components/tdls/dispatcher/src/wlan_tdls_api.c b/components/tdls/dispatcher/src/wlan_tdls_api.c index ea3d4f0f0d..8c7028f9ff 100644 --- a/components/tdls/dispatcher/src/wlan_tdls_api.c +++ b/components/tdls/dispatcher/src/wlan_tdls_api.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. 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 @@ -29,6 +29,7 @@ #include #include #include "wlan_tdls_cfg_api.h" +#include "wlan_policy_mgr_api.h" static QDF_STATUS tdls_teardown_flush_cb(struct scheduler_msg *msg) { @@ -112,6 +113,39 @@ release_ref: WLAN_TDLS_NB_ID); } +#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES +static void wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc *psoc) +{ + QDF_STATUS status; + struct scheduler_msg msg = {0}; + + msg.callback = tdls_process_cmd; + msg.type = TDLS_CMD_START_BSS; + msg.bodyptr = psoc; + status = scheduler_post_message(QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TDLS, + QDF_MODULE_ID_TARGET_IF, &msg); + if (QDF_IS_STATUS_ERROR(status)) { + tdls_err("post start bss msg fail"); + return; + } +} +#else +static inline void +wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc *psoc) +{} +#endif + +void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc) +{ + if (tdls_is_concurrency_allowed(psoc)) { + wlan_tdls_handle_sap_start(psoc); + return; + } + + wlan_tdls_teardown_links_sync(psoc); +} + static QDF_STATUS tdls_notify_flush_cb(struct scheduler_msg *msg) { struct tdls_sta_notify_params *notify = msg->bodyptr;