blob: 337c2b1da9dc62d896cf9f07e5eb8e063cda84b6 [file] [log] [blame]
/*
* Copyright (c) 2016-2019 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 copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/**
* DOC: This file has the DFS dispatcher API implementation which is exposed
* to outside of DFS component.
*/
#include <wlan_objmgr_vdev_obj.h>
#include "wlan_dfs_utils_api.h"
#include "wlan_dfs_init_deinit_api.h"
#include "wlan_dfs_mlme_api.h"
#include "../../core/src/dfs.h"
#include "../../core/src/dfs_zero_cac.h"
#include <wlan_reg_services_api.h>
#include "../../core/src/dfs_random_chan_sel.h"
#ifdef QCA_DFS_USE_POLICY_MANAGER
#include "wlan_policy_mgr_api.h"
#endif
#ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
#include <pld_common.h>
#endif
#include <qdf_module.h>
struct dfs_nol_info {
uint16_t num_chans;
struct dfsreq_nolelem dfs_nol[DFS_MAX_NOL_CHANNEL];
};
QDF_STATUS utils_dfs_reset(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_reset(dfs);
dfs_nol_update(dfs);
dfs_reset_precaclists(dfs);
return QDF_STATUS_SUCCESS;
}
bool utils_dfs_is_freq_in_nol(struct wlan_objmgr_pdev *pdev, uint32_t freq)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return false;
return dfs_is_freq_in_nol(dfs, freq);
}
#ifdef CONFIG_CHAN_NUM_API
QDF_STATUS utils_dfs_cac_valid_reset(struct wlan_objmgr_pdev *pdev,
uint8_t prevchan_ieee,
uint32_t prevchan_flags)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_cac_valid_reset(dfs, prevchan_ieee, prevchan_flags);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_cac_valid_reset);
#endif
#ifdef CONFIG_CHAN_FREQ_API
QDF_STATUS utils_dfs_cac_valid_reset_for_freq(struct wlan_objmgr_pdev *pdev,
uint16_t prevchan_freq,
uint32_t prevchan_flags)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_cac_valid_reset_for_freq(dfs, prevchan_freq, prevchan_flags);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_cac_valid_reset_for_freq);
#endif
QDF_STATUS utils_dfs_reset_precaclists(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_reset_precaclists(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_reset_precaclists);
#ifdef CONFIG_CHAN_NUM_API
void utils_dfs_unmark_precac_nol(struct wlan_objmgr_pdev *pdev, uint8_t chan)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return;
dfs_unmark_precac_nol(dfs, chan);
}
qdf_export_symbol(utils_dfs_unmark_precac_nol);
#endif
#ifdef CONFIG_CHAN_FREQ_API
void utils_dfs_unmark_precac_nol_for_freq(struct wlan_objmgr_pdev *pdev,
uint16_t chan_freq)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return;
dfs_unmark_precac_nol_for_freq(dfs, chan_freq);
}
qdf_export_symbol(utils_dfs_unmark_precac_nol_for_freq);
#endif
QDF_STATUS utils_dfs_cancel_precac_timer(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_cancel_precac_timer(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_cancel_precac_timer);
#ifdef CONFIG_CHAN_FREQ_API
QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs");
return QDF_STATUS_E_FAILURE;
}
if (!dfs->dfs_precac_secondary_freq_mhz)
return QDF_STATUS_E_FAILURE;
dfs_start_precac_timer_for_freq(dfs,
dfs->dfs_precac_secondary_freq_mhz);
return QDF_STATUS_SUCCESS;
}
#else
#ifdef CONFIG_CHAN_NUM_API
QDF_STATUS utils_dfs_start_precac_timer(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs");
return QDF_STATUS_E_FAILURE;
}
if (!dfs->dfs_precac_secondary_freq)
return QDF_STATUS_E_FAILURE;
dfs_start_precac_timer(dfs,
dfs->dfs_precac_secondary_freq);
return QDF_STATUS_SUCCESS;
}
#endif
#endif
#ifdef WLAN_DFS_PRECAC_AUTO_CHAN_SUPPORT
#ifdef CONFIG_CHAN_NUM_API
bool
utils_dfs_precac_decide_pref_chan(struct wlan_objmgr_pdev *pdev,
uint8_t *ch_ieee,
enum wlan_phymode mode)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs");
return false;
}
return dfs_decide_precac_preferred_chan(dfs, ch_ieee, mode);
}
#endif
#ifdef CONFIG_CHAN_FREQ_API
bool
utils_dfs_precac_decide_pref_chan_for_freq(struct wlan_objmgr_pdev *pdev,
uint16_t *chan_freq,
enum wlan_phymode mode)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "NULL dfs");
return false;
}
return dfs_decide_precac_preferred_chan_for_freq(dfs, chan_freq, mode);
}
#endif
#endif
QDF_STATUS utils_dfs_cancel_cac_timer(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_cancel_cac_timer(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_cancel_cac_timer);
QDF_STATUS utils_dfs_start_cac_timer(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_start_cac_timer(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_start_cac_timer);
QDF_STATUS utils_dfs_cac_stop(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_cac_stop(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_cac_stop);
/** dfs_fill_chan_info() - Fill the dfs channel structure with wlan
* channel.
* @chan: Pointer to DFS channel structure.
* @wlan_chan: Pointer to WLAN Channel structure.
*
* Return: void
*/
#ifdef CONFIG_CHAN_FREQ_API
static void dfs_fill_chan_info(struct dfs_channel *chan,
struct wlan_channel *wlan_chan)
{
chan->dfs_ch_freq = wlan_chan->ch_freq;
chan->dfs_ch_flags = wlan_chan->ch_flags;
chan->dfs_ch_flagext = wlan_chan->ch_flagext;
chan->dfs_ch_ieee = wlan_chan->ch_ieee;
chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1;
chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2;
chan->dfs_ch_mhz_freq_seg1 = wlan_chan->ch_cfreq1;
chan->dfs_ch_mhz_freq_seg2 = wlan_chan->ch_cfreq2;
}
#else
#ifdef CONFIG_CHAN_NUM_API
static void dfs_fill_chan_info(struct dfs_channel *chan,
struct wlan_channel *wlan_chan)
{
chan->dfs_ch_freq = wlan_chan->ch_freq;
chan->dfs_ch_flags = wlan_chan->ch_flags;
chan->dfs_ch_flagext = wlan_chan->ch_flagext;
chan->dfs_ch_ieee = wlan_chan->ch_ieee;
chan->dfs_ch_vhtop_ch_freq_seg1 = wlan_chan->ch_freq_seg1;
chan->dfs_ch_vhtop_ch_freq_seg2 = wlan_chan->ch_freq_seg2;
}
#endif
#endif
bool utils_dfs_is_precac_done(struct wlan_objmgr_pdev *pdev,
struct wlan_channel *wlan_chan)
{
struct wlan_dfs *dfs;
struct dfs_channel chan;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return false;
dfs_fill_chan_info(&chan, wlan_chan);
return dfs_is_precac_done(dfs, &chan);
}
bool utils_dfs_is_cac_required(struct wlan_objmgr_pdev *pdev,
struct wlan_channel *cur_chan,
struct wlan_channel *prev_chan,
bool *continue_current_cac)
{
struct wlan_dfs *dfs;
struct dfs_channel cur_channel;
struct dfs_channel prev_channel;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return false;
dfs_fill_chan_info(&cur_channel, cur_chan);
dfs_fill_chan_info(&prev_channel, prev_chan);
return dfs_is_cac_required(dfs,
&cur_channel,
&prev_channel,
continue_current_cac);
}
bool
utils_dfs_is_cac_required_on_dfs_curchan(struct wlan_objmgr_pdev *pdev,
bool *continue_current_cac)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return false;
return dfs_is_cac_required(dfs,
dfs->dfs_curchan,
dfs->dfs_prevchan,
continue_current_cac);
}
QDF_STATUS utils_dfs_stacac_stop(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_stacac_stop(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_stacac_stop);
QDF_STATUS utils_dfs_get_usenol(struct wlan_objmgr_pdev *pdev, uint16_t *usenol)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
*usenol = dfs_get_use_nol(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_get_usenol);
QDF_STATUS utils_dfs_radar_disable(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_radar_disable(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_radar_disable);
QDF_STATUS utils_dfs_set_update_nol_flag(struct wlan_objmgr_pdev *pdev,
bool val)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_set_update_nol_flag(dfs, val);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_set_update_nol_flag);
QDF_STATUS utils_dfs_get_update_nol_flag(struct wlan_objmgr_pdev *pdev,
bool *nol_flag)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
*nol_flag = dfs_get_update_nol_flag(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_get_update_nol_flag);
QDF_STATUS utils_dfs_get_dfs_use_nol(struct wlan_objmgr_pdev *pdev,
int *dfs_use_nol)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
*dfs_use_nol = dfs_get_use_nol(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_get_dfs_use_nol);
QDF_STATUS utils_dfs_get_nol_timeout(struct wlan_objmgr_pdev *pdev,
int *dfs_nol_timeout)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
*dfs_nol_timeout = dfs_get_nol_timeout(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_get_nol_timeout);
QDF_STATUS utils_dfs_nol_addchan(struct wlan_objmgr_pdev *pdev,
uint16_t freq,
uint32_t dfs_nol_timeout)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
DFS_NOL_ADD_CHAN_LOCKED(dfs, freq, dfs_nol_timeout);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_nol_addchan);
QDF_STATUS utils_dfs_nol_update(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_nol_update(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_nol_update);
QDF_STATUS utils_dfs_second_segment_radar_disable(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_second_segment_radar_disable(dfs);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS utils_dfs_bw_reduce(struct wlan_objmgr_pdev *pdev, bool bw_reduce)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs->dfs_bw_reduced = bw_reduce;
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_bw_reduce);
QDF_STATUS utils_dfs_is_bw_reduce(struct wlan_objmgr_pdev *pdev,
bool *bw_reduce)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
*bw_reduce = dfs->dfs_bw_reduced;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS utils_dfs_fetch_nol_ie_info(struct wlan_objmgr_pdev *pdev,
uint8_t *nol_ie_bandwidth,
uint16_t *nol_ie_startfreq,
uint8_t *nol_ie_bitmap)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_fetch_nol_ie_info(dfs, nol_ie_bandwidth, nol_ie_startfreq,
nol_ie_bitmap);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS utils_dfs_set_rcsa_flags(struct wlan_objmgr_pdev *pdev,
bool is_rcsa_ie_sent,
bool is_nol_ie_sent)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_set_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS utils_dfs_get_rcsa_flags(struct wlan_objmgr_pdev *pdev,
bool *is_rcsa_ie_sent,
bool *is_nol_ie_sent)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_get_rcsa_flags(dfs, is_rcsa_ie_sent, is_nol_ie_sent);
return QDF_STATUS_SUCCESS;
}
bool utils_dfs_process_nol_ie_bitmap(struct wlan_objmgr_pdev *pdev,
uint8_t nol_ie_bandwidth,
uint16_t nol_ie_startfreq,
uint8_t nol_ie_bitmap)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return false;
return dfs_process_nol_ie_bitmap(dfs, nol_ie_bandwidth,
nol_ie_startfreq,
nol_ie_bitmap);
}
QDF_STATUS utils_dfs_set_cac_timer_running(struct wlan_objmgr_pdev *pdev,
int val)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs->dfs_cac_timer_running = val;
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_set_cac_timer_running);
QDF_STATUS utils_dfs_get_nol_chfreq_and_chwidth(struct wlan_objmgr_pdev *pdev,
void *nollist,
uint32_t *nol_chfreq,
uint32_t *nol_chwidth,
int index)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_get_nol_chfreq_and_chwidth(nollist, nol_chfreq, nol_chwidth, index);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_get_nol_chfreq_and_chwidth);
QDF_STATUS utils_dfs_update_cur_chan_flags(struct wlan_objmgr_pdev *pdev,
uint64_t flags,
uint16_t flagext)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return QDF_STATUS_E_FAILURE;
dfs_update_cur_chan_flags(dfs, flags, flagext);
return QDF_STATUS_SUCCESS;
}
static void utils_dfs_get_max_phy_mode(struct wlan_objmgr_pdev *pdev,
uint32_t *phy_mode)
{
return;
}
static void utils_dfs_get_max_sup_width(struct wlan_objmgr_pdev *pdev,
uint8_t *ch_width)
{
return;
}
#ifndef QCA_DFS_USE_POLICY_MANAGER
void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev,
void *clist, uint32_t *num_chan)
{
int i, j = 0;
struct regulatory_channel *cur_chan_list;
struct wlan_dfs *dfs;
struct dfs_channel *chan_list = (struct dfs_channel *)clist;
*num_chan = 0;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return;
cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(*cur_chan_list));
if (!cur_chan_list)
return;
if (wlan_reg_get_current_chan_list(
pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
"failed to get cur_chan list");
qdf_mem_free(cur_chan_list);
return;
}
for (i = 0; i < NUM_CHANNELS; i++) {
if (cur_chan_list[i].nol_history) {
chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq;
j++;
}
}
*num_chan = j;
qdf_mem_free(cur_chan_list);
}
void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
void *clist, uint32_t *num_chan)
{
int i = 0, j = 0;
enum channel_state state;
struct regulatory_channel *cur_chan_list;
struct wlan_dfs *dfs;
struct dfs_channel *chan_list = (struct dfs_channel *)clist;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return;
cur_chan_list = qdf_mem_malloc(NUM_CHANNELS *
sizeof(struct regulatory_channel));
if (!cur_chan_list) {
*num_chan = 0;
return;
}
if (wlan_reg_get_current_chan_list(
pdev, cur_chan_list) != QDF_STATUS_SUCCESS) {
*num_chan = 0;
dfs_alert(dfs, WLAN_DEBUG_DFS_ALWAYS,
"failed to get curr channel list");
return;
}
for (i = 0; i < NUM_CHANNELS; i++) {
state = cur_chan_list[i].state;
if (state == CHANNEL_STATE_DFS ||
state == CHANNEL_STATE_ENABLE) {
chan_list[j].dfs_ch_ieee = cur_chan_list[i].chan_num;
chan_list[j].dfs_ch_freq = cur_chan_list[i].center_freq;
if (state == CHANNEL_STATE_DFS)
chan_list[j].dfs_ch_flagext =
WLAN_CHAN_DFS;
if (cur_chan_list[i].nol_history)
chan_list[j].dfs_ch_flagext |=
WLAN_CHAN_HISTORY_RADAR;
j++;
}
}
*num_chan = j;
qdf_mem_free(cur_chan_list);
return;
}
/**
* utils_dfs_get_channel_list() - Get channel list from regdb component, based
* on current channel list.
* @pdev: Pointer to pdev structure.
* @vdev: vdev of request
* @chan: Pointer to channel list.
* @num_chan: number of channels.
*
* Get regdb channel list based on dfs current channel.
* Ex: When AP is operating in 5GHz channel, filter 2.4GHz and 4.9GHZ channels
* so that the random channel function does not select either 2.4GHz or 4.9GHz
* channel.
*/
#ifdef CONFIG_CHAN_FREQ_API
static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
struct dfs_channel *chan_list,
uint32_t *num_chan)
{
struct dfs_channel *tmp_chan_list = NULL;
struct wlan_dfs *dfs;
bool is_curchan_5g;
bool is_curchan_24g;
bool is_curchan_49g;
uint32_t chan_num;
uint32_t center_freq;
uint16_t flagext;
int i, j = 0;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return;
}
tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list));
if (!tmp_chan_list)
return;
utils_dfs_get_chan_list(pdev, (void *)tmp_chan_list, num_chan);
chan_num = dfs->dfs_curchan->dfs_ch_ieee;
center_freq = dfs->dfs_curchan->dfs_ch_freq;
is_curchan_5g = WLAN_REG_IS_5GHZ_CH_FREQ(center_freq);
is_curchan_24g = WLAN_REG_IS_24GHZ_CH_FREQ(center_freq);
is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq);
for (i = 0; i < *num_chan; i++) {
chan_num = tmp_chan_list[i].dfs_ch_ieee;
center_freq = tmp_chan_list[i].dfs_ch_freq;
flagext = tmp_chan_list[i].dfs_ch_flagext;
/* No change in prototype needed. Hence retaining same func */
if (!dfs_mlme_check_allowed_prim_chanlist(pdev, center_freq))
continue;
if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH_FREQ(center_freq)) {
chan_list[j].dfs_ch_ieee = chan_num;
chan_list[j].dfs_ch_freq = center_freq;
chan_list[j].dfs_ch_flagext = flagext;
j++;
} else if ((is_curchan_24g) &&
WLAN_REG_IS_24GHZ_CH_FREQ(center_freq)) {
chan_list[j].dfs_ch_ieee = chan_num;
chan_list[j].dfs_ch_freq = center_freq;
j++;
} else if ((is_curchan_49g) &&
WLAN_REG_IS_49GHZ_FREQ(center_freq)) {
chan_list[j].dfs_ch_ieee = chan_num;
chan_list[j].dfs_ch_freq = center_freq;
j++;
}
}
*num_chan = j;
qdf_mem_free(tmp_chan_list);
}
#else /* NUM_API */
#ifdef CONFIG_CHAN_NUM_API
static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
struct dfs_channel *chan_list,
uint32_t *num_chan)
{
struct dfs_channel *tmp_chan_list = NULL;
struct wlan_dfs *dfs;
bool is_curchan_5g;
bool is_curchan_24g;
bool is_curchan_49g;
uint32_t chan_num;
uint32_t center_freq;
uint16_t flagext;
int i, j = 0;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return;
}
tmp_chan_list = qdf_mem_malloc(*num_chan * sizeof(*tmp_chan_list));
if (!tmp_chan_list)
return;
utils_dfs_get_chan_list(pdev, (void *)tmp_chan_list, num_chan);
chan_num = dfs->dfs_curchan->dfs_ch_ieee;
center_freq = dfs->dfs_curchan->dfs_ch_freq;
is_curchan_5g = WLAN_REG_IS_5GHZ_CH(chan_num);
is_curchan_24g = WLAN_REG_IS_24GHZ_CH(chan_num);
is_curchan_49g = WLAN_REG_IS_49GHZ_FREQ(center_freq);
for (i = 0; i < *num_chan; i++) {
chan_num = tmp_chan_list[i].dfs_ch_ieee;
center_freq = tmp_chan_list[i].dfs_ch_freq;
flagext = tmp_chan_list[i].dfs_ch_flagext;
if (!dfs_mlme_check_allowed_prim_chanlist(pdev, chan_num))
continue;
if ((is_curchan_5g) && WLAN_REG_IS_5GHZ_CH(chan_num)) {
chan_list[j].dfs_ch_ieee = chan_num;
chan_list[j].dfs_ch_freq = center_freq;
chan_list[j].dfs_ch_flagext = flagext;
j++;
} else if ((is_curchan_24g) &&
WLAN_REG_IS_24GHZ_CH(chan_num)) {
chan_list[j].dfs_ch_ieee = chan_num;
chan_list[j].dfs_ch_freq = center_freq;
j++;
} else if ((is_curchan_49g) &&
WLAN_REG_IS_49GHZ_FREQ(center_freq)) {
chan_list[j].dfs_ch_ieee = chan_num;
chan_list[j].dfs_ch_freq = center_freq;
j++;
}
}
*num_chan = j;
qdf_mem_free(tmp_chan_list);
}
#endif
#endif
#else
void utils_dfs_get_nol_history_chan_list(struct wlan_objmgr_pdev *pdev,
void *clist, uint32_t *num_chan)
{
utils_dfs_get_chan_list(pdev, clist, num_chan);
}
static void utils_dfs_get_channel_list(struct wlan_objmgr_pdev *pdev,
struct wlan_objmgr_vdev *vdev,
struct dfs_channel *chan_list,
uint32_t *num_chan)
{
uint32_t pcl_ch[QDF_MAX_NUM_CHAN] = {0};
uint8_t weight_list[QDF_MAX_NUM_CHAN] = {0};
uint32_t len;
uint32_t weight_len;
int i;
struct wlan_objmgr_psoc *psoc;
uint32_t conn_count = 0;
enum policy_mgr_con_mode mode;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
*num_chan = 0;
dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
return;
}
len = QDF_ARRAY_SIZE(pcl_ch);
weight_len = QDF_ARRAY_SIZE(weight_list);
if (vdev)
mode = policy_mgr_convert_device_mode_to_qdf_type(
wlan_vdev_mlme_get_opmode(vdev));
else
mode = PM_SAP_MODE;
conn_count = policy_mgr_mode_specific_connection_count(
psoc, mode, NULL);
if (0 == conn_count)
policy_mgr_get_pcl(psoc, mode, pcl_ch,
&len, weight_list, weight_len);
else
policy_mgr_get_pcl_for_existing_conn(
psoc, mode, pcl_ch, &len, weight_list,
weight_len, true);
if (*num_chan < len) {
dfs_err(NULL, WLAN_DEBUG_DFS_ALWAYS,
"Invalid len src=%d, dst=%d",
*num_chan, len);
*num_chan = 0;
return;
}
for (i = 0; i < len; i++) {
chan_list[i].dfs_ch_ieee =
wlan_reg_freq_to_chan(pdev, pcl_ch[i]);
chan_list[i].dfs_ch_freq = pcl_ch[i];
}
*num_chan = i;
dfs_info(NULL, WLAN_DEBUG_DFS_ALWAYS, "num channels %d", i);
}
void utils_dfs_get_chan_list(struct wlan_objmgr_pdev *pdev,
void *clist, uint32_t *num_chan)
{
utils_dfs_get_channel_list(pdev, NULL, (struct dfs_channel *)clist,
num_chan);
}
#endif
#ifdef CONFIG_CHAN_NUM_API
QDF_STATUS utils_dfs_get_vdev_random_channel(
struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev,
uint16_t flags, struct ch_params *ch_params, uint32_t *hw_mode,
uint8_t *target_chan, struct dfs_acs_info *acs_info)
{
uint32_t dfs_reg;
uint32_t num_chan = NUM_CHANNELS;
struct wlan_dfs *dfs = NULL;
struct wlan_objmgr_psoc *psoc;
struct dfs_channel *chan_list = NULL;
struct dfs_channel cur_chan;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
*target_chan = 0;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
goto random_chan_error;
}
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
goto random_chan_error;
}
wlan_reg_get_dfs_region(pdev, &dfs_reg);
chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list));
if (!chan_list)
goto random_chan_error;
utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan);
if (!num_chan) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels");
goto random_chan_error;
}
cur_chan.dfs_ch_vhtop_ch_freq_seg1 = ch_params->center_freq_seg0;
cur_chan.dfs_ch_vhtop_ch_freq_seg2 = ch_params->center_freq_seg1;
if (!ch_params->ch_width)
utils_dfs_get_max_sup_width(pdev,
(uint8_t *)&ch_params->ch_width);
*target_chan = dfs_prepare_random_channel(dfs, chan_list,
num_chan, flags, (uint8_t *)&ch_params->ch_width,
&cur_chan, (uint8_t)dfs_reg, acs_info);
ch_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1;
ch_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2;
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"input width=%d", ch_params->ch_width);
if (*target_chan) {
wlan_reg_set_channel_params(pdev,
*target_chan, 0, ch_params);
utils_dfs_get_max_phy_mode(pdev, hw_mode);
status = QDF_STATUS_SUCCESS;
}
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"ch=%d, seg0=%d, seg1=%d, width=%d",
*target_chan, ch_params->center_freq_seg0,
ch_params->center_freq_seg1, ch_params->ch_width);
random_chan_error:
qdf_mem_free(chan_list);
return status;
}
qdf_export_symbol(utils_dfs_get_vdev_random_channel);
#endif
#ifdef CONFIG_CHAN_FREQ_API
QDF_STATUS utils_dfs_get_vdev_random_channel_for_freq(
struct wlan_objmgr_pdev *pdev, struct wlan_objmgr_vdev *vdev,
uint16_t flags, struct ch_params *chan_params, uint32_t *hw_mode,
uint16_t *target_chan_freq, struct dfs_acs_info *acs_info)
{
uint32_t dfs_reg;
uint32_t num_chan = NUM_CHANNELS;
struct wlan_dfs *dfs = NULL;
struct wlan_objmgr_psoc *psoc;
struct dfs_channel *chan_list = NULL;
struct dfs_channel cur_chan;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
*target_chan_freq = 0;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
goto random_chan_error;
}
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
goto random_chan_error;
}
wlan_reg_get_dfs_region(pdev, &dfs_reg);
chan_list = qdf_mem_malloc(num_chan * sizeof(*chan_list));
if (!chan_list)
goto random_chan_error;
utils_dfs_get_channel_list(pdev, vdev, chan_list, &num_chan);
if (!num_chan) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "zero channels");
goto random_chan_error;
}
cur_chan.dfs_ch_vhtop_ch_freq_seg1 = chan_params->center_freq_seg0;
cur_chan.dfs_ch_vhtop_ch_freq_seg2 = chan_params->center_freq_seg1;
cur_chan.dfs_ch_mhz_freq_seg1 = chan_params->mhz_freq_seg0;
cur_chan.dfs_ch_mhz_freq_seg2 = chan_params->mhz_freq_seg1;
if (!chan_params->ch_width)
utils_dfs_get_max_sup_width(pdev,
(uint8_t *)&chan_params->ch_width);
*target_chan_freq = dfs_prepare_random_channel_for_freq(dfs, chan_list,
num_chan, flags, (uint8_t *)&chan_params->ch_width,
&cur_chan, (uint8_t)dfs_reg, acs_info);
chan_params->center_freq_seg0 = cur_chan.dfs_ch_vhtop_ch_freq_seg1;
chan_params->center_freq_seg1 = cur_chan.dfs_ch_vhtop_ch_freq_seg2;
chan_params->mhz_freq_seg0 = cur_chan.dfs_ch_mhz_freq_seg1;
chan_params->mhz_freq_seg1 = cur_chan.dfs_ch_mhz_freq_seg2;
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"input width=%d", chan_params->ch_width);
if (*target_chan_freq) {
wlan_reg_set_channel_params_for_freq(pdev, *target_chan_freq, 0,
chan_params);
utils_dfs_get_max_phy_mode(pdev, hw_mode);
status = QDF_STATUS_SUCCESS;
}
dfs_info(dfs, WLAN_DEBUG_DFS_RANDOM_CHAN,
"ch=%d, seg0=%d, seg1=%d, width=%d",
*target_chan_freq, chan_params->center_freq_seg0,
chan_params->center_freq_seg1, chan_params->ch_width);
random_chan_error:
qdf_mem_free(chan_list);
return status;
}
qdf_export_symbol(utils_dfs_get_vdev_random_channel_for_freq);
#endif
#ifdef CONFIG_CHAN_NUM_API
QDF_STATUS utils_dfs_get_random_channel(
struct wlan_objmgr_pdev *pdev,
uint16_t flags,
struct ch_params *ch_params,
uint32_t *hw_mode,
uint8_t *target_chan,
struct dfs_acs_info *acs_info)
{
return utils_dfs_get_vdev_random_channel(
pdev, NULL, flags, ch_params, hw_mode, target_chan,
acs_info);
}
qdf_export_symbol(utils_dfs_get_random_channel);
#endif
#ifdef CONFIG_CHAN_FREQ_API
QDF_STATUS utils_dfs_get_random_channel_for_freq(
struct wlan_objmgr_pdev *pdev,
uint16_t flags,
struct ch_params *ch_params,
uint32_t *hw_mode,
uint16_t *target_chan_freq,
struct dfs_acs_info *acs_info)
{
return utils_dfs_get_vdev_random_channel_for_freq(pdev, NULL, flags,
ch_params, hw_mode,
target_chan_freq,
acs_info);
}
qdf_export_symbol(utils_dfs_get_random_channel_for_freq);
#endif
#ifdef CONFIG_CHAN_NUM_API
QDF_STATUS utils_dfs_bw_reduced_channel(
struct wlan_objmgr_pdev *pdev,
struct ch_params *ch_params,
uint32_t *hw_mode,
uint8_t *target_chan)
{
struct wlan_dfs *dfs = NULL;
struct wlan_objmgr_psoc *psoc;
enum channel_state ch_state;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
*target_chan = 0;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
return status;
}
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return status;
}
ch_state = wlan_reg_get_channel_state(pdev,
dfs->dfs_curchan->dfs_ch_ieee);
if (ch_state == CHANNEL_STATE_DFS ||
ch_state == CHANNEL_STATE_ENABLE) {
ch_params->center_freq_seg0 =
dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg1;
ch_params->center_freq_seg1 =
dfs->dfs_curchan->dfs_ch_vhtop_ch_freq_seg2;
wlan_reg_set_channel_params(pdev,
dfs->dfs_curchan->dfs_ch_ieee,
0, ch_params);
*target_chan = dfs->dfs_curchan->dfs_ch_ieee;
utils_dfs_get_max_phy_mode(pdev, hw_mode);
return QDF_STATUS_SUCCESS;
}
return status;
}
qdf_export_symbol(utils_dfs_bw_reduced_channel);
#endif
#ifdef CONFIG_CHAN_FREQ_API
QDF_STATUS utils_dfs_bw_reduced_channel_for_freq(
struct wlan_objmgr_pdev *pdev,
struct ch_params *chan_params,
uint32_t *hw_mode,
uint16_t *target_chan_freq)
{
struct wlan_dfs *dfs = NULL;
struct wlan_objmgr_psoc *psoc;
enum channel_state ch_state;
QDF_STATUS status = QDF_STATUS_E_FAILURE;
struct dfs_channel *dfs_curchan;
*target_chan_freq = 0;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
return status;
}
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return status;
}
dfs_curchan = dfs->dfs_curchan;
ch_state =
wlan_reg_get_channel_state_for_freq(pdev,
dfs_curchan->dfs_ch_freq);
if (ch_state == CHANNEL_STATE_DFS ||
ch_state == CHANNEL_STATE_ENABLE) {
chan_params->mhz_freq_seg0 =
dfs_curchan->dfs_ch_mhz_freq_seg1;
chan_params->mhz_freq_seg1 =
dfs_curchan->dfs_ch_mhz_freq_seg2;
wlan_reg_set_channel_params_for_freq(pdev,
dfs_curchan->dfs_ch_freq,
0, chan_params);
*target_chan_freq = dfs_curchan->dfs_ch_freq;
utils_dfs_get_max_phy_mode(pdev, hw_mode);
return QDF_STATUS_SUCCESS;
}
return status;
}
qdf_export_symbol(utils_dfs_bw_reduced_channel_for_freq);
#endif
#ifdef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
void utils_dfs_init_nol(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
struct wlan_objmgr_psoc *psoc;
qdf_device_t qdf_dev;
struct dfs_nol_info *dfs_nolinfo;
int len;
dfs = wlan_pdev_get_dfs_obj(pdev);
psoc = wlan_pdev_get_psoc(pdev);
if (!dfs || !psoc) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
"dfs %pK, psoc %pK", dfs, psoc);
return;
}
qdf_dev = psoc->soc_objmgr.qdf_dev;
if (!qdf_dev->dev) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null device");
return;
}
dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo));
if (!dfs_nolinfo)
return;
qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo));
len = pld_wlan_get_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo,
(uint16_t)sizeof(*dfs_nolinfo));
if (len > 0) {
dfs_set_nol(dfs, dfs_nolinfo->dfs_nol, dfs_nolinfo->num_chans);
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "nol channels in pld");
DFS_PRINT_NOL_LOCKED(dfs);
} else {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "no nol in pld");
}
qdf_mem_free(dfs_nolinfo);
}
#endif
qdf_export_symbol(utils_dfs_init_nol);
#ifndef QCA_DFS_NOL_PLATFORM_DRV_SUPPORT
void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
{
}
#else
void utils_dfs_save_nol(struct wlan_objmgr_pdev *pdev)
{
struct dfs_nol_info *dfs_nolinfo;
struct wlan_dfs *dfs = NULL;
struct wlan_objmgr_psoc *psoc;
qdf_device_t qdf_dev;
int num_chans = 0;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null psoc");
return;
}
qdf_dev = psoc->soc_objmgr.qdf_dev;
if (!qdf_dev->dev) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null device");
return;
}
dfs_nolinfo = qdf_mem_malloc(sizeof(*dfs_nolinfo));
if (!dfs_nolinfo)
return;
qdf_mem_zero(dfs_nolinfo, sizeof(*dfs_nolinfo));
DFS_GET_NOL_LOCKED(dfs, dfs_nolinfo->dfs_nol, &num_chans);
if (num_chans > 0) {
if (num_chans > DFS_MAX_NOL_CHANNEL)
dfs_nolinfo->num_chans = DFS_MAX_NOL_CHANNEL;
else
dfs_nolinfo->num_chans = num_chans;
pld_wlan_set_dfs_nol(qdf_dev->dev, (void *)dfs_nolinfo,
(uint16_t)sizeof(*dfs_nolinfo));
}
qdf_mem_free(dfs_nolinfo);
}
#endif
qdf_export_symbol(utils_dfs_save_nol);
void utils_dfs_print_nol_channels(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs = NULL;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return;
}
DFS_PRINT_NOL_LOCKED(dfs);
}
qdf_export_symbol(utils_dfs_print_nol_channels);
void utils_dfs_clear_nol_channels(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs = NULL;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return;
}
/* First print list */
DFS_PRINT_NOL_LOCKED(dfs);
/* clear local cache first */
dfs_nol_timer_cleanup(dfs);
dfs_nol_update(dfs);
/*
* update platform driver nol list with local cache which is zero,
* cleared in above step, so this will clear list in platform driver.
*/
utils_dfs_save_nol(pdev);
}
qdf_export_symbol(utils_dfs_clear_nol_channels);
#ifdef CONFIG_CHAN_NUM_API
void utils_dfs_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev,
uint8_t *ch_list,
uint8_t num_ch,
bool nol_ch)
{
/* TODO : Need locking?*/
wlan_reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch);
}
qdf_export_symbol(utils_dfs_reg_update_nol_ch);
#endif
#ifdef CONFIG_CHAN_FREQ_API
void utils_dfs_reg_update_nol_chan_for_freq(struct wlan_objmgr_pdev *pdev,
uint16_t *freq_list,
uint8_t num_chan,
bool nol_chan)
{
wlan_reg_update_nol_ch_for_freq(pdev, freq_list, num_chan, nol_chan);
}
qdf_export_symbol(utils_dfs_reg_update_nol_chan_for_freq);
#endif
#ifdef CONFIG_CHAN_NUM_API
void utils_dfs_reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev,
uint8_t *ch_list,
uint8_t num_ch,
bool nol_history_ch)
{
wlan_reg_update_nol_history_ch(pdev, ch_list, num_ch, nol_history_ch);
}
#endif
#ifdef CONFIG_CHAN_FREQ_API
void
utils_dfs_reg_update_nol_history_chan_for_freq(struct wlan_objmgr_pdev *pdev,
uint16_t *freq_list,
uint8_t num_chan,
bool nol_history_chan)
{
wlan_reg_update_nol_history_ch_for_freq(pdev, freq_list, num_chan,
nol_history_chan);
}
#endif
uint8_t utils_dfs_freq_to_chan(uint32_t freq)
{
uint8_t chan;
if (freq == 0)
return 0;
if (freq > DFS_24_GHZ_BASE_FREQ && freq < DFS_CHAN_14_FREQ)
chan = ((freq - DFS_24_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ);
else if (freq == DFS_CHAN_14_FREQ)
chan = DFS_24_GHZ_CHANNEL_14;
else if ((freq > DFS_24_GHZ_BASE_FREQ) && (freq < DFS_5_GHZ_BASE_FREQ))
chan = (((freq - DFS_CHAN_15_FREQ) / DFS_CHAN_SPACING_20MHZ) +
DFS_24_GHZ_CHANNEL_15);
else
chan = (freq - DFS_5_GHZ_BASE_FREQ) / DFS_CHAN_SPACING_5MHZ;
return chan;
}
qdf_export_symbol(utils_dfs_freq_to_chan);
uint32_t utils_dfs_chan_to_freq(uint8_t chan)
{
if (chan == 0)
return 0;
if (chan < DFS_24_GHZ_CHANNEL_14)
return DFS_24_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
else if (chan == DFS_24_GHZ_CHANNEL_14)
return DFS_CHAN_14_FREQ;
else if (chan < DFS_24_GHZ_CHANNEL_27)
return DFS_CHAN_15_FREQ + ((chan - DFS_24_GHZ_CHANNEL_15) *
DFS_CHAN_SPACING_20MHZ);
else if (chan == DFS_5_GHZ_CHANNEL_170)
return DFS_CHAN_170_FREQ;
else
return DFS_5_GHZ_BASE_FREQ + (chan * DFS_CHAN_SPACING_5MHZ);
}
qdf_export_symbol(utils_dfs_chan_to_freq);
#ifdef QCA_MCL_DFS_SUPPORT
#ifdef CONFIG_CHAN_NUM_API
QDF_STATUS utils_dfs_mark_leaking_ch(struct wlan_objmgr_pdev *pdev,
enum phy_ch_width ch_width,
uint8_t temp_ch_lst_sz,
uint8_t *temp_ch_lst)
{
struct wlan_dfs *dfs = NULL;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return QDF_STATUS_E_FAILURE;
}
return dfs_mark_leaking_ch(dfs, ch_width, temp_ch_lst_sz, temp_ch_lst);
}
qdf_export_symbol(utils_dfs_mark_leaking_ch);
#endif
#ifdef CONFIG_CHAN_FREQ_API
QDF_STATUS utils_dfs_mark_leaking_chan_for_freq(struct wlan_objmgr_pdev *pdev,
enum phy_ch_width ch_width,
uint8_t temp_chan_lst_sz,
uint16_t *temp_freq_lst)
{
struct wlan_dfs *dfs = NULL;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "null dfs");
return QDF_STATUS_E_FAILURE;
}
return dfs_mark_leaking_chan_for_freq(dfs, ch_width, temp_chan_lst_sz,
temp_freq_lst);
}
qdf_export_symbol(utils_dfs_mark_leaking_chan_for_freq);
#endif
#endif
int utils_get_dfsdomain(struct wlan_objmgr_pdev *pdev)
{
enum dfs_reg dfsdomain;
wlan_reg_get_dfs_region(pdev, &dfsdomain);
return dfsdomain;
}
uint16_t utils_dfs_get_cur_rd(struct wlan_objmgr_pdev *pdev)
{
struct cur_regdmn_info cur_regdmn;
wlan_reg_get_curr_regdomain(pdev, &cur_regdmn);
return cur_regdmn.regdmn_pair_id;
}
#if defined(WLAN_DFS_PARTIAL_OFFLOAD) && defined(HOST_DFS_SPOOF_TEST)
QDF_STATUS utils_dfs_is_spoof_check_failed(struct wlan_objmgr_pdev *pdev,
bool *is_spoof_check_failed)
{
struct wlan_dfs *dfs;
if (!tgt_dfs_is_pdev_5ghz(pdev))
return QDF_STATUS_SUCCESS;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null");
return QDF_STATUS_E_FAILURE;
}
*is_spoof_check_failed = dfs->dfs_spoof_check_failed;
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_is_spoof_check_failed);
#endif
int dfs_get_num_chans(void)
{
return NUM_CHANNELS;
}
#if defined(WLAN_DFS_FULL_OFFLOAD) && defined(QCA_DFS_NOL_OFFLOAD)
QDF_STATUS utils_dfs_get_disable_radar_marking(struct wlan_objmgr_pdev *pdev,
bool *disable_radar_marking)
{
struct wlan_dfs *dfs;
if (!tgt_dfs_is_pdev_5ghz(pdev))
return QDF_STATUS_SUCCESS;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null");
return QDF_STATUS_E_FAILURE;
}
*disable_radar_marking = dfs_get_disable_radar_marking(dfs);
return QDF_STATUS_SUCCESS;
}
qdf_export_symbol(utils_dfs_get_disable_radar_marking);
bool utils_is_dfs_cfreq2_ch(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs)
return false;
return WLAN_IS_CHAN_DFS_CFREQ2(dfs->dfs_curchan);
}
qdf_export_symbol(utils_is_dfs_cfreq2_ch);
#endif
void utils_dfs_deliver_event(struct wlan_objmgr_pdev *pdev, uint16_t freq,
enum WLAN_DFS_EVENTS event)
{
if (global_dfs_to_mlme.mlme_dfs_deliver_event)
global_dfs_to_mlme.mlme_dfs_deliver_event(pdev, freq, event);
}
void utils_dfs_reset_dfs_prevchan(struct wlan_objmgr_pdev *pdev)
{
struct wlan_dfs *dfs;
if (!tgt_dfs_is_pdev_5ghz(pdev))
return;
dfs = wlan_pdev_get_dfs_obj(pdev);
if (!dfs) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "dfs is null");
return;
}
dfs_reset_dfs_prevchan(dfs);
}