qcacld-3.0: Handle TDLS concurrency during CSA
If CSA on SAP/P2P GO causes MCC with the current STA TDLS vdev, then teardown the TDLS connections, disable off channel and send disable TDLS to firmware. If CSA causes MCC -> DBS or MCC -> SCC then allow TDLS and update the peer off channel list to firmware Disable TDLS off-channel before SAP/P2P GO vdev restart. Once CSA is complete, TDLS off-channel will be re-enabled based on the concurrency. Add interface manager changes to notify STA channel switch. Change-Id: I36b359a7e1cf570cfb2b2f0e6abedf148a8fd174 CRs-Fixed: 3445112
This commit is contained in:

committed by
Madan Koyyalamudi

parent
2a0bd88990
commit
282f018e47
@@ -1474,7 +1474,7 @@ void tdls_disable_offchan_and_teardown_links(
|
||||
tdls_soc->tdls_configs.tdls_pre_off_chan_num);
|
||||
tdls_set_tdls_secoffchanneloffset(tdls_soc,
|
||||
TDLS_SEC_OFFCHAN_OFFSET_40PLUS);
|
||||
tdls_set_tdls_offchannelmode(vdev, DISABLE_CHANSWITCH);
|
||||
tdls_set_tdls_offchannelmode(vdev, DISABLE_ACTIVE_CHANSWITCH);
|
||||
|
||||
/* Send Msg to PE for deleting all the TDLS peers */
|
||||
tdls_delete_all_tdls_peers(vdev, tdls_soc);
|
||||
|
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
|
||||
#include "wlan_tdls_main.h"
|
||||
#include "wlan_tdls_cmds_process.h"
|
||||
#include "wlan_tdls_peer.h"
|
||||
#include "wlan_tdls_ct.h"
|
||||
#include "wlan_tdls_mgmt.h"
|
||||
@@ -92,10 +91,20 @@ static char *tdls_get_cmd_type_str(enum tdls_command_type cmd_type)
|
||||
return "TDLS_CMD_TEARDOWN_LINKS";
|
||||
case TDLS_NOTIFY_RESET_ADAPTERS:
|
||||
return "TDLS_NOTIFY_RESET_ADAPTERS";
|
||||
case TDLS_CMD_GET_ALL_PEERS:
|
||||
return "TDLS_CMD_GET_ALL_PEERS";
|
||||
case TDLS_CMD_ANTENNA_SWITCH:
|
||||
return "TDLS_CMD_ANTENNA_SWITCH";
|
||||
case TDLS_CMD_START_BSS:
|
||||
return "TDLS_CMD_START_BSS";
|
||||
case TDLS_CMD_SET_OFFCHANMODE:
|
||||
return "TDLS_CMD_SET_OFFCHANMODE";
|
||||
case TDLS_CMD_SET_OFFCHANNEL:
|
||||
return "TDLS_CMD_SET_OFFCHANNEL";
|
||||
case TDLS_CMD_SET_SECOFFCHANOFFSET:
|
||||
return "TDLS_CMD_SET_SECOFFCHANOFFSET";
|
||||
case TDLS_DELETE_ALL_PEERS_INDICATION:
|
||||
return "TDLS_DELETE_ALL_PEERS_INDICATION";
|
||||
default:
|
||||
return "Invalid TDLS command";
|
||||
}
|
||||
@@ -646,8 +655,7 @@ QDF_STATUS tdls_process_cmd(struct scheduler_msg *msg)
|
||||
break;
|
||||
case TDLS_CMD_SESSION_DECREMENT:
|
||||
tdls_process_decrement_active_session(msg->bodyptr);
|
||||
/* take decision on connection tracker */
|
||||
fallthrough;
|
||||
break;
|
||||
case TDLS_CMD_SESSION_INCREMENT:
|
||||
tdls_process_policy_mgr_notification(msg->bodyptr);
|
||||
break;
|
||||
@@ -1131,7 +1139,8 @@ set_state:
|
||||
else
|
||||
tdls_implicit_disable(tdls_vdev_obj);
|
||||
|
||||
tdls_debug("enable_tdls_connection_tracker %d current_mode:%d feature_flags:0x%x",
|
||||
tdls_debug("vdev:%d enable_tdls_connection_tracker %d current_mode:%d feature_flags:0x%x",
|
||||
wlan_vdev_get_id(vdev),
|
||||
tdls_soc_obj->enable_tdls_connection_tracker,
|
||||
tdls_soc_obj->tdls_current_mode, tdls_feature_flags);
|
||||
}
|
||||
@@ -1139,33 +1148,45 @@ set_state:
|
||||
QDF_STATUS
|
||||
tdls_process_policy_mgr_notification(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
struct wlan_objmgr_vdev *tdls_obj_vdev;
|
||||
struct wlan_objmgr_vdev *tdls_vdev;
|
||||
struct tdls_vdev_priv_obj *tdls_priv_vdev;
|
||||
struct tdls_soc_priv_obj *tdls_priv_soc;
|
||||
QDF_STATUS status;
|
||||
|
||||
if (!psoc) {
|
||||
tdls_err("psoc: %pK", psoc);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
tdls_obj_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
|
||||
if (!tdls_obj_vdev) {
|
||||
tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
|
||||
if (!tdls_vdev) {
|
||||
tdls_err("No TDLS vdev");
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
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);
|
||||
status = tdls_get_vdev_objects(tdls_vdev, &tdls_priv_vdev,
|
||||
&tdls_priv_soc);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
tdls_debug("TDLS vdev objects NULL");
|
||||
wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
tdls_set_tdls_offchannelmode(tdls_obj_vdev, ENABLE_CHANSWITCH);
|
||||
if (!tdls_check_is_tdls_allowed(tdls_vdev)) {
|
||||
tdls_disable_offchan_and_teardown_links(tdls_vdev);
|
||||
tdls_debug("Disable the tdls in FW due to concurrency");
|
||||
wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
|
||||
return QDF_STATUS_E_NULL_VALUE;
|
||||
}
|
||||
|
||||
tdls_debug("enter ");
|
||||
tdls_set_ct_mode(psoc, tdls_obj_vdev);
|
||||
tdls_debug("vdev:%d enter", wlan_vdev_get_id(tdls_vdev));
|
||||
|
||||
wlan_objmgr_vdev_release_ref(tdls_obj_vdev, WLAN_TDLS_NB_ID);
|
||||
tdls_set_tdls_offchannelmode(tdls_vdev, ENABLE_CHANSWITCH);
|
||||
tdls_set_ct_mode(psoc, tdls_vdev);
|
||||
|
||||
wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
|
||||
tdls_debug("exit ");
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1278,10 +1299,6 @@ struct wlan_objmgr_vdev *tdls_get_vdev(struct wlan_objmgr_psoc *psoc,
|
||||
{
|
||||
uint32_t vdev_id;
|
||||
|
||||
if (policy_mgr_get_connection_count_with_mlo(psoc) > 1 &&
|
||||
!tdls_is_concurrency_allowed(psoc))
|
||||
return NULL;
|
||||
|
||||
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,
|
||||
@@ -1500,6 +1517,43 @@ done:
|
||||
return;
|
||||
}
|
||||
|
||||
void tdls_process_enable_for_vdev(struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct tdls_vdev_priv_obj *tdls_vdev_obj;
|
||||
struct tdls_soc_priv_obj *tdls_soc_obj;
|
||||
struct tdls_sta_notify_params *ap_cap;
|
||||
enum QDF_OPMODE opmode;
|
||||
QDF_STATUS status;
|
||||
uint8_t sta_count;
|
||||
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
if (!psoc)
|
||||
return;
|
||||
|
||||
sta_count = policy_mgr_mode_specific_connection_count(psoc, PM_STA_MODE,
|
||||
NULL);
|
||||
opmode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
if (opmode == QDF_P2P_CLIENT_MODE && sta_count) {
|
||||
tdls_debug("STA + P2P concurrency. Don't allow TDLS on P2P vdev");
|
||||
return;
|
||||
}
|
||||
|
||||
status = tdls_get_vdev_objects(vdev, &tdls_vdev_obj, &tdls_soc_obj);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return;
|
||||
|
||||
ap_cap = &tdls_vdev_obj->tdls_caps;
|
||||
if (!tdls_soc_obj->tdls_disable_in_progress)
|
||||
tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj,
|
||||
ap_cap->tdls_prohibited,
|
||||
ap_cap->tdls_chan_swit_prohibited, true,
|
||||
ap_cap->session_id);
|
||||
|
||||
/* check and set the connection tracker */
|
||||
tdls_set_ct_mode(tdls_soc_obj->soc, vdev);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
tdls_process_sta_connect(struct tdls_sta_notify_params *notify)
|
||||
{
|
||||
@@ -1515,15 +1569,10 @@ tdls_process_sta_connect(struct tdls_sta_notify_params *notify)
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
/* Association event */
|
||||
if (!tdls_soc_obj->tdls_disable_in_progress)
|
||||
tdls_send_update_to_fw(tdls_vdev_obj, tdls_soc_obj,
|
||||
notify->tdls_prohibited,
|
||||
notify->tdls_chan_swit_prohibited, true,
|
||||
notify->session_id);
|
||||
if (tdls_vdev_obj)
|
||||
tdls_vdev_obj->tdls_caps = *notify;
|
||||
|
||||
/* check and set the connection tracker */
|
||||
tdls_set_ct_mode(tdls_soc_obj->soc, notify->vdev);
|
||||
tdls_process_enable_for_vdev(notify->vdev);
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
@@ -278,6 +278,7 @@ struct tdls_soc_priv_obj {
|
||||
* @discovery_sent_cnt: discovery sent count
|
||||
* @curr_candidate: current candidate
|
||||
* @ct_peer_table: linear mac address table for counting the packets
|
||||
* @tdls_caps: AP TDLS capabilities
|
||||
* @valid_mac_entries: number of valid mac entry in @ct_peer_mac_table
|
||||
* @rx_mgmt: the pointer of rx mgmt info
|
||||
* @link_score: select tdls vdev per the score
|
||||
@@ -297,6 +298,7 @@ struct tdls_vdev_priv_obj {
|
||||
struct tdls_peer *curr_candidate;
|
||||
struct tdls_conn_tracker_mac_table
|
||||
ct_peer_table[WLAN_TDLS_CT_TABLE_SIZE];
|
||||
struct tdls_sta_notify_params tdls_caps;
|
||||
uint8_t valid_mac_entries;
|
||||
struct tdls_rx_mgmt_frame *rx_mgmt;
|
||||
uint32_t link_score;
|
||||
@@ -606,6 +608,15 @@ QDF_STATUS tdls_set_operation_mode(struct tdls_set_mode_params *tdls_set_mode);
|
||||
*/
|
||||
QDF_STATUS tdls_notify_sta_connect(struct tdls_sta_notify_params *notify);
|
||||
|
||||
/**
|
||||
* tdls_process_enable_for_vdev() - Enable TDLS in firmware and activate the
|
||||
* connection tracker
|
||||
* @vdev: Pointer to vdev object
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void tdls_process_enable_for_vdev(struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* tdls_notify_sta_disconnect() - Update tdls state for every
|
||||
* disconnect event.
|
||||
|
@@ -29,7 +29,6 @@
|
||||
#include "wlan_mgmt_txrx_utils_api.h"
|
||||
#include "wlan_tdls_peer.h"
|
||||
#include "wlan_tdls_ct.h"
|
||||
#include "wlan_tdls_cmds_process.h"
|
||||
#include "wlan_tdls_mgmt.h"
|
||||
#include "wlan_policy_mgr_api.h"
|
||||
#include <wlan_reg_services_api.h>
|
||||
|
@@ -26,6 +26,8 @@
|
||||
#ifndef _WLAN_TDLS_MGMT_H_
|
||||
#define _WLAN_TDLS_MGMT_H_
|
||||
|
||||
#include "wlan_tdls_cmds_process.h"
|
||||
|
||||
#define TDLS_PUBLIC_ACTION_FRAME_OFFSET 24
|
||||
/* TDLS_PUBLIC_ACTION_FRAME_OFFSET(category[1]) + action[1] + dialog[1]
|
||||
* + cap[2]
|
||||
|
@@ -63,12 +63,14 @@ void wlan_tdls_get_features_info(struct wlan_objmgr_psoc *psoc,
|
||||
QDF_STATUS wlan_tdls_teardown_links(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* wlan_tdls_teardown_links_sync() - teardown all the TDLS links
|
||||
* wlan_tdls_check_and_teardown_links_sync() - teardown all the TDLS links
|
||||
* @psoc: psoc object
|
||||
* @vdev: Vdev object pointer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc);
|
||||
void wlan_tdls_check_and_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* wlan_tdls_notify_sta_disconnect() - notify sta disconnect
|
||||
@@ -127,10 +129,62 @@ void wlan_tdls_update_rx_pkt_cnt(struct wlan_objmgr_vdev *vdev,
|
||||
/**
|
||||
* wlan_tdls_notify_start_bss() - Notify TDLS module on start bss
|
||||
* @psoc: Pointer to PSOC object
|
||||
* @vdev: Vdev object pointer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc);
|
||||
void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
|
||||
/**
|
||||
* wlan_tdls_notify_channel_switch_complete() - Notify TDLS module about the
|
||||
* channel switch completion
|
||||
* @psoc: Pointer to PSOC object
|
||||
* @vdev_id: vdev id
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void wlan_tdls_notify_channel_switch_complete(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id);
|
||||
|
||||
/**
|
||||
* wlan_tdls_notify_channel_switch_start() - Process channel switch start
|
||||
* for SAP/P2P GO vdev. For STA vdev, TDLS teardown happens, so explicit
|
||||
* disable off channel is not required.
|
||||
* @psoc: Pointer to PSOC object
|
||||
* @vdev: Pointer to current vdev on which CSA is triggered
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void wlan_tdls_notify_channel_switch_start(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* wlan_tdls_handle_p2p_client_connect() - Handle P2P Client connect start
|
||||
* @psoc: Pointer to PSOC object
|
||||
* @vdev: Pointer to P2P client vdev
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void wlan_tdls_handle_p2p_client_connect(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev);
|
||||
#else
|
||||
static inline
|
||||
void wlan_tdls_notify_channel_switch_complete(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id)
|
||||
{}
|
||||
|
||||
static inline
|
||||
void wlan_tdls_notify_channel_switch_start(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{}
|
||||
|
||||
static inline
|
||||
void wlan_tdls_handle_p2p_client_connect(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{}
|
||||
#endif /* WLAN_FEATURE_TDLS_CONCURRENCIES */
|
||||
#else
|
||||
|
||||
#ifdef FEATURE_SET
|
||||
@@ -152,7 +206,9 @@ static inline QDF_STATUS wlan_tdls_teardown_links(struct wlan_objmgr_psoc *psoc)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static inline void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc)
|
||||
static inline void
|
||||
wlan_tdls_check_and_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{}
|
||||
|
||||
static inline
|
||||
@@ -181,7 +237,23 @@ 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)
|
||||
void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{}
|
||||
|
||||
static inline
|
||||
void wlan_tdls_notify_channel_switch_complete(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id)
|
||||
{}
|
||||
|
||||
static inline
|
||||
void wlan_tdls_notify_channel_switch_start(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{}
|
||||
|
||||
static inline
|
||||
void wlan_tdls_handle_p2p_client_connect(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{}
|
||||
#endif
|
||||
#endif
|
||||
|
@@ -298,10 +298,12 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_psoc *psoc);
|
||||
/**
|
||||
* ucfg_tdls_teardown_links_sync() - teardown all TDLS links.
|
||||
* @psoc: psoc object
|
||||
* @vdev: Vdev object pointer
|
||||
*
|
||||
* Return: None
|
||||
*/
|
||||
void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc);
|
||||
void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev);
|
||||
|
||||
/**
|
||||
* ucfg_tdls_notify_reset_adapter() - notify reset adapter
|
||||
@@ -534,7 +536,8 @@ QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_psoc *psoc)
|
||||
}
|
||||
|
||||
static inline
|
||||
void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc)
|
||||
void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -88,17 +88,18 @@ bool wlan_tdls_is_fw_11be_mlo_capable(struct wlan_objmgr_psoc *psoc)
|
||||
}
|
||||
#endif
|
||||
|
||||
void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc)
|
||||
static void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
struct tdls_vdev_priv_obj *vdev_priv_obj;
|
||||
QDF_STATUS status;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
struct wlan_objmgr_vdev *tdls_vdev;
|
||||
|
||||
vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
|
||||
tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
|
||||
if (!vdev)
|
||||
return;
|
||||
|
||||
vdev_priv_obj = wlan_vdev_get_tdls_vdev_obj(vdev);
|
||||
vdev_priv_obj = wlan_vdev_get_tdls_vdev_obj(tdls_vdev);
|
||||
if (!vdev_priv_obj) {
|
||||
tdls_err("vdev priv is NULL");
|
||||
goto release_ref;
|
||||
@@ -112,7 +113,8 @@ void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc)
|
||||
goto release_ref;
|
||||
}
|
||||
|
||||
tdls_debug("Wait for tdls teardown completion. Timeout %u ms",
|
||||
tdls_debug("vdev:%d Wait for tdls teardown completion. Timeout %u ms",
|
||||
wlan_vdev_get_id(tdls_vdev),
|
||||
WAIT_TIME_FOR_TDLS_TEARDOWN_LINKS);
|
||||
|
||||
status = qdf_wait_for_event_completion(
|
||||
@@ -126,10 +128,34 @@ void wlan_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc)
|
||||
tdls_debug("TDLS teardown completion status %d ", status);
|
||||
|
||||
release_ref:
|
||||
wlan_objmgr_vdev_release_ref(vdev,
|
||||
wlan_objmgr_vdev_release_ref(tdls_vdev,
|
||||
WLAN_TDLS_NB_ID);
|
||||
}
|
||||
|
||||
void wlan_tdls_check_and_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
uint8_t sta_count;
|
||||
enum QDF_OPMODE opmode;
|
||||
bool tgt_tdls_concurrency_supported;
|
||||
|
||||
tgt_tdls_concurrency_supported =
|
||||
wlan_psoc_nif_fw_ext2_cap_get(psoc,
|
||||
WLAN_TDLS_CONCURRENCIES_SUPPORT);
|
||||
/* Don't initiate teardown in case of STA + P2P Client concurreny */
|
||||
sta_count = policy_mgr_mode_specific_connection_count(psoc,
|
||||
PM_STA_MODE,
|
||||
NULL);
|
||||
opmode = wlan_vdev_mlme_get_opmode(vdev);
|
||||
if (tgt_tdls_concurrency_supported && opmode == QDF_P2P_CLIENT_MODE &&
|
||||
sta_count) {
|
||||
tdls_debug("Don't teardown tdls for existing STA vdev");
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_tdls_teardown_links_sync(psoc, vdev);
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
|
||||
static void wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc *psoc)
|
||||
{
|
||||
@@ -147,20 +173,125 @@ static void wlan_tdls_handle_sap_start(struct wlan_objmgr_psoc *psoc)
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void wlan_tdls_notify_channel_switch_complete(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t vdev_id)
|
||||
{
|
||||
struct wlan_objmgr_vdev *tdls_vdev;
|
||||
struct tdls_vdev_priv_obj *tdls_vdev_priv;
|
||||
struct tdls_soc_priv_obj *tdls_soc_priv;
|
||||
QDF_STATUS status;
|
||||
|
||||
tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
|
||||
if (!tdls_vdev)
|
||||
return;
|
||||
|
||||
status = tdls_get_vdev_objects(tdls_vdev, &tdls_vdev_priv,
|
||||
&tdls_soc_priv);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
tdls_err("Failed to get TDLS objects");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Channel Switch can cause SCC -> MCC switch on
|
||||
* STA vdev. Disable TDLS if CSA causes STA vdev to be in MCC with
|
||||
* other vdev.
|
||||
*/
|
||||
if (!tdls_is_concurrency_allowed(psoc)) {
|
||||
tdls_disable_offchan_and_teardown_links(tdls_vdev);
|
||||
tdls_debug("Disable the tdls in FW after CSA");
|
||||
} else {
|
||||
tdls_process_enable_for_vdev(tdls_vdev);
|
||||
tdls_set_tdls_offchannelmode(tdls_vdev, ENABLE_CHANSWITCH);
|
||||
}
|
||||
|
||||
exit:
|
||||
wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
|
||||
}
|
||||
|
||||
static QDF_STATUS
|
||||
wlan_tdls_post_set_off_channel_mode(struct wlan_objmgr_psoc *psoc,
|
||||
uint8_t off_chan_mode)
|
||||
{
|
||||
struct wlan_objmgr_vdev *tdls_vdev;
|
||||
struct tdls_vdev_priv_obj *tdls_vdev_priv;
|
||||
struct tdls_soc_priv_obj *tdls_soc_priv;
|
||||
struct tdls_set_offchanmode *req;
|
||||
struct scheduler_msg msg = {0};
|
||||
QDF_STATUS status;
|
||||
|
||||
tdls_vdev = tdls_get_vdev(psoc, WLAN_TDLS_NB_ID);
|
||||
if (!tdls_vdev)
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
|
||||
status = tdls_get_vdev_objects(tdls_vdev, &tdls_vdev_priv,
|
||||
&tdls_soc_priv);
|
||||
if (QDF_IS_STATUS_ERROR(status)) {
|
||||
wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
|
||||
tdls_err("Failed to get TDLS objects");
|
||||
return QDF_STATUS_E_FAILURE;
|
||||
}
|
||||
|
||||
req = qdf_mem_malloc(sizeof(*req));
|
||||
if (!req) {
|
||||
wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
|
||||
return QDF_STATUS_E_NOMEM;
|
||||
}
|
||||
|
||||
req->offchan_mode = off_chan_mode;
|
||||
req->vdev = tdls_vdev;
|
||||
req->callback = wlan_tdls_offchan_parms_callback;
|
||||
|
||||
msg.callback = tdls_process_cmd;
|
||||
msg.type = TDLS_CMD_SET_OFFCHANMODE;
|
||||
msg.bodyptr = req;
|
||||
|
||||
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 set offchanmode msg fail");
|
||||
wlan_objmgr_vdev_release_ref(tdls_vdev, WLAN_TDLS_NB_ID);
|
||||
qdf_mem_free(req);
|
||||
}
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
void wlan_tdls_notify_channel_switch_start(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
wlan_tdls_post_set_off_channel_mode(psoc, DISABLE_ACTIVE_CHANSWITCH);
|
||||
}
|
||||
|
||||
void wlan_tdls_handle_p2p_client_connect(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
if (policy_mgr_get_connection_count(psoc) < 2)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Disable TDLS off-channel when P2P CLI comes up as
|
||||
* 3rd interface. It will be re-enabled based on the
|
||||
* concurrency once P2P connection is complete
|
||||
*/
|
||||
wlan_tdls_post_set_off_channel_mode(psoc, DISABLE_ACTIVE_CHANSWITCH);
|
||||
}
|
||||
#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)
|
||||
void wlan_tdls_notify_start_bss(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
if (tdls_is_concurrency_allowed(psoc)) {
|
||||
wlan_tdls_handle_sap_start(psoc);
|
||||
return;
|
||||
}
|
||||
|
||||
wlan_tdls_teardown_links_sync(psoc);
|
||||
wlan_tdls_check_and_teardown_links_sync(psoc, vdev);
|
||||
}
|
||||
|
||||
static QDF_STATUS tdls_notify_flush_cb(struct scheduler_msg *msg)
|
||||
|
@@ -985,9 +985,10 @@ QDF_STATUS ucfg_tdls_responder(struct tdls_set_responder_req *req)
|
||||
return status;
|
||||
}
|
||||
|
||||
void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc)
|
||||
void ucfg_tdls_teardown_links_sync(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_objmgr_vdev *vdev)
|
||||
{
|
||||
return wlan_tdls_teardown_links_sync(psoc);
|
||||
return wlan_tdls_check_and_teardown_links_sync(psoc, vdev);
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_tdls_teardown_links(struct wlan_objmgr_psoc *psoc)
|
||||
|
Reference in New Issue
Block a user