|
@@ -36,18 +36,6 @@
|
|
|
#include <wlan_dfs_utils_api.h>
|
|
|
#include <wlan_scan_cfg.h>
|
|
|
|
|
|
-/* Beacon/probe weightage multiplier */
|
|
|
-#define BCN_PROBE_WEIGHTAGE 5
|
|
|
-
|
|
|
-/* Saved profile weightage multiplier */
|
|
|
-#define SAVED_PROFILE_WEIGHTAGE 10
|
|
|
-
|
|
|
-/* maximum number of 6ghz hints can be sent per scan request */
|
|
|
-#define MAX_HINTS_PER_SCAN_REQ 15
|
|
|
-
|
|
|
-/* maximum number of hints can be sent per 6ghz channel */
|
|
|
-#define MAX_HINTS_PER_CHANNEL 4
|
|
|
-
|
|
|
QDF_STATUS
|
|
|
scm_scan_free_scan_request_mem(struct scan_start_request *req)
|
|
|
{
|
|
@@ -865,259 +853,6 @@ static inline void scm_scan_chlist_concurrency_modify(
|
|
|
}
|
|
|
#endif
|
|
|
|
|
|
-#ifdef CONFIG_BAND_6GHZ
|
|
|
-static void
|
|
|
-scm_update_6ghz_channel_list(struct wlan_objmgr_vdev *vdev,
|
|
|
- struct chan_list *chan_list,
|
|
|
- struct wlan_scan_obj *scan_obj)
|
|
|
-{
|
|
|
- uint8_t i;
|
|
|
- struct regulatory_channel *chan_list_6g;
|
|
|
- bool psc_channel_found = false;
|
|
|
- bool channel_6g_found = false;
|
|
|
- uint8_t num_scan_channels = 0, channel_count;
|
|
|
- struct wlan_objmgr_pdev *pdev;
|
|
|
- uint32_t freq;
|
|
|
-
|
|
|
- pdev = wlan_vdev_get_pdev(vdev);
|
|
|
- if (!pdev)
|
|
|
- return;
|
|
|
-
|
|
|
- scm_debug("6g scan mode %d", scan_obj->scan_def.scan_mode_6g);
|
|
|
- for (i = 0; i < chan_list->num_chan; i++) {
|
|
|
- freq = chan_list->chan[i].freq;
|
|
|
- if ((scan_obj->scan_def.scan_mode_6g ==
|
|
|
- SCAN_MODE_6G_NO_CHANNEL) &&
|
|
|
- (wlan_reg_is_6ghz_chan_freq(freq))) {
|
|
|
- /* Drop the 6Ghz channels */
|
|
|
- continue;
|
|
|
- } else if ((scan_obj->scan_def.scan_mode_6g ==
|
|
|
- SCAN_MODE_6G_PSC_CHANNEL) &&
|
|
|
- (wlan_reg_is_6ghz_chan_freq(freq))) {
|
|
|
- /* Allow only PSC channels */
|
|
|
- if (wlan_reg_is_6ghz_psc_chan_freq(freq))
|
|
|
- psc_channel_found = true;
|
|
|
- else
|
|
|
- continue;
|
|
|
- } else if ((scan_obj->scan_def.scan_mode_6g ==
|
|
|
- SCAN_MODE_6G_ALL_CHANNEL) &&
|
|
|
- (wlan_reg_is_6ghz_chan_freq(freq))) {
|
|
|
- /* Allow any 6ghz channel */
|
|
|
- channel_6g_found = true;
|
|
|
- }
|
|
|
- chan_list->chan[num_scan_channels++] =
|
|
|
- chan_list->chan[i];
|
|
|
- }
|
|
|
-
|
|
|
- scm_debug("psc_channel_found %d channel_6g_found%d",
|
|
|
- psc_channel_found, channel_6g_found);
|
|
|
- if ((scan_obj->scan_def.scan_mode_6g == SCAN_MODE_6G_PSC_CHANNEL &&
|
|
|
- !psc_channel_found) ||
|
|
|
- (scan_obj->scan_def.scan_mode_6g == SCAN_MODE_6G_ALL_CHANNEL &&
|
|
|
- !channel_6g_found)) {
|
|
|
- chan_list_6g = qdf_mem_malloc(NUM_6GHZ_CHANNELS *
|
|
|
- sizeof(struct regulatory_channel));
|
|
|
- if (!chan_list_6g)
|
|
|
- goto end;
|
|
|
-
|
|
|
- /* Add the 6Ghz channels based on config*/
|
|
|
- channel_count = wlan_reg_get_band_channel_list(pdev,
|
|
|
- BIT(REG_BAND_6G),
|
|
|
- chan_list_6g);
|
|
|
- scm_debug("Number of 6G channels %d", channel_count);
|
|
|
- for (i = 0; i < channel_count; i++) {
|
|
|
- if ((scan_obj->scan_def.scan_mode_6g ==
|
|
|
- SCAN_MODE_6G_PSC_CHANNEL) &&
|
|
|
- (!psc_channel_found) &&
|
|
|
- wlan_reg_is_6ghz_psc_chan_freq(chan_list_6g[i].
|
|
|
- center_freq)) {
|
|
|
- chan_list->chan[num_scan_channels++].freq =
|
|
|
- chan_list_6g[i].center_freq;
|
|
|
- } else if ((scan_obj->scan_def.scan_mode_6g ==
|
|
|
- SCAN_MODE_6G_ALL_CHANNEL) &&
|
|
|
- (!channel_6g_found)) {
|
|
|
- chan_list->chan[num_scan_channels++].freq =
|
|
|
- chan_list_6g[i].center_freq;
|
|
|
- }
|
|
|
- }
|
|
|
- qdf_mem_free(chan_list_6g);
|
|
|
- }
|
|
|
-end:
|
|
|
- chan_list->num_chan = num_scan_channels;
|
|
|
-}
|
|
|
-#else
|
|
|
-static void
|
|
|
-scm_update_6ghz_channel_list(struct wlan_objmgr_vdev *vdev,
|
|
|
- struct chan_list *chan_list,
|
|
|
- struct wlan_scan_obj *scan_obj)
|
|
|
-{
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
-#ifdef FEATURE_6G_SCAN_CHAN_SORT_ALGO
|
|
|
-static void scm_sort_6ghz_channel_list(struct wlan_objmgr_vdev *vdev,
|
|
|
- struct chan_list *chan_list)
|
|
|
-{
|
|
|
- uint8_t i, j = 0, max, tmp_list_count;
|
|
|
- struct meta_rnr_channel *channel;
|
|
|
- struct chan_info temp_list[MAX_6GHZ_CHANNEL];
|
|
|
- struct rnr_chan_weight *rnr_chan_info, *temp;
|
|
|
- uint32_t weight;
|
|
|
- struct wlan_objmgr_psoc *psoc;
|
|
|
-
|
|
|
- rnr_chan_info = qdf_mem_malloc(sizeof(rnr_chan_info) * MAX_6GHZ_CHANNEL);
|
|
|
- if (!rnr_chan_info)
|
|
|
- return;
|
|
|
-
|
|
|
- for (i = 0; i < chan_list->num_chan; i++) {
|
|
|
- if (WLAN_REG_IS_6GHZ_CHAN_FREQ(chan_list->chan[i].freq))
|
|
|
- temp_list[j++].freq = chan_list->chan[i].freq;
|
|
|
- }
|
|
|
- tmp_list_count = j;
|
|
|
- scm_debug("Total 6ghz channels %d", tmp_list_count);
|
|
|
-
|
|
|
- /* No Need to sort if the 6ghz channels are less than one */
|
|
|
- if (tmp_list_count < 1) {
|
|
|
- qdf_mem_free(rnr_chan_info);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- psoc = wlan_vdev_get_psoc(vdev);
|
|
|
- if (!psoc) {
|
|
|
- scm_err("Psoc is NULL");
|
|
|
- qdf_mem_free(rnr_chan_info);
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- /* compute the weightage */
|
|
|
- for (i = 0, j = 0; i < tmp_list_count; i++) {
|
|
|
- channel = scm_get_chan_meta(psoc, temp_list[i].freq);
|
|
|
- if (!channel)
|
|
|
- continue;
|
|
|
- weight = channel->bss_beacon_probe_count * BCN_PROBE_WEIGHTAGE +
|
|
|
- channel->saved_profile_count * SAVED_PROFILE_WEIGHTAGE;
|
|
|
- rnr_chan_info[j].weight = weight;
|
|
|
- rnr_chan_info[j].chan_freq = temp_list[i].freq;
|
|
|
- j++;
|
|
|
- scm_debug("Freq %d weight %d bcn_cnt %d", temp_list[i].freq,
|
|
|
- weight, channel->bss_beacon_probe_count);
|
|
|
- }
|
|
|
-
|
|
|
- /* Sort the channel using selection sort - descending order */
|
|
|
- for (i = 0; i < tmp_list_count - 1; i++) {
|
|
|
- max = i;
|
|
|
- for (j = i + 1; j < tmp_list_count; j++) {
|
|
|
- if (rnr_chan_info[j].weight >
|
|
|
- rnr_chan_info[max].weight)
|
|
|
- max = j;
|
|
|
- }
|
|
|
- if (max != i) {
|
|
|
- qdf_mem_copy(&temp, &rnr_chan_info[max],
|
|
|
- sizeof(*rnr_chan_info));
|
|
|
- qdf_mem_copy(&rnr_chan_info[max], &rnr_chan_info[i],
|
|
|
- sizeof(*rnr_chan_info));
|
|
|
- qdf_mem_copy(&rnr_chan_info[i], &temp,
|
|
|
- sizeof(*rnr_chan_info));
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /* update the 6g list based on the weightage */
|
|
|
- for (i = 0, j = 0; (i < NUM_CHANNELS && j < tmp_list_count); i++) {
|
|
|
- if (wlan_reg_is_6ghz_chan_freq(chan_list->chan[i].freq))
|
|
|
- chan_list->chan[i].freq = rnr_chan_info[j++].chan_freq;
|
|
|
- }
|
|
|
- qdf_mem_free(rnr_chan_info);
|
|
|
-}
|
|
|
-
|
|
|
-static void scm_update_rnr_info(struct wlan_objmgr_psoc *psoc,
|
|
|
- struct scan_start_request *req)
|
|
|
-{
|
|
|
- uint8_t i, num_bssid = 0, num_ssid = 0;
|
|
|
- uint8_t total_count = MAX_HINTS_PER_SCAN_REQ;
|
|
|
- uint32_t freq;
|
|
|
- struct meta_rnr_channel *chan;
|
|
|
- qdf_list_node_t *cur_node, *next_node = NULL;
|
|
|
- struct scan_rnr_node *rnr_node;
|
|
|
- struct chan_list *chan_list;
|
|
|
- QDF_STATUS status;
|
|
|
-
|
|
|
- if (!req)
|
|
|
- return;
|
|
|
-
|
|
|
- chan_list = &req->scan_req.chan_list;
|
|
|
- for (i = 0; i < chan_list->num_chan; i++) {
|
|
|
- freq = chan_list->chan[i].freq;
|
|
|
-
|
|
|
- chan = scm_get_chan_meta(psoc, freq);
|
|
|
- if (!chan || qdf_list_empty(&chan->rnr_list))
|
|
|
- continue;
|
|
|
-
|
|
|
- qdf_list_peek_front(&chan->rnr_list, &cur_node);
|
|
|
- while (cur_node && total_count) {
|
|
|
- rnr_node = qdf_container_of(cur_node,
|
|
|
- struct scan_rnr_node,
|
|
|
- node);
|
|
|
- if (!qdf_is_macaddr_zero(&rnr_node->entry.bssid) &&
|
|
|
- req->scan_req.num_hint_bssid <
|
|
|
- WLAN_SCAN_MAX_HINT_BSSID) {
|
|
|
- qdf_mem_copy(&req->scan_req.hint_bssid[num_bssid++].bssid,
|
|
|
- &rnr_node->entry.bssid,
|
|
|
- QDF_MAC_ADDR_SIZE);
|
|
|
- req->scan_req.num_hint_bssid++;
|
|
|
- total_count--;
|
|
|
- } else if (rnr_node->entry.short_ssid &&
|
|
|
- req->scan_req.num_hint_s_ssid <
|
|
|
- WLAN_SCAN_MAX_HINT_S_SSID) {
|
|
|
- req->scan_req.hint_s_ssid[num_ssid++].short_ssid =
|
|
|
- rnr_node->entry.short_ssid;
|
|
|
- req->scan_req.num_hint_s_ssid++;
|
|
|
- total_count--;
|
|
|
- }
|
|
|
- status = qdf_list_peek_next(&chan->rnr_list, cur_node,
|
|
|
- &next_node);
|
|
|
- if (QDF_IS_STATUS_ERROR(status))
|
|
|
- break;
|
|
|
- cur_node = next_node;
|
|
|
- next_node = NULL;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static void scm_add_rnr_info(struct wlan_objmgr_pdev *pdev,
|
|
|
- struct scan_start_request *req)
|
|
|
-{
|
|
|
- struct wlan_objmgr_psoc *psoc;
|
|
|
- struct channel_list_db *rnr_db;
|
|
|
-
|
|
|
- psoc = wlan_pdev_get_psoc(pdev);
|
|
|
- if (!psoc)
|
|
|
- return;
|
|
|
- rnr_db = scm_get_rnr_channel_db(psoc);
|
|
|
- if (!rnr_db)
|
|
|
- return;
|
|
|
-
|
|
|
- rnr_db->scan_count++;
|
|
|
- if (rnr_db->scan_count >= RNR_UPDATE_SCAN_CNT_THRESHOLD) {
|
|
|
- rnr_db->scan_count = 0;
|
|
|
- scm_rnr_db_flush(psoc);
|
|
|
- scm_update_rnr_from_scan_cache(pdev);
|
|
|
- }
|
|
|
-
|
|
|
- scm_update_rnr_info(psoc, req);
|
|
|
-}
|
|
|
-
|
|
|
-#else
|
|
|
-static void scm_sort_6ghz_channel_list(struct wlan_objmgr_vdev *vdev,
|
|
|
- struct chan_list *chan_list)
|
|
|
-{
|
|
|
-}
|
|
|
-
|
|
|
-static void scm_add_rnr_info(struct wlan_objmgr_pdev *pdev,
|
|
|
- struct scan_start_request *req)
|
|
|
-{
|
|
|
-}
|
|
|
-#endif
|
|
|
-
|
|
|
/**
|
|
|
* scm_update_channel_list() - update scan req params depending on dfs inis
|
|
|
* and initial scan request.
|
|
@@ -1138,7 +873,6 @@ scm_update_channel_list(struct scan_start_request *req,
|
|
|
bool p2p_search = false;
|
|
|
bool skip_dfs_ch = true;
|
|
|
uint32_t first_freq;
|
|
|
- enum QDF_OPMODE op_mode;
|
|
|
|
|
|
pdev = wlan_vdev_get_pdev(req->vdev);
|
|
|
|
|
@@ -1198,21 +932,8 @@ scm_update_channel_list(struct scan_start_request *req,
|
|
|
}
|
|
|
|
|
|
req->scan_req.chan_list.num_chan = num_scan_channels;
|
|
|
- /* Dont update the channel list:
|
|
|
- * - if not STA mode and
|
|
|
- * - if scan mode is set to SCAN_MODE_6G_NO_OPERATION
|
|
|
- */
|
|
|
- op_mode = wlan_vdev_mlme_get_opmode(req->vdev);
|
|
|
- if (op_mode != QDF_SAP_MODE &&
|
|
|
- op_mode != QDF_P2P_DEVICE_MODE &&
|
|
|
- op_mode != QDF_P2P_CLIENT_MODE &&
|
|
|
- op_mode != QDF_P2P_GO_MODE &&
|
|
|
- scan_obj->scan_def.scan_mode_6g != SCAN_MODE_6G_NO_OPERATION) {
|
|
|
- scm_update_6ghz_channel_list(req->vdev,
|
|
|
- &req->scan_req.chan_list,
|
|
|
- scan_obj);
|
|
|
- scm_sort_6ghz_channel_list(req->vdev, &req->scan_req.chan_list);
|
|
|
- }
|
|
|
+
|
|
|
+ scm_update_6ghz_channel_list(req, scan_obj);
|
|
|
scm_scan_chlist_concurrency_modify(req->vdev, req);
|
|
|
}
|
|
|
|
|
@@ -1233,7 +954,6 @@ scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev,
|
|
|
struct chan_list *custom_chan_list;
|
|
|
struct wlan_objmgr_pdev *pdev;
|
|
|
uint8_t pdev_id;
|
|
|
- enum QDF_OPMODE op_mode;
|
|
|
|
|
|
/* Ensure correct number of probes are sent on active channel */
|
|
|
if (!req->scan_req.repeat_probe_time)
|
|
@@ -1345,10 +1065,6 @@ scm_scan_req_update_params(struct wlan_objmgr_vdev *vdev,
|
|
|
else if (!req->scan_req.chan_list.num_chan)
|
|
|
ucfg_scan_init_chanlist_params(req, 0, NULL, NULL);
|
|
|
|
|
|
- op_mode = wlan_vdev_mlme_get_opmode(vdev);
|
|
|
- if (scan_obj->scan_def.scan_mode_6g != SCAN_MODE_6G_NO_CHANNEL &&
|
|
|
- op_mode == QDF_STA_MODE)
|
|
|
- scm_add_rnr_info(pdev, req);
|
|
|
scm_update_channel_list(req, scan_obj);
|
|
|
}
|
|
|
|