wlbt: Driver changes for VTS Q Support for Auto Channel Selection
authorAbhishek Chaudhary <ab.chaudhary@samsung.com>
Mon, 23 Sep 2019 17:34:11 +0000 (23:04 +0530)
committerYue Sun <sunyue5@lenovo.com>
Mon, 11 Nov 2019 04:20:34 +0000 (22:20 -0600)
Auto Channel Selection driver changes for
"WPA_DRIVER_FLAGS_SUPPORT_HW_MODE_ANY"

SCSC-Bug-Id: HOST-10725
Moto-CRs-Fixed: (CR)

Change-Id: Ib53209068b432ae4c37914d9ee4a413816eebdd5
Signed-off-by: Abhishek Chaudhary <ab.chaudhary@samsung.com>
Reviewed-on: https://gerrit.mot.com/1452201
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Hua Tan <tanhua1@motorola.com>
Submit-Approved: Jira Key

drivers/net/wireless/scsc/mgt.c
drivers/net/wireless/scsc/nl80211_vendor.c
drivers/net/wireless/scsc/nl80211_vendor.h
drivers/net/wireless/scsc/rx.c

index 1f3fa05ec4f45669d55f3883083d92a9f21e11b0..9cf0906c906a96602a27afccddca5d6d6dff1096 100755 (executable)
@@ -6107,19 +6107,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
index acce94d1f19a979b62cab4f2a09fc473ed328f01..27d62b7cd4ddcf815672c255536bd75a0251c1e0 100755 (executable)
@@ -4391,7 +4391,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;
@@ -4536,9 +4536,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;
index 759294c113582043d3c3d719ec750da2e4ac76aa..b33464f6a9c706d690f2018ca991cb9ac1d13ad9 100755 (executable)
@@ -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;
index 3051d07176c21a8317dcfef29f0c5cfd417b0d91..5f32c6c184dcf824a3945961b9433f24fd1ba20f 100755 (executable)
@@ -760,7 +760,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;
@@ -873,6 +873,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};
@@ -935,7 +1010,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;
                }
@@ -983,6 +1058,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) {