diff options
author | Thomson Kang <thomson.kang@broadcom.corp-partner.google.com> | 2023-07-27 21:51:37 +0900 |
---|---|---|
committer | Isaac Chiou <isaacchiou@google.com> | 2023-08-14 03:08:19 +0000 |
commit | 66376a2fe0bfa55c10ebaa8f76e512a797c3aad0 (patch) | |
tree | 1b78b87827713776d54a139429d2ad086c3e95b4 | |
parent | faee739d4f060efde08fe191bb36f63932687fb9 (diff) | |
download | bcm4389-66376a2fe0bfa55c10ebaa8f76e512a797c3aad0.tar.gz |
bcmdhd: Added to check overlap channel's channel info for avoiding restrict condition to overlap channel.
[Issue]
Did not removed 165/40 and 165/80 ch for avail channel list in wl_cellavoid_verify_avail_chan_list.
When checking the comment for the comment, wl_cellavoid_verify_avail_chan_list function made purpose for removing the channel.
/* This function is used verifying channel items
* created by wl_cellavoid_alloc_avail_chan_list are valid
* by comparing the channel item to chan_info_list from FW
* If it does not match with chan_info_list, drop
* CH165 only support 20MHz BW, so 165/40, 165/80 chanspecs created by
* wl_cellavoid_alloc_avail_chan_list_band are dropped by this function
*/
But did not removed 165/40 and 165/80 caused by this channels was not CLM restrict.
panther:/ # wl chan_info_list
1 (0x1001)2G Band
...snip...
165l (0xd8a7)5G Band
169u (0xd9a7)5G Band, CLM Restrict
..snip..
165/80 (0xe0ab)5G Band
169/80 (0xe1ab)5G Band, CLM Restrict
So could select 165/80 channel when detecting lte coex channel.
In this case request to switch 165/80 channel, but failed the CSA command caused by not support the channel in softap.
[Fix]
Check channel info of the overlap channel.
And if the channel was the restrict channel, then removed the channel in avail list.
Bug: 281906332
Test: Tested done for P22.
Change-Id: I51a5c0c529407feb6b147bdd5ff1e13aa47330e3
Signed-off-by: Thomson Kang <thomson.kang@broadcom.corp-partner.google.com>
-rwxr-xr-x | wl_cfg_cellavoid.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/wl_cfg_cellavoid.c b/wl_cfg_cellavoid.c index 1d59abe..85188c4 100755 --- a/wl_cfg_cellavoid.c +++ b/wl_cfg_cellavoid.c @@ -880,6 +880,8 @@ free_list: return BCME_NOMEM; } +#define MAX_20MHZ_CHANNELS 16u + /* This function is used verifying channel items * created by wl_cellavoid_alloc_avail_chan_list are valid * by comparing the channel item to chan_info_list from FW @@ -895,10 +897,13 @@ wl_cellavoid_verify_avail_chan_list(struct bcm_cfg80211 *cfg, wl_cellavoid_info_ void *dngl_chan_list; bool legacy_chan_info = FALSE; bool found; - int i, err; + int i, j, k, err; chanspec_t chanspec = 0; char chanspec_str[CHANSPEC_STR_LEN]; uint32 restrict_chan, chaninfo; + u32 arr_idx = 0, band; + u8 chan_array[MAX_20MHZ_CHANNELS] = {0}; + wl_chanspec_attr_v1_t overlap[MAX_20MHZ_CHANNELS]; /* Get chan_info_list or chanspec from FW */ #define LOCAL_BUF_LEN 4096 @@ -937,6 +942,10 @@ wl_cellavoid_verify_avail_chan_list(struct bcm_cfg80211 *cfg, wl_cellavoid_info_ GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST(); list_for_each_entry_safe(chan_info, next, &cellavoid_info->avail_chan_info_list, list) { GCC_DIAGNOSTIC_POP(); + wf_get_all_ext(chan_info->chanspec, chan_array); + bzero(overlap, sizeof(overlap)); + band = CHSPEC_BAND(chan_info->chanspec); + arr_idx = 0; found = FALSE; for (i = 0; i < dtoh32(list_count); i++) { if (legacy_chan_info) { @@ -949,9 +958,40 @@ wl_cellavoid_verify_avail_chan_list(struct bcm_cfg80211 *cfg, wl_cellavoid_info_ chaninfo = dtoh32 (((wl_chanspec_list_v1_t *)dngl_chan_list)->chspecs[i].chaninfo); + + /* Store chanspec attribute of subbands channel. */ + if ((CHSPEC_BAND(chanspec) == band) && + (CHSPEC_BW(chanspec) == WL_CHANSPEC_BW_20)) { + for (j = 0; j < MAX_20MHZ_CHANNELS; j++) { + if (!chan_array[j]) { + /* if entry is empty, break */ + break; + } + if (chan_array[j] == CHSPEC_CHANNEL(chanspec)) { + overlap[arr_idx].chanspec = chanspec; + overlap[arr_idx].chaninfo = chaninfo; + WL_DBG(("sel_chspec:%x overlap_chspec:%x\n", + chan_info->chanspec, + overlap[arr_idx].chanspec)); + arr_idx++; + break; + } + } + } + restrict_chan = ((chaninfo & WL_CHAN_RADAR) || (chaninfo & WL_CHAN_PASSIVE) || (chaninfo & WL_CHAN_CLM_RESTRICTED)); + + if (chan_info->chanspec == chanspec) { + for (k = 0; k < arr_idx; k++) { + restrict_chan |= + ((overlap[k].chaninfo & WL_CHAN_RADAR) || + (overlap[k].chaninfo & WL_CHAN_PASSIVE) || + (overlap[k].chaninfo & + WL_CHAN_CLM_RESTRICTED)); + } + } } if ((!restrict_chan) && (chan_info->chanspec == chanspec)) { |