qcacld-3.0: Add support for TDLS offchannel
Add support for TDLS offchannel changes required for supporting TDLS offchannel on 6 GHz band. Change-Id: Ie150ff7e5a8237dab445ccb0ab6a4959a7c7fbf0 CRs-Fixed: 3223640
This commit is contained in:

committed by
Madan Koyyalamudi

parent
186163bc5a
commit
50885ab717
@@ -46,39 +46,6 @@ static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj)
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11AX
|
||||
static uint32_t tdls_get_6g_pwr(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t freq,
|
||||
enum supported_6g_pwr_types pwr_typ)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
|
||||
struct regulatory_channel chan[NUM_CHANNELS] = {0};
|
||||
uint8_t chn_idx, num_chan;
|
||||
uint8_t band_mask = BIT(REG_BAND_6G);
|
||||
|
||||
if (!pdev)
|
||||
return 0;
|
||||
|
||||
/* No power check is required for non 6 Ghz channel */
|
||||
if (!wlan_reg_is_6ghz_chan_freq(freq))
|
||||
return 0;
|
||||
|
||||
num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev,
|
||||
band_mask,
|
||||
chan,
|
||||
REG_CLI_DEF_VLP);
|
||||
|
||||
for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
|
||||
if (chan[chn_idx].center_freq == freq) {
|
||||
tdls_debug("VLP power for channel %d is %d",
|
||||
chan[chn_idx].center_freq,
|
||||
chan[chn_idx].tx_power);
|
||||
return chan[chn_idx].tx_power;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
uint8_t tdls_get_mlme_ch_power(struct vdev_mlme_obj *mlme_obj, qdf_freq_t freq)
|
||||
{
|
||||
@@ -107,7 +74,7 @@ void tdls_set_mlme_ch_power(struct wlan_objmgr_vdev *vdev,
|
||||
struct reg_tpc_power_info *reg_power_info = &mlme_obj->reg_tpc_obj;
|
||||
|
||||
if (REG_VERY_LOW_POWER_AP == reg_power_info->power_type_6g)
|
||||
tx_power = tdls_get_6g_pwr(vdev, freq,
|
||||
tx_power = tdls_get_6g_pwr_for_power_type(vdev, freq,
|
||||
REG_CLI_DEF_VLP);
|
||||
else
|
||||
tx_power = tdls_soc_obj->bss_sta_power;
|
||||
@@ -1987,6 +1954,7 @@ QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req)
|
||||
struct tdls_soc_priv_obj *soc_obj;
|
||||
struct wlan_objmgr_vdev *vdev;
|
||||
QDF_STATUS status;
|
||||
uint8_t reg_bw_offset;
|
||||
|
||||
tdls_debug("Configure external TDLS peer " QDF_MAC_ADDR_FMT,
|
||||
QDF_MAC_ADDR_REF(req->peer_addr));
|
||||
@@ -2011,7 +1979,14 @@ QDF_STATUS tdls_process_setup_peer(struct tdls_oper_request *req)
|
||||
}
|
||||
|
||||
peer_req.chan = soc_obj->tdls_configs.tdls_pre_off_chan_num;
|
||||
if (!peer_req.op_class)
|
||||
peer_req.op_class = tdls_get_opclass_from_bandwidth(
|
||||
soc_obj, peer_req.chan,
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_bw,
|
||||
®_bw_offset);
|
||||
|
||||
tdls_debug("peer chan %d peer opclass %d", peer_req.chan,
|
||||
peer_req.op_class);
|
||||
status = tdls_config_force_peer(&peer_req);
|
||||
error:
|
||||
wlan_objmgr_vdev_release_ref(vdev, WLAN_TDLS_NB_ID);
|
||||
|
@@ -846,6 +846,39 @@ QDF_STATUS tdls_update_fw_tdls_state(struct tdls_soc_priv_obj *tdls_soc_obj,
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11AX
|
||||
uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t freq,
|
||||
enum supported_6g_pwr_types pwr_typ)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
|
||||
struct regulatory_channel chan[NUM_CHANNELS] = {0};
|
||||
uint8_t chn_idx, num_chan;
|
||||
uint8_t band_mask = BIT(REG_BAND_6G);
|
||||
|
||||
if (!pdev)
|
||||
return 0;
|
||||
|
||||
/* No power check is required for non 6 Ghz channel */
|
||||
if (!wlan_reg_is_6ghz_chan_freq(freq))
|
||||
return 0;
|
||||
|
||||
num_chan = wlan_reg_get_band_channel_list_for_pwrmode(pdev,
|
||||
band_mask,
|
||||
chan,
|
||||
REG_CLI_DEF_VLP);
|
||||
|
||||
for (chn_idx = 0; chn_idx < num_chan; chn_idx++) {
|
||||
if (chan[chn_idx].center_freq == freq) {
|
||||
tdls_debug("VLP power for channel %d is %d",
|
||||
chan[chn_idx].center_freq,
|
||||
chan[chn_idx].tx_power);
|
||||
return chan[chn_idx].tx_power;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t freq)
|
||||
{
|
||||
@@ -897,6 +930,13 @@ bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t freq,
|
||||
enum supported_6g_pwr_types pwr_typ)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool tdls_check_is_tdls_allowed(struct wlan_objmgr_vdev *vdev)
|
||||
@@ -1923,7 +1963,11 @@ uint8_t tdls_get_opclass_from_bandwidth(struct tdls_soc_priv_obj *soc_obj,
|
||||
{
|
||||
uint8_t opclass;
|
||||
|
||||
if (bw_offset & (1 << BW_80_OFFSET_BIT)) {
|
||||
if (bw_offset & (1 << BW_160_OFFSET_BIT)) {
|
||||
opclass = tdls_find_opclass(soc_obj->soc,
|
||||
channel, BWALL);
|
||||
*reg_bw_offset = BWALL;
|
||||
} else if (bw_offset & (1 << BW_80_OFFSET_BIT)) {
|
||||
opclass = tdls_find_opclass(soc_obj->soc,
|
||||
channel, BW80);
|
||||
*reg_bw_offset = BW80;
|
||||
|
@@ -318,6 +318,7 @@ struct tdls_peer_mlme_info {
|
||||
* @is_forced_peer: is forced peer
|
||||
* @op_class_for_pref_off_chan: op class for preferred off channel
|
||||
* @pref_off_chan_num: preferred off channel number
|
||||
* @pref_off_chan_width: preferred off channel width
|
||||
* @peer_idle_timer: time to check idle traffic in tdls peers
|
||||
* @is_peer_idle_timer_initialised: Flag to check idle timer init
|
||||
* @spatial_streams: Number of TX/RX spatial streams for TDLS
|
||||
@@ -349,6 +350,7 @@ struct tdls_peer {
|
||||
bool is_forced_peer;
|
||||
uint8_t op_class_for_pref_off_chan;
|
||||
uint8_t pref_off_chan_num;
|
||||
uint8_t pref_off_chan_width;
|
||||
qdf_mc_timer_t peer_idle_timer;
|
||||
bool is_peer_idle_timer_initialised;
|
||||
uint8_t spatial_streams;
|
||||
@@ -664,6 +666,21 @@ void tdls_send_update_to_fw(struct tdls_vdev_priv_obj *tdls_vdev_obj,
|
||||
*/
|
||||
void tdls_notify_increment_session(struct wlan_objmgr_psoc *psoc);
|
||||
|
||||
/**
|
||||
* tdls_get_6g_pwr_for_power_type() - get power for a 6g freq for paticular
|
||||
* power type
|
||||
* @vdev: vdev object
|
||||
* @freq: 6g freq
|
||||
* @pwr_typ: power type
|
||||
*
|
||||
* Function that gets power for a 6g freq for paticular power type
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
uint32_t tdls_get_6g_pwr_for_power_type(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t freq,
|
||||
enum supported_6g_pwr_types pwr_typ);
|
||||
|
||||
/**
|
||||
* tdls_is_6g_freq_allowed() - check is tdls 6ghz allowed or not
|
||||
* @vdev: vdev object
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 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
|
||||
@@ -146,6 +147,33 @@ uint8_t tdls_find_opclass(struct wlan_objmgr_psoc *psoc, uint8_t channel,
|
||||
bw_offset);
|
||||
}
|
||||
|
||||
static void tdls_fill_pref_off_chan_num(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
struct tdls_soc_priv_obj *soc_obj,
|
||||
struct tdls_peer *peer)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev_obj->vdev);
|
||||
|
||||
/*
|
||||
* Fill preffered offchannel number here and prefferd bw here.
|
||||
* Bw and channel number can be used to later calculate Op_class
|
||||
* which will be used to identify the channels
|
||||
*/
|
||||
peer->pref_off_chan_width = soc_obj->tdls_configs.tdls_pre_off_chan_bw;
|
||||
|
||||
if (soc_obj->tdls_configs.tdls_pre_off_chan_freq_6g &&
|
||||
tdls_is_6g_freq_allowed(vdev_obj->vdev,
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_freq_6g)) {
|
||||
peer->pref_off_chan_num =
|
||||
wlan_reg_freq_to_chan(pdev,
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_freq_6g);
|
||||
} else {
|
||||
peer->pref_off_chan_num =
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_num;
|
||||
if (CHECK_BIT(peer->pref_off_chan_width, BW_160_OFFSET_BIT))
|
||||
peer->pref_off_chan_width &= ~(1 << BW_160_OFFSET_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* tdls_add_peer() - add TDLS peer in TDLS vdev object
|
||||
* @vdev_obj: TDLS vdev object
|
||||
@@ -180,8 +208,7 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
qdf_mem_copy(&peer->peer_mac, macaddr, sizeof(peer->peer_mac));
|
||||
peer->vdev_priv = vdev_obj;
|
||||
|
||||
peer->pref_off_chan_num =
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_num;
|
||||
tdls_fill_pref_off_chan_num(vdev_obj, soc_obj, peer);
|
||||
peer->op_class_for_pref_off_chan =
|
||||
tdls_get_opclass_from_bandwidth(
|
||||
soc_obj, peer->pref_off_chan_num,
|
||||
@@ -479,6 +506,7 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param,
|
||||
uint8_t chan_id;
|
||||
uint32_t cur_band;
|
||||
qdf_freq_t ch_freq;
|
||||
uint32_t tx_power = 0;
|
||||
|
||||
vdev_obj = peer->vdev_priv;
|
||||
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
|
||||
@@ -501,10 +529,11 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param,
|
||||
peer_param->peer_cap.peer_off_chan_support =
|
||||
peer->off_channel_capable;
|
||||
peer_param->peer_cap.peer_curr_operclass = 0;
|
||||
peer_param->peer_cap.self_curr_operclass = 0;
|
||||
peer_param->peer_cap.self_curr_operclass =
|
||||
peer->op_class_for_pref_off_chan;
|
||||
peer_param->peer_cap.pref_off_channum = peer->pref_off_chan_num;
|
||||
peer_param->peer_cap.pref_off_chan_bandwidth =
|
||||
soc_obj->tdls_configs.tdls_pre_off_chan_bw;
|
||||
peer->pref_off_chan_width;
|
||||
peer_param->peer_cap.opclass_for_prefoffchan =
|
||||
peer->op_class_for_pref_off_chan;
|
||||
|
||||
@@ -539,8 +568,17 @@ void tdls_extract_peer_state_param(struct tdls_peer_update_state *peer_param,
|
||||
CHANNEL_STATE_DFS != ch_state &&
|
||||
!wlan_reg_is_dsrc_freq(ch_freq)) {
|
||||
peer_param->peer_cap.peer_chan[num].chan_id = chan_id;
|
||||
peer_param->peer_cap.peer_chan[num].pwr =
|
||||
wlan_reg_get_channel_reg_power_for_freq(pdev, ch_freq);
|
||||
if (!wlan_reg_is_6ghz_chan_freq(ch_freq)) {
|
||||
tx_power =
|
||||
wlan_reg_get_channel_reg_power_for_freq(pdev,
|
||||
ch_freq);
|
||||
} else {
|
||||
tx_power =
|
||||
tdls_get_6g_pwr_for_power_type(vdev_obj->vdev,
|
||||
ch_freq,
|
||||
REG_CLI_DEF_VLP);
|
||||
}
|
||||
peer_param->peer_cap.peer_chan[num].pwr = tx_power;
|
||||
peer_param->peer_cap.peer_chan[num].dfs_set = false;
|
||||
peer_param->peer_cap.peer_chanlen++;
|
||||
num++;
|
||||
@@ -860,7 +898,7 @@ QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj,
|
||||
|
||||
if (!curr_peer->is_forced_peer) {
|
||||
config = &soc_obj->tdls_configs;
|
||||
curr_peer->pref_off_chan_num = config->tdls_pre_off_chan_num;
|
||||
tdls_fill_pref_off_chan_num(vdev_obj, soc_obj, curr_peer);
|
||||
curr_peer->op_class_for_pref_off_chan =
|
||||
tdls_get_opclass_from_bandwidth(
|
||||
soc_obj, curr_peer->pref_off_chan_num,
|
||||
|
@@ -461,19 +461,48 @@
|
||||
CFG_VALUE_OR_DEFAULT, \
|
||||
"Preferred TDLS channel number")
|
||||
|
||||
/*
|
||||
* <ini>
|
||||
* tdls_pref_off_chan_num_6g - Preferred TDLS 6g channel freq when off-channel
|
||||
* support is enabled.
|
||||
* @Min: 0
|
||||
* @Max: 7115
|
||||
* @Default: 5975
|
||||
*
|
||||
* This ini is used to configure preferred TDLS 6G channel number when
|
||||
* off-channel support is enabled. If this is set to 0, 6Ghz offchannel is
|
||||
* disabled.
|
||||
*
|
||||
* Related: gEnableTDLSSupport, gEnableTDLSOffChannel.
|
||||
*
|
||||
* Supported Feature: TDLS
|
||||
*
|
||||
* Usage: Internal/External
|
||||
*
|
||||
* </ini>
|
||||
*/
|
||||
#define CFG_TDLS_PREFERRED_OFF_CHANNEL_FREQ_6G CFG_INI_UINT( \
|
||||
"tdls_pref_off_chan_freq_6g", \
|
||||
0, \
|
||||
7115, \
|
||||
5975, \
|
||||
CFG_VALUE_OR_DEFAULT, \
|
||||
"Preferred TDLS channel frequency for 6ghz channels")
|
||||
|
||||
/*
|
||||
* <ini>
|
||||
* gTDLSPrefOffChanBandwidth - Preferred TDLS channel bandwidth when
|
||||
* off-channel support is enabled.
|
||||
* @Min: 0x01
|
||||
* @Max: 0x0F
|
||||
* @Default: 0x07
|
||||
* @Min: 1
|
||||
* @Max: 15
|
||||
* @Default: 15
|
||||
*
|
||||
* This ini is used to configure preferred TDLS channel bandwidth when
|
||||
* off-channel support is enabled.
|
||||
* 0x1: 20 MHz 0x2: 40 MHz 0x4: 80 MHz 0x8: 160 MHz
|
||||
* When more than one bits are set then firmware starts from the highest and
|
||||
* selects one based on capability of peer.
|
||||
* selects one based on capability of peer. So, that means if 0xF is set that
|
||||
* means fw will try intersect with 160 MHz BW and the peer supported BW.
|
||||
*
|
||||
* Related: gEnableTDLSSupport, gEnableTDLSOffChannel.
|
||||
*
|
||||
@@ -487,7 +516,7 @@
|
||||
"gTDLSPrefOffChanBandwidth", \
|
||||
1, \
|
||||
15, \
|
||||
7, \
|
||||
15, \
|
||||
CFG_VALUE_OR_DEFAULT, \
|
||||
"Preferred TDLS channel bandwidth")
|
||||
|
||||
@@ -734,6 +763,7 @@
|
||||
CFG(CFG_TDLS_RSSI_TEARDOWN_THRESHOLD) \
|
||||
CFG(CFG_TDLS_RSSI_DELTA) \
|
||||
CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM) \
|
||||
CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_FREQ_6G) \
|
||||
CFG(CFG_TDLS_PREFERRED_OFF_CHANNEL_BW) \
|
||||
CFG(CFG_TDLS_PUAPSD_PEER_TRAFFIC_IND_WINDOW) \
|
||||
CFG(CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT) \
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2022 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
|
||||
@@ -467,6 +468,7 @@ enum tdls_feature_bit {
|
||||
* @tdls_uapsd_ptr_timeout: tdls peer response timeout
|
||||
* @tdls_feature_flags: tdls feature flags
|
||||
* @tdls_pre_off_chan_num: tdls off channel number
|
||||
* @tdls_pre_off_chan_freq_6g: tdls pref off channel freq for 6g band
|
||||
* @tdls_pre_off_chan_bw: tdls off channel bandwidth
|
||||
* @tdls_peer_kickout_threshold: sta kickout threshold for tdls peer
|
||||
* @tdls_discovery_wake_timeout: tdls discovery wake timeout
|
||||
@@ -499,6 +501,7 @@ struct tdls_user_config {
|
||||
uint32_t tdls_uapsd_ptr_timeout;
|
||||
uint32_t tdls_feature_flags;
|
||||
uint32_t tdls_pre_off_chan_num;
|
||||
uint32_t tdls_pre_off_chan_freq_6g;
|
||||
uint32_t tdls_pre_off_chan_bw;
|
||||
uint32_t tdls_peer_kickout_threshold;
|
||||
uint32_t tdls_discovery_wake_timeout;
|
||||
|
@@ -202,6 +202,8 @@ static QDF_STATUS tdls_object_init_params(
|
||||
cfg_get(psoc, CFG_TDLS_PUAPSD_PEER_TRAFFIC_RSP_TIMEOUT);
|
||||
tdls_soc_obj->tdls_configs.tdls_pre_off_chan_num =
|
||||
cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_NUM);
|
||||
tdls_soc_obj->tdls_configs.tdls_pre_off_chan_freq_6g =
|
||||
cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_FREQ_6G);
|
||||
tdls_soc_obj->tdls_configs.tdls_pre_off_chan_bw =
|
||||
cfg_get(psoc, CFG_TDLS_PREFERRED_OFF_CHANNEL_BW);
|
||||
tdls_soc_obj->tdls_configs.tdls_peer_kickout_threshold =
|
||||
|
@@ -213,10 +213,10 @@ static void populate_dot11f_tdls_offchannel_params(
|
||||
mac->mlme_cfg->reg.valid_channel_freq_list[i]);
|
||||
}
|
||||
|
||||
if (wlan_reg_is_5ghz_ch_freq(pe_session->curr_op_freq))
|
||||
band = BAND_5G;
|
||||
else
|
||||
if (wlan_reg_is_24ghz_ch_freq(pe_session->curr_op_freq))
|
||||
band = BAND_2G;
|
||||
else
|
||||
band = BAND_5G;
|
||||
|
||||
nss_5g = QDF_MIN(mac->vdev_type_nss_5g.tdls,
|
||||
mac->user_configured_nss);
|
||||
|
Reference in New Issue
Block a user