qcacmn: Enhance DCS event handler to support AWGN event
Handle DCS-AWGN event and take actions accordingly: For STA mode, if the interference locates on primary 20MHz, disconnect from AP; otherwise, find a max interference free width and trigger channel change. For SAP mode, if the interference locates on primary 20MHz, try to select a random interference free channel and trigger channel change (stop SAP if no channel is selected); otherwise, find a max interference free width and trigger channel change. Change-Id: I33e79f454b459b12ad84f8b0f3259403037464ee CRs-Fixed: 2958675
This commit is contained in:
parent
61d75799c8
commit
98a3fceeb3
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, 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 above
|
||||
@ -41,7 +41,7 @@ static int target_if_dcs_interference_event_handler(ol_scn_t scn,
|
||||
uint32_t datalen)
|
||||
{
|
||||
QDF_STATUS status;
|
||||
struct dcs_stats_event ev;
|
||||
struct wlan_host_dcs_event ev;
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wmi_unified *wmi_handle;
|
||||
struct wlan_target_if_dcs_rx_ops *rx_ops;
|
||||
@ -70,17 +70,25 @@ static int target_if_dcs_interference_event_handler(ol_scn_t scn,
|
||||
|
||||
if (wmi_extract_dcs_interference_type(wmi_handle, data,
|
||||
&ev.dcs_param) !=
|
||||
QDF_STATUS_SUCCESS) {
|
||||
QDF_STATUS_SUCCESS) {
|
||||
target_if_err("Unable to extract dcs interference type");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (wmi_extract_dcs_im_tgt_stats(wmi_handle, data, &ev.wlan_stat) !=
|
||||
QDF_STATUS_SUCCESS) {
|
||||
if (ev.dcs_param.interference_type == WLAN_HOST_DCS_WLANIM &&
|
||||
wmi_extract_dcs_im_tgt_stats(wmi_handle, data, &ev.wlan_stat) !=
|
||||
QDF_STATUS_SUCCESS) {
|
||||
target_if_err("Unable to extract WLAN IM stats");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ev.dcs_param.interference_type == WLAN_HOST_DCS_AWGNIM &&
|
||||
wmi_extract_dcs_awgn_info(wmi_handle, data, &ev.awgn_info) !=
|
||||
QDF_STATUS_SUCCESS) {
|
||||
target_if_err("Unable to extract AWGN info");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
status = rx_ops->process_dcs_event(psoc, &ev);
|
||||
|
||||
return qdf_status_to_os_return(status);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, 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 above
|
||||
@ -25,6 +25,11 @@
|
||||
|
||||
#include <target_if_dcs.h>
|
||||
#include "wlan_dcs.h"
|
||||
#include <wlan_objmgr_psoc_obj_i.h>
|
||||
#include "wlan_utility.h"
|
||||
#ifdef WLAN_POLICY_MGR_ENABLE
|
||||
#include "wlan_policy_mgr_api.h"
|
||||
#endif
|
||||
|
||||
struct dcs_pdev_priv_obj *
|
||||
wlan_dcs_get_pdev_private_obj(struct wlan_objmgr_psoc *psoc, uint32_t pdev_id)
|
||||
@ -593,7 +598,7 @@ void wlan_dcs_disable_timer_fn(void *dcs_timer_args)
|
||||
*/
|
||||
static void wlan_dcs_frequency_control(struct wlan_objmgr_psoc *psoc,
|
||||
struct dcs_pdev_priv_obj *dcs_pdev_priv,
|
||||
struct dcs_stats_event *event)
|
||||
struct wlan_host_dcs_event *event)
|
||||
{
|
||||
struct dcs_psoc_priv_obj *dcs_psoc_priv;
|
||||
struct pdev_dcs_freq_ctrl_params *dcs_freq_ctrl_params;
|
||||
@ -667,8 +672,659 @@ static void wlan_dcs_frequency_control(struct wlan_objmgr_psoc *psoc,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_switch_chan() - switch channel for vdev
|
||||
* @vdev: vdev ptr
|
||||
* @tgt_freq: target frequency
|
||||
* @tgt_width: target channel width
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS
|
||||
wlan_dcs_switch_chan(struct wlan_objmgr_vdev *vdev, qdf_freq_t tgt_freq,
|
||||
enum phy_ch_width tgt_width)
|
||||
{
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct dcs_psoc_priv_obj *dcs_psoc_priv;
|
||||
dcs_switch_chan_cb switch_chan_cb;
|
||||
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
if (!psoc)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
dcs_psoc_priv = wlan_objmgr_psoc_get_comp_private_obj(psoc,
|
||||
WLAN_UMAC_COMP_DCS);
|
||||
if (!dcs_psoc_priv)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
switch_chan_cb = dcs_psoc_priv->switch_chan_cb;
|
||||
if (!switch_chan_cb)
|
||||
return QDF_STATUS_E_NOSUPPORT;
|
||||
|
||||
return switch_chan_cb(vdev, tgt_freq, tgt_width);
|
||||
}
|
||||
|
||||
#ifdef WLAN_POLICY_MGR_ENABLE
|
||||
/**
|
||||
* wlan_dcs_get_pcl_for_sap() - get preferred channel list for SAP
|
||||
* @vdev: vdev ptr
|
||||
* @freq_list: Pointer to PCL
|
||||
* @freq_list_sz: Max size of PCL
|
||||
*
|
||||
* Return: number of channels in PCL
|
||||
*/
|
||||
static uint32_t wlan_dcs_get_pcl_for_sap(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t *freq_list,
|
||||
uint32_t freq_list_sz)
|
||||
{
|
||||
struct wlan_objmgr_psoc *psoc;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
struct policy_mgr_pcl_list *pcl;
|
||||
qdf_freq_t freq;
|
||||
enum channel_state state;
|
||||
QDF_STATUS status;
|
||||
int i, j;
|
||||
|
||||
psoc = wlan_vdev_get_psoc(vdev);
|
||||
if (!psoc)
|
||||
return 0;
|
||||
|
||||
pdev = wlan_vdev_get_pdev(vdev);
|
||||
if (!pdev)
|
||||
return 0;
|
||||
|
||||
pcl = qdf_mem_malloc(sizeof(*pcl));
|
||||
if (!pcl)
|
||||
return 0;
|
||||
|
||||
status = policy_mgr_get_pcl_for_vdev_id(psoc,
|
||||
PM_SAP_MODE,
|
||||
pcl->pcl_list, &pcl->pcl_len,
|
||||
pcl->weight_list,
|
||||
QDF_ARRAY_SIZE(pcl->weight_list),
|
||||
wlan_vdev_get_id(vdev));
|
||||
if (QDF_IS_STATUS_ERROR(status) || !pcl->pcl_len) {
|
||||
qdf_mem_free(pcl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < pcl->pcl_len && i < freq_list_sz; i++) {
|
||||
freq = (qdf_freq_t)pcl->pcl_list[i];
|
||||
state = wlan_reg_get_channel_state_for_freq(pdev, freq);
|
||||
if (state != CHANNEL_STATE_ENABLE)
|
||||
continue;
|
||||
|
||||
freq_list[j++] = freq;
|
||||
}
|
||||
|
||||
qdf_mem_free(pcl);
|
||||
return j;
|
||||
}
|
||||
#else
|
||||
static uint32_t wlan_dcs_get_pcl_for_sap(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t *freq_list,
|
||||
uint32_t freq_list_sz)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
struct regulatory_channel *cur_chan_list;
|
||||
qdf_freq_t freq;
|
||||
enum channel_state state;
|
||||
int i, j;
|
||||
|
||||
pdev = wlan_vdev_get_pdev(vdev);
|
||||
if (!pdev)
|
||||
return 0;
|
||||
|
||||
cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
|
||||
sizeof(struct regulatory_channel));
|
||||
if (!cur_chan_list)
|
||||
return 0;
|
||||
|
||||
if (wlan_reg_get_current_chan_list(pdev, cur_chan_list) !=
|
||||
QDF_STATUS_SUCCESS) {
|
||||
qdf_mem_free(cur_chan_list);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0, j = 0; i < NUM_CHANNELS && i < freq_list_sz; i++) {
|
||||
freq = cur_chan_list[i].center_freq;
|
||||
state = wlan_reg_get_channel_state_for_freq(pdev, freq);
|
||||
if (state != CHANNEL_STATE_ENABLE)
|
||||
continue;
|
||||
|
||||
freq_list[j++] = freq;
|
||||
}
|
||||
|
||||
qdf_mem_free(cur_chan_list);
|
||||
return j;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* wlan_dcs_awgn_get_intf_for_seg() - get interference for specified segment
|
||||
* @awgn_info: awgn info pointer
|
||||
* @segment: segment index in channel band
|
||||
*
|
||||
* This function extracts the information from awgn event and check interference
|
||||
* within the specified segment.
|
||||
*
|
||||
* Return: true if interference is found within the segment, false otherwise.
|
||||
*/
|
||||
static bool
|
||||
wlan_dcs_awgn_get_intf_for_seg(struct wlan_host_dcs_awgn_info *awgn_info,
|
||||
uint32_t segment)
|
||||
{
|
||||
uint32_t seg_mask;
|
||||
|
||||
switch (segment) {
|
||||
case WLAN_DCS_SEG_PRI20:
|
||||
seg_mask = WLAN_DCS_SEG_PRI20_MASK;
|
||||
break;
|
||||
case WLAN_DCS_SEG_SEC20:
|
||||
seg_mask = WLAN_DCS_SEG_SEC20_MASK;
|
||||
break;
|
||||
case WLAN_DCS_SEG_SEC40:
|
||||
seg_mask = WLAN_DCS_SEG_SEC40_MASK;
|
||||
break;
|
||||
case WLAN_DCS_SEG_SEC80:
|
||||
seg_mask = WLAN_DCS_SEG_SEC80_MASK;
|
||||
break;
|
||||
case WLAN_DCS_SEG_SEC160:
|
||||
seg_mask = WLAN_DCS_SEG_SEC160_MASK;
|
||||
break;
|
||||
default:
|
||||
seg_mask = 0xFFFFFFFF;
|
||||
break;
|
||||
}
|
||||
|
||||
return (awgn_info->chan_bw_intf_bitmap & seg_mask);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_get_max_seg_idx() - get max segment index for channel width
|
||||
* @width: channel width
|
||||
*
|
||||
* Return: max segment index(enum wlan_dcs_chan_seg) for the channel width.
|
||||
*/
|
||||
static enum wlan_dcs_chan_seg wlan_dcs_get_max_seg_idx(enum phy_ch_width width)
|
||||
{
|
||||
switch (width) {
|
||||
case CH_WIDTH_160MHZ: /* fallthrough */
|
||||
case CH_WIDTH_80P80MHZ:
|
||||
return WLAN_DCS_SEG_SEC80;
|
||||
case CH_WIDTH_80MHZ:
|
||||
return WLAN_DCS_SEG_SEC40;
|
||||
case CH_WIDTH_40MHZ:
|
||||
return WLAN_DCS_SEG_SEC20;
|
||||
case CH_WIDTH_20MHZ:
|
||||
return WLAN_DCS_SEG_PRI20;
|
||||
default:
|
||||
dcs_err("Invalid ch width %d", width);
|
||||
return WLAN_DCS_SEG_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_get_chan_width_for_seg() - get channel width for specified segment
|
||||
* @seg_idx: segment index
|
||||
*
|
||||
* Return: channel width for segment index
|
||||
*/
|
||||
static enum phy_ch_width
|
||||
wlan_dcs_get_chan_width_for_seg(enum wlan_dcs_chan_seg seg_idx)
|
||||
{
|
||||
switch (seg_idx) {
|
||||
case WLAN_DCS_SEG_SEC80:
|
||||
return CH_WIDTH_160MHZ;
|
||||
case WLAN_DCS_SEG_SEC40:
|
||||
return CH_WIDTH_80MHZ;
|
||||
case WLAN_DCS_SEG_SEC20:
|
||||
return CH_WIDTH_40MHZ;
|
||||
case WLAN_DCS_SEG_PRI20:
|
||||
return CH_WIDTH_20MHZ;
|
||||
default:
|
||||
dcs_err("Invalid seg idx %d", seg_idx);
|
||||
return CH_WIDTH_INVALID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_get_max_no_intf_bw() - get max no interference band width
|
||||
* @awgn_info: pointer to awgn info
|
||||
* @width: pointer to channel width
|
||||
*
|
||||
* This function trys to get max no interference band width according to
|
||||
* awgn event.
|
||||
*
|
||||
* Return: true if valid no interference band width is found, false otherwise.
|
||||
*/
|
||||
static bool
|
||||
wlan_dcs_get_max_no_intf_bw(struct wlan_host_dcs_awgn_info *awgn_info,
|
||||
enum phy_ch_width *width)
|
||||
{
|
||||
enum wlan_dcs_chan_seg seg_idx, max_seg_idx;
|
||||
|
||||
max_seg_idx = wlan_dcs_get_max_seg_idx(awgn_info->channel_width);
|
||||
if (max_seg_idx == WLAN_DCS_SEG_INVALID)
|
||||
return false;
|
||||
|
||||
seg_idx = WLAN_DCS_SEG_PRI20;
|
||||
while (seg_idx <= max_seg_idx) {
|
||||
if (wlan_dcs_awgn_get_intf_for_seg(awgn_info, seg_idx)) {
|
||||
dcs_debug("Intf found for seg idx %d", seg_idx);
|
||||
break;
|
||||
}
|
||||
seg_idx++;
|
||||
}
|
||||
|
||||
/* scroll back to the last no-intf idx */
|
||||
seg_idx--;
|
||||
|
||||
if (seg_idx == WLAN_DCS_SEG_INVALID) {
|
||||
/* If pri20 contains interference, do full channel change */
|
||||
dcs_debug("Primary 20MHz Channel interference detected");
|
||||
return false;
|
||||
}
|
||||
|
||||
*width = wlan_dcs_get_chan_width_for_seg(seg_idx);
|
||||
if (*width == CH_WIDTH_160MHZ &&
|
||||
awgn_info->channel_width == CH_WIDTH_80P80MHZ)
|
||||
*width = CH_WIDTH_80P80MHZ;
|
||||
|
||||
dcs_debug("Found the max no intf width %d", *width);
|
||||
return (*width != CH_WIDTH_INVALID);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_get_available_chan_for_bw() - get available channel for specified
|
||||
* band width
|
||||
* @pdev: pdev ptr
|
||||
* @awgn_info: pointer to awgn info
|
||||
* @bw: channel width
|
||||
* @freq_list: List of preferred channels
|
||||
* @freq_num: Number of channels in the PCL
|
||||
* @random: request for random channel
|
||||
*
|
||||
* Return: the selected channel frequency, 0 if no available chan is found.
|
||||
*/
|
||||
static qdf_freq_t
|
||||
wlan_dcs_get_available_chan_for_bw(struct wlan_objmgr_pdev *pdev,
|
||||
struct wlan_host_dcs_awgn_info *awgn_info,
|
||||
enum phy_ch_width bw, qdf_freq_t *freq_list,
|
||||
uint32_t freq_num, bool random)
|
||||
{
|
||||
int i, j = 0;
|
||||
uint32_t random_chan_idx;
|
||||
qdf_freq_t freq, selected_freq = 0;
|
||||
const struct bonded_channel_freq *bonded_chan_ptr = NULL;
|
||||
enum channel_state state;
|
||||
uint16_t chan_cfreq;
|
||||
bool is_safe = true;
|
||||
|
||||
if (!freq_list || !freq_num)
|
||||
return selected_freq;
|
||||
|
||||
for (i = 0; i < freq_num; i++) {
|
||||
if (j && !random) {
|
||||
selected_freq = freq_list[0];
|
||||
dcs_debug("get the first available freq %u for bw %u",
|
||||
selected_freq, bw);
|
||||
break;
|
||||
}
|
||||
|
||||
freq = freq_list[i];
|
||||
if (!WLAN_REG_IS_SAME_BAND_FREQS(freq, awgn_info->center_freq))
|
||||
continue;
|
||||
|
||||
/**
|
||||
* DFS channel may need CAC during restart, which costs time
|
||||
* and may cause failure.
|
||||
*/
|
||||
if (wlan_reg_is_dfs_for_freq(pdev, freq)) {
|
||||
dcs_debug("skip dfs freq %u", freq);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bonded_chan_ptr &&
|
||||
freq >= bonded_chan_ptr->start_freq &&
|
||||
freq <= bonded_chan_ptr->end_freq) {
|
||||
if (is_safe) {
|
||||
dcs_debug("add freq directly [%d] = %u",
|
||||
j, freq);
|
||||
freq_list[j++] = freq;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
state = wlan_reg_get_5g_bonded_channel_and_state_for_freq(
|
||||
pdev, freq, bw, &bonded_chan_ptr);
|
||||
if (state != CHANNEL_STATE_ENABLE)
|
||||
continue;
|
||||
|
||||
/* no bonding channel for 20MHz */
|
||||
if (bw == CH_WIDTH_20MHZ) {
|
||||
if (WLAN_DCS_IS_FREQ_IN_WIDTH(awgn_info->center_freq,
|
||||
awgn_info->center_freq0,
|
||||
awgn_info->center_freq1,
|
||||
awgn_info->channel_width,
|
||||
freq))
|
||||
continue;
|
||||
|
||||
dcs_debug("add freq[%d] = %u", j, freq);
|
||||
freq_list[j++] = freq;
|
||||
continue;
|
||||
}
|
||||
|
||||
is_safe = true;
|
||||
chan_cfreq = bonded_chan_ptr->start_freq;
|
||||
while (chan_cfreq <= bonded_chan_ptr->end_freq) {
|
||||
if (WLAN_DCS_IS_FREQ_IN_WIDTH(awgn_info->center_freq,
|
||||
awgn_info->center_freq0,
|
||||
awgn_info->center_freq1,
|
||||
awgn_info->channel_width,
|
||||
chan_cfreq)) {
|
||||
is_safe = false;
|
||||
break;
|
||||
}
|
||||
chan_cfreq = chan_cfreq + 20;
|
||||
}
|
||||
if (is_safe) {
|
||||
dcs_debug("add freq[%d] = %u", j, freq);
|
||||
freq_list[j++] = freq;
|
||||
}
|
||||
}
|
||||
|
||||
if (j && random) {
|
||||
qdf_get_random_bytes(&random_chan_idx, sizeof(random_chan_idx));
|
||||
random_chan_idx = random_chan_idx % j;
|
||||
selected_freq = freq_list[random_chan_idx];
|
||||
dcs_debug("get freq[%d] = %u for bw %u",
|
||||
random_chan_idx, selected_freq, bw);
|
||||
}
|
||||
|
||||
return selected_freq;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_sap_get_available_chan() - get available channel for sap
|
||||
* @vdev: vdev ptr
|
||||
* @awgn_info: pointer to awgn info
|
||||
* @tgt_freq: frequency of the selected channel
|
||||
* @tgt_width: band width of the selected channel
|
||||
* @random: request for random channel
|
||||
*
|
||||
* This function trys to get no-interference chan with max possible bandwidth
|
||||
* from pcl for sap according to awgn info.
|
||||
*
|
||||
* Return: true if available channel is found, false otherwise.
|
||||
*/
|
||||
static bool
|
||||
wlan_dcs_sap_select_chan(struct wlan_objmgr_vdev *vdev,
|
||||
struct wlan_host_dcs_awgn_info *awgn_info,
|
||||
qdf_freq_t *tgt_freq, enum phy_ch_width *tgt_width,
|
||||
bool random)
|
||||
{
|
||||
int32_t tmp_width;
|
||||
qdf_freq_t tmp_freq = 0;
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
qdf_freq_t *freq_list;
|
||||
uint32_t freq_num;
|
||||
|
||||
freq_list = qdf_mem_malloc(sizeof(*freq_list) * NUM_CHANNELS);
|
||||
if (!freq_list)
|
||||
return false;
|
||||
|
||||
freq_num = wlan_dcs_get_pcl_for_sap(vdev, freq_list, NUM_CHANNELS);
|
||||
if (!freq_num) {
|
||||
qdf_mem_free(freq_list);
|
||||
return false;
|
||||
}
|
||||
|
||||
tmp_width = awgn_info->channel_width;
|
||||
pdev = wlan_vdev_get_pdev(vdev);
|
||||
if (!pdev) {
|
||||
qdf_mem_free(freq_list);
|
||||
return false;
|
||||
}
|
||||
|
||||
while (tmp_width >= CH_WIDTH_20MHZ) {
|
||||
tmp_freq = wlan_dcs_get_available_chan_for_bw(pdev, awgn_info,
|
||||
tmp_width,
|
||||
freq_list,
|
||||
freq_num,
|
||||
random);
|
||||
if (tmp_freq)
|
||||
break;
|
||||
tmp_width--;
|
||||
}
|
||||
|
||||
if (tmp_freq) {
|
||||
*tgt_width = tmp_width;
|
||||
*tgt_freq = tmp_freq;
|
||||
dcs_debug("new_width: %d new_freq %u", tmp_width, tmp_freq);
|
||||
|
||||
qdf_mem_free(freq_list);
|
||||
return true;
|
||||
}
|
||||
|
||||
qdf_mem_free(freq_list);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_is_awgnim_valid() - validate awgn info
|
||||
* @awgn_info: pointer to awgn info
|
||||
*
|
||||
* Return: true if valid, false otherwise.
|
||||
*/
|
||||
static inline bool
|
||||
wlan_dcs_is_awgnim_valid(struct wlan_host_dcs_awgn_info *awgn_info)
|
||||
{
|
||||
return (awgn_info &&
|
||||
awgn_info->center_freq && awgn_info->chan_bw_intf_bitmap &&
|
||||
awgn_info->channel_width != CH_WIDTH_INVALID &&
|
||||
WLAN_REG_IS_6GHZ_CHAN_FREQ(awgn_info->center_freq));
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_vdev_get_op_chan_info() - get operating channel info for vdev
|
||||
* @vdev: pointer to vdev object
|
||||
* @cfreq: Center frequency of primary channel
|
||||
* @cfreq0: Center frequency of segment 1
|
||||
* @cfreq1: Center frequency of segment 2
|
||||
* @ch_width: Channel width, enum phy_ch_width
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
static QDF_STATUS
|
||||
wlan_dcs_vdev_get_op_chan_info(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t *cfreq, qdf_freq_t *cfreq0,
|
||||
qdf_freq_t *cfreq1, enum phy_ch_width *ch_width)
|
||||
{
|
||||
struct wlan_channel *chan;
|
||||
|
||||
if (!vdev)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
*cfreq = 0;
|
||||
*cfreq0 = 0;
|
||||
*cfreq1 = 0;
|
||||
*ch_width = 0;
|
||||
|
||||
if (wlan_vdev_mlme_is_active(vdev) != QDF_STATUS_SUCCESS)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
chan = wlan_vdev_get_active_channel(vdev);
|
||||
if (!chan)
|
||||
return QDF_STATUS_E_INVAL;
|
||||
|
||||
*cfreq = chan->ch_freq;
|
||||
*cfreq0 = chan->ch_cfreq1;
|
||||
*cfreq1 = chan->ch_cfreq2;
|
||||
*ch_width = chan->ch_width;
|
||||
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_process_awgn_sta() - process AWGN event for STA
|
||||
* @pdev: pointer to pdev object
|
||||
* @object: vdev object
|
||||
* @arg: Arguments to the handler
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void wlan_dcs_process_awgn_sta(struct wlan_objmgr_pdev *pdev,
|
||||
void *object, void *arg)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev = object;
|
||||
struct wlan_host_dcs_awgn_info *awgn_info = arg;
|
||||
enum phy_ch_width ch_width;
|
||||
enum phy_ch_width tgt_width = CH_WIDTH_INVALID;
|
||||
qdf_freq_t op_freq, cfreq0, cfreq1;
|
||||
qdf_freq_t tgt_freq = 0;
|
||||
QDF_STATUS status;
|
||||
uint8_t vdev_id;
|
||||
bool found;
|
||||
|
||||
if (!vdev || !pdev)
|
||||
return;
|
||||
|
||||
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
|
||||
return;
|
||||
|
||||
vdev_id = wlan_vdev_get_id(vdev);
|
||||
status = wlan_dcs_vdev_get_op_chan_info(vdev, &op_freq, &cfreq0,
|
||||
&cfreq1, &ch_width);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return;
|
||||
|
||||
if (awgn_info->center_freq != op_freq) {
|
||||
dcs_debug("STA-%d: freq not match", vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
found = wlan_dcs_get_max_no_intf_bw(awgn_info, &tgt_width);
|
||||
if (found) {
|
||||
if (ch_width <= tgt_width) {
|
||||
dcs_debug("STA-%d: freq and bw are unchanged", vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
tgt_freq = op_freq;
|
||||
}
|
||||
|
||||
/* If no width is found, means to disconnect */
|
||||
dcs_debug("STA-%d: target freq %u width %u",
|
||||
vdev_id, tgt_freq, tgt_width);
|
||||
wlan_dcs_switch_chan(vdev, tgt_freq, tgt_width);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_process_awgn_sap() - process AWGN event for SAP
|
||||
* @pdev: pointer to pdev object
|
||||
* @object: vdev object
|
||||
* @arg: Arguments to the handler
|
||||
*
|
||||
* Return: void
|
||||
*/
|
||||
static void wlan_dcs_process_awgn_sap(struct wlan_objmgr_pdev *pdev,
|
||||
void *object, void *arg)
|
||||
{
|
||||
struct wlan_objmgr_vdev *vdev = object;
|
||||
struct wlan_host_dcs_awgn_info *awgn_info = arg;
|
||||
enum phy_ch_width ch_width;
|
||||
enum phy_ch_width tgt_width = CH_WIDTH_INVALID;
|
||||
qdf_freq_t op_freq, cfreq0, cfreq1;
|
||||
qdf_freq_t tgt_freq = 0;
|
||||
QDF_STATUS status;
|
||||
uint8_t vdev_id;
|
||||
bool found;
|
||||
|
||||
if (!vdev || !pdev)
|
||||
return;
|
||||
|
||||
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_SAP_MODE)
|
||||
return;
|
||||
|
||||
vdev_id = wlan_vdev_get_id(vdev);
|
||||
status = wlan_dcs_vdev_get_op_chan_info(vdev, &op_freq, &cfreq0, &cfreq1, &ch_width);
|
||||
if (QDF_IS_STATUS_ERROR(status))
|
||||
return;
|
||||
|
||||
if (awgn_info->center_freq != op_freq) {
|
||||
dcs_debug("SAP-%d: freq not match rpt:%u - op:%u",
|
||||
vdev_id, awgn_info->center_freq, op_freq);
|
||||
return;
|
||||
}
|
||||
|
||||
found = wlan_dcs_get_max_no_intf_bw(awgn_info, &tgt_width);
|
||||
if (found) {
|
||||
if (ch_width <= tgt_width) {
|
||||
dcs_debug("SAP-%d: both freq and bw are unchanged",
|
||||
vdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
tgt_freq = op_freq;
|
||||
} else {
|
||||
wlan_dcs_sap_select_chan(vdev, awgn_info, &tgt_freq,
|
||||
&tgt_width, true);
|
||||
}
|
||||
|
||||
/* If no chan is selected, means to stop sap */
|
||||
dcs_debug("SAP-%d: target freq %u width %u",
|
||||
vdev_id, tgt_freq, tgt_width);
|
||||
wlan_dcs_switch_chan(vdev, tgt_freq, tgt_width);
|
||||
}
|
||||
|
||||
/**
|
||||
* wlan_dcs_awgnim_process() - process awgn IM
|
||||
* @psoc: psoc ptr
|
||||
* @pdev_id: pdev id
|
||||
* @awgn_info: pointer to awgn info
|
||||
*
|
||||
* This function triggers channel change for all STAs and SAPs, according
|
||||
* to AWGN info.
|
||||
*
|
||||
* Return: None.
|
||||
*/
|
||||
static void
|
||||
wlan_dcs_awgn_process(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id,
|
||||
struct wlan_host_dcs_awgn_info *awgn_info)
|
||||
{
|
||||
struct wlan_objmgr_pdev *pdev;
|
||||
|
||||
if (!wlan_dcs_is_awgnim_valid(awgn_info)) {
|
||||
dcs_err("Invalid awgnim event");
|
||||
return;
|
||||
}
|
||||
|
||||
pdev = wlan_objmgr_get_pdev_by_id(psoc, pdev_id, WLAN_DCS_ID);
|
||||
if (!pdev) {
|
||||
dcs_err("Invalid pdev id %d", pdev_id);
|
||||
return;
|
||||
}
|
||||
|
||||
dcs_debug("pdev id %u width %u freq %u freq0 %u fre1 %u bitmap 0x%x",
|
||||
pdev_id, awgn_info->channel_width, awgn_info->center_freq,
|
||||
awgn_info->center_freq0, awgn_info->center_freq1,
|
||||
awgn_info->chan_bw_intf_bitmap);
|
||||
|
||||
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
|
||||
wlan_dcs_process_awgn_sta,
|
||||
awgn_info, 0, WLAN_DCS_ID);
|
||||
|
||||
wlan_objmgr_pdev_iterate_obj_list(pdev, WLAN_VDEV_OP,
|
||||
wlan_dcs_process_awgn_sap,
|
||||
awgn_info, 0, WLAN_DCS_ID);
|
||||
|
||||
wlan_objmgr_pdev_release_ref(pdev, WLAN_DCS_ID);
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
wlan_dcs_process(struct wlan_objmgr_psoc *psoc, struct dcs_stats_event *event)
|
||||
wlan_dcs_process(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_host_dcs_event *event)
|
||||
{
|
||||
struct dcs_pdev_priv_obj *dcs_pdev_priv;
|
||||
bool start_dcs_cbk_handler = false;
|
||||
@ -692,14 +1348,15 @@ wlan_dcs_process(struct wlan_objmgr_psoc *psoc, struct dcs_stats_event *event)
|
||||
event->dcs_param.interference_type,
|
||||
event->dcs_param.pdev_id);
|
||||
|
||||
if (!dcs_pdev_priv->dcs_host_params.dcs_enable)
|
||||
return QDF_STATUS_SUCCESS;
|
||||
|
||||
switch (event->dcs_param.interference_type) {
|
||||
case CAP_DCS_CWIM:
|
||||
case WLAN_HOST_DCS_CWIM:
|
||||
break;
|
||||
case CAP_DCS_WLANIM:
|
||||
if (dcs_pdev_priv->dcs_host_params.dcs_enable & CAP_DCS_WLANIM)
|
||||
case WLAN_HOST_DCS_WLANIM:
|
||||
if (!dcs_pdev_priv->dcs_host_params.dcs_enable)
|
||||
break;
|
||||
|
||||
if (dcs_pdev_priv->dcs_host_params.dcs_enable &
|
||||
WLAN_HOST_DCS_WLANIM)
|
||||
start_dcs_cbk_handler =
|
||||
wlan_dcs_wlan_interference_process(
|
||||
&event->wlan_stat,
|
||||
@ -716,6 +1373,11 @@ wlan_dcs_process(struct wlan_objmgr_psoc *psoc, struct dcs_stats_event *event)
|
||||
dcs_pdev_priv,
|
||||
event);
|
||||
break;
|
||||
case WLAN_HOST_DCS_AWGNIM:
|
||||
/* Skip frequency control for AWGNIM */
|
||||
wlan_dcs_awgn_process(psoc, event->dcs_param.pdev_id,
|
||||
&event->awgn_info);
|
||||
break;
|
||||
default:
|
||||
dcs_err("unidentified interference type reported");
|
||||
break;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, 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 above
|
||||
@ -163,14 +163,61 @@ struct dcs_pdev_priv_obj {
|
||||
int status);
|
||||
};
|
||||
|
||||
/**
|
||||
* wlan_dcs_chan_seg - Different segments in the channel band.
|
||||
* @WLAN_DCS_SEG_INVALID: invalid segment
|
||||
* @WLAN_DCS_SEG_PRI20: primary 20MHz
|
||||
* @WLAN_DCS_SEG_SEC20: secondary 20MHz
|
||||
* @WLAN_DCS_SEG_SEC40: secondary 40MHz
|
||||
* @WLAN_DCS_SEG_SEC80: secondary 80MHz
|
||||
* @WLAN_DCS_SEG_SEC160: secondary 160MHz
|
||||
*/
|
||||
enum wlan_dcs_chan_seg {
|
||||
WLAN_DCS_SEG_INVALID,
|
||||
WLAN_DCS_SEG_PRI20,
|
||||
WLAN_DCS_SEG_SEC20,
|
||||
WLAN_DCS_SEG_SEC40,
|
||||
WLAN_DCS_SEG_SEC80,
|
||||
WLAN_DCS_SEG_SEC160,
|
||||
};
|
||||
|
||||
/* masks for segments */
|
||||
#define WLAN_DCS_SEG_PRI20_MASK BIT(0)
|
||||
#define WLAN_DCS_SEG_SEC20_MASK BIT(1)
|
||||
#define WLAN_DCS_SEG_SEC40_MASK (BIT(2) | BIT(3))
|
||||
#define WLAN_DCS_SEG_SEC80_MASK (BIT(4) | BIT(5) | BIT(6) | BIT(7))
|
||||
#define WLAN_DCS_SEG_SEC160_MASK (BIT(8) | BIT(9) | BIT(10) | BIT(11) | \
|
||||
BIT(12) | BIT(13) | BIT(14) | BIT(15))
|
||||
|
||||
#define WLAN_DCS_CHAN_FREQ_OFFSET 5
|
||||
#define WLAN_DCS_IS_FREQ_IN_WIDTH(__cfreq, __cfreq0, __cfreq1, __width, __freq)\
|
||||
((((__width) == CH_WIDTH_20MHZ) && \
|
||||
((__cfreq) == (__freq))) || \
|
||||
(((__width) == CH_WIDTH_40MHZ) && \
|
||||
(((__freq) >= ((__cfreq0) - (2 * WLAN_DCS_CHAN_FREQ_OFFSET))) && \
|
||||
((__freq) <= ((__cfreq0) + (2 * WLAN_DCS_CHAN_FREQ_OFFSET))))) || \
|
||||
(((__width) == CH_WIDTH_80MHZ) && \
|
||||
(((__freq) >= ((__cfreq0) - (6 * WLAN_DCS_CHAN_FREQ_OFFSET))) && \
|
||||
((__freq) <= ((__cfreq0) + (6 * WLAN_DCS_CHAN_FREQ_OFFSET))))) || \
|
||||
(((__width) == CH_WIDTH_160MHZ) && \
|
||||
(((__freq) >= ((__cfreq1) - (14 * WLAN_DCS_CHAN_FREQ_OFFSET))) && \
|
||||
((__freq) <= ((__cfreq1) + (14 * WLAN_DCS_CHAN_FREQ_OFFSET))))) || \
|
||||
(((__width) == CH_WIDTH_80P80MHZ) && \
|
||||
((((__freq) >= ((__cfreq0) - (6 * WLAN_DCS_CHAN_FREQ_OFFSET))) && \
|
||||
((__freq) <= ((__cfreq0) + (6 * WLAN_DCS_CHAN_FREQ_OFFSET)))) || \
|
||||
(((__freq) >= ((__cfreq1) - (6 * WLAN_DCS_CHAN_FREQ_OFFSET))) && \
|
||||
((__freq) <= ((__cfreq1) + (6 * WLAN_DCS_CHAN_FREQ_OFFSET)))))))
|
||||
|
||||
/**
|
||||
* struct dcs_psoc_priv_obj - define dcs psoc priv
|
||||
* @dcs_pdev_priv: dcs pdev priv
|
||||
* @dcs_cbk: dcs callback
|
||||
* @switch_chan_cb: callback for switching channel
|
||||
*/
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -222,7 +269,7 @@ QDF_STATUS wlan_dcs_cmd_send(struct wlan_objmgr_psoc *psoc,
|
||||
/**
|
||||
* wlan_dcs_process() - dcs process main entry
|
||||
* @psoc: psoc pointer
|
||||
* @event: dcs stats event pointer
|
||||
* @event: dcs event pointer
|
||||
*
|
||||
* This function is the main entry to do dcs related operation
|
||||
* such as algorithm handling and dcs frequency control.
|
||||
@ -230,7 +277,7 @@ QDF_STATUS wlan_dcs_cmd_send(struct wlan_objmgr_psoc *psoc,
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS wlan_dcs_process(struct wlan_objmgr_psoc *psoc,
|
||||
struct dcs_stats_event *event);
|
||||
struct wlan_host_dcs_event *event);
|
||||
|
||||
/**
|
||||
* wlan_dcs_disable_timer_fn() - dcs disable timer callback
|
||||
|
@ -21,6 +21,20 @@
|
||||
#ifndef _WLAN_DCS_PUBLIC_STRUCTS_H_
|
||||
#define _WLAN_DCS_PUBLIC_STRUCTS_H_
|
||||
|
||||
/**
|
||||
* enum wlan_host_dcs_type - types of DCS interference events
|
||||
* @WLAN_HOST_DCS_NONE: invalid type
|
||||
* @WLAN_HOST_DCS_CWIM: continuous wave interference
|
||||
* @WLAN_HOST_DCS_WLANIM: wlan interference stats
|
||||
* @WLAN_HOST_DCS_AWGNIM: additive white Gaussian noise (awgn) interference
|
||||
*/
|
||||
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 */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_host_dcs_interference_param - dcs interference parameters
|
||||
* @interference_type: type of DCS interference
|
||||
@ -119,4 +133,16 @@ struct wlan_host_dcs_awgn_info {
|
||||
qdf_freq_t center_freq1;
|
||||
uint32_t chan_bw_intf_bitmap;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct wlan_host_dcs_event - define dcs event
|
||||
* @wlan_stat: wlan interference target statistics
|
||||
* @dcs_param: dcs event param
|
||||
* @awgn_info: awgn info
|
||||
*/
|
||||
struct wlan_host_dcs_event {
|
||||
struct wlan_host_dcs_im_tgt_stats wlan_stat;
|
||||
struct wlan_host_dcs_interference_param dcs_param;
|
||||
struct wlan_host_dcs_awgn_info awgn_info;
|
||||
};
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, 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 above
|
||||
@ -25,26 +25,16 @@
|
||||
#include <wlan_objmgr_cmn.h>
|
||||
#include <wlan_dcs_public_structs.h>
|
||||
|
||||
/**
|
||||
* struct dcs_stats_event - define dcs stats event
|
||||
* @wlan_stat: wlan interference target statistics
|
||||
* @dcs_param: dcs event param
|
||||
*/
|
||||
struct dcs_stats_event {
|
||||
struct wlan_host_dcs_im_tgt_stats wlan_stat;
|
||||
struct wlan_host_dcs_interference_param dcs_param;
|
||||
};
|
||||
|
||||
/**
|
||||
* tgt_dcs_process_event(): dcs FW event process
|
||||
* @psoc: pointer to psoc object
|
||||
* @event: pointer to dcs stats event
|
||||
* @event: pointer to dcs event
|
||||
*
|
||||
* This function gets called to process dcs FW event
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS tgt_dcs_process_event(struct wlan_objmgr_psoc *psoc,
|
||||
struct dcs_stats_event *event);
|
||||
struct wlan_host_dcs_event *event);
|
||||
|
||||
#endif /* __WLAN_DCS_TGT_API_H__ */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, 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 above
|
||||
@ -25,16 +25,6 @@
|
||||
#include <wlan_objmgr_pdev_obj.h>
|
||||
#include <wlan_dcs_public_structs.h>
|
||||
|
||||
/**
|
||||
* @brief List of DCS capabilities that can be set or unset
|
||||
* dynamically
|
||||
* @see UMAC auto channel selection document for details on each feature
|
||||
*
|
||||
*/
|
||||
#define CAP_DCS_CWIM 0x1
|
||||
#define CAP_DCS_WLANIM 0x2
|
||||
#define CAP_DCS_MASK (CAP_DCS_CWIM | CAP_DCS_WLANIM)
|
||||
|
||||
/**
|
||||
* typedef dcs_callback() - DCS callback
|
||||
* @psoc: Pointer to psoc
|
||||
@ -48,6 +38,16 @@ typedef void (*dcs_callback)(
|
||||
uint8_t interference_type,
|
||||
void *arg);
|
||||
|
||||
/**
|
||||
* typedef dcs_switch_chan_cb() - DCS callback for switching channel
|
||||
* @vdev: Pointer to vdev
|
||||
* @tgt_freq: target channel frequency
|
||||
* @tgt_width: target channel width
|
||||
*/
|
||||
typedef QDF_STATUS (*dcs_switch_chan_cb)(struct wlan_objmgr_vdev *vdev,
|
||||
qdf_freq_t tgt_freq,
|
||||
enum phy_ch_width tgt_width);
|
||||
|
||||
#ifdef DCS_INTERFERENCE_DETECTION
|
||||
/**
|
||||
* ucfg_dcs_register_cb() - API to register dcs callback
|
||||
@ -79,6 +79,16 @@ void ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
|
||||
struct wlan_host_dcs_im_user_stats *stats,
|
||||
int status));
|
||||
|
||||
/**
|
||||
* ucfg_dcs_register_awgn_cb() - API to register dcs awgn callback
|
||||
* @psoc: pointer to psoc object
|
||||
* @cb: dcs switch channel callback to be registered
|
||||
*
|
||||
* Return: QDF_STATUS
|
||||
*/
|
||||
QDF_STATUS ucfg_dcs_register_awgn_cb(struct wlan_objmgr_psoc *psoc,
|
||||
dcs_switch_chan_cb cb);
|
||||
|
||||
/**
|
||||
* ucfg_wlan_dcs_cmd(): API to send dcs command
|
||||
* @psoc: pointer to psoc object
|
||||
@ -98,7 +108,7 @@ ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
* ucfg_config_dcs_enable() - API to config dcs enable
|
||||
* @psoc: pointer to psoc object
|
||||
* @mac_id: mac id
|
||||
* @interference_type: CAP_DCS_CWIM, CAP_DCS_WLANIM, CAP_DCS_MASK
|
||||
* @interference_type: type mask(WLAN_HOST_DCS_CWIM / WLAN_HOST_DCS_WLANIM)
|
||||
*
|
||||
* This function gets called to config dcs enable
|
||||
*
|
||||
@ -112,7 +122,7 @@ void ucfg_config_dcs_enable(struct wlan_objmgr_psoc *psoc,
|
||||
* ucfg_config_dcs_disable() - API to config dcs disable
|
||||
* @psoc: pointer to psoc object
|
||||
* @mac_id: mac id
|
||||
* @interference_type: CAP_DCS_CWIM, CAP_DCS_WLANIM, CAP_DCS_MASK
|
||||
* @interference_type: type mask(WLAN_HOST_DCS_CWIM / WLAN_HOST_DCS_WLANIM)
|
||||
*
|
||||
* This function gets called to config dcs disable
|
||||
*
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021, 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 above
|
||||
@ -24,7 +24,7 @@
|
||||
#include "../../core/src/wlan_dcs.h"
|
||||
|
||||
QDF_STATUS tgt_dcs_process_event(struct wlan_objmgr_psoc *psoc,
|
||||
struct dcs_stats_event *event)
|
||||
struct wlan_host_dcs_event *event)
|
||||
{
|
||||
return wlan_dcs_process(psoc, event);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020-2021 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 above
|
||||
@ -60,6 +60,22 @@ ucfg_dcs_register_user_cb(struct wlan_objmgr_psoc *psoc,
|
||||
dcs_pdev_priv->user_cb = cb;
|
||||
}
|
||||
|
||||
QDF_STATUS ucfg_dcs_register_awgn_cb(struct wlan_objmgr_psoc *psoc,
|
||||
dcs_switch_chan_cb cb)
|
||||
{
|
||||
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->switch_chan_cb = cb;
|
||||
return QDF_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
QDF_STATUS
|
||||
ucfg_wlan_dcs_cmd(struct wlan_objmgr_psoc *psoc,
|
||||
uint32_t mac_id,
|
||||
|
@ -210,7 +210,7 @@ struct wlan_target_if_dcs_tx_ops {
|
||||
*/
|
||||
struct wlan_target_if_dcs_rx_ops {
|
||||
QDF_STATUS (*process_dcs_event)(struct wlan_objmgr_psoc *psoc,
|
||||
struct dcs_stats_event *event);
|
||||
struct wlan_host_dcs_event *event);
|
||||
};
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user