qcacld-3.0: Add support to disable TDLS offchannel completely
Add support for new TDLS off-channel mode type: DISABLE_ACTIVE_CHANSWITCH. With this off channel mode, the TDLS off-channel will be disabled completely without passive disable mode. DISABLE_CHANSWITCH -> Passive channel switch can be done i.e if peer requests channel switch then firmware can do channel switch DISABLE_ACTIVE_CHANSWITCH -> Disable all off-channel switches. Add support to send peer channel lists based on concurrency combination. Override the ini configured frequency to the supported frequency based on the current concurrency. Change-Id: Ie3210178eb8b57d6ab126a730ed91895b70edaa1 CRs-Fixed: 3416213
This commit is contained in:

committed by
Madan Koyyalamudi

parent
9d72a8fc92
commit
06be2cbc56
@@ -4919,4 +4919,23 @@ uint32_t policy_mgr_get_connection_count_with_ch_freq(uint32_t ch_freq);
|
|||||||
bool policy_mgr_is_sap_allowed_on_indoor(struct wlan_objmgr_pdev *pdev,
|
bool policy_mgr_is_sap_allowed_on_indoor(struct wlan_objmgr_pdev *pdev,
|
||||||
uint8_t vdev_id, qdf_freq_t ch_freq);
|
uint8_t vdev_id, qdf_freq_t ch_freq);
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
|
||||||
|
/**
|
||||||
|
* policy_mgr_get_allowed_tdls_offchannel_freq() - Check if TDLS off-channel is
|
||||||
|
* allowed during concurrency. When off-channel is allowed, update the provided
|
||||||
|
* input channel frequency with concurrent vdev frequency in DBS case.
|
||||||
|
* Fill the provided channel frequency as 0 if all 5GHz/6GHz channels are
|
||||||
|
* allowed for off-channel operation in SCC case.
|
||||||
|
* Don't allow off channel operation in any MCC case.
|
||||||
|
* @psoc: psoc pointer
|
||||||
|
* @vdev: vdev pointer
|
||||||
|
* @ch_freq: Frequency pointer
|
||||||
|
*
|
||||||
|
* Return: true or false based on current concurrency combination
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc,
|
||||||
|
struct wlan_objmgr_vdev *vdev,
|
||||||
|
qdf_freq_t *ch_freq);
|
||||||
|
#endif /* WLAN_FEATURE_TDLS_CONCURRENCIES */
|
||||||
#endif /* __WLAN_POLICY_MGR_API_H */
|
#endif /* __WLAN_POLICY_MGR_API_H */
|
||||||
|
@@ -3543,3 +3543,122 @@ ret_value:
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
|
||||||
|
bool
|
||||||
|
policy_mgr_get_allowed_tdls_offchannel_freq(struct wlan_objmgr_psoc *psoc,
|
||||||
|
struct wlan_objmgr_vdev *vdev,
|
||||||
|
qdf_freq_t *ch_freq)
|
||||||
|
{
|
||||||
|
struct connection_info info[MAX_NUMBER_OF_CONC_CONNECTIONS] = {0};
|
||||||
|
uint8_t connection_count, i, j, sta_vdev_id;
|
||||||
|
|
||||||
|
*ch_freq = 0;
|
||||||
|
/*
|
||||||
|
* TDLS off channel is not allowed in any MCC scenario
|
||||||
|
*/
|
||||||
|
if (policy_mgr_current_concurrency_is_mcc(psoc)) {
|
||||||
|
policy_mgr_dump_current_concurrency(psoc);
|
||||||
|
policy_mgr_debug("TDLS off channel not allowed in MCC");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TDLS offchannel is done only when STA is connected on 2G channel and
|
||||||
|
* the current concurrency is not MCC
|
||||||
|
*/
|
||||||
|
if (!policy_mgr_is_sta_connected_2g(psoc)) {
|
||||||
|
policy_mgr_debug("STA not-connected on 2.4 Ghz");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 2 Port DBS scenario - Allow non-STA vdev channel for
|
||||||
|
* TDLS off-channel operation
|
||||||
|
*
|
||||||
|
* 3 Port Scenario - If STA Vdev is on SCC, allow TDLS off-channel on
|
||||||
|
* the channel of vdev on the other MAC
|
||||||
|
* If STA vdev is standalone on one mac, and scc on another mac, then
|
||||||
|
* allow TDLS off channel on other mac scc channel
|
||||||
|
*/
|
||||||
|
sta_vdev_id = wlan_vdev_get_id(vdev);
|
||||||
|
connection_count = policy_mgr_get_connection_info(psoc, info);
|
||||||
|
switch (connection_count) {
|
||||||
|
case 1:
|
||||||
|
return true;
|
||||||
|
case 2:
|
||||||
|
/*
|
||||||
|
* Allow all the 5GHz/6GHz channels when STA is in SCC
|
||||||
|
*/
|
||||||
|
if (policy_mgr_current_concurrency_is_scc(psoc)) {
|
||||||
|
*ch_freq = 0;
|
||||||
|
return true;
|
||||||
|
} else if (policy_mgr_is_current_hwmode_dbs(psoc)) {
|
||||||
|
/*
|
||||||
|
* In DBS case, allow off-channel operation on the
|
||||||
|
* other mac 5GHz/6GHz channel where the STA is not
|
||||||
|
* present
|
||||||
|
* Don't consider SBS case since STA should be
|
||||||
|
* connected in 2.4GHz channel for TDLS
|
||||||
|
* off-channel and MCC on SBS ex. 3 PORT
|
||||||
|
* 2.4GHz STA + 5GHz Lower MCC + 5GHz Upper will
|
||||||
|
* not be allowed
|
||||||
|
*/
|
||||||
|
if (sta_vdev_id == info[0].vdev_id)
|
||||||
|
*ch_freq = info[1].ch_freq;
|
||||||
|
else
|
||||||
|
*ch_freq = info[0].ch_freq;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 3 Vdev SCC on 2.4GHz band. Allow TDLS off-channel operation
|
||||||
|
* on all the 5GHz & 6GHz channels
|
||||||
|
*/
|
||||||
|
if (info[0].ch_freq == info[1].ch_freq &&
|
||||||
|
info[0].ch_freq == info[2].ch_freq) {
|
||||||
|
*ch_freq = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DBS with SCC on one vdev scenario. Allow TDLS off-channel
|
||||||
|
* on other mac frequency where STA is not present
|
||||||
|
* SBS case is not considered since STA should be connected
|
||||||
|
* on 2.4GHz and TDLS off-channel on SBS MCC is not allowed
|
||||||
|
*/
|
||||||
|
for (i = 0; i < connection_count; i++) {
|
||||||
|
for (j = i + 1; j < connection_count; j++) {
|
||||||
|
/*
|
||||||
|
* Find 2 vdevs such that STA is one of the vdev
|
||||||
|
* and STA + other vdev are not on same mac.
|
||||||
|
* Return the foreign vdev frequency which is
|
||||||
|
* not on same mac along with STA
|
||||||
|
*/
|
||||||
|
if (!policy_mgr_2_freq_always_on_same_mac(
|
||||||
|
psoc, info[i].ch_freq,
|
||||||
|
info[j].ch_freq)) {
|
||||||
|
if (sta_vdev_id == info[i].vdev_id) {
|
||||||
|
*ch_freq = info[j].ch_freq;
|
||||||
|
return true;
|
||||||
|
} else if (sta_vdev_id ==
|
||||||
|
info[j].vdev_id) {
|
||||||
|
*ch_freq = info[j].ch_freq;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
policy_mgr_debug("TDLS off channel not allowed on > 3 port conc");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021 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
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -28,6 +28,7 @@
|
|||||||
#include "wlan_tdls_ct.h"
|
#include "wlan_tdls_ct.h"
|
||||||
#include "wlan_tdls_cmds_process.h"
|
#include "wlan_tdls_cmds_process.h"
|
||||||
#include "wlan_reg_services_api.h"
|
#include "wlan_reg_services_api.h"
|
||||||
|
#include "wlan_policy_mgr_api.h"
|
||||||
|
|
||||||
bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev)
|
bool tdls_is_vdev_authenticated(struct wlan_objmgr_vdev *vdev)
|
||||||
{
|
{
|
||||||
@@ -1044,11 +1045,117 @@ int tdls_set_tdls_secoffchanneloffset(struct tdls_soc_priv_obj *tdls_soc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
tdls_update_opclass(struct wlan_objmgr_psoc *psoc,
|
||||||
|
struct tdls_channel_switch_params *params)
|
||||||
|
{
|
||||||
|
params->oper_class = tdls_find_opclass(psoc, params->tdls_off_ch,
|
||||||
|
params->tdls_off_ch_bw_offset);
|
||||||
|
if (params->oper_class)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (params->tdls_off_ch_bw_offset == BW40_HIGH_PRIMARY)
|
||||||
|
params->oper_class = tdls_find_opclass(psoc,
|
||||||
|
params->tdls_off_ch,
|
||||||
|
BW40_LOW_PRIMARY);
|
||||||
|
else if (params->tdls_off_ch_bw_offset == BW40_LOW_PRIMARY)
|
||||||
|
params->oper_class = tdls_find_opclass(psoc,
|
||||||
|
params->tdls_off_ch,
|
||||||
|
BW40_HIGH_PRIMARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef WLAN_FEATURE_TDLS_CONCURRENCIES
|
||||||
|
static inline QDF_STATUS
|
||||||
|
tdls_update_peer_off_channel_list(struct wlan_objmgr_pdev *pdev,
|
||||||
|
struct tdls_soc_priv_obj *tdls_soc,
|
||||||
|
struct wlan_objmgr_vdev *vdev,
|
||||||
|
struct tdls_peer *peer,
|
||||||
|
struct tdls_channel_switch_params *params)
|
||||||
|
{
|
||||||
|
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
|
||||||
|
struct tdls_peer_update_state *peer_info;
|
||||||
|
struct tdls_ch_params *off_channels = params->allowed_off_channels;
|
||||||
|
uint16_t i;
|
||||||
|
qdf_freq_t freq, peer_freq;
|
||||||
|
|
||||||
|
if (!wlan_psoc_nif_fw_ext2_cap_get(psoc,
|
||||||
|
WLAN_TDLS_CONCURRENCIES_SUPPORT))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!policy_mgr_get_allowed_tdls_offchannel_freq(psoc, vdev, &freq)) {
|
||||||
|
tdls_debug("off channel not allowed for current concurrency");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Overwrite the preferred off channel freq in case of concurrency
|
||||||
|
*/
|
||||||
|
if (freq) {
|
||||||
|
params->tdls_off_ch = wlan_reg_freq_to_chan(pdev, freq);
|
||||||
|
params->tdls_off_chan_freq = freq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tdls_off_ch_bw_offset is already filled in the caller
|
||||||
|
*/
|
||||||
|
if (tdls_soc->tdls_off_channel &&
|
||||||
|
tdls_soc->tdls_channel_offset != BW_INVALID) {
|
||||||
|
tdls_update_opclass(psoc, params);
|
||||||
|
} else if (peer->off_channel_capable &&
|
||||||
|
peer->pref_off_chan_freq) {
|
||||||
|
params->oper_class =
|
||||||
|
tdls_get_opclass_from_bandwidth(
|
||||||
|
vdev, params->tdls_off_chan_freq,
|
||||||
|
peer->pref_off_chan_width,
|
||||||
|
¶ms->tdls_off_ch_bw_offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
peer_info = qdf_mem_malloc(sizeof(*peer_info));
|
||||||
|
if (!peer_info)
|
||||||
|
return QDF_STATUS_E_NOMEM;
|
||||||
|
|
||||||
|
tdls_extract_peer_state_param(peer_info, peer);
|
||||||
|
params->num_off_channels = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If TDLS concurrency is supported and freq == 0,
|
||||||
|
* then allow all the 5GHz and 6GHz peer supported frequencies for
|
||||||
|
* off-channel operation. If particular frequency is provided based on
|
||||||
|
* concurrency combination then only allow that channel for off-channel.
|
||||||
|
*/
|
||||||
|
for (i = 0; i < peer_info->peer_cap.peer_chanlen; i++) {
|
||||||
|
peer_freq = peer_info->peer_cap.peer_chan[i].ch_freq;
|
||||||
|
if ((!freq || freq == peer_freq) &&
|
||||||
|
(!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];
|
||||||
|
params->num_off_channels++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tdls_debug("Num allowed off channels:%d freq:%u",
|
||||||
|
params->num_off_channels, freq);
|
||||||
|
qdf_mem_free(peer_info);
|
||||||
|
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static inline QDF_STATUS
|
||||||
|
tdls_update_peer_off_channel_list(struct wlan_objmgr_pdev *pdev,
|
||||||
|
struct tdls_soc_priv_obj *tdls_soc,
|
||||||
|
struct wlan_objmgr_vdev *vdev,
|
||||||
|
struct tdls_peer *peer,
|
||||||
|
struct tdls_channel_switch_params *params)
|
||||||
|
{
|
||||||
|
return QDF_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
|
int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
|
||||||
int offchanmode)
|
int offchanmode)
|
||||||
{
|
{
|
||||||
struct tdls_peer *conn_peer = NULL;
|
struct tdls_peer *conn_peer = NULL;
|
||||||
struct tdls_channel_switch_params chan_switch_params = {0};
|
struct tdls_channel_switch_params *chan_switch_params;
|
||||||
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
QDF_STATUS status = QDF_STATUS_E_FAILURE;
|
||||||
int ret_value = 0;
|
int ret_value = 0;
|
||||||
struct tdls_vdev_priv_obj *tdls_vdev;
|
struct tdls_vdev_priv_obj *tdls_vdev;
|
||||||
@@ -1063,7 +1170,7 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
|
|||||||
|
|
||||||
|
|
||||||
if (offchanmode < ENABLE_CHANSWITCH ||
|
if (offchanmode < ENABLE_CHANSWITCH ||
|
||||||
offchanmode > DISABLE_CHANSWITCH) {
|
offchanmode > DISABLE_ACTIVE_CHANSWITCH) {
|
||||||
tdls_err("Invalid tdls off channel mode %d", offchanmode);
|
tdls_err("Invalid tdls off channel mode %d", offchanmode);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1091,103 +1198,92 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
|
|||||||
offchanmode, tdls_soc->tdls_off_channel,
|
offchanmode, tdls_soc->tdls_off_channel,
|
||||||
tdls_soc->tdls_channel_offset);
|
tdls_soc->tdls_channel_offset);
|
||||||
|
|
||||||
|
chan_switch_params = qdf_mem_malloc(sizeof(*chan_switch_params));
|
||||||
|
if (!chan_switch_params)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
switch (offchanmode) {
|
switch (offchanmode) {
|
||||||
case ENABLE_CHANSWITCH:
|
case ENABLE_CHANSWITCH:
|
||||||
if (tdls_soc->tdls_off_channel &&
|
if (tdls_soc->tdls_off_channel &&
|
||||||
tdls_soc->tdls_channel_offset != BW_INVALID) {
|
tdls_soc->tdls_channel_offset != BW_INVALID) {
|
||||||
chan_switch_params.tdls_off_ch =
|
chan_switch_params->tdls_off_ch =
|
||||||
tdls_soc->tdls_off_channel;
|
tdls_soc->tdls_off_channel;
|
||||||
chan_switch_params.tdls_off_ch_bw_offset =
|
chan_switch_params->tdls_off_ch_bw_offset =
|
||||||
tdls_soc->tdls_channel_offset;
|
tdls_soc->tdls_channel_offset;
|
||||||
chan_switch_params.oper_class =
|
tdls_update_opclass(wlan_pdev_get_psoc(pdev),
|
||||||
tdls_find_opclass(tdls_soc->soc,
|
chan_switch_params);
|
||||||
chan_switch_params.tdls_off_ch,
|
|
||||||
chan_switch_params.tdls_off_ch_bw_offset);
|
|
||||||
if (!chan_switch_params.oper_class) {
|
|
||||||
if (chan_switch_params.tdls_off_ch_bw_offset ==
|
|
||||||
BW40_HIGH_PRIMARY)
|
|
||||||
chan_switch_params.oper_class =
|
|
||||||
tdls_find_opclass(tdls_soc->soc,
|
|
||||||
chan_switch_params.tdls_off_ch,
|
|
||||||
BW40_LOW_PRIMARY);
|
|
||||||
else if (chan_switch_params.
|
|
||||||
tdls_off_ch_bw_offset ==
|
|
||||||
BW40_LOW_PRIMARY)
|
|
||||||
chan_switch_params.oper_class =
|
|
||||||
tdls_find_opclass(tdls_soc->soc,
|
|
||||||
chan_switch_params.tdls_off_ch,
|
|
||||||
BW40_HIGH_PRIMARY);
|
|
||||||
tdls_debug("oper_class:%d",
|
|
||||||
chan_switch_params.oper_class);
|
|
||||||
}
|
|
||||||
} else if (conn_peer->off_channel_capable &&
|
} else if (conn_peer->off_channel_capable &&
|
||||||
conn_peer->pref_off_chan_freq) {
|
conn_peer->pref_off_chan_freq) {
|
||||||
chan_switch_params.tdls_off_ch =
|
chan_switch_params->tdls_off_ch =
|
||||||
wlan_reg_freq_to_chan(pdev,
|
wlan_reg_freq_to_chan(pdev,
|
||||||
conn_peer->pref_off_chan_freq);
|
conn_peer->pref_off_chan_freq);
|
||||||
chan_switch_params.oper_class =
|
chan_switch_params->oper_class =
|
||||||
tdls_get_opclass_from_bandwidth(
|
tdls_get_opclass_from_bandwidth(
|
||||||
vdev, conn_peer->pref_off_chan_freq,
|
vdev, conn_peer->pref_off_chan_freq,
|
||||||
conn_peer->pref_off_chan_width,
|
conn_peer->pref_off_chan_width,
|
||||||
&chan_switch_params.tdls_off_ch_bw_offset);
|
&chan_switch_params->tdls_off_ch_bw_offset);
|
||||||
chan_switch_params.tdls_off_chan_freq =
|
chan_switch_params->tdls_off_chan_freq =
|
||||||
conn_peer->pref_off_chan_freq;
|
conn_peer->pref_off_chan_freq;
|
||||||
} else {
|
} else {
|
||||||
tdls_err("TDLS off-channel parameters are not set yet!!!");
|
tdls_err("TDLS off-channel parameters are not set yet!!!");
|
||||||
|
qdf_mem_free(chan_switch_params);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Retain the connected peer preferred off-channel frequency
|
||||||
|
* and opclass that was calculated during update peer caps and
|
||||||
|
* don't overwrite it based on concurrency in
|
||||||
|
* tdls_update_peer_off_channel_list().
|
||||||
|
*/
|
||||||
|
conn_peer->pref_off_chan_freq =
|
||||||
|
wlan_reg_chan_opclass_to_freq(
|
||||||
|
chan_switch_params->tdls_off_ch,
|
||||||
|
chan_switch_params->oper_class, false);
|
||||||
|
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);
|
||||||
break;
|
break;
|
||||||
case DISABLE_CHANSWITCH:
|
case DISABLE_CHANSWITCH:
|
||||||
chan_switch_params.tdls_off_ch = 0;
|
case DISABLE_ACTIVE_CHANSWITCH:
|
||||||
chan_switch_params.tdls_off_ch_bw_offset = 0;
|
chan_switch_params->tdls_off_ch = 0;
|
||||||
chan_switch_params.oper_class = 0;
|
chan_switch_params->tdls_off_ch_bw_offset = 0;
|
||||||
|
chan_switch_params->oper_class = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tdls_err("Incorrect Parameters mode: %d tdls_off_channel: %d offchanoffset: %d",
|
tdls_err("Incorrect Parameters mode: %d tdls_off_channel: %d offchanoffset: %d",
|
||||||
offchanmode, tdls_soc->tdls_off_channel,
|
offchanmode, tdls_soc->tdls_off_channel,
|
||||||
tdls_soc->tdls_channel_offset);
|
tdls_soc->tdls_channel_offset);
|
||||||
|
qdf_mem_free(chan_switch_params);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
} /* end switch */
|
} /* end switch */
|
||||||
|
|
||||||
chan_switch_params.vdev_id = tdls_vdev->session_id;
|
chan_switch_params->vdev_id = tdls_vdev->session_id;
|
||||||
chan_switch_params.tdls_sw_mode = offchanmode;
|
chan_switch_params->tdls_sw_mode = offchanmode;
|
||||||
chan_switch_params.is_responder =
|
chan_switch_params->is_responder = conn_peer->is_responder;
|
||||||
conn_peer->is_responder;
|
qdf_mem_copy(&chan_switch_params->peer_mac_addr,
|
||||||
qdf_mem_copy(&chan_switch_params.peer_mac_addr,
|
&conn_peer->peer_mac.bytes, QDF_MAC_ADDR_SIZE);
|
||||||
&conn_peer->peer_mac.bytes,
|
|
||||||
QDF_MAC_ADDR_SIZE);
|
|
||||||
tdls_notice("Peer " QDF_MAC_ADDR_FMT " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d",
|
tdls_notice("Peer " QDF_MAC_ADDR_FMT " vdevId: %d, off channel: %d, offset: %d, mode: %d, is_responder: %d",
|
||||||
QDF_MAC_ADDR_REF(chan_switch_params.peer_mac_addr),
|
QDF_MAC_ADDR_REF(chan_switch_params->peer_mac_addr),
|
||||||
chan_switch_params.vdev_id,
|
chan_switch_params->vdev_id,
|
||||||
chan_switch_params.tdls_off_ch,
|
chan_switch_params->tdls_off_ch,
|
||||||
chan_switch_params.tdls_off_ch_bw_offset,
|
chan_switch_params->tdls_off_ch_bw_offset,
|
||||||
chan_switch_params.tdls_sw_mode,
|
chan_switch_params->tdls_sw_mode,
|
||||||
chan_switch_params.is_responder);
|
chan_switch_params->is_responder);
|
||||||
|
|
||||||
status = tdls_set_offchan_mode(tdls_soc->soc,
|
status = tdls_set_offchan_mode(tdls_soc->soc, chan_switch_params);
|
||||||
&chan_switch_params);
|
if (QDF_IS_STATUS_ERROR(status)) {
|
||||||
|
qdf_mem_free(chan_switch_params);
|
||||||
if (status != QDF_STATUS_SUCCESS) {
|
|
||||||
tdls_err("Failed to send channel switch request to wmi");
|
tdls_err("Failed to send channel switch request to wmi");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
tdls_soc->tdls_fw_off_chan_mode = offchanmode;
|
tdls_soc->tdls_fw_off_chan_mode = offchanmode;
|
||||||
|
qdf_mem_free(chan_switch_params);
|
||||||
if (ENABLE_CHANSWITCH == offchanmode) {
|
|
||||||
conn_peer = tdls_find_first_connected_peer(tdls_vdev);
|
|
||||||
if (!conn_peer) {
|
|
||||||
tdls_err("No TDLS Connected Peer");
|
|
||||||
return -EPERM;
|
|
||||||
}
|
|
||||||
conn_peer->pref_off_chan_freq = wlan_reg_chan_opclass_to_freq(
|
|
||||||
chan_switch_params.tdls_off_ch,
|
|
||||||
chan_switch_params.oper_class,
|
|
||||||
false);
|
|
||||||
conn_peer->op_class_for_pref_off_chan =
|
|
||||||
chan_switch_params.oper_class;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret_value;
|
return ret_value;
|
||||||
}
|
}
|
||||||
@@ -1318,8 +1414,7 @@ void tdls_disable_offchan_and_teardown_links(
|
|||||||
/* Send Msg to PE for deleting all the TDLS peers */
|
/* Send Msg to PE for deleting all the TDLS peers */
|
||||||
tdls_delete_all_tdls_peers(vdev, tdls_soc);
|
tdls_delete_all_tdls_peers(vdev, tdls_soc);
|
||||||
|
|
||||||
for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta;
|
for (staidx = 0; staidx < tdls_soc->max_num_tdls_sta; staidx++) {
|
||||||
staidx++) {
|
|
||||||
if (!tdls_soc->tdls_conn_info[staidx].valid_entry)
|
if (!tdls_soc->tdls_conn_info[staidx].valid_entry)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -1332,8 +1427,7 @@ void tdls_disable_offchan_and_teardown_links(
|
|||||||
QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes));
|
QDF_MAC_ADDR_REF(curr_peer->peer_mac.bytes));
|
||||||
|
|
||||||
/* Indicate teardown to supplicant */
|
/* Indicate teardown to supplicant */
|
||||||
tdls_indicate_teardown(tdls_vdev,
|
tdls_indicate_teardown(tdls_vdev, curr_peer,
|
||||||
curr_peer,
|
|
||||||
TDLS_TEARDOWN_PEER_UNSPEC_REASON);
|
TDLS_TEARDOWN_PEER_UNSPEC_REASON);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
* Copyright (c) 2017-2021 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
|
* Permission to use, copy, modify, and/or distribute this software for
|
||||||
* any purpose with or without fee is hereby granted, provided that the
|
* any purpose with or without fee is hereby granted, provided that the
|
||||||
@@ -45,8 +45,11 @@
|
|||||||
#define WLAN_MAX_SUPP_OPER_CLASSES 32
|
#define WLAN_MAX_SUPP_OPER_CLASSES 32
|
||||||
#define WLAN_MAC_MAX_SUPP_RATES 32
|
#define WLAN_MAC_MAX_SUPP_RATES 32
|
||||||
#define WLAN_CHANNEL_14 14
|
#define WLAN_CHANNEL_14 14
|
||||||
|
|
||||||
#define ENABLE_CHANSWITCH 1
|
#define ENABLE_CHANSWITCH 1
|
||||||
#define DISABLE_CHANSWITCH 2
|
#define DISABLE_CHANSWITCH 2
|
||||||
|
#define DISABLE_ACTIVE_CHANSWITCH 3
|
||||||
|
|
||||||
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1
|
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MIN 1
|
||||||
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165
|
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_MAX 165
|
||||||
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF 36
|
#define WLAN_TDLS_PREFERRED_OFF_CHANNEL_NUM_DEF 36
|
||||||
@@ -1008,6 +1011,8 @@ struct tdls_peer_update_state {
|
|||||||
* @oper_class: Operating class for target channel
|
* @oper_class: Operating class for target channel
|
||||||
* @is_responder: Responder or initiator
|
* @is_responder: Responder or initiator
|
||||||
* @tdls_off_chan_freq: Target Off Channel frequency
|
* @tdls_off_chan_freq: Target Off Channel frequency
|
||||||
|
* @num_off_channels: Number of channels allowed for off channel operation
|
||||||
|
* @allowed_off_channels: Channel list allowed for off channels
|
||||||
*/
|
*/
|
||||||
struct tdls_channel_switch_params {
|
struct tdls_channel_switch_params {
|
||||||
uint32_t vdev_id;
|
uint32_t vdev_id;
|
||||||
@@ -1018,6 +1023,8 @@ struct tdls_channel_switch_params {
|
|||||||
uint8_t oper_class;
|
uint8_t oper_class;
|
||||||
uint8_t is_responder;
|
uint8_t is_responder;
|
||||||
uint32_t tdls_off_chan_freq;
|
uint32_t tdls_off_chan_freq;
|
||||||
|
uint16_t num_off_channels;
|
||||||
|
struct tdls_ch_params allowed_off_channels[WLAN_MAC_WMI_MAX_SUPP_CHANNELS];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user