Merge "qca-wifi: Add support for 160MHz precac tree"

This commit is contained in:
Linux Build Service Account
2020-03-24 05:53:44 -07:00
gecommit door Gerrit - the friendly Code Review server
bovenliggende ff323f757d a5540082df
commit 0bc90ed6d4

Bestand weergeven

@@ -488,8 +488,9 @@ static bool dfs_find_cac_status_for_chan(struct dfs_precac_entry *precac_entry,
* Return true if CAC done, else false.
* @dfs_precac_entry: Precac entry which has the root of the precac BSTree.
* @chan_freq: IEEE channel freq. This is the center of a
* 20/40/80 MHz channel and the center channel is unique
* irrespective of the bandwidth(20/40/80 MHz).
* 20/40/80/160/165 MHz channel and the center channel is
* unique irrespective of the bandwidth
* (20/40/80/160/165 MHz).
*/
#ifdef CONFIG_CHAN_FREQ_API
static bool
@@ -497,7 +498,7 @@ dfs_find_cac_status_for_chan_for_freq(struct dfs_precac_entry *precac_entry,
uint16_t chan_freq)
{
struct precac_tree_node *node = precac_entry->tree_root;
uint8_t n_cur_lvl_subchs = N_SUBCHANS_FOR_80BW;
uint8_t n_cur_lvl_subchs = N_SUBCHANS_FOR_160BW;
while (node) {
if (node->ch_freq == chan_freq)
@@ -517,6 +518,12 @@ dfs_find_cac_status_for_chan_for_freq(struct dfs_precac_entry *precac_entry,
#ifdef CONFIG_CHAN_FREQ_API
#define VHT80_FREQ_OFFSET 30
/* For any 160MHz channel, a frequency offset of 70MHz would have been enough
* to include the right edge and left edge channels. But, the restricted 80P80
* or the 165MHz channel is also assumed to have a 160MHz root ie channel 146,
* so an offset of 75MHz is chosen.
*/
#define VHT160_FREQ_OFFSET 75
#endif
#define IS_WITHIN_RANGE(_A, _B, _C) \
@@ -1261,8 +1268,8 @@ void dfs_mark_precac_done_for_freq(struct wlan_dfs *dfs,
pe_list,
tmp_precac_entry) {
if (IS_WITHIN_RANGE(channels[i],
precac_entry->vht80_ch_freq,
VHT80_FREQ_OFFSET)) {
precac_entry->center_ch_freq,
VHT160_FREQ_OFFSET)) {
dfs_mark_tree_node_as_cac_done_for_freq
(dfs, precac_entry, channels[i]);
break;
@@ -1735,8 +1742,8 @@ void dfs_mark_precac_nol_for_freq(struct wlan_dfs *dfs,
pe_list,
tmp_precac_entry) {
if (IS_WITHIN_RANGE(freq_lst[i],
precac_entry->vht80_ch_freq,
VHT80_FREQ_OFFSET)) {
precac_entry->center_ch_freq,
VHT160_FREQ_OFFSET)) {
dfs_mark_tree_node_as_nol_for_freq(dfs,
precac_entry,
freq_lst[i]);
@@ -2158,10 +2165,20 @@ static os_timer_func(dfs_precac_timeout)
current_time / 1000);
if (dfs_soc_obj->ocac_status == OCAC_SUCCESS) {
dfs_soc_obj->ocac_status = OCAC_RESET;
dfs_mark_precac_done_for_freq(dfs,
dfs->dfs_agile_precac_freq_mhz,
0,
dfs->dfs_precac_chwidth);
if (dfs->dfs_agile_precac_freq_mhz ==
RESTRICTED_80P80_CHAN_CENTER_FREQ) {
dfs_mark_precac_done_for_freq(
dfs,
RESTRICTED_80P80_LEFT_80_CENTER_FREQ,
RESTRICTED_80P80_RIGHT_80_CENTER_FREQ,
CH_WIDTH_80P80MHZ);
} else {
dfs_mark_precac_done_for_freq(
dfs,
dfs->dfs_agile_precac_freq_mhz,
0,
dfs->dfs_precac_chwidth);
}
}
/* check if CAC done on home channel */
is_cac_done_on_des_chan = dfs_precac_check_home_chan_change(dfs);
@@ -2295,12 +2312,15 @@ static inline void dfs_init_precac_tree_node(struct precac_tree_node *node,
* @node: Precac_tree_node to be filled.
* @freq: IEEE channel freq value.
* @bandwidth: Bandwidth of the channel.
* @depth: Depth of the tree. The depth of the tree when the root is 160MHz
* channel is 4, 80MHz is 3, 40MHz is 2 and 20MHz is 1.
*/
#ifdef CONFIG_CHAN_FREQ_API
static inline void
dfs_init_precac_tree_node_for_freq(struct precac_tree_node *node,
uint16_t freq,
uint8_t bandwidth)
uint8_t bandwidth,
uint8_t depth)
{
node->left_child = NULL;
node->right_child = NULL;
@@ -2310,6 +2330,8 @@ dfs_init_precac_tree_node_for_freq(struct precac_tree_node *node,
node->n_nol_subchs = 0;
node->n_valid_subchs = N_SUBCHS_FOR_BANDWIDTH(bandwidth);
node->bandwidth = bandwidth;
node->depth = depth;
}
#endif
@@ -2364,6 +2386,8 @@ dfs_insert_node_into_bstree(struct precac_tree_node **root,
* @root: The preCAC BSTree root pointer.
* @chan: IEEE freq of the new node.
* @bandwidth: Bandwidth of the channel.
* @depth: Depth of the tree. The depth of the tree when the root is 160MHz
* channel is 4, 80MHz is 3, 40MHz is 2 and 20MHz is 1.
*
* Return: EOK if new node is allocated, else return ENOMEM.
*/
@@ -2371,7 +2395,8 @@ dfs_insert_node_into_bstree(struct precac_tree_node **root,
static QDF_STATUS
dfs_insert_node_into_bstree_for_freq(struct precac_tree_node **root,
uint16_t chan_freq,
uint8_t bandwidth)
uint8_t bandwidth,
uint8_t depth)
{
struct precac_tree_node *new_node = NULL;
struct precac_tree_node *curr_node, *prev_node = NULL;
@@ -2380,7 +2405,10 @@ dfs_insert_node_into_bstree_for_freq(struct precac_tree_node **root,
new_node = qdf_mem_malloc(sizeof(*new_node));
if (!new_node)
return -ENOMEM;
dfs_init_precac_tree_node_for_freq(new_node, chan_freq, bandwidth);
dfs_init_precac_tree_node_for_freq(new_node,
chan_freq,
bandwidth,
depth);
/* If root node is null, assign the newly allocated node
* to this node and return.
@@ -2439,13 +2467,13 @@ dfs_create_precac_tree(struct wlan_dfs *dfs,
struct precac_tree_node *root = NULL;
int chan, i, bandwidth = DFS_CHWIDTH_80_VAL;
QDF_STATUS status = EOK;
static const int initial_and_next_offsets[TREE_DEPTH][N_OFFSETS] = {
static const int initial_and_next_offsets[TREE_DEPTH_MAX][N_OFFSETS] = {
{INITIAL_80_CHAN_OFFSET, NEXT_80_CHAN_OFFSET},
{INITIAL_40_CHAN_OFFSET, NEXT_40_CHAN_OFFSET},
{INITIAL_20_CHAN_OFFSET, NEXT_20_CHAN_OFFSET}
};
for (i = 0; i < TREE_DEPTH; i++) {
for (i = 0; i < TREE_DEPTH_MAX; i++) {
/* In offset array,
* column 0 is initial chan offset,
* column 1 is next chan offset.
@@ -2473,89 +2501,208 @@ dfs_create_precac_tree(struct wlan_dfs *dfs,
}
#endif
/* dfs_create_precac_tree_for_freq() - Fill precac entry tree (level insertion).
* @dfs: WLAN DFS structure
* @ch_freq: root_node freq.
*/
#ifdef CONFIG_CHAN_FREQ_API
static QDF_STATUS
dfs_create_precac_tree_for_freq(struct wlan_dfs *dfs,
struct dfs_precac_entry *precac_entry,
uint16_t ch_freq)
{
struct precac_tree_node *root = NULL;
int chan_freq, i, bandwidth = DFS_CHWIDTH_80_VAL;
QDF_STATUS status = EOK;
static const int initial_and_next_offsets[TREE_DEPTH][N_OFFSETS] = {
/**
* struct precac_tree_offset_for_different_bw - Bandwidth, tree depth and
* channel offsets information to build the precac tree.
* @bandwidth: Bandwidth of the the root node.
* @tree_depth: Tree depth of the precac tree.
* @initial_and_next_offsets: Offset to root node to find the initial and the
* next channels of the node.
*/
struct precac_tree_offset_for_different_bw {
int bandwidth;
int tree_depth;
int initial_and_next_offsets[TREE_DEPTH_MAX][N_OFFSETS];
};
static const
struct precac_tree_offset_for_different_bw offset20 = {DFS_CHWIDTH_20_VAL,
TREE_DEPTH_20,
{
{0, NEXT_20_CHAN_FREQ_OFFSET}
}
};
static const
struct precac_tree_offset_for_different_bw offset40 = {DFS_CHWIDTH_40_VAL,
TREE_DEPTH_40,
{
{0, NEXT_40_CHAN_FREQ_OFFSET},
{-10, NEXT_20_CHAN_FREQ_OFFSET}
}
};
static const
struct precac_tree_offset_for_different_bw offset80 = {DFS_CHWIDTH_80_VAL,
TREE_DEPTH_80,
{
{0, NEXT_80_CHAN_FREQ_OFFSET},
{-20, NEXT_40_CHAN_FREQ_OFFSET},
{-30, NEXT_20_CHAN_FREQ_OFFSET}
}
};
static const
struct precac_tree_offset_for_different_bw offset160 = {DFS_CHWIDTH_160_VAL,
TREE_DEPTH_160,
{
{INITIAL_160_CHAN_FREQ_OFFSET, NEXT_160_CHAN_FREQ_OFFSET},
{INITIAL_80_CHAN_FREQ_OFFSET, NEXT_80_CHAN_FREQ_OFFSET},
{INITIAL_40_CHAN_FREQ_OFFSET, NEXT_40_CHAN_FREQ_OFFSET},
{INITIAL_20_CHAN_FREQ_OFFSET, NEXT_20_CHAN_FREQ_OFFSET}
};
}
};
for (i = 0; i < TREE_DEPTH; i++) {
static const
struct precac_tree_offset_for_different_bw default_offset = {0, 0};
/* dfs_create_precac_tree_for_freq() - Fill precac entry tree (level insertion).
* @dfs: WLAN DFS structure
* @ch_freq: root_node freq.
* @root: Pointer to the node that will be filled and inserted as tree
* root.
* @bandwidth: Bandwidth value of the root.
*/
static QDF_STATUS
dfs_create_precac_tree_for_freq(struct wlan_dfs *dfs,
uint16_t ch_freq,
struct precac_tree_node **root,
int bandwidth)
{
int chan_freq, i;
QDF_STATUS status = EOK;
struct precac_tree_offset_for_different_bw current_mode;
uint8_t top_lvl_step;
bool is_node_part_of_165_tree = false;
if (ch_freq == RESTRICTED_80P80_LEFT_80_CENTER_FREQ ||
ch_freq == RESTRICTED_80P80_RIGHT_80_CENTER_FREQ)
is_node_part_of_165_tree = true;
switch (bandwidth) {
case DFS_CHWIDTH_160_VAL:
current_mode = offset160;
break;
case DFS_CHWIDTH_80_VAL:
current_mode = offset80;
break;
case DFS_CHWIDTH_40_VAL:
current_mode = offset40;
break;
case DFS_CHWIDTH_20_VAL:
current_mode = offset20;
break;
default:
current_mode = default_offset;
break;
}
top_lvl_step = current_mode.initial_and_next_offsets[0][1];
for (i = 0; i < current_mode.tree_depth; i++) {
/* In offset array,
* column 0 is initial chan offset,
* column 1 is next chan offset.
* Boundary offset is initial offset and next offset
* of root level (since root level can have only 1 node)
*/
int offset = initial_and_next_offsets[i][START_INDEX];
int step = initial_and_next_offsets[i][STEP_INDEX];
uint8_t top_lvl_step = NEXT_80_CHAN_FREQ_OFFSET;
int offset =
current_mode.initial_and_next_offsets[i][START_INDEX];
int step = current_mode.initial_and_next_offsets[i][STEP_INDEX];
int boundary_offset = offset + top_lvl_step;
uint8_t depth = is_node_part_of_165_tree ? i + 1 : i;
for (; offset < boundary_offset; offset += step) {
chan_freq = (int)ch_freq + offset;
status =
dfs_insert_node_into_bstree_for_freq(&root,
dfs_insert_node_into_bstree_for_freq(root,
chan_freq,
bandwidth);
bandwidth,
depth);
if (status)
return status;
}
bandwidth /= 2;
}
precac_entry->tree_root = root;
return status;
}
#endif
/*
* dfs_init_precac_list() - Initialize preCAC lists.
* @dfs: Pointer to wlan_dfs.
*/
#ifdef CONFIG_CHAN_FREQ_API
void dfs_init_precac_list(struct wlan_dfs *dfs)
/**
* struct dfs_channel_bw - Structure to store the information about precac
* root's primary channel frequency, maximum bandwidth and the center frequency.
*
* @dfs_pri_ch_freq: Primary channel frequency of the root channel.
* @dfs_center_ch_freq: Center frequency of the 20/40/80/160 channel.In case of
* the 165MHz channel, it is 5730MHz.
* @dfs_max_bw: Maximum bandwidth of the channel available in the
* current channel list.
*/
struct dfs_channel_bw {
uint16_t dfs_pri_ch_freq;
uint16_t dfs_center_ch_freq;
uint16_t dfs_max_bw;
};
static void
dfs_calculate_bw_for_same_pri_ch(struct wlan_dfs *dfs,
struct dfs_channel_bw *dfs_max_bw_info,
int index,
struct dfs_channel *ichan,
int *delimiter)
{
u_int i;
uint8_t found;
struct dfs_precac_entry *tmp_precac_entry;
int nchans = 0;
QDF_STATUS status;
uint8_t temp_bw = 0;
/* Right now, only ETSI domain supports preCAC. Check if current
* DFS domain is ETSI and only then build the preCAC list.
*/
if (utils_get_dfsdomain(dfs->dfs_pdev_obj) != DFS_ETSI_DOMAIN)
return;
dfs_max_bw_info[index].dfs_pri_ch_freq = ichan->dfs_ch_freq;
dfs_max_bw_info[index].dfs_center_ch_freq = ichan->dfs_ch_mhz_freq_seg1;
if (WLAN_IS_CHAN_MODE_20(ichan)) {
temp_bw = DFS_CHWIDTH_20_VAL;
} else if (WLAN_IS_CHAN_MODE_40(ichan)) {
temp_bw = DFS_CHWIDTH_40_VAL;
} else if (WLAN_IS_CHAN_MODE_80(ichan) ||
WLAN_IS_CHAN_MODE_80_80(ichan)) {
temp_bw = DFS_CHWIDTH_80_VAL;
if (dfs_is_restricted_80p80mhz_supported(dfs) &&
WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(ichan) &&
(ichan->dfs_ch_vhtop_ch_freq_seg1 ==
RESTRICTED_80P80_LEFT_80_CENTER_CHAN) &&
(ichan->dfs_ch_vhtop_ch_freq_seg2 ==
RESTRICTED_80P80_RIGHT_80_CENTER_CHAN)) {
temp_bw = DFS_CHWIDTH_165_VAL;
dfs_max_bw_info[index].dfs_center_ch_freq =
RESTRICTED_80P80_CHAN_CENTER_FREQ;
}
} else if (WLAN_IS_CHAN_MODE_160(ichan)) {
temp_bw = DFS_CHWIDTH_160_VAL;
dfs_max_bw_info[index].dfs_center_ch_freq =
ichan->dfs_ch_mhz_freq_seg2;
}
if (temp_bw > dfs_max_bw_info[index].dfs_max_bw)
dfs_max_bw_info[index].dfs_max_bw = temp_bw;
*delimiter = dfs_max_bw_info[index].dfs_pri_ch_freq +
dfs_max_bw_info[index].dfs_max_bw;
}
/* dfs_fill_max_bw_for_chan() - Finds unique precac tree node in the channel
* list and stores the primary channel frequency, maximum bandwidth and the
* center frequency. The algorithm is based on the data structure ic_channels
* where the channels are organized as 36HT20, 36HT40, 36HT80,... and so on..
* @dfs: WLAN DFS structure
* @dfs_max_bw_info: Structure to store precac tree root channel's
* information.
* @num_precac_roots: Number of unique.
*/
static void dfs_fill_max_bw_for_chan(struct wlan_dfs *dfs,
struct dfs_channel_bw *dfs_max_bw_info,
int *num_precac_roots)
{
int nchans = 0, i, j = 0, prev_ch_freq = 0, delimiter = 0;
/*
* We need to prepare list of uniq VHT80 center frequencies. But at the
* beginning we do not know how many uniq frequencies are present.
* Therefore, we calculate the MAX size and allocate a temporary
* list/array. However we fill the temporary array with uniq frequencies
* and copy the uniq list of frequencies to the final list with exact
* size.
*/
TAILQ_INIT(&dfs->dfs_precac_list);
dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans);
PRECAC_LIST_LOCK(dfs);
/* Fill the precac_list with unique elements */
for (i = 0; i < nchans; i++) {
struct dfs_channel *ichan = NULL, lc;
uint16_t pri_chan_cfreq = 0;
ichan = &lc;
dfs_mlme_get_dfs_channels_for_freq
@@ -2569,60 +2716,242 @@ void dfs_init_precac_list(struct wlan_dfs *dfs)
&ichan->dfs_ch_mhz_freq_seg1,
&ichan->dfs_ch_mhz_freq_seg2,
i);
pri_chan_cfreq = ichan->dfs_ch_mhz_freq_seg1;
if (!WLAN_IS_PRIMARY_OR_SECONDARY_CHAN_DFS(ichan))
continue;
if (ichan->dfs_ch_freq == prev_ch_freq) {
dfs_calculate_bw_for_same_pri_ch(dfs,
dfs_max_bw_info,
j,
ichan,
&delimiter);
} else if (ichan->dfs_ch_freq < delimiter) {
continue;
} else {
prev_ch_freq = ichan->dfs_ch_freq;
j++;
}
}
*num_precac_roots = j + 1;
}
if (WLAN_IS_CHAN_11AC_VHT80(ichan) &&
WLAN_IS_CHAN_DFS(ichan)) {
found = 0;
TAILQ_FOREACH(tmp_precac_entry,
&dfs->dfs_precac_list,
pe_list) {
if (tmp_precac_entry->vht80_ch_freq ==
pri_chan_cfreq) {
found = 1;
break;
}
static QDF_STATUS
dfs_precac_create_precac_entry(struct wlan_dfs *dfs,
struct dfs_precac_entry *precac_entry,
struct dfs_channel_bw *dfs_max_bw_info,
int index)
{
QDF_STATUS status;
uint16_t precac_center_freq =
dfs_max_bw_info[index].dfs_center_ch_freq;
precac_entry->center_ch_freq = precac_center_freq;
precac_entry->center_ch_ieee =
utils_dfs_freq_to_chan(precac_center_freq);
precac_entry->bw = dfs_max_bw_info[index].dfs_max_bw;
precac_entry->dfs = dfs;
status =
dfs_create_precac_tree_for_freq(dfs,
precac_entry->center_ch_freq,
&precac_entry->tree_root,
precac_entry->bw);
if (status) {
dfs_debug(dfs, WLAN_DEBUG_DFS,
"PreCAC entry for channel %d not created",
precac_entry->center_ch_ieee);
} else {
TAILQ_INSERT_TAIL(
&dfs->dfs_precac_list,
precac_entry, pe_list);
}
return status;
}
static QDF_STATUS
dfs_precac_create_165mhz_precac_entry(struct wlan_dfs *dfs,
struct dfs_precac_entry *precac_entry)
{
QDF_STATUS status;
precac_entry->center_ch_freq =
RESTRICTED_80P80_CHAN_CENTER_FREQ;
precac_entry->center_ch_ieee =
utils_dfs_freq_to_chan(precac_entry->center_ch_freq);
precac_entry->bw = DFS_CHWIDTH_160_VAL;
precac_entry->dfs = dfs;
dfs_insert_node_into_bstree_for_freq(&precac_entry->tree_root,
RESTRICTED_80P80_CHAN_CENTER_FREQ,
DFS_CHWIDTH_160_VAL,
DEPTH_160_ROOT);
status =
dfs_create_precac_tree_for_freq
(dfs,
RESTRICTED_80P80_LEFT_80_CENTER_FREQ,
&precac_entry->tree_root->left_child,
DFS_CHWIDTH_80_VAL);
if (!status)
status =
dfs_create_precac_tree_for_freq(
dfs,
RESTRICTED_80P80_RIGHT_80_CENTER_FREQ,
&precac_entry->tree_root->right_child,
DFS_CHWIDTH_80_VAL);
TAILQ_INSERT_TAIL(
&dfs->dfs_precac_list,
precac_entry, pe_list);
return status;
}
static void
dfs_mark_non_dfs_as_precac_done(struct wlan_dfs *dfs,
uint16_t dfs_pri_ch_freq,
enum wlan_phymode mode)
{
struct dfs_channel *ichan, lc;
ichan = &lc;
dfs_mlme_find_dot11_chan_for_freq(dfs->dfs_pdev_obj,
dfs_pri_ch_freq,
0,
mode,
&ichan->dfs_ch_freq,
&ichan->dfs_ch_flags,
&ichan->dfs_ch_flagext,
&ichan->dfs_ch_ieee,
&ichan->dfs_ch_vhtop_ch_freq_seg1,
&ichan->dfs_ch_vhtop_ch_freq_seg2,
&ichan->dfs_ch_mhz_freq_seg1,
&ichan->dfs_ch_mhz_freq_seg2);
if (!WLAN_IS_CHAN_DFS(ichan)) {
PRECAC_LIST_UNLOCK(dfs);
dfs_mark_precac_done_for_freq(dfs,
ichan->dfs_ch_mhz_freq_seg1,
0,
CH_WIDTH_80MHZ);
PRECAC_LIST_LOCK(dfs);
} else if (!WLAN_IS_CHAN_DFS_CFREQ2(ichan)) {
PRECAC_LIST_UNLOCK(dfs);
dfs_mark_precac_done_for_freq(dfs,
ichan->dfs_ch_mhz_freq_seg2,
0,
CH_WIDTH_80MHZ);
PRECAC_LIST_LOCK(dfs);
}
}
/*
* dfs_init_precac_list() - Initialize preCAC lists.
* @dfs: Pointer to wlan_dfs.
*/
void dfs_init_precac_list(struct wlan_dfs *dfs)
{
u_int i;
uint8_t found;
struct dfs_precac_entry *tmp_precac_entry;
int nchans = 0;
QDF_STATUS status;
struct dfs_channel_bw *dfs_max_bw_info;
int num_precac_roots;
/* Right now, only ETSI domain supports preCAC. Check if current
* DFS domain is ETSI and only then build the preCAC list.
*/
if (utils_get_dfsdomain(dfs->dfs_pdev_obj) != DFS_ETSI_DOMAIN)
return;
/*
* We need to prepare list of uniquee center frequencies of maximum
* possible bandwidths. But at the beginning we do not know how many
* unique frequencies are present. Therefore, we calculate the MAX size
* and allocate a temporary list/array. However we fill the temporary
* array with unique frequencies and copy the unique list of frequencies
* to the final list with exact size.
*/
dfs_mlme_get_dfs_ch_nchans(dfs->dfs_pdev_obj, &nchans);
dfs_max_bw_info = qdf_mem_malloc(nchans *
sizeof(struct dfs_channel_bw));
if (!dfs_max_bw_info) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
"memory allocation failed");
return;
}
dfs_fill_max_bw_for_chan(dfs, dfs_max_bw_info, &num_precac_roots);
TAILQ_INIT(&dfs->dfs_precac_list);
PRECAC_LIST_LOCK(dfs);
for (i = 0; i < num_precac_roots; i++) {
uint16_t pri_chan_cfreq = dfs_max_bw_info[i].dfs_center_ch_freq;
found = 0;
TAILQ_FOREACH(tmp_precac_entry,
&dfs->dfs_precac_list,
pe_list) {
if (tmp_precac_entry->center_ch_freq ==
pri_chan_cfreq) {
found = 1;
break;
}
if (!found && pri_chan_cfreq) {
struct dfs_precac_entry *precac_entry;
}
if (!found && pri_chan_cfreq) {
struct dfs_precac_entry *precac_entry;
precac_entry =
qdf_mem_malloc(sizeof(*precac_entry));
if (!precac_entry) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
"entry alloc fail for : %d", i);
continue;
}
precac_entry->vht80_ch_freq =
pri_chan_cfreq;
precac_entry->vht80_ch_ieee =
utils_dfs_freq_to_chan(pri_chan_cfreq);
precac_entry->dfs = dfs;
status =
dfs_create_precac_tree_for_freq
(dfs, precac_entry, pri_chan_cfreq);
precac_entry =
qdf_mem_malloc(sizeof(*precac_entry));
if (!precac_entry) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
"entry alloc fail for : %d", i);
continue;
}
if (dfs_max_bw_info[i].dfs_max_bw ==
DFS_CHWIDTH_165_VAL) {
status = dfs_precac_create_165mhz_precac_entry(
dfs,
precac_entry);
if (status) {
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS,
"tree_node alloc failed");
dfs_debug(dfs,
WLAN_DEBUG_DFS,
"PreCAC entry for channel 146 not created");
continue;
}
TAILQ_INSERT_TAIL(
&dfs->dfs_precac_list,
precac_entry, pe_list);
/* The restricted 80p80 or the 165MHz channel might
* have a non DFS part with center frequency 5775.
* Mark the non DFS portion as precac done.
*/
dfs_mark_non_dfs_as_precac_done(
dfs,
dfs_max_bw_info[i].dfs_pri_ch_freq,
WLAN_PHYMODE_11AC_VHT80_80);
} else {
status =
dfs_precac_create_precac_entry(dfs,
precac_entry,
dfs_max_bw_info,
i);
if (status)
continue;
/* Some channels like 36HT160 might have a non DFS
* part. Mark the non DFS portion as precac done.
*/
dfs_mark_non_dfs_as_precac_done(
dfs,
dfs_max_bw_info[i].dfs_pri_ch_freq,
WLAN_PHYMODE_11AC_VHT160);
}
}
}
PRECAC_LIST_UNLOCK(dfs);
qdf_mem_free(dfs_max_bw_info);
dfs_debug(dfs, WLAN_DEBUG_DFS,
"Print the list of VHT80 frequencies from linked list");
"Print the list of PreCAC ieee chan from linked list");
TAILQ_FOREACH(tmp_precac_entry,
&dfs->dfs_precac_list,
pe_list) {
uint8_t ch_ieee;
uint8_t ch_ieee, bw;
ch_ieee = utils_dfs_freq_to_chan(tmp_precac_entry->vht80_ch_freq);
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ieee=%u", ch_ieee);
ch_ieee = utils_dfs_freq_to_chan(tmp_precac_entry->center_ch_freq);
bw = tmp_precac_entry->bw;
dfs_info(dfs, WLAN_DEBUG_DFS_ALWAYS, "ieee=%u bw=%u", ch_ieee, bw);
}
}
#else
@@ -3663,7 +3992,7 @@ void dfs_start_precac_timer_for_freq(struct wlan_dfs *dfs,
* based on the level (and by our logic, bandwidth) of the current node.
*
*/
#define MAX_PREFIX_CHAR 20
#define MAX_PREFIX_CHAR 28
/*Retaining IEEE to print node data */
static void dfs_print_node_data(struct wlan_dfs *dfs,
struct precac_tree_node *node)
@@ -3672,17 +4001,25 @@ static void dfs_print_node_data(struct wlan_dfs *dfs,
char prev_line_prefix[MAX_PREFIX_CHAR] = "";
char inv[4] = "inv";
switch (node->bandwidth) {
case DFS_CHWIDTH_80_VAL:
switch (node->depth) {
case DEPTH_160_ROOT:
break;
case DFS_CHWIDTH_40_VAL:
case DEPTH_80_ROOT:
qdf_str_lcopy(prev_line_prefix, "|", MAX_PREFIX_CHAR);
qdf_str_lcopy(prefix, "|------- ", MAX_PREFIX_CHAR);
break;
case DFS_CHWIDTH_20_VAL:
case DEPTH_40_ROOT:
qdf_str_lcopy(prev_line_prefix, "| |", MAX_PREFIX_CHAR);
qdf_str_lcopy(prefix, "| |------- ", MAX_PREFIX_CHAR);
break;
case DEPTH_20_ROOT:
qdf_str_lcopy(prev_line_prefix,
"| | |",
MAX_PREFIX_CHAR);
qdf_str_lcopy(prefix,
"| | |------- ",
MAX_PREFIX_CHAR);
break;
default:
return;
}
@@ -4243,8 +4580,12 @@ dfs_find_agile_width(struct wlan_dfs *dfs, enum phy_ch_width chwidth)
case CH_WIDTH_40MHZ:
return CH_WIDTH_40MHZ;
case CH_WIDTH_80MHZ:
return CH_WIDTH_80MHZ;
case CH_WIDTH_80P80MHZ:
case CH_WIDTH_160MHZ:
if (dfs_is_true_160mhz_supported(dfs) ||
dfs_is_restricted_80p80mhz_supported(dfs))
return CH_WIDTH_160MHZ;
return CH_WIDTH_80MHZ;
default:
dfs_err(dfs, WLAN_DEBUG_DFS_ALWAYS, "Invalid chwidth enum!");
@@ -4360,6 +4701,13 @@ void dfs_get_ieeechan_for_agilecac_for_freq(struct wlan_dfs *dfs,
else
dfs->dfs_agile_precac_freq_mhz = 0;
/* It was assumed that the bandwidth of the restricted 80p80 channel is
* 160MHz to build the precac tree. But when configuring Agile the
* channel width should be given as 80p80.
*/
if (ieee_chan_freq == RESTRICTED_80P80_CHAN_CENTER_FREQ)
dfs->dfs_precac_chwidth = CH_WIDTH_80P80MHZ;
*ch_freq = dfs->dfs_agile_precac_freq_mhz;
}
#endif