qcacld-3.0: Configure TDLS off channel mode when band switches

Disable TDLS off channel if 2g or 5g is disabled, restore TDLS off
channel configure when all bands are enabled.

Change-Id: Iabfdcdbf84e4a6313ad04e381b70e21c871d66c2
CRs-Fixed: 2595303
This commit is contained in:
bings
2019-12-31 18:24:21 +08:00
committed by nshrivas
parent a71b36fc0a
commit 059c4a06c2
10 changed files with 209 additions and 19 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020 The Linux Foundation. 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
@@ -1074,6 +1074,15 @@ int tdls_set_tdls_offchannelmode(struct wlan_objmgr_vdev *vdev,
tdls_debug("oper_class:%d",
chan_switch_params.oper_class);
}
} else if (conn_peer->off_channel_capable &&
conn_peer->pref_off_chan_num) {
chan_switch_params.tdls_off_ch =
conn_peer->pref_off_chan_num;
chan_switch_params.oper_class =
tdls_get_opclass_from_bandwidth(
tdls_soc, conn_peer->pref_off_chan_num,
tdls_soc->tdls_configs.tdls_pre_off_chan_bw,
&chan_switch_params.tdls_off_ch_bw_offset);
} else {
tdls_err("TDLS off-channel parameters are not set yet!!!");
return -EINVAL;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020 The Linux Foundation. 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
@@ -1806,26 +1806,32 @@ void tdls_scan_serialization_comp_info_cb(struct wlan_objmgr_vdev *vdev,
uint8_t tdls_get_opclass_from_bandwidth(struct tdls_soc_priv_obj *soc_obj,
uint8_t channel, uint8_t bw_offset)
uint8_t channel, uint8_t bw_offset,
uint8_t *reg_bw_offset)
{
uint8_t opclass;
if (bw_offset & (1 << BW_80_OFFSET_BIT)) {
opclass = tdls_find_opclass(soc_obj->soc,
channel, BW80);
*reg_bw_offset = BW80;
} else if (bw_offset & (1 << BW_40_OFFSET_BIT)) {
opclass = tdls_find_opclass(soc_obj->soc,
channel, BW40_LOW_PRIMARY);
*reg_bw_offset = BW40_LOW_PRIMARY;
if (!opclass) {
opclass = tdls_find_opclass(soc_obj->soc,
channel, BW40_HIGH_PRIMARY);
*reg_bw_offset = BW40_HIGH_PRIMARY;
}
} else if (bw_offset & (1 << BW_20_OFFSET_BIT)) {
opclass = tdls_find_opclass(soc_obj->soc,
channel, BW20);
*reg_bw_offset = BW20;
} else {
opclass = tdls_find_opclass(soc_obj->soc,
channel, BWALL);
*reg_bw_offset = BWALL;
}
return opclass;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020 The Linux Foundation. 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
@@ -751,11 +751,13 @@ QDF_STATUS tdls_delete_all_peers_indication(struct wlan_objmgr_psoc *psoc,
* @soc_obj: tdls soc object.
* @channel: Channel number.
* @bw_offset: Bandwidth offset.
* @reg_bw_offset: enum offset_t type bandwidth
*
* To return the opclas.
*
* Return: opclass
*/
uint8_t tdls_get_opclass_from_bandwidth(struct tdls_soc_priv_obj *soc_obj,
uint8_t channel, uint8_t bw_offset);
uint8_t channel, uint8_t bw_offset,
uint8_t *reg_bw_offset);
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020 The Linux Foundation. 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
@@ -161,6 +161,7 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj,
struct tdls_soc_priv_obj *soc_obj;
uint8_t key = 0;
qdf_list_t *head;
uint8_t reg_bw_offset;
peer = qdf_mem_malloc(sizeof(*peer));
if (!peer) {
@@ -183,9 +184,10 @@ static struct tdls_peer *tdls_add_peer(struct tdls_vdev_priv_obj *vdev_obj,
peer->pref_off_chan_num =
soc_obj->tdls_configs.tdls_pre_off_chan_num;
peer->op_class_for_pref_off_chan =
tdls_get_opclass_from_bandwidth(soc_obj,
peer->pref_off_chan_num,
soc_obj->tdls_configs.tdls_pre_off_chan_bw);
tdls_get_opclass_from_bandwidth(
soc_obj, peer->pref_off_chan_num,
soc_obj->tdls_configs.tdls_pre_off_chan_bw,
&reg_bw_offset);
peer->valid_entry = false;
@@ -748,6 +750,7 @@ QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj,
struct tdls_soc_priv_obj *soc_obj;
struct tdls_peer *curr_peer;
struct tdls_user_config *config;
uint8_t reg_bw_offset;
soc_obj = wlan_vdev_get_tdls_soc_obj(vdev_obj->vdev);
if (!soc_obj) {
@@ -765,9 +768,10 @@ QDF_STATUS tdls_reset_peer(struct tdls_vdev_priv_obj *vdev_obj,
config = &soc_obj->tdls_configs;
curr_peer->pref_off_chan_num = config->tdls_pre_off_chan_num;
curr_peer->op_class_for_pref_off_chan =
tdls_get_opclass_from_bandwidth(soc_obj,
curr_peer->pref_off_chan_num,
soc_obj->tdls_configs.tdls_pre_off_chan_bw);
tdls_get_opclass_from_bandwidth(
soc_obj, curr_peer->pref_off_chan_num,
soc_obj->tdls_configs.tdls_pre_off_chan_bw,
&reg_bw_offset);
}
tdls_set_peer_link_status(curr_peer, TDLS_LINK_IDLE,

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2020 The Linux Foundation. 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
@@ -137,6 +137,35 @@ QDF_STATUS
cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc,
bool val);
/**
* cfg_tdls_get_off_channel_enable_orig() - get tdls off channel enable orig
* @psoc: pointer to psoc object
* @val: pointer to tdls off channel enable
*
* This function gets tdls off channel enable orig
*/
QDF_STATUS
cfg_tdls_get_off_channel_enable_orig(struct wlan_objmgr_psoc *psoc,
bool *val);
/**
* cfg_tdls_restore_off_channel_enable() - set tdls off channel enable to
* tdls_off_chan_enable_orig
* @psoc: pointer to psoc object
*
* Return: NULL
*/
void cfg_tdls_restore_off_channel_enable(struct wlan_objmgr_psoc *psoc);
/**
* cfg_tdls_store_off_channel_enable() - save tdls off channel enable to
* tdls_off_chan_enable_orig
* @psoc: pointer to psoc object
*
* Return: NULL
*/
void cfg_tdls_store_off_channel_enable(struct wlan_objmgr_psoc *psoc);
/**
* cfg_tdls_get_wmm_mode_enable() - get tdls wmm mode enable
* @psoc: pointer to psoc object

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2017-2019 The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2020 The Linux Foundation. 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
@@ -461,6 +461,7 @@ enum tdls_feature_bit {
* @tdls_vdev_nss_5g: tdls NSS setting for 5G band
* @tdls_buffer_sta_enable: tdls buffer station enable
* @tdls_off_chan_enable: tdls off channel enable
* @tdls_off_chan_enable_orig: original tdls off channel enable
* @tdls_wmm_mode_enable: tdls wmm mode enable
* @tdls_external_control: tdls external control enable
* @tdls_implicit_trigger_enable: tdls implicit trigger enable
@@ -492,6 +493,7 @@ struct tdls_user_config {
uint8_t tdls_vdev_nss_5g;
bool tdls_buffer_sta_enable;
bool tdls_off_chan_enable;
bool tdls_off_chan_enable_orig;
bool tdls_wmm_mode_enable;
bool tdls_external_control;
bool tdls_implicit_trigger_enable;
@@ -929,7 +931,7 @@ struct tdls_peer_update_state {
struct tdls_channel_switch_params {
uint32_t vdev_id;
uint8_t peer_mac_addr[QDF_MAC_ADDR_SIZE];
uint16_t tdls_off_ch_bw_offset;
uint8_t tdls_off_ch_bw_offset;
uint8_t tdls_off_ch;
uint8_t tdls_sw_mode;
uint8_t oper_class;

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2020 The Linux Foundation. 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
@@ -201,6 +201,53 @@ cfg_tdls_set_off_channel_enable(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
cfg_tdls_get_off_channel_enable_orig(struct wlan_objmgr_psoc *psoc,
bool *val)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
*val = false;
tdls_err("tdls soc null");
return QDF_STATUS_E_INVAL;
}
*val = soc_obj->tdls_configs.tdls_off_chan_enable_orig;
return QDF_STATUS_SUCCESS;
}
void cfg_tdls_store_off_channel_enable(struct wlan_objmgr_psoc *psoc)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return;
}
soc_obj->tdls_configs.tdls_off_chan_enable_orig =
soc_obj->tdls_configs.tdls_off_chan_enable;
}
void cfg_tdls_restore_off_channel_enable(struct wlan_objmgr_psoc *psoc)
{
struct tdls_soc_priv_obj *soc_obj;
soc_obj = wlan_psoc_get_tdls_soc_obj(psoc);
if (!soc_obj) {
tdls_err("tdls soc null");
return;
}
soc_obj->tdls_configs.tdls_off_chan_enable =
soc_obj->tdls_configs.tdls_off_chan_enable_orig;
soc_obj->tdls_configs.tdls_off_chan_enable_orig = false;
}
QDF_STATUS
cfg_tdls_get_wmm_mode_enable(struct wlan_objmgr_psoc *psoc,
bool *val)