summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Jeon <dennis.jeon@broadcom.corp-partner.google.com>2022-06-28 19:37:34 +0900
committerTreeHugger Robot <treehugger-gerrit@google.com>2022-08-08 08:02:48 +0000
commit2963b8469d7a2ca440dd7bbb1f2f5686bf09d3c0 (patch)
tree4fc0211f2a0d5ae589160d441b74d976846e94d1
parentc547d31ebcbc249a466dad735ce538ac5eb11c91 (diff)
downloadbcm4389-android-gs-bluejay-5.10-android13-qpr1-beta.tar.gz
bcmdhd: Fixed to filter out SOFTAP flag from 5G channels when STA is connected DFSandroid-t-qpr1-beta-1_r0.4android-gs-bluejay-5.10-android13-qpr1-beta
[Issues] 1. The expectation is that the getUsableChannelsI should filter 5G channels when STA is connected to DFS 5G and operational mode is Soft AP. But, getAvailableChannelFreqsForBand returns didn't apply the filter with concurrency limitation. 2. API returns that MCC channels of the band to which the STA is connected are available as SOFTAP ex) returns that MCC channels(Ch40,Ch44, ..) are available when STA connected to Ch36 [Solution] Added to check if STA is connected DFS channel. if so, SOFTAP flag will be filtered out in 5G channels. and fixed to be returned correct SOFTAP concurrency regarding wl_handle_acs_concurrency_cases(). Bug: 236333332 Test: halutil command Signed-off-by: Dennis Jeon <dennis.jeon@broadcom.corp-partner.google.com> Change-Id: I9252c544ad12bada5579553478d809512a753d39
-rw-r--r--wl_cfg80211.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/wl_cfg80211.c b/wl_cfg80211.c
index b34236d..96112d4 100644
--- a/wl_cfg80211.c
+++ b/wl_cfg80211.c
@@ -25248,21 +25248,33 @@ int wl_check_exist_freq_in_list(usable_channel_t *channels, int cur_idx, u32 fre
void wl_usable_channels_filter(struct bcm_cfg80211 *cfg, uint32 cur_chspec, uint32 *mask,
usable_channel_info_t *u_info, uint32 *conn,
- chanspec_t sta_chspec)
+ chanspec_t sta_chspec, uint32 sta_chaninfo)
{
#ifdef WL_CELLULAR_CHAN_AVOID
wifi_interface_mode mode;
#endif /* WL_CELLULAR_CHAN_AVOID */
drv_acs_params_t param = { 0 };
int ret;
- uint32 cur_band;
+ uint32 cur_band, sta_band;
uint32 filter = 0;
- bool filter_softap = true;
+ bool restrict_chan = false;
/* If there is STA connection on 5GHz DFS channel,
* none of the 5GHz channels are usable for SoftAP
*/
if (u_info->filter_mask & WIFI_USABLE_CHANNEL_FILTER_CONCURRENCY) {
+ sta_band = CHSPEC_TO_WLC_BAND(CHSPEC_BAND(sta_chspec));
+ cur_band = CHSPEC_TO_WLC_BAND(CHSPEC_BAND(cur_chspec));
+ restrict_chan = ((sta_chaninfo & WL_CHAN_RADAR) ||
+ (sta_chaninfo & WL_CHAN_PASSIVE)||
+ (sta_chaninfo & WL_CHAN_CLM_RESTRICTED));
+
+ /* Filter out SOFTAP when STA connected DFS channel */
+ if (sta_band == WLC_BAND_5G && restrict_chan) {
+ if (cur_band == WLC_BAND_5G) {
+ filter |= (1U << WIFI_INTERFACE_SOFTAP);
+ }
+ }
/* Filter out P2P_GO, P2P_CLIENT and NAN under condition */
if (conn[WL_IF_TYPE_STA] && conn[WL_IF_TYPE_AP]) {
@@ -25270,7 +25282,6 @@ void wl_usable_channels_filter(struct bcm_cfg80211 *cfg, uint32 cur_chspec, uint
filter |= ((1U << WIFI_INTERFACE_P2P_GO) |
(1U << WIFI_INTERFACE_P2P_CLIENT) |
(1U << WIFI_INTERFACE_NAN));
- filter_softap = false;
} else if (conn[WL_IF_TYPE_STA] && conn[WL_IF_TYPE_P2P_GO]) {
/* STA + GO */
filter |= ((1U << WIFI_INTERFACE_P2P_CLIENT) |
@@ -25293,8 +25304,7 @@ void wl_usable_channels_filter(struct bcm_cfg80211 *cfg, uint32 cur_chspec, uint
/* Filter out SOFTAP under condition */
/* Check whether the cur_chspec is available for SOFTAP (include scc case) */
- cur_band = CHSPEC_TO_WLC_BAND(CHSPEC_BAND(cur_chspec));
- if (!filter_softap) {
+ if (!(filter & (1U << WIFI_INTERFACE_SOFTAP))) {
param.freq_bands |= cur_band;
ret = wl_handle_acs_concurrency_cases(cfg, &param, 1, &cur_chspec);
@@ -25302,6 +25312,23 @@ void wl_usable_channels_filter(struct bcm_cfg80211 *cfg, uint32 cur_chspec, uint
WL_DBG(("Clear SOFAP bit chspec:%x ret:%d freq_bands(%d)\n",
cur_chspec, ret, param.freq_bands));
filter |= (1U << WIFI_INTERFACE_SOFTAP);
+ } else {
+ /* the function could returns TRUE even if the requested chspec is
+ * not unavailable due to DHD_ACS_CHECK_SCC_2G_ACTIVE_CH feature.
+ * scc_chspec can be zero when STA doesn't exist
+ * or band is not matched.
+ * here, we just interested in requested chspec.
+ * so, should check the requested chspec
+ * and selected chspec are the same
+ */
+ if (param.scc_chspec != 0 &&
+ (wf_chspec_primary20_chan(cur_chspec) !=
+ wf_chspec_primary20_chan(param.scc_chspec))) {
+ WL_DBG(("Clear SOFTAP bit chspec:"
+ "%x p_chspec:%x p_band:%x\n",
+ cur_chspec, param.scc_chspec, param.freq_bands));
+ filter |= (1U << WIFI_INTERFACE_SOFTAP);
+ }
}
}
@@ -25320,6 +25347,7 @@ void wl_usable_channels_filter(struct bcm_cfg80211 *cfg, uint32 cur_chspec, uint
}
}
+ /* Only interfaces queried from upper layer are left. */
*mask &= ~(filter);
}
@@ -25396,7 +25424,7 @@ int wl_get_usable_channels(struct bcm_cfg80211 *cfg, usable_channel_info_t *u_in
u32 mask = 0;
uint32 channel;
uint32 freq, width;
- uint32 chspec, chaninfo;
+ uint32 chspec, chaninfo, sta_chaninfo = 0;
u16 list_count;
int found_idx = BCME_NOTFOUND;
bool ch_160mhz_5g;
@@ -25406,7 +25434,7 @@ int wl_get_usable_channels(struct bcm_cfg80211 *cfg, usable_channel_info_t *u_in
#endif /* WL_SOFTAP_6G */
uint32 conn[WL_IF_TYPE_MAX] = {0};
struct net_device *p2p_ndev = NULL;
- chanspec_t sta_chanspec;
+ chanspec_t sta_chanspec = 0;
uint32 sta_assoc_freq = 0;
bool is_unii4 = false;
#ifdef WL_NAN_INSTANT_MODE
@@ -25467,6 +25495,11 @@ int wl_get_usable_channels(struct bcm_cfg80211 *cfg, usable_channel_info_t *u_in
freq = wl_channel_to_frequency(channel, band);
width = wl_chanspec_to_host_bw_map(chspec);
+ if (sta_chanspec == chspec) {
+ sta_chaninfo = chaninfo;
+ WL_DBG(("Found STA chspec in chan_list sta_chanspec:%x\n", sta_chanspec));
+ }
+
WL_DBG(("chspec:%x channel:%u chaninfo:%x freq:%u band:%u "
"req_band:%u req_iface_mode:%u filter:%u\n",
chspec, channel, chaninfo, freq, CHSPEC_TO_WLC_BAND(band),
@@ -25574,6 +25607,7 @@ int wl_get_usable_channels(struct bcm_cfg80211 *cfg, usable_channel_info_t *u_in
if (found_idx != BCME_NOTFOUND) {
if (width > u_info->channels[found_idx].width) {
u_info->channels[found_idx].width = width;
+ u_info->channels[found_idx].chspec = chspec;
}
continue;
}
@@ -25624,7 +25658,7 @@ int wl_get_usable_channels(struct bcm_cfg80211 *cfg, usable_channel_info_t *u_in
for (i = 0; i < u_info->size; i++) {
cur_ch = &u_info->channels[i];
wl_usable_channels_filter(cfg, cur_ch->chspec, &cur_ch->iface_mode_mask,
- u_info, conn, sta_chanspec);
+ u_info, conn, sta_chanspec, sta_chaninfo);
}
}