From 4a09f081deccbf3495df6a8479e28586b79b952f Mon Sep 17 00:00:00 2001 From: Abhishek Chaudhary Date: Mon, 23 Sep 2019 23:04:11 +0530 Subject: [PATCH] [RAMEN9610-20880]wlbt: Driver changes for VTS Q Support for Auto Channel Selection Auto Channel Selection driver changes for "WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY" Change-Id: Ib53209068b432ae4c37914d9ee4a413816eebdd5 SCSC-Bug-Id: HOST-10725 Signed-off-by: Abhishek Chaudhary --- drivers/net/wireless/scsc/mgt.c | 28 ++++++-- drivers/net/wireless/scsc/nl80211_vendor.c | 9 ++- drivers/net/wireless/scsc/nl80211_vendor.h | 6 +- drivers/net/wireless/scsc/rx.c | 83 +++++++++++++++++++++- include/scsc/scsc_release.h | 2 +- 5 files changed, 113 insertions(+), 15 deletions(-) diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c index 8a7032e06d57..8f3c6eb346db 100755 --- a/drivers/net/wireless/scsc/mgt.c +++ b/drivers/net/wireless/scsc/mgt.c @@ -6061,19 +6061,33 @@ int slsi_find_chan_idx(u16 chan, u8 hw_mode) { int idx = 0, i = 0; u16 slsi_5ghz_channels_list[25] = {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112, 116, 120, 124, 128, 132, - 136, 140, 144, 149, 153, 157, 161, 165}; + 136, 140, 144, 149, 153, 157, 161, 165}; if (hw_mode == SLSI_ACS_MODE_IEEE80211B || hw_mode == SLSI_ACS_MODE_IEEE80211G) { idx = chan - 1; return idx; - } - for (i = 0; i < 25; i++) { - if (chan == slsi_5ghz_channels_list[i]) { - idx = i; - break; + } else if (hw_mode == SLSI_ACS_MODE_IEEE80211A) { + for (i = 0; i < MAX_5G_CHANNELS; i++) { + if (chan == slsi_5ghz_channels_list[i]) { + idx = i; + break; + } + } + return idx; + } else { + if (chan <=MAX_24G_CHANNELS) { + idx = chan -1; + return idx; + } else { + for (i = 0; i < MAX_5G_CHANNELS; i++) { + if (chan == slsi_5ghz_channels_list[i]) { + idx = i; + break; + } + } + return (idx + MAX_24G_CHANNELS); } } - return idx; } #ifdef CONFIG_SCSC_WLAN_SET_NUM_ANTENNAS diff --git a/drivers/net/wireless/scsc/nl80211_vendor.c b/drivers/net/wireless/scsc/nl80211_vendor.c index 0b3301cb3c31..2e6658d61b62 100755 --- a/drivers/net/wireless/scsc/nl80211_vendor.c +++ b/drivers/net/wireless/scsc/nl80211_vendor.c @@ -4384,7 +4384,7 @@ exit: static int slsi_acs_validate_width_hw_mode(struct slsi_acs_request *request) { if (request->hw_mode != SLSI_ACS_MODE_IEEE80211A && request->hw_mode != SLSI_ACS_MODE_IEEE80211B && - request->hw_mode != SLSI_ACS_MODE_IEEE80211G) + request->hw_mode != SLSI_ACS_MODE_IEEE80211G && request->hw_mode != SLSI_ACS_MODE_IEEE80211ANY) return -EINVAL; if (request->ch_width != 20 && request->ch_width != 40 && request->ch_width != 80) return -EINVAL; @@ -4527,9 +4527,12 @@ static int slsi_acs_init(struct wiphy *wiphy, } if (request->hw_mode == SLSI_ACS_MODE_IEEE80211A) - request->ch_list_len = 25; + request->ch_list_len = MAX_5G_CHANNELS; + else if (request->hw_mode == SLSI_ACS_MODE_IEEE80211B || request->hw_mode == SLSI_ACS_MODE_IEEE80211G) + request->ch_list_len = MAX_24G_CHANNELS; else - request->ch_list_len = 14; + request->ch_list_len = MAX_CHAN_VALUE_ACS; + memcpy(&request->acs_chan_info[0], &ch_info[0], sizeof(ch_info)); ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request = request; ndev_vif->scan[SLSI_SCAN_HW_ID].is_blocking_scan = false; diff --git a/drivers/net/wireless/scsc/nl80211_vendor.h b/drivers/net/wireless/scsc/nl80211_vendor.h index 759294c11358..b33464f6a9c7 100755 --- a/drivers/net/wireless/scsc/nl80211_vendor.h +++ b/drivers/net/wireless/scsc/nl80211_vendor.h @@ -956,7 +956,11 @@ struct slsi_rtt_config { u16 LCR_request; /* 1: request LCR, 0: do not request LCR */ }; -#define MAX_CHAN_VALUE_ACS 25 /*Max number of supported channel is 25*/ +#define MAX_CHAN_VALUE_ACS 39 /*Max number of supported channel is 39*/ +#define MAX_24G_CHANNELS 14 /*Max number of 2.4G channels*/ +#define MAX_5G_CHANNELS 25 /*Max number of 5G channels*/ +#define MAX_AP_THRESHOLD 10 /*Max AP threshold in ACS*/ + struct slsi_acs_chan_info { u16 chan; diff --git a/drivers/net/wireless/scsc/rx.c b/drivers/net/wireless/scsc/rx.c index 59be452a291e..43d5b1fc0ead 100755 --- a/drivers/net/wireless/scsc/rx.c +++ b/drivers/net/wireless/scsc/rx.c @@ -629,7 +629,7 @@ int slsi_set_2g_auto_channel(struct slsi_dev *sdev, struct netdev_vif *ndev_vif int min_avg_chan_utilization_20 = INT_MAX, min_adjacent_rssi_20 = INT_MAX; int ch_idx_min_load_20 = 0, ch_idx_min_rssi_20 = 0; int ret = 0; - int ch_list_len = ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->ch_list_len; + int ch_list_len = MAX_24G_CHANNELS; acs_selected_channels->ch_width = ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->ch_width; acs_selected_channels->hw_mode = ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->hw_mode; @@ -757,7 +757,7 @@ int slsi_set_5g_auto_channel(struct slsi_dev *sdev, struct netdev_vif *ndev_vif int min_avg_chan_utilization_20 = INT_MAX, min_num_ap_20 = INT_MAX; int ch_idx_min_load_20 = 0, ch_idx_min_ap_20 = 0; int ret = 0; - int ch_list_len = ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->ch_list_len; + int ch_list_len = MAX_5G_CHANNELS; acs_selected_channels->ch_width = ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->ch_width; acs_selected_channels->hw_mode = ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->hw_mode; @@ -870,6 +870,81 @@ int slsi_set_5g_auto_channel(struct slsi_dev *sdev, struct netdev_vif *ndev_vif return ret; } +int slsi_set_band_any_auto_channel(struct slsi_dev *sdev, struct netdev_vif *ndev_vif, + struct slsi_acs_selected_channels *acs_selected_channels, + struct slsi_acs_chan_info *ch_info) +{ + struct slsi_acs_chan_info ch_info_2g[MAX_24G_CHANNELS]; + struct slsi_acs_chan_info ch_info_5g[MAX_5G_CHANNELS]; + struct slsi_acs_selected_channels acs_selected_channels_5g; + struct slsi_acs_selected_channels acs_selected_channels_2g; + int Best_channel_5g = -1; + int Best_channel_5g_num_ap = 0; + int Best_channel_2g = -1; + int Best_channel_2g_num_ap = 0; + int i, ret = 0; + int j = 0; + + memset(&acs_selected_channels_5g, 0, sizeof(acs_selected_channels_5g)); + memset(&acs_selected_channels_2g, 0, sizeof(acs_selected_channels_2g)); + memset(&ch_info_5g, 0, sizeof(ch_info_5g)); + memset(&ch_info_2g, 0, sizeof(ch_info_2g)); + + for(i = MAX_24G_CHANNELS; i < MAX_CHAN_VALUE_ACS; i++) { + ch_info_5g[j] = ch_info[i]; + j++; + } + ret = slsi_set_5g_auto_channel(sdev, ndev_vif, &acs_selected_channels_5g, ch_info_5g); + + if(ret == 0) { + Best_channel_5g = acs_selected_channels_5g.pri_channel; + for(i = 0; i < MAX_5G_CHANNELS; i++) { + if (ch_info_5g[i].chan == Best_channel_5g) { + Best_channel_5g_num_ap = ch_info_5g[i].num_ap; + break; + } + } + SLSI_DBG3(sdev, SLSI_MLME, "Best 5G channel = %d, num_ap = %d\n", Best_channel_5g, + Best_channel_5g_num_ap); + + if (Best_channel_5g_num_ap < MAX_AP_THRESHOLD) { + *acs_selected_channels = acs_selected_channels_5g; + return ret; + } + } + + SLSI_DBG3(sdev, SLSI_MLME, "5G AP threshold exceed, trying to select from 2G band\n"); + + for(i =0; i < MAX_24G_CHANNELS; i++) { + ch_info_2g[i] = ch_info[i]; + } + ret = slsi_set_2g_auto_channel(sdev, ndev_vif, &acs_selected_channels_2g, ch_info_2g); + + if(ret == 0) { + Best_channel_2g = acs_selected_channels_2g.pri_channel; + for(i =0; i < MAX_24G_CHANNELS; i++) { + if (ch_info_2g[i].chan == Best_channel_2g) { + Best_channel_2g_num_ap = ch_info_2g[i].num_ap; + break; + } + } + SLSI_DBG3(sdev, SLSI_MLME, "Best 2G channel = %d, num_ap = %d\n", Best_channel_2g, + Best_channel_2g_num_ap); + if (Best_channel_5g == -1) { + *acs_selected_channels = acs_selected_channels_2g; + return ret; + } else { + /* Based on min no of APs selecting channel from that band */ + /* If no. of APs are equal, selecting the 5G channel */ + if(Best_channel_5g_num_ap > Best_channel_2g_num_ap) + *acs_selected_channels = acs_selected_channels_2g; + else + *acs_selected_channels = acs_selected_channels_5g; + } + } + return ret; +} + int slsi_acs_get_rssi_factor(struct slsi_dev *sdev, int rssi, int ch_util) { int frac_pow_val[10] = {10, 12, 15, 19, 25, 31, 39, 50, 63, 79}; @@ -932,7 +1007,7 @@ struct slsi_acs_chan_info *slsi_acs_scan_results(struct slsi_dev *sdev, struct n idx = slsi_find_chan_idx(scan_channel->hw_value, ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->hw_mode); SLSI_DBG3(sdev, SLSI_MLME, "chan_idx:%d chan_value: %d\n", idx, ch_info[idx].chan); - if ((idx < 0) || (idx > 24)) { + if ((idx < 0) || (idx == MAX_CHAN_VALUE_ACS)) { SLSI_DBG3(sdev, SLSI_MLME, "idx is not in range idx=%d\n", idx); goto next_scan; } @@ -980,6 +1055,8 @@ void slsi_acs_scan_complete(struct slsi_dev *sdev, struct netdev_vif *ndev_vif, else if (ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->hw_mode == SLSI_ACS_MODE_IEEE80211B || ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->hw_mode == SLSI_ACS_MODE_IEEE80211G) r = slsi_set_2g_auto_channel(sdev, ndev_vif, &acs_selected_channels, ch_info); + else if (ndev_vif->scan[SLSI_SCAN_HW_ID].acs_request->hw_mode == SLSI_ACS_MODE_IEEE80211ANY) + r = slsi_set_band_any_auto_channel(sdev, ndev_vif, &acs_selected_channels, ch_info); else r = -EINVAL; if (!r) { diff --git a/include/scsc/scsc_release.h b/include/scsc/scsc_release.h index 64324dc81287..05e1b4c19aa9 100644 --- a/include/scsc/scsc_release.h +++ b/include/scsc/scsc_release.h @@ -23,7 +23,7 @@ #define SCSC_RELEASE_ITERATION 6 #define SCSC_RELEASE_CANDIDATE 1 -#define SCSC_RELEASE_POINT 3 +#define SCSC_RELEASE_POINT 4 #endif -- 2.20.1