qcacmn: Support 11d for non-offload platform

Support 11d for non-offload platform by maintaining
count of beacons encountered for each country code
and choosing country code with max votes as device's
country code.

Change-Id: I83b66e980854eded17e254386561fa32b1f8c4ac
CRs-Fixed: 2154048
This commit is contained in:
Paul Zhang
2018-02-02 17:43:37 +08:00
committad av snandini
förälder e6d32a9f38
incheckning ca6152167b
14 ändrade filer med 660 tillägg och 15 borttagningar

Visa fil

@@ -95,6 +95,11 @@ typedef struct qdf_sglist {
*/
#define qdf_packed __qdf_packed
/**
* qdf_toupper - char lower to upper.
*/
#define qdf_toupper __qdf_toupper
typedef void *qdf_net_handle_t;
typedef void *qdf_netlink_handle_t;

Visa fil

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2014-2017 The Linux Foundation. All rights reserved.
* Copyright (c) 2014-2018 The Linux Foundation. All rights reserved.
*
* Previously licensed under the ISC license by Qualcomm Atheros, Inc.
*
@@ -55,6 +55,7 @@
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/types.h>
#include <linux/ctype.h>
#include <linux/sched.h>
#include <linux/completion.h>
#include <linux/string.h>
@@ -255,6 +256,7 @@ enum __qdf_net_wireless_evcode {
#define __qdf_vprint vprintk
#define __qdf_snprint snprintf
#define __qdf_vsnprint vsnprintf
#define __qdf_toupper toupper
#define __QDF_DMA_BIDIRECTIONAL DMA_BIDIRECTIONAL
#define __QDF_DMA_TO_DEVICE DMA_TO_DEVICE

Visa fil

@@ -843,7 +843,8 @@ QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev,
reg_channels = pdev_priv_obj->cur_chan_list;
for (i = 0, count = 0; i < NUM_CHANNELS; i++) {
if (reg_channels[i].state) {
if (reg_channels[i].state &&
reg_channels[i].state != REGULATORY_CHAN_DISABLED) {
ch_list[count].chan_num =
reg_channels[i].chan_num;
ch_list[count++].tx_power =
@@ -1376,6 +1377,22 @@ QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
bool reg_is_world_alpha2(uint8_t *alpha2)
{
if ((alpha2[0] == '0') && (alpha2[1] == '0'))
return true;
return false;
}
bool reg_is_us_alpha2(uint8_t *alpha2)
{
if ((alpha2[0] == 'U') && (alpha2[1] == 'S'))
return true;
return false;
}
QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev,
uint8_t *country)
{
@@ -1430,6 +1447,55 @@ QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev,
return QDF_STATUS_SUCCESS;
}
QDF_STATUS reg_set_11d_country(struct wlan_objmgr_pdev *pdev,
uint8_t *country)
{
struct wlan_regulatory_psoc_priv_obj *psoc_reg;
struct set_country country_code;
struct wlan_objmgr_psoc *psoc;
struct cc_regdmn_s rd;
QDF_STATUS status;
if (!country) {
reg_err("country code is NULL");
return QDF_STATUS_E_INVAL;
}
psoc = wlan_pdev_get_psoc(pdev);
psoc_reg = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_reg)) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_INVAL;
}
if (!qdf_mem_cmp(psoc_reg->cur_country,
country, REG_ALPHA2_LEN)) {
reg_debug("country is not different");
return QDF_STATUS_SUCCESS;
}
reg_info("programming new 11d country:%c%c to firmware",
country[0], country[1]);
qdf_mem_copy(country_code.country,
country, REG_ALPHA2_LEN + 1);
country_code.pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
psoc_reg->new_11d_ctry_pending = true;
if (psoc_reg->offload_enabled) {
reg_err("reg offload, 11d offload too!");
status = QDF_STATUS_E_FAULT;
} else {
qdf_mem_copy(rd.cc.alpha, country, REG_ALPHA2_LEN + 1);
rd.flags = ALPHA_IS_SET;
reg_program_chan_list(pdev, &rd);
status = QDF_STATUS_SUCCESS;
}
return status;
}
QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_reg;
@@ -1864,9 +1930,16 @@ static void reg_populate_band_channels(enum channel_enum start_chan,
if (found_rule_ptr) {
mas_chan_list[chan_enum].max_bw = bw;
reg_fill_channel_info(chan_enum, found_rule_ptr,
mas_chan_list, min_bw);
/* Disable 2.4 Ghz channels that dont have 20 mhz bw */
if (start_chan == MIN_24GHZ_CHANNEL &&
20 > mas_chan_list[chan_enum].max_bw) {
mas_chan_list[chan_enum].chan_flags |=
REGULATORY_CHAN_DISABLED;
mas_chan_list[chan_enum].state =
REGULATORY_CHAN_DISABLED;
}
}
}
}
@@ -3967,6 +4040,23 @@ QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc,
return QDF_STATUS_SUCCESS;
}
bool reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj =
wlan_objmgr_psoc_get_comp_private_obj(psoc,
WLAN_UMAC_COMP_REGULATORY);
if (NULL == psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return QDF_STATUS_E_FAILURE;
}
return (psoc_priv_obj->enable_11d_supp_original &&
!psoc_priv_obj->is_11d_offloaded);
}
bool reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;

Visa fil

@@ -164,6 +164,22 @@ QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc,
QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country);
/**
* reg_is_world_alpha2 - is reg world mode
* @alpha2: country code pointer
*
* Return: true or false
*/
bool reg_is_world_alpha2(uint8_t *alpha2);
/**
* reg_is_us_alpha2 - is US country code
* @alpha2: country code pointer
*
* Return: true or false
*/
bool reg_is_us_alpha2(uint8_t *alpha2);
/**
* reg_set_country() - Set the current regulatory country
* @pdev: pdev device for country information
@@ -173,6 +189,15 @@ QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc,
*/
QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev, uint8_t *country);
/**
* reg_set_11d_country() - Set the 11d regulatory country
* @pdev: pdev device for country information
* @country: country value
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_11d_country(struct wlan_objmgr_pdev *pdev, uint8_t *country);
/**
* reg_reset_country() - Reset the regulatory country to default
* @psoc: The physical SoC to reset country for
@@ -336,6 +361,14 @@ enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country);
/**
* reg_11d_original_enabled_on_host() - whether 11d original enabled on host
* @psoc: psoc ptr
*
* Return: bool
*/
bool reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc);
/**
* reg_11d_enabled_on_host() - know whether 11d enabled on host
* @psoc: psoc ptr

Visa fil

@@ -372,6 +372,21 @@ uint32_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev,
*/
uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev,
uint32_t chan);
/**
* wlan_reg_is_world() - reg is world mode
* @country: The country information
*
* Return: true or false
*/
bool wlan_reg_is_world(uint8_t *country);
/**
* wlan_reg_is_us() - reg is us country
* @country: The country information
*
* Return: true or false
*/
bool wlan_reg_is_us(uint8_t *country);
/**
* wlan_reg_set_country() - Set the current regulatory country
@@ -381,7 +396,17 @@ uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev,
* Return: QDF_STATUS
*/
QDF_STATUS wlan_reg_set_country(struct wlan_objmgr_pdev *pdev,
uint8_t *country);
uint8_t *country);
/**
* wlan_reg_set_11d_country() - Set the 11d regulatory country
* @pdev: The physical dev to set current country for
* @country: The country information to configure
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_reg_set_11d_country(struct wlan_objmgr_pdev *pdev,
uint8_t *country);
/**
* wlan_reg_register_chan_change_callback () - add chan change cbk
@@ -404,6 +429,15 @@ void wlan_reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
*/
void wlan_reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk);
/**
* wlan_reg_11d_original_enabled_on_host() - 11d original enabled don host
* @psoc: psoc ptr
*
* Return: bool
*/
bool wlan_reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc);
/**
* wlan_reg_11d_enabled_on_host() - 11d enabled don host
* @psoc: psoc ptr

Visa fil

@@ -451,6 +451,22 @@ QDF_STATUS wlan_reg_set_country(struct wlan_objmgr_pdev *pdev,
return reg_set_country(pdev, country);
}
QDF_STATUS wlan_reg_set_11d_country(struct wlan_objmgr_pdev *pdev,
uint8_t *country)
{
return reg_set_11d_country(pdev, country);
}
bool wlan_reg_is_world(uint8_t *country)
{
return reg_is_world_alpha2(country);
}
bool wlan_reg_is_us(uint8_t *country)
{
return reg_is_us_alpha2(country);
}
void wlan_reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk,
void *arg)
@@ -465,6 +481,11 @@ void wlan_reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_unregister_chan_change_callback(psoc, cbk);
}
bool wlan_reg_11d_original_enabled_on_host(struct wlan_objmgr_psoc *psoc)
{
return reg_11d_original_enabled_on_host(psoc);
}
bool wlan_reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc)
{
return reg_11d_enabled_on_host(psoc);

Visa fil

@@ -0,0 +1,354 @@
/*
* Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* DOC: contains scan 11d api and functionality
*/
#include <qdf_status.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_scan_public_structs.h>
#include <wlan_scan_utils_api.h>
#include "wlan_scan_main.h"
#include "wlan_scan_11d.h"
#include "wlan_reg_services_api.h"
#include "wlan_reg_ucfg_api.h"
/**
* wlan_pdevid_get_cc_db() - private API to get cc db from pdev id
* @psoc: psoc object
* @pdev_id: pdev id
*
* Return: cc db for the pdev id
*/
static struct scan_country_code_db *
wlan_pdevid_get_cc_db(struct wlan_objmgr_psoc *psoc, uint8_t pdev_id)
{
struct wlan_scan_obj *scan_obj;
if (pdev_id > WLAN_UMAC_MAX_PDEVS) {
scm_err("invalid pdev_id %d", pdev_id);
return NULL;
}
scan_obj = wlan_psoc_get_scan_obj(psoc);
if (!scan_obj)
return NULL;
return &scan_obj->cc_db[pdev_id];
}
/**
* wlan_pdev_get_cc_db() - private API to get cc db from pdev
* @psoc: psoc object
* @pdev: Pdev object
*
* Return: cc db for the pdev
*/
static struct scan_country_code_db *
wlan_pdev_get_cc_db(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
{
uint8_t pdev_id;
if (!pdev) {
scm_err("pdev is NULL");
return NULL;
}
pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
return wlan_pdevid_get_cc_db(psoc, pdev_id);
}
/**
* scm_11d_elected_country_algo_fcc - private api to get cc per fcc algo
* @cc_db: scan country code db
*
* Return: true or false
*/
static bool
scm_11d_elected_country_algo_fcc(struct scan_country_code_db *cc_db)
{
uint8_t i;
uint8_t country_idx;
uint16_t max_votes;
bool found = false;
if (!cc_db->num_country_codes) {
scm_err("No AP with 11d Country code is present in scan list");
return false;
}
max_votes = cc_db->votes[0].votes;
if (wlan_reg_is_us(cc_db->votes[0].cc)) {
found = true;
country_idx = 0;
goto algo_done;
} else if (max_votes >= MIN_11D_AP_COUNT) {
found = true;
country_idx = 0;
}
for (i = 1; i < cc_db->num_country_codes; i++) {
if (wlan_reg_is_us(cc_db->votes[i].cc)) {
found = true;
country_idx = i;
goto algo_done;
}
if ((max_votes < cc_db->votes[i].votes) &&
(cc_db->votes[i].votes >= MIN_11D_AP_COUNT)) {
scm_debug("Votes for Country %c%c : %d",
cc_db->votes[i].cc[0],
cc_db->votes[i].cc[1],
cc_db->votes[i].votes);
max_votes = cc_db->votes[i].votes;
country_idx = i;
found = true;
}
}
algo_done:
if (found) {
qdf_mem_copy(cc_db->elected_cc,
cc_db->votes[country_idx].cc,
REG_ALPHA2_LEN + 1);
scm_debug("Selected Country is %c%c With count %d",
cc_db->votes[country_idx].cc[0],
cc_db->votes[country_idx].cc[1],
cc_db->votes[country_idx].votes);
}
return found;
}
/**
* scm_11d_elected_country_info - private api to get cc
* @cc_db: scan country code db
*
* Return: true or false
*/
static bool
scm_11d_elected_country_info(struct scan_country_code_db *cc_db)
{
uint8_t i, j = 0;
uint8_t max_votes;
if (!cc_db->num_country_codes) {
scm_err("No AP with 11d Country code is present in scan list");
return false;
}
max_votes = cc_db->votes[0].votes;
for (i = 1; i < cc_db->num_country_codes; i++) {
/*
* If we have a tie for max votes for 2 different country codes,
* pick random.
*/
if (max_votes < cc_db->votes[i].votes) {
scm_debug("Votes for Country %c%c : %d",
cc_db->votes[i].cc[0],
cc_db->votes[i].cc[1],
cc_db->votes[i].votes);
max_votes = cc_db->votes[i].votes;
j = i;
}
}
qdf_mem_copy(cc_db->elected_cc, cc_db->votes[j].cc,
REG_ALPHA2_LEN + 1);
scm_debug("Selected Country is %c%c With count %d",
cc_db->votes[j].cc[0],
cc_db->votes[j].cc[1],
cc_db->votes[j].votes);
return true;
}
/**
* scm_11d_set_country_code - private api to set cc per 11d learning
* @pdev: pdev object
* @elected_cc: elected country code
* @current_cc: current country code
*
* Return: true or false
*/
static bool
scm_11d_set_country_code(struct wlan_objmgr_pdev *pdev,
uint8_t *elected_cc, uint8_t *current_cc)
{
scm_debug("elected country %c%c, current country %c%c",
elected_cc[0], elected_cc[1], current_cc[0], current_cc[1]);
if (!qdf_mem_cmp(elected_cc, current_cc, REG_ALPHA2_LEN + 1))
return true;
wlan_reg_set_11d_country(pdev, elected_cc);
return true;
}
/**
* scm_11d_reset_cc_db - reset the country code db
* @cc_db: the pointer of country code db
*
* Return: void
*/
static void scm_11d_reset_cc_db(struct scan_country_code_db *cc_db)
{
qdf_mem_zero(cc_db->votes, sizeof(cc_db->votes));
qdf_mem_zero(cc_db->elected_cc, sizeof(cc_db->elected_cc));
cc_db->num_country_codes = 0;
}
QDF_STATUS scm_11d_cc_db_init(struct wlan_objmgr_psoc *psoc)
{
struct scan_country_code_db *cc_db;
struct wlan_scan_obj *scan_obj;
if (!psoc) {
scm_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
scan_obj = wlan_psoc_get_scan_obj(psoc);
if (!scan_obj) {
scm_err("scan_obj is NULL");
return QDF_STATUS_E_INVAL;
}
cc_db = (struct scan_country_code_db *)qdf_mem_malloc(
sizeof(struct scan_country_code_db) * WLAN_UMAC_MAX_PDEVS);
if (!cc_db) {
scm_err("alloc country code db error");
return QDF_STATUS_E_INVAL;
}
qdf_mem_zero(cc_db,
sizeof(struct scan_country_code_db) *
WLAN_UMAC_MAX_PDEVS);
scan_obj->cc_db = cc_db;
return QDF_STATUS_SUCCESS;
}
QDF_STATUS scm_11d_cc_db_deinit(struct wlan_objmgr_psoc *psoc)
{
struct wlan_scan_obj *scan_obj;
if (!psoc) {
scm_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
scan_obj = wlan_psoc_get_scan_obj(psoc);
if (!scan_obj) {
scm_err("scan_obj is NULL");
return QDF_STATUS_E_INVAL;
}
qdf_mem_free(scan_obj->cc_db);
return QDF_STATUS_SUCCESS;
}
void scm_11d_handle_country_info(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_entry)
{
uint8_t i;
bool match = false;
uint8_t num_country_codes;
struct scan_country_code_db *cc_db;
struct wlan_country_ie *cc_ie;
cc_ie = util_scan_entry_country(scan_entry);
if (!cc_ie)
return;
cc_db = wlan_pdev_get_cc_db(psoc, pdev);
if (!cc_db)
return;
/* just to be sure, convert to UPPER case here */
for (i = 0; i < 3; i++)
cc_ie->cc[i] = qdf_toupper(cc_ie->cc[i]);
num_country_codes = cc_db->num_country_codes;
for (i = 0; i < num_country_codes; i++) {
match = !qdf_mem_cmp(cc_db->votes[i].cc, cc_ie->cc,
REG_ALPHA2_LEN);
if (match)
break;
}
if (match) {
cc_db->votes[i].votes++;
return;
}
if (num_country_codes >= SCAN_MAX_NUM_COUNTRY_CODE) {
scm_debug("country code db already full: %d",
num_country_codes);
return;
}
/* add country code to end of the list */
qdf_mem_copy(cc_db->votes[num_country_codes].cc, cc_ie->cc,
REG_ALPHA2_LEN + 1);
cc_db->votes[num_country_codes].votes = 1;
cc_db->num_country_codes++;
}
void scm_11d_decide_country_code(struct wlan_objmgr_vdev *vdev)
{
uint8_t current_cc[REG_ALPHA2_LEN + 1];
bool found;
struct scan_country_code_db *cc_db;
struct wlan_objmgr_pdev *pdev = wlan_vdev_get_pdev(vdev);
struct wlan_objmgr_psoc *psoc = wlan_pdev_get_psoc(pdev);
if (!wlan_reg_11d_enabled_on_host(psoc)) {
scm_err("11d is not enabled");
return;
}
if (SOURCE_UNKNOWN == ucfg_reg_get_cc_and_src(psoc, current_cc)) {
scm_err("fail to get current country code");
return;
}
cc_db = wlan_pdev_get_cc_db(psoc, pdev);
if (!cc_db) {
scm_err("scan_db is NULL");
return;
}
if (wlan_reg_is_us(current_cc) || wlan_reg_is_world(current_cc))
found = scm_11d_elected_country_algo_fcc(cc_db);
else
found = scm_11d_elected_country_info(cc_db);
if (found)
scm_11d_set_country_code(pdev, cc_db->elected_cc,
current_cc);
scm_11d_reset_cc_db(cc_db);
}

Visa fil

@@ -0,0 +1,95 @@
/*
* Copyright (c) 2011-2018 The Linux Foundation. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for
* any purpose with or without fee is hereby granted, provided that the
* above copyright notice and this permission notice appear in all
* copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
* AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
* TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
/*
* DOC: contains scan 11d entry api
*/
#ifndef _WLAN_SCAN_11D_H_
#define _WLAN_SCAN_11D_H_
#define SCAN_MAX_NUM_COUNTRY_CODE 100
#define MIN_11D_AP_COUNT 3
/**
* struct scan_country_code_votes - votes to country code mapping structure
* @votes: votes
* @cc: country code
*/
struct scan_country_code_votes {
uint16_t votes;
uint8_t cc[REG_ALPHA2_LEN + 1];
};
/**
* struct scan_country_code_db - country code data base definition
* @elected_cc: elected country code
* @num_country_codes: number of country codes encountered
* @votes: votes to country code mapping array
*/
struct scan_country_code_db {
uint8_t elected_cc[REG_ALPHA2_LEN + 1];
uint8_t num_country_codes;
struct scan_country_code_votes votes[SCAN_MAX_NUM_COUNTRY_CODE];
};
/**
* scm_11d_cc_db_init() - API to init 11d country code db
* @psoc: psoc object
*
* Initialize the country code database.
*
* Return: QDF_STATUS
*/
QDF_STATUS scm_11d_cc_db_init(struct wlan_objmgr_psoc *psoc);
/**
* scm_11d_cc_db_deinit() - API to deinit 11d country code db
* @psoc: psoc object
*
* free the country code database.
*
* Return: QDF_STATUS
*/
QDF_STATUS scm_11d_cc_db_deinit(struct wlan_objmgr_psoc *psoc);
/**
* scm_11d_handle_country_info() - API to handle 11d country info
* @psoc: psoc object
* @pdev: pdev object
* @scan_entry: the pointer to scan entry
*
* Update the country code database per the country code from country IE.
*
* Return: void
*/
void scm_11d_handle_country_info(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
struct scan_cache_entry *scan_entry);
/**
* scm_11d_decide_country_code() - API to decide the country code per 11d
* @vdev: vdev object
*
* Decide which country will be elected from the country database. If one
* cadidate country is found, then it set the country code.
*
* Return: void
*/
void scm_11d_decide_country_code(struct wlan_objmgr_vdev *vdev);
#endif

Visa fil

@@ -37,6 +37,8 @@
#include <wlan_scan_utils_api.h>
#include "wlan_scan_main.h"
#include "wlan_scan_cache_db_i.h"
#include "wlan_reg_services_api.h"
#include "wlan_reg_ucfg_api.h"
/**
* scm_del_scan_node() - API to remove scan node from the list
@@ -692,6 +694,9 @@ QDF_STATUS scm_handle_bcn_probe(struct scheduler_msg *msg)
scan_entry = scan_node->entry;
if (wlan_reg_11d_enabled_on_host(psoc))
scm_11d_handle_country_info(psoc, pdev, scan_entry);
status = scm_add_update_entry(scan_db, scan_entry);
if (QDF_IS_STATUS_ERROR(status)) {
util_scan_free_cache_entry(scan_entry);

Visa fil

@@ -893,6 +893,7 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc,
bool match = false;
struct roam_filter_params *roam_params;
struct scan_default_params *def_param;
struct wlan_country_ie *cc_ie;
def_param = wlan_scan_psoc_get_def_params(psoc);
if (!def_param)
@@ -972,8 +973,8 @@ bool scm_filter_match(struct wlan_objmgr_psoc *psoc,
if (!scm_is_fils_config_match(filter, db_entry))
return false;
if (!util_country_code_match(filter->country,
db_entry->ie_list.country))
cc_ie = util_scan_entry_country(db_entry);
if (!util_country_code_match(filter->country, cc_ie))
return false;
if (!util_mdie_match(filter->mobility_domain,

Visa fil

@@ -29,6 +29,7 @@
#include <wlan_objmgr_vdev_obj.h>
#include <wlan_scan_public_structs.h>
#include "wlan_scan_cache_db.h"
#include "wlan_scan_11d.h"
#define scm_log(level, args...) \
QDF_TRACE(QDF_MODULE_ID_SCAN, level, ## args)
@@ -396,6 +397,7 @@ struct scan_cb {
* struct wlan_scan_obj - scan object definition
* @enable_scan: if scan is enabled
* @scan_db: scan cache data base
* @cc_db: pointer of country code data base
* @lock: spin lock
* @scan_def: default scan parameters
* @cb: nif/sif function callbacks
@@ -414,6 +416,7 @@ struct wlan_scan_obj {
qdf_spinlock_t lock;
qdf_atomic_t scan_ids;
struct scan_dbs scan_db[WLAN_UMAC_MAX_PDEVS];
struct scan_country_code_db *cc_db;
struct scan_default_params scan_def;
struct scan_cb cb;
struct scan_requester_info requesters[WLAN_MAX_REQUESTORS];

Visa fil

@@ -727,6 +727,8 @@ scm_scan_event_handler(struct scheduler_msg *msg)
switch (event->type) {
case SCAN_EVENT_TYPE_COMPLETED:
scm_11d_decide_country_code(vdev);
/* fall through to release the command */
case SCAN_EVENT_TYPE_START_FAILED:
case SCAN_EVENT_TYPE_DEQUEUED:
scm_release_serialization_command(vdev, event->scan_id);

Visa fil

@@ -339,11 +339,8 @@ static inline bool util_is_bss_type_match(enum wlan_bss_type bss_type,
* Return: true if country match
*/
static inline bool util_country_code_match(uint8_t *country,
uint8_t *country_ie)
struct wlan_country_ie *cc)
{
struct wlan_country_ie *cc =
(struct wlan_country_ie *)country;
if (!country || !country[0])
return true;
@@ -351,7 +348,7 @@ static inline bool util_country_code_match(uint8_t *country,
return false;
if (cc->cc[0] == country[0] &&
cc->cc[1] == country[1])
cc->cc[1] == country[1])
return true;
return false;
@@ -1034,10 +1031,10 @@ util_scan_entry_vendor(struct scan_cache_entry *scan_entry)
*
* Return: countryie or NULL if ie is not present
*/
static inline uint8_t*
static inline struct wlan_country_ie*
util_scan_entry_country(struct scan_cache_entry *scan_entry)
{
return scan_entry->ie_list.country;
return (struct wlan_country_ie *)scan_entry->ie_list.country;
}
/**
@@ -1060,8 +1057,7 @@ util_scan_entry_copy_country(struct scan_cache_entry *scan_entry,
if (!cntry)
return QDF_STATUS_E_INVAL;
country_ie = (struct wlan_country_ie *)
util_scan_entry_country(scan_entry);
country_ie = util_scan_entry_country(scan_entry);
if (!country_ie)
return QDF_STATUS_E_NOMEM;

Visa fil

@@ -1722,6 +1722,8 @@ ucfg_scan_psoc_enable(struct wlan_objmgr_psoc *psoc)
status = tgt_scan_register_ev_handler(psoc);
QDF_ASSERT(status == QDF_STATUS_SUCCESS);
scm_db_init(psoc);
if (wlan_reg_11d_original_enabled_on_host(psoc))
scm_11d_cc_db_init(psoc);
ucfg_scan_register_unregister_bcn_cb(psoc, true);
status = wlan_serialization_register_apply_rules_cb(psoc,
WLAN_SER_CMD_SCAN,
@@ -1744,6 +1746,8 @@ ucfg_scan_psoc_disable(struct wlan_objmgr_psoc *psoc)
status = tgt_scan_unregister_ev_handler(psoc);
QDF_ASSERT(status == QDF_STATUS_SUCCESS);
ucfg_scan_register_unregister_bcn_cb(psoc, false);
if (wlan_reg_11d_original_enabled_on_host(psoc))
scm_11d_cc_db_deinit(psoc);
scm_db_deinit(psoc);
return status;