qcacmn: Add MCL/SAP DCS process after AFC event update

When AFC event come and update 6 GHz SP channels' state and power
attribution, SAP which already started on 5 GHz or 6 GHz channel
can move in or out from SP channel, which has higher tx power limit.

SAP target channel/bandwidth is decided by ACS channel select callback
register to SAP module, which will take channel max tx power limit
into account.

After target channel/bandwidth determined, SAPs move to same target
channel/bandwidth with eCSA process. If violate any concurrency
limitation, AFC DCS process should abort.

Add AFC component id and reference id.

Change-Id: Iba6933a30c0957eabf549fd6c8442bed547e8152
CRs-Fixed: 3204172
This commit is contained in:
Will Huang 2022-05-10 16:34:50 +08:00 committed by Madan Koyyalamudi
parent 051821c54f
commit dc9e47060f
10 changed files with 630 additions and 3 deletions

View File

@ -34,6 +34,9 @@
#include <target_if_reg_lte.h>
#include <wlan_reg_ucfg_api.h>
#include <wlan_utility.h>
#ifdef CONFIG_REG_CLIENT
#include <wlan_dcs_tgt_api.h>
#endif
/**
* get_chan_list_cc_event_id() - Get chan_list_cc event i
@ -849,11 +852,19 @@ static void target_if_register_afc_event_handler(
tgt_if_regulatory_unregister_afc_event_handler;
}
#ifdef CONFIG_REG_CLIENT
static void target_if_register_acs_trigger_for_afc
(struct wlan_lmac_if_reg_tx_ops *reg_ops)
{
reg_ops->trigger_acs_for_afc = tgt_afc_trigger_dcs;
}
#else
static void target_if_register_acs_trigger_for_afc
(struct wlan_lmac_if_reg_tx_ops *reg_ops)
{
reg_ops->trigger_acs_for_afc = NULL;
}
#endif
#else
static void target_if_register_afc_event_handler(
struct wlan_lmac_if_reg_tx_ops *reg_ops)

View File

@ -297,6 +297,7 @@
* @WLAN_COMP_DP: DP component
* @WLAN_UMAC_COMP_COAP: Constrained Application Protocol component
* @WLAN_UMAC_COMP_QMI: QMI component
* @WLAN_UMAC_COMP_AFC: AFC component
* @WLAN_UMAC_COMP_ID_MAX: Maximum components in UMAC
*
* This id is static.
@ -353,6 +354,7 @@ enum wlan_umac_comp_id {
WLAN_COMP_TELEMETRY_AGENT = 47,
WLAN_UMAC_COMP_COAP = 48,
WLAN_UMAC_COMP_QMI = 49,
WLAN_UMAC_COMP_AFC = 50,
WLAN_UMAC_COMP_ID_MAX,
};

View File

@ -291,6 +291,7 @@ typedef void (*wlan_objmgr_peer_status_handler)(
* @WLAN_COAP_ID: Constrained Application Protocol reference id
* @WLAN_SAWF_ID: Service Aware Wifi reference id
* @WLAN_QMI_ID: QMI component id
* @WLAN_AFC_ID: AFC reference id
* @WLAN_REF_ID_MAX: Max id used to generate ref count tracking array
*/
/* New value added to the enum must also be reflected in function
@ -400,6 +401,7 @@ typedef enum {
WLAN_COAP_ID = 99,
WLAN_SAWF_ID = 100,
WLAN_QMI_ID = 101,
WLAN_AFC_ID = 102,
WLAN_REF_ID_MAX,
} wlan_objmgr_ref_dbgid;
@ -513,7 +515,8 @@ static inline const char *string_from_dbgid(wlan_objmgr_ref_dbgid id)
"WLAN_DP_ID",
"WLAN_COAP_ID",
"WLAN_SAWF_ID",
"WLAN_QMI_ID"
"WLAN_QMI_ID",
"WLAN_AFC_ID"
};
if (id >= WLAN_REF_ID_MAX)

View File

@ -31,6 +31,7 @@
#ifdef WLAN_POLICY_MGR_ENABLE
#include "wlan_policy_mgr_api.h"
#endif
#include <wlan_reg_services_api.h>
struct dcs_pdev_priv_obj *
wlan_dcs_get_pdev_private_obj(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
@ -1371,6 +1372,485 @@ wlan_dcs_awgn_process(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
wlan_objmgr_pdev_release_ref(pdev, WLAN_DCS_ID);
}
#ifdef CONFIG_AFC_SUPPORT
/**
* wlan_dcs_afc_sel_chan() - Select SAP new channel/bandwidth when AFC updated
* @psoc: pointer to soc
* @vdev_id: vdev id
* @cur_freq: current channel frequency
* @cur_bw: current channel bandwidth
* @pref_bw: pointer to bandwidth of prefer to switch to when input, and target
* bandwidth decided to switch to
*
* Return: target channel frequency to switch to
*/
static qdf_freq_t wlan_dcs_afc_sel_chan(struct wlan_objmgr_psoc *psoc,
uint32_t vdev_id,
qdf_freq_t cur_freq,
enum phy_ch_width cur_bw,
enum phy_ch_width *pref_bw)
{
struct dcs_psoc_priv_obj *dcs_psoc_priv;
dcs_afc_select_chan_cb afc_sel_chan_cb;
if (!psoc)
return 0;
dcs_psoc_priv = wlan_objmgr_psoc_get_comp_private_obj(
psoc,
WLAN_UMAC_COMP_DCS);
if (!dcs_psoc_priv)
return 0;
afc_sel_chan_cb = dcs_psoc_priv->afc_sel_chan_cbk.cbk;
if (!afc_sel_chan_cb)
return 0;
return afc_sel_chan_cb(dcs_psoc_priv->afc_sel_chan_cbk.arg,
vdev_id, cur_freq, cur_bw, pref_bw);
}
/**
* wlan_dcs_afc_get_conn_info() - Iterate function to get connection channel
* information of every vdev
* @pdev: pointer to pdev
* @object: pointer to iteration object
* @arg: pointer to iteration argument
*
* Return: void
*/
static void
wlan_dcs_afc_get_conn_info(struct wlan_objmgr_pdev *pdev,
void *object, void *arg)
{
struct wlan_objmgr_vdev *vdev = object;
struct wlan_dcs_conn_info *conn_info = arg;
enum QDF_OPMODE op_mode;
struct wlan_channel *chan;
uint8_t vdev_id;
if (!vdev || !pdev || !conn_info)
return;
if (conn_info->exit_condition)
return;
if (wlan_vdev_mlme_is_active(vdev) != QDF_STATUS_SUCCESS)
return;
vdev_id = wlan_vdev_get_id(vdev);
op_mode = wlan_vdev_mlme_get_opmode(vdev);
chan = wlan_vdev_get_active_channel(vdev);
if (!chan)
return;
switch (op_mode) {
case QDF_STA_MODE:
if (conn_info->sta_cnt >= WLAN_DCS_MAX_STA_NUM) {
dcs_debug("too many STAs");
conn_info->exit_condition = true;
break;
}
conn_info->sta[conn_info->sta_cnt].freq = chan->ch_freq;
conn_info->sta[conn_info->sta_cnt].bw = chan->ch_width;
conn_info->sta[conn_info->sta_cnt].vdev_id = vdev_id;
conn_info->sta_cnt++;
break;
case QDF_SAP_MODE:
if (WLAN_REG_IS_5GHZ_CH_FREQ(chan->ch_freq)) {
if (conn_info->sap_5ghz_cnt >= WLAN_DCS_MAX_SAP_NUM) {
dcs_debug("too many 5 GHz SAPs");
conn_info->exit_condition = true;
}
conn_info->sap_5ghz[conn_info->sap_5ghz_cnt].freq =
chan->ch_freq;
conn_info->sap_5ghz[conn_info->sap_5ghz_cnt].bw =
chan->ch_width;
conn_info->sap_5ghz[conn_info->sap_5ghz_cnt].vdev_id =
vdev_id;
conn_info->sap_5ghz_cnt++;
} else if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan->ch_freq)) {
if (conn_info->sap_6ghz_cnt >= WLAN_DCS_MAX_SAP_NUM) {
dcs_debug("too many 6 GHz SAPs");
conn_info->exit_condition = true;
}
conn_info->sap_6ghz[conn_info->sap_6ghz_cnt].freq =
chan->ch_freq;
conn_info->sap_6ghz[conn_info->sap_6ghz_cnt].bw =
chan->ch_width;
conn_info->sap_6ghz[conn_info->sap_6ghz_cnt].vdev_id =
vdev_id;
conn_info->sap_6ghz_cnt++;
}
break;
default:
dcs_debug("not support op mode %d", op_mode);
conn_info->exit_condition = true;
break;
}
}
/**
* wlan_dcs_afc_reduce_bw() - Get target bandwidth with fixed channel frequency
* @pdev: pointer to pdev
* @freq: channel frequency which is fixed because SCC with STA
* @input_bw: SAP current channel bandwidth
*
* This function check every sub 20 MHz channel state which update by AFC, and
* reduce channel bandwidth if sub channel is disable.
*
* Return: Reduced channel bandwidth
*/
static enum phy_ch_width wlan_dcs_afc_reduce_bw(struct wlan_objmgr_pdev *pdev,
qdf_freq_t freq,
enum phy_ch_width input_bw)
{
const struct bonded_channel_freq *bonded_chan_ptr = NULL;
enum channel_state state;
qdf_freq_t start_freq;
bool find;
if (input_bw <= CH_WIDTH_20MHZ)
return input_bw;
while (input_bw > CH_WIDTH_20MHZ) {
state = wlan_reg_get_5g_bonded_channel_and_state_for_freq(
pdev, freq, input_bw, &bonded_chan_ptr);
if (state != CHANNEL_STATE_ENABLE) {
input_bw = wlan_reg_get_next_lower_bandwidth(input_bw);
continue;
}
find = false;
start_freq = bonded_chan_ptr->start_freq;
while (start_freq <= bonded_chan_ptr->end_freq) {
if (wlan_reg_is_disable_in_secondary_list_for_freq(
pdev, start_freq)) {
find = true;
break;
}
start_freq += 20;
}
if (find)
input_bw = wlan_reg_get_next_lower_bandwidth(input_bw);
else
return input_bw;
}
return input_bw;
}
/**
* wlan_sap_update_tpc_on_channel() - Update vdev channel TPC parameters and
* send TPC command
* @pdev: pointer to pdev
* @vdev_id: vdev id
* @freq: SAP 6 GHz channel frequency
* @bw: SAP 6 GHz channel bandwidth
*
* Return: void
*/
static void
wlan_sap_update_tpc_on_channel(struct wlan_objmgr_pdev *pdev, uint8_t vdev_id,
qdf_freq_t freq, enum phy_ch_width bw)
{
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
struct wlan_lmac_if_reg_tx_ops *tx_ops;
struct vdev_mlme_obj *mlme_obj;
struct wlan_objmgr_vdev *vdev;
struct reg_tpc_power_info *tpc;
bool is_psd;
uint32_t i;
uint16_t tx_power;
int16_t psd_eirp;
enum reg_6g_ap_type power_type;
if (!wlan_reg_is_ext_tpc_supported(psoc))
return;
if (wlan_reg_decide_6ghz_power_within_bw_for_freq(
pdev, freq, bw, &is_psd, &tx_power, &psd_eirp, &power_type) !=
QDF_STATUS_SUCCESS)
return;
vdev = wlan_objmgr_get_vdev_by_id_from_psoc(psoc, vdev_id, WLAN_DCS_ID);
if (!vdev)
return;
tx_ops = wlan_reg_get_tx_ops(psoc);
mlme_obj = wlan_vdev_mlme_get_cmpt_obj(vdev);
if (!mlme_obj) {
dcs_err("vdev mlme obj is NULL");
goto release_vdev;
}
tpc = &mlme_obj->reg_tpc_obj;
if (tpc->is_psd_power != is_psd) {
dcs_debug("psd flag changed");
goto release_vdev;
}
tpc->eirp_power = tx_power;
tpc->power_type_6g = power_type;
for (i = 0; i < tpc->num_pwr_levels; i++) {
if (is_psd)
tpc->chan_power_info[i].tx_power = (uint8_t)psd_eirp;
else
tpc->chan_power_info[i].tx_power = (uint8_t)tx_power;
}
dcs_debug("6 GHz pwr type %d, is psd %d, pwr %d, psd %d, num pwr %d",
power_type, is_psd, tx_power, psd_eirp, tpc->num_pwr_levels);
if (tx_ops->set_tpc_power)
tx_ops->set_tpc_power(psoc, vdev_id, tpc);
release_vdev:
wlan_objmgr_vdev_release_ref(vdev, WLAN_DCS_ID);
}
/**
* wlan_dcs_afc_sap_dcs_with_sta() - SAP channel switch when coexist with STA
* @pdev: pointer to pdev handle
* @conn_info: pointer to connection context of AFC DCS
*
* This function update TPC or restart SAP if doing SCC on 6 GHz with STA
*
* Return: void
*/
static void
wlan_dcs_afc_sap_dcs_with_sta(struct wlan_objmgr_pdev *pdev,
struct wlan_dcs_conn_info *conn_info)
{
uint32_t i;
qdf_freq_t target_freq = conn_info->sta[0].freq;
enum phy_ch_width target_bw = CH_WIDTH_20MHZ;
struct wlan_objmgr_vdev *vdev;
if (!WLAN_REG_IS_6GHZ_CHAN_FREQ(conn_info->sta[0].freq))
return;
for (i = 0; i < conn_info->sap_6ghz_cnt; i++) {
if (conn_info->sap_6ghz[i].freq ==
conn_info->sta[0].freq) {
/*
* sta operate under control of ap, if stop sap,
* cannot start by itself, so just update tpc as sta,
* if tx power is minimum of SCC tpc commands, no
* need to update sap tpc command.
* assume sta will move to safe channel by ap and
* sap can move channel accordingly.
*/
if (wlan_reg_is_disable_in_secondary_list_for_freq(
pdev, conn_info->sta[0].freq))
continue;
target_bw = wlan_dcs_afc_reduce_bw(
pdev,
conn_info->sap_6ghz[i].freq,
conn_info->sap_6ghz[i].bw);
if (target_bw == conn_info->sap_6ghz[i].bw) {
wlan_sap_update_tpc_on_channel(
pdev,
conn_info->sap_6ghz[i].vdev_id,
conn_info->sap_6ghz[i].freq,
target_bw);
continue;
}
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(
pdev,
conn_info->sap_6ghz[i].vdev_id,
WLAN_DCS_ID);
if (!vdev)
continue;
/* tpc update once csa complete */
wlan_dcs_switch_chan(vdev, target_freq, target_bw);
wlan_objmgr_vdev_release_ref(vdev, WLAN_DCS_ID);
}
}
}
#ifdef WLAN_POLICY_MGR_ENABLE
/**
* wlan_dcs_afc_6ghz_capable() - API to check SAP configure is able to operate
* on 6 GHz
* @psoc: pointer to SOC
* @vdev_id: vdev id
*
* Return: Return true if SAP is able to operate on 6 GHz
*/
static inline bool
wlan_dcs_afc_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
{
return policy_mgr_get_ap_6ghz_capable(psoc, vdev_id, NULL);
}
#else
static inline bool
wlan_dcs_afc_6ghz_capable(struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
{
return false;
}
#endif
/**
* wlan_dcs_afc_5ghz6ghz_sap_dcs() - SAP on 5 GHz or 6 GHz channel to do
* channel switch.
* @pdev: pointer to pdev handle
* @conn_info: pointer to connection context for AFC DCS
*
* This function is trigger by AFC event and 6 GHz channels' state has been
* updated, restart SAP to SP channel if possible, gain better performance.
*
* Return: void
*/
static void
wlan_dcs_afc_5ghz6ghz_sap_dcs(struct wlan_objmgr_pdev *pdev,
struct wlan_dcs_conn_info *conn_info)
{
uint32_t i;
struct wlan_objmgr_vdev *vdev;
uint8_t max_bw_vdev_id;
qdf_freq_t max_bw_freq, target_freq;
enum phy_ch_width max_bw = CH_WIDTH_20MHZ;
enum phy_ch_width pref_bw;
if (conn_info->sap_5ghz_cnt) {
max_bw = conn_info->sap_5ghz[0].bw;
max_bw_vdev_id = conn_info->sap_5ghz[0].vdev_id;
max_bw_freq = conn_info->sap_5ghz[0].freq;
for (i = 1; i < conn_info->sap_5ghz_cnt; i++) {
if (conn_info->sap_5ghz[i].bw > max_bw) {
max_bw = conn_info->sap_5ghz[i].bw;
max_bw_vdev_id = conn_info->sap_5ghz[i].vdev_id;
max_bw_freq = conn_info->sap_5ghz[i].freq;
}
}
} else if (conn_info->sap_6ghz_cnt) {
max_bw = conn_info->sap_6ghz[0].bw;
max_bw_vdev_id = conn_info->sap_6ghz[0].vdev_id;
max_bw_freq = conn_info->sap_6ghz[0].freq;
for (i = 1; i < conn_info->sap_6ghz_cnt; i++) {
if (conn_info->sap_6ghz[i].bw > max_bw) {
max_bw = conn_info->sap_6ghz[i].bw;
max_bw_vdev_id = conn_info->sap_6ghz[i].vdev_id;
max_bw_freq = conn_info->sap_6ghz[i].freq;
}
}
} else {
return;
}
/*
* After several AFC event update, if maximum bandwidth shrink to
* 20 MHz, set prefer bandwidth to pre-defined value like 80 MHz,
* so it can expand bandwidth and gain better performance.
*/
if (max_bw == CH_WIDTH_20MHZ)
pref_bw = WLAN_DCS_AFC_PREFER_BW;
else
pref_bw = max_bw;
target_freq = wlan_dcs_afc_sel_chan(
wlan_pdev_get_psoc(pdev),
max_bw_vdev_id,
max_bw_freq, max_bw, &pref_bw);
if (!target_freq)
return;
if (WLAN_REG_IS_6GHZ_CHAN_FREQ(target_freq) &&
conn_info->sap_5ghz_cnt) {
for (i = 0; i < conn_info->sap_5ghz_cnt; i++) {
if (!wlan_dcs_afc_6ghz_capable(
wlan_pdev_get_psoc(pdev),
conn_info->sap_5ghz[i].vdev_id)) {
dcs_debug("vdev %d has no 6 GHz capability",
conn_info->sap_5ghz[i].vdev_id);
return;
}
}
}
if (conn_info->sap_5ghz_cnt) {
for (i = 0; i < conn_info->sap_5ghz_cnt; i++) {
if (target_freq == conn_info->sap_5ghz[i].freq &&
pref_bw == conn_info->sap_5ghz[i].bw)
continue;
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(
pdev,
conn_info->sap_5ghz[i].vdev_id,
WLAN_DCS_ID);
if (!vdev)
continue;
wlan_dcs_switch_chan(vdev, target_freq, pref_bw);
wlan_objmgr_vdev_release_ref(vdev, WLAN_DCS_ID);
}
} else if (conn_info->sap_6ghz_cnt) {
for (i = 0; i < conn_info->sap_6ghz_cnt; i++) {
if (target_freq == conn_info->sap_6ghz[i].freq &&
pref_bw == conn_info->sap_6ghz[i].bw)
continue;
vdev = wlan_objmgr_get_vdev_by_id_from_pdev(
pdev,
conn_info->sap_6ghz[i].vdev_id,
WLAN_DCS_ID);
if (!vdev)
continue;
wlan_dcs_switch_chan(vdev, target_freq, pref_bw);
wlan_objmgr_vdev_release_ref(vdev, WLAN_DCS_ID);
}
}
}
/**
* wlan_dcs_afc_process() - Dynamic SAP channel switch after AFC update
* @psoc: psoc handle
* @pdev_id: pdev id
*
* Return: void
*/
static void
wlan_dcs_afc_process(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
{
struct wlan_objmgr_pdev *pdev;
struct wlan_dcs_conn_info conn_info = {0};
pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_DCS_ID);
if (!pdev) {
dcs_err("Invalid pdev id %d", pdev_id);
return;
}
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
wlan_dcs_afc_get_conn_info,
&conn_info, 0, WLAN_DCS_ID);
if (conn_info.exit_condition)
goto pdev_release;
if ((conn_info.sap_5ghz_cnt && conn_info.sap_6ghz_cnt) ||
(!conn_info.sap_5ghz_cnt && !conn_info.sap_6ghz_cnt)) {
dcs_debug("NA for %d 5 GHz SAP, %d 6 GHz SAP",
conn_info.sap_5ghz_cnt, conn_info.sap_6ghz_cnt);
goto pdev_release;
}
if (conn_info.sta_cnt &&
!WLAN_REG_IS_24GHZ_CH_FREQ(conn_info.sta[0].freq))
wlan_dcs_afc_sap_dcs_with_sta(pdev, &conn_info);
else
wlan_dcs_afc_5ghz6ghz_sap_dcs(pdev, &conn_info);
pdev_release:
wlan_objmgr_pdev_release_ref(pdev, WLAN_DCS_ID);
}
#else
static inline void
wlan_dcs_afc_process(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id) {}
#endif
QDF_STATUS
wlan_dcs_process(struct wlan_objmgr_psoc *psoc,
struct wlan_host_dcs_event *event)
@ -1427,6 +1907,9 @@ wlan_dcs_process(struct wlan_objmgr_psoc *psoc,
wlan_dcs_awgn_process(psoc, event->dcs_param.pdev_id,
&event->awgn_info);
break;
case WLAN_HOST_DCS_AFC:
wlan_dcs_afc_process(psoc, event->dcs_param.pdev_id);
break;
default:
dcs_err("unidentified interference type reported");
break;

View File

@ -144,6 +144,52 @@ struct psoc_dcs_cbk {
void *arg;
};
#define WLAN_DCS_MAX_STA_NUM 1
#define WLAN_DCS_MAX_SAP_NUM 2
#define WLAN_DCS_AFC_PREFER_BW CH_WIDTH_80MHZ
/**
* struct connection_chan_info - define connection channel information
* @freq: channel frequency
* @bw: channel bandwidth
* @vdev_id: connection vdev id
*/
struct connection_chan_info {
qdf_freq_t freq;
enum phy_ch_width bw;
uint8_t vdev_id;
};
/**
* struct wlan_dcs_conn_info - define arguments list for DCS when AFC updated
* @sta_cnt: station count
* @sap_5ghz_cnt: 5 GHz sap count
* @sap_6ghz_cnt: 6 GHz sap count
* @sta: connection info of station
* @sap_5ghz: connection info of 5 GHz sap
* @sap_6ghz: connection info of 6 GHz sap
* @exit_condition: flag to exit iteration immediately
*/
struct wlan_dcs_conn_info {
uint8_t sta_cnt;
uint8_t sap_5ghz_cnt;
uint8_t sap_6ghz_cnt;
struct connection_chan_info sta[WLAN_DCS_MAX_STA_NUM];
struct connection_chan_info sap_5ghz[WLAN_DCS_MAX_SAP_NUM];
struct connection_chan_info sap_6ghz[WLAN_DCS_MAX_SAP_NUM];
bool exit_condition;
};
/**
* struct dcs_afc_select_chan_cbk - define sap afc select channel callback
* @cbk: callback
* @arg: argument supply by register
*/
struct dcs_afc_select_chan_cbk {
dcs_afc_select_chan_cb cbk;
void *arg;
};
/**
* struct dcs_pdev_priv_obj - define dcs pdev priv
* @dcs_host_params: dcs host configuration parameter
@ -218,11 +264,13 @@ enum wlan_dcs_chan_seg {
* @dcs_pdev_priv: dcs pdev priv
* @dcs_cbk: dcs callback
* @switch_chan_cb: callback for switching channel
* @afc_sel_chan_cbk: callback for afc channel selection
*/
struct dcs_psoc_priv_obj {
struct dcs_pdev_priv_obj dcs_pdev_priv[WLAN_DCS_MAX_PDEVS];
struct psoc_dcs_cbk dcs_cbk;
dcs_switch_chan_cb switch_chan_cb;
struct dcs_afc_select_chan_cbk afc_sel_chan_cbk;
};
/**

View File

@ -28,12 +28,14 @@
* @WLAN_HOST_DCS_CWIM: continuous wave interference
* @WLAN_HOST_DCS_WLANIM: wlan interference stats
* @WLAN_HOST_DCS_AWGNIM: additive white Gaussian noise (awgn) interference
* @WLAN_HOST_DCS_AFC: AFC data update 6 GHz SP channels
*/
enum wlan_host_dcs_type {
WLAN_HOST_DCS_NONE = 0, /* 0x0 */
WLAN_HOST_DCS_CWIM = BIT(0), /* 0x1 */
WLAN_HOST_DCS_WLANIM = BIT(1), /* 0x2 */
WLAN_HOST_DCS_AWGNIM = BIT(2), /* 0x4 */
WLAN_HOST_DCS_AFC = BIT(3), /* 0x8 */
};
/**

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020-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 above
@ -36,5 +37,13 @@
*/
QDF_STATUS tgt_dcs_process_event(struct wlan_objmgr_psoc *psoc,
struct wlan_host_dcs_event *event);
#ifdef CONFIG_AFC_SUPPORT
/**
* tgt_afc_trigger_dcs() - AFC event DCS process
* @pdev: pointer to pdev object
*
* Return: QDF_STATUS
*/
QDF_STATUS tgt_afc_trigger_dcs(struct wlan_objmgr_pdev *pdev);
#endif
#endif /* __WLAN_DCS_TGT_API_H__ */

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2021-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 above
@ -49,6 +49,21 @@ typedef QDF_STATUS (*dcs_switch_chan_cb)(struct wlan_objmgr_vdev *vdev,
qdf_freq_t tgt_freq,
enum phy_ch_width tgt_width);
/**
* typedef dcs_afc_select_chan_cb() - DCS callback for AFC channel selection
* @arg: pointer to argument
* @vdev_id: vdev id
* @cur_freq: current channel frequency
* @cur_bw: current channel bandwidth
* @pref_bw: pointer to bandwidth of prefer bandwidth when input, and target
* bandwidth switch to when output
*/
typedef qdf_freq_t (*dcs_afc_select_chan_cb)(void *arg,
uint32_t vdev_id,
qdf_freq_t cur_freq,
enum phy_ch_width cur_bw,
enum phy_ch_width *pref_bw);
#ifdef DCS_INTERFERENCE_DETECTION
/**
* ucfg_dcs_register_cb() - API to register dcs callback
@ -90,6 +105,18 @@ void ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
QDF_STATUS ucfg_dcs_register_awgn_cb(struct wlan_objmgr_psoc *psoc,
dcs_switch_chan_cb cb);
/**
* ucfg_dcs_register_afc_sel_chan_cb() - API to register SAP channel selection
* callback for AFC DCS
* @psoc: pointer to psoc object
* @cb: dcs user callback to be registered
* @arg: argument
*
* Return: QDF_STATUS
*/
QDF_STATUS ucfg_dcs_register_afc_sel_chan_cb(struct wlan_objmgr_psoc *psoc,
dcs_afc_select_chan_cb cb,
void *arg);
/**
* ucfg_wlan_dcs_cmd(): API to send dcs command
* @psoc: pointer to psoc object

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020-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 above
@ -28,3 +29,25 @@ QDF_STATUS tgt_dcs_process_event(struct wlan_objmgr_psoc *psoc,
{
return wlan_dcs_process(psoc, event);
}
#ifdef CONFIG_AFC_SUPPORT
QDF_STATUS tgt_afc_trigger_dcs(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc;
struct wlan_host_dcs_event *event;
QDF_STATUS status;
psoc = wlan_pdev_get_psoc(pdev);
event = qdf_mem_malloc(sizeof(*event));
if (!event)
return QDF_STATUS_E_NOMEM;
event->dcs_param.interference_type = WLAN_HOST_DCS_AFC;
event->dcs_param.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
status = wlan_dcs_process(psoc, event);
qdf_mem_free(event);
return status;
}
#endif

View File

@ -1,5 +1,6 @@
/*
* Copyright (c) 2020-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 above
@ -77,6 +78,24 @@ QDF_STATUS ucfg_dcs_register_awgn_cb(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS ucfg_dcs_register_afc_sel_chan_cb(struct wlan_objmgr_psoc *psoc,
dcs_afc_select_chan_cb cb,
void *arg)
{
struct dcs_psoc_priv_obj *dcs_psoc_priv;
dcs_psoc_priv =
wlan_objmgr_psoc_get_comp_private_obj(psoc, WLAN_UMAC_COMP_DCS);
if (!dcs_psoc_priv) {
dcs_err("dcs psoc private object is null");
return QDF_STATUS_E_INVAL;
}
dcs_psoc_priv->afc_sel_chan_cbk.cbk = cb;
dcs_psoc_priv->afc_sel_chan_cbk.arg = arg;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS
ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc *psoc,
uint32_t mac_id,