qcacld-3.0: Set VLP mode for STA if TDLS enabled
For STA+TDLS on 6 GHz band, set power mode as VLP if the country supports it. Once there is no connected peer then restore the mode which was there before the TDLS connection. Change-Id: I551ec77545e33cc70d1ce51a0a92cd7d8a56a8db CRs-Fixed: 3223647
This commit is contained in:

committed by
Madan Koyyalamudi

parent
77afc58054
commit
31fa2f653e
@@ -38,12 +38,181 @@
|
||||
#include "wlan_tdls_tgt_api.h"
|
||||
#include "wlan_policy_mgr_api.h"
|
||||
#include "nan_ucfg_api.h"
|
||||
#include "wlan_mlme_main.h"
|
||||
|
||||
static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj)
|
||||
{
|
||||
return soc_obj->connected_peer_count;
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
uint8_t num_power = mlme_obj->reg_tpc_obj.num_pwr_levels;
|
||||
uint8_t idx;
|
||||
struct reg_tpc_power_info *reg_power_info;
|
||||
|
||||
reg_power_info = &mlme_obj->reg_tpc_obj;
|
||||
for (idx = 0; idx < num_power; idx++) {
|
||||
if (freq == reg_power_info->chan_power_info[idx].chan_cfreq)
|
||||
return reg_power_info->chan_power_info[idx].tx_power;
|
||||
}
|
||||
|
||||
tdls_debug("channel %d not present in reg power info", freq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void tdls_set_mlme_ch_power(struct wlan_objmgr_vdev *vdev,
|
||||
struct vdev_mlme_obj *mlme_obj,
|
||||
struct tdls_soc_priv_obj *tdls_soc_obj,
|
||||
qdf_freq_t freq)
|
||||
{
|
||||
uint8_t num_power = mlme_obj->reg_tpc_obj.num_pwr_levels;
|
||||
uint8_t idx, tx_power;
|
||||
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,
|
||||
REG_CLI_DEF_VLP);
|
||||
else
|
||||
tx_power = tdls_soc_obj->bss_sta_power;
|
||||
|
||||
for (idx = 0; idx < num_power; idx++) {
|
||||
if (freq == reg_power_info->chan_power_info[idx].chan_cfreq) {
|
||||
reg_power_info->chan_power_info[idx].tx_power =
|
||||
tx_power;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
tdls_debug("channel %d not present in reg power info", freq);
|
||||
}
|
||||
|
||||
static
|
||||
void tdls_update_6g_power(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_soc_priv_obj *tdls_soc_obj,
|
||||
bool enable_link)
|
||||
{
|
||||
struct wlan_lmac_if_reg_tx_ops *tx_ops;
|
||||
struct vdev_mlme_obj *mlme_obj;
|
||||
struct wlan_objmgr_psoc *psoc = wlan_vdev_get_psoc(vdev);
|
||||
qdf_freq_t freq = wlan_get_operation_chan_freq(vdev);
|
||||
|
||||
if (!psoc) {
|
||||
tdls_err("psoc is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether the frequency is 6ghz and tdls connection on 6ghz freq
|
||||
* is allowed.
|
||||
*/
|
||||
if (!tdls_is_6g_freq_allowed(vdev, freq))
|
||||
return;
|
||||
|
||||
/*
|
||||
* Since, 8 TDLS peers can be connected. If connected peer already
|
||||
* exist then no need to set the power again.
|
||||
* Similarily, for disconnection case, this function is called after
|
||||
* just after connected peer count is decreased. If connected peer
|
||||
* count exist after decrement of peer count that mean another peer
|
||||
* exist and then no need to reset the BSS power.
|
||||
* The power should only be set/reset when 1st peer gets connected or
|
||||
* last connected peer gets disconnected.
|
||||
*/
|
||||
if (tdls_soc_obj->connected_peer_count) {
|
||||
tdls_debug("Number of connected peer %d",
|
||||
tdls_soc_obj->connected_peer_count);
|
||||
return;
|
||||
}
|
||||
|
||||
mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
|
||||
if (!mlme_obj) {
|
||||
tdls_err("vdev component object is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable_link) {
|
||||
tdls_soc_obj->bss_sta_power_type = REG_VERY_LOW_POWER_AP;
|
||||
/*
|
||||
* No need to update power if BSS-STA link is already configured
|
||||
* as VLP
|
||||
*/
|
||||
if (tdls_soc_obj->bss_sta_power_type ==
|
||||
mlme_obj->reg_tpc_obj.power_type_6g)
|
||||
return;
|
||||
|
||||
tdls_soc_obj->bss_sta_power_type =
|
||||
mlme_obj->reg_tpc_obj.power_type_6g;
|
||||
mlme_obj->reg_tpc_obj.power_type_6g = REG_VERY_LOW_POWER_AP;
|
||||
tdls_soc_obj->bss_sta_power = tdls_get_mlme_ch_power(mlme_obj,
|
||||
freq);
|
||||
tdls_debug("Updated power_type from %d to %d bss link power %d",
|
||||
tdls_soc_obj->bss_sta_power_type,
|
||||
mlme_obj->reg_tpc_obj.power_type_6g,
|
||||
tdls_soc_obj->bss_sta_power);
|
||||
} else {
|
||||
if (REG_VERY_LOW_POWER_AP == tdls_soc_obj->bss_sta_power_type)
|
||||
return;
|
||||
|
||||
tdls_debug("Updated power_type_6g from %d to %d",
|
||||
mlme_obj->reg_tpc_obj.power_type_6g,
|
||||
tdls_soc_obj->bss_sta_power_type);
|
||||
mlme_obj->reg_tpc_obj.power_type_6g =
|
||||
tdls_soc_obj->bss_sta_power_type;
|
||||
}
|
||||
tdls_set_mlme_ch_power(vdev, mlme_obj, tdls_soc_obj, freq);
|
||||
|
||||
tx_ops = wlan_reg_get_tx_ops(psoc);
|
||||
if (tx_ops->set_tpc_power)
|
||||
tx_ops->set_tpc_power(psoc,
|
||||
wlan_vdev_get_id(vdev),
|
||||
&mlme_obj->reg_tpc_obj);
|
||||
}
|
||||
#else
|
||||
static
|
||||
void tdls_update_6g_power(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_soc_priv_obj *tdls_soc_obj,
|
||||
bool enable_link)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* tdls_decrement_peer_count() - decrement connected TDLS peer counter
|
||||
* @soc_obj: TDLS soc object
|
||||
@@ -52,12 +221,15 @@ static uint16_t tdls_get_connected_peer(struct tdls_soc_priv_obj *soc_obj)
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj)
|
||||
void tdls_decrement_peer_count(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_soc_priv_obj *soc_obj)
|
||||
{
|
||||
if (soc_obj->connected_peer_count)
|
||||
soc_obj->connected_peer_count--;
|
||||
|
||||
tdls_debug("Connected peer count %d", soc_obj->connected_peer_count);
|
||||
|
||||
tdls_update_6g_power(vdev, soc_obj, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1530,7 +1702,7 @@ QDF_STATUS tdls_process_del_peer_rsp(struct tdls_del_sta_rsp *rsp)
|
||||
id = wlan_vdev_get_id(vdev);
|
||||
|
||||
if (TDLS_IS_LINK_CONNECTED(curr_peer))
|
||||
tdls_decrement_peer_count(soc_obj);
|
||||
tdls_decrement_peer_count(vdev, soc_obj);
|
||||
}
|
||||
tdls_reset_peer(vdev_obj, macaddr);
|
||||
conn_rec[sta_idx].valid_entry = false;
|
||||
@@ -1670,6 +1842,7 @@ QDF_STATUS tdls_process_enable_link(struct tdls_oper_request *req)
|
||||
goto error;
|
||||
}
|
||||
|
||||
tdls_update_6g_power(vdev, soc_obj, true);
|
||||
tdls_increment_peer_count(soc_obj);
|
||||
feature = soc_obj->tdls_configs.tdls_feature_flags;
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2017-2019 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
|
||||
@@ -222,13 +223,15 @@ int tdls_set_responder(struct tdls_set_responder_req *set_req);
|
||||
|
||||
/**
|
||||
* tdls_decrement_peer_count() - decrement connected TDLS peer counter
|
||||
* @vdev: vdev obj mgr
|
||||
* @soc_obj: TDLS soc object
|
||||
*
|
||||
* Used in scheduler thread context, no lock needed.
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
void tdls_decrement_peer_count(struct tdls_soc_priv_obj *soc_obj);
|
||||
void tdls_decrement_peer_count(struct wlan_objmgr_vdev *vdev,
|
||||
struct tdls_soc_priv_obj *soc_obj);
|
||||
|
||||
/**
|
||||
* wlan_tdls_offchan_parms_callback() - Callback to release ref count
|
||||
|
@@ -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
|
||||
@@ -1335,7 +1336,7 @@ void tdls_disable_offchan_and_teardown_links(
|
||||
*/
|
||||
tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes);
|
||||
|
||||
tdls_decrement_peer_count(tdls_soc);
|
||||
tdls_decrement_peer_count(vdev, tdls_soc);
|
||||
tdls_soc->tdls_conn_info[staidx].valid_entry = false;
|
||||
tdls_soc->tdls_conn_info[staidx].session_id = 255;
|
||||
tdls_soc->tdls_conn_info[staidx].index =
|
||||
|
@@ -528,7 +528,7 @@ static QDF_STATUS tdls_process_reset_all_peers(struct wlan_objmgr_vdev *vdev)
|
||||
|
||||
tdls_reset_peer(tdls_vdev, curr_peer->peer_mac.bytes);
|
||||
|
||||
tdls_decrement_peer_count(tdls_soc);
|
||||
tdls_decrement_peer_count(vdev, tdls_soc);
|
||||
tdls_soc->tdls_conn_info[staidx].valid_entry = false;
|
||||
tdls_soc->tdls_conn_info[staidx].session_id = 255;
|
||||
tdls_soc->tdls_conn_info[staidx].index =
|
||||
@@ -845,7 +845,7 @@ QDF_STATUS tdls_update_fw_tdls_state(struct tdls_soc_priv_obj *tdls_soc_obj,
|
||||
}
|
||||
|
||||
#ifdef WLAN_FEATURE_11AX
|
||||
static bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
|
||||
bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t freq)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
|
||||
@@ -855,8 +855,7 @@ static bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
|
||||
uint8_t chn_idx, num_chan = 0;
|
||||
uint8_t band_mask = BIT(REG_BAND_6G);
|
||||
|
||||
/* No power check is required for non 6 Ghz channel */
|
||||
|
||||
/* Return if freq is not 6 Ghz freq */
|
||||
if (!wlan_reg_is_6ghz_chan_freq(freq))
|
||||
goto error;
|
||||
|
||||
@@ -889,7 +888,7 @@ error:
|
||||
return is_allowed;
|
||||
}
|
||||
#else
|
||||
static bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
|
||||
bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t freq)
|
||||
{
|
||||
return false;
|
||||
|
@@ -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
|
||||
@@ -192,6 +193,8 @@ struct tdls_set_state_info {
|
||||
* @tdls_osif_init_cb: Callback to initialize the tdls private
|
||||
* @tdls_osif_deinit_cb: Callback to deinitialize the tdls private
|
||||
* @fw_tdls_11ax_capablity: bool for tdls 11ax fw capability
|
||||
* @bss_sta_power: bss sta power
|
||||
* @@bss_sta_power_type: bss sta power type
|
||||
*/
|
||||
struct tdls_soc_priv_obj {
|
||||
struct wlan_objmgr_psoc *soc;
|
||||
@@ -242,6 +245,8 @@ struct tdls_soc_priv_obj {
|
||||
tdls_vdev_deinit_cb tdls_osif_deinit_cb;
|
||||
#ifdef WLAN_FEATURE_11AX
|
||||
bool fw_tdls_11ax_capability;
|
||||
uint8_t bss_sta_power;
|
||||
uint8_t bss_sta_power_type;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -657,6 +662,17 @@ 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_is_6g_freq_allowed() - check is tdls 6ghz allowed or not
|
||||
* @vdev: vdev object
|
||||
* @freq: 6g freq
|
||||
*
|
||||
* Function determines the whether TDLS on 6ghz is allowed in the system
|
||||
*
|
||||
* Return: true or false
|
||||
*/
|
||||
bool tdls_is_6g_freq_allowed(struct wlan_objmgr_vdev *vdev, qdf_freq_t freq);
|
||||
|
||||
/**
|
||||
* tdls_check_is_tdls_allowed() - check is tdls allowed or not
|
||||
* @vdev: vdev object
|
||||
|
Reference in New Issue
Block a user