qcacmn: Add 11d, LTE, opclass, getset and callback regdb files

Create below regdb file in core component and move the code from
reg_services.c file.

These files has only MCL specific code.

reg_db_lte.c: this file has LTE feature code.
reg_host_11d.c: this file has 11d feature code.
reg_opclass.c: this file has opclass related code.
reg_getset.c: this file has the functions related to setting and getting
              regdb related variables.
reg_callbacks.c: this file has regdb callbacks/notificatoion functions.

Change-Id: Ie43acc03a5c35200f3e43bc978b792d5047eeb77
CRs-Fixed: 2349173
Цей коміт міститься в:
Shashikala Prabhu
2019-01-18 10:02:20 +05:30
зафіксовано nshrivas
джерело c8c709f6d4
коміт daa645bcab
14 змінених файлів з 2988 додано та 5811 видалено

Переглянути файл

@@ -22,6 +22,8 @@
* This file contains regulatory target LTE interface
*/
#ifdef CONFIG_LTE_COEX
#include "target_if_reg_lte.h"
/**
@@ -104,3 +106,4 @@ QDF_STATUS tgt_if_regulatory_unregister_ch_avoid_event_handler(
return wmi_unified_unregister_event(wmi_handle,
wmi_wlan_freq_avoid_event_id);
}
#endif

Переглянути файл

@@ -231,10 +231,20 @@ static void reg_modify_chan_list_for_indoor_channels(
enum channel_enum chan_enum;
struct regulatory_channel *chan_list = pdev_priv_obj->cur_chan_list;
if (pdev_priv_obj->indoor_chan_enabled)
return;
if (!pdev_priv_obj->indoor_chan_enabled) {
for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
if (REGULATORY_CHAN_INDOOR_ONLY &
chan_list[chan_enum].chan_flags) {
chan_list[chan_enum].state =
CHANNEL_STATE_DFS;
chan_list[chan_enum].chan_flags |=
REGULATORY_CHAN_NO_IR;
}
}
}
if (!pdev_priv_obj->force_ssc_disable_indoor_channel) {
if (pdev_priv_obj->force_ssc_disable_indoor_channel &&
pdev_priv_obj->sap_state) {
for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
if (REGULATORY_CHAN_INDOOR_ONLY &
chan_list[chan_enum].chan_flags) {
@@ -244,26 +254,6 @@ static void reg_modify_chan_list_for_indoor_channels(
REGULATORY_CHAN_DISABLED;
}
}
} else {
for (chan_enum = 0; chan_enum < NUM_CHANNELS; chan_enum++) {
if (pdev_priv_obj->sap_state) {
if (REGULATORY_CHAN_INDOOR_ONLY &
chan_list[chan_enum].chan_flags) {
chan_list[chan_enum].state =
CHANNEL_STATE_DISABLE;
chan_list[chan_enum].chan_flags |=
REGULATORY_CHAN_DISABLED;
}
} else {
if (REGULATORY_CHAN_INDOOR_ONLY &
chan_list[chan_enum].chan_flags) {
chan_list[chan_enum].state =
CHANNEL_STATE_DFS;
chan_list[chan_enum].chan_flags |=
REGULATORY_CHAN_NO_IR;
}
}
}
}
}
@@ -725,12 +715,18 @@ QDF_STATUS reg_process_master_chan_list(
reg_err("pdev is NULL");
return QDF_STATUS_E_FAILURE;
}
wlan_objmgr_pdev_release_ref(pdev, dbg_id);
if (tx_ops->set_country_failed)
tx_ops->set_country_failed(pdev);
return QDF_STATUS_E_FAILURE;
wlan_objmgr_pdev_release_ref(pdev, dbg_id);
if (regulat_info->status_code != REG_CURRENT_ALPHA2_NOT_FOUND)
return QDF_STATUS_E_FAILURE;
soc_reg->new_user_ctry_pending[phy_id] = false;
soc_reg->new_11d_ctry_pending[phy_id] = false;
soc_reg->world_country_pending[phy_id] = true;
}
mas_chan_list = soc_reg->mas_chan_params[phy_id].mas_chan_list;

378
umac/regulatory/core/src/reg_callbacks.c Звичайний файл
Переглянути файл

@@ -0,0 +1,378 @@
/*
* Copyright (c) 2014-2019 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: reg_callbacks.c
* This file defines regulatory callback functions
*/
#include <wlan_cmn.h>
#include <reg_services_public_struct.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include "reg_priv_objs.h"
#include "reg_getset.h"
#include <scheduler_api.h>
#include "reg_callbacks.h"
#include "reg_services_common.h"
#include "reg_build_chan_list.h"
/**
* reg_call_chan_change_cbks() - Call registered callback functions on channel
* change.
* @psoc: Pointer to global psoc structure.
* @pdev: Pointer to global pdev structure.
*/
static void reg_call_chan_change_cbks(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
{
struct chan_change_cbk_entry *cbk_list;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct regulatory_channel *cur_chan_list;
uint32_t ctr;
struct avoid_freq_ind_data *avoid_freq_ind = NULL;
reg_chan_change_callback callback;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
reg_alert("psoc reg component is NULL");
return;
}
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_alert("pdev reg component is NULL");
return;
}
cur_chan_list = qdf_mem_malloc(NUM_CHANNELS * sizeof(*cur_chan_list));
if (!cur_chan_list) {
reg_alert("Mem alloc failed for current channel list");
return;
}
qdf_mem_copy(cur_chan_list,
pdev_priv_obj->cur_chan_list,
NUM_CHANNELS *
sizeof(struct regulatory_channel));
if (psoc_priv_obj->ch_avoid_ind) {
avoid_freq_ind = qdf_mem_malloc(sizeof(*avoid_freq_ind));
if (!avoid_freq_ind) {
reg_alert("Mem alloc failed for avoid freq ind");
goto skip_ch_avoid_ind;
}
qdf_mem_copy(&avoid_freq_ind->freq_list,
&psoc_priv_obj->avoid_freq_list,
sizeof(struct ch_avoid_ind_type));
qdf_mem_copy(&avoid_freq_ind->chan_list,
&psoc_priv_obj->unsafe_chan_list,
sizeof(struct unsafe_ch_list));
psoc_priv_obj->ch_avoid_ind = false;
}
skip_ch_avoid_ind:
cbk_list = psoc_priv_obj->cbk_list;
for (ctr = 0; ctr < REG_MAX_CHAN_CHANGE_CBKS; ctr++) {
callback = NULL;
qdf_spin_lock_bh(&psoc_priv_obj->cbk_list_lock);
if (cbk_list[ctr].cbk)
callback = cbk_list[ctr].cbk;
qdf_spin_unlock_bh(&psoc_priv_obj->cbk_list_lock);
if (callback)
callback(psoc, pdev, cur_chan_list, avoid_freq_ind,
cbk_list[ctr].arg);
}
qdf_mem_free(cur_chan_list);
if (avoid_freq_ind)
qdf_mem_free(avoid_freq_ind);
}
/**
* reg_alloc_and_fill_payload() - Alloc and fill payload structure.
* @psoc: Pointer to global psoc structure.
* @pdev: Pointer to global pdev structure.
*/
static void reg_alloc_and_fill_payload(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
struct reg_sched_payload **payload)
{
*payload = qdf_mem_malloc(sizeof(**payload));
if (*payload) {
(*payload)->psoc = psoc;
(*payload)->pdev = pdev;
}
}
/**
* reg_chan_change_flush_cbk_sb() - Flush south bound channel change callbacks.
* @msg: Pointer to scheduler msg structure.
*/
static QDF_STATUS reg_chan_change_flush_cbk_sb(struct scheduler_msg *msg)
{
struct reg_sched_payload *load = msg->bodyptr;
struct wlan_objmgr_psoc *psoc = load->psoc;
struct wlan_objmgr_pdev *pdev = load->pdev;
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_SB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
qdf_mem_free(load);
return QDF_STATUS_SUCCESS;
}
/**
* reg_sched_chan_change_cbks_sb() - Schedule south bound channel change
* callbacks.
* @msg: Pointer to scheduler msg structure.
*/
static QDF_STATUS reg_sched_chan_change_cbks_sb(struct scheduler_msg *msg)
{
struct reg_sched_payload *load = msg->bodyptr;
struct wlan_objmgr_psoc *psoc = load->psoc;
struct wlan_objmgr_pdev *pdev = load->pdev;
reg_call_chan_change_cbks(psoc, pdev);
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_SB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
qdf_mem_free(load);
return QDF_STATUS_SUCCESS;
}
/**
* reg_chan_change_flush_cbk_nb() - Flush north bound channel change callbacks.
* @msg: Pointer to scheduler msg structure.
*/
static QDF_STATUS reg_chan_change_flush_cbk_nb(struct scheduler_msg *msg)
{
struct reg_sched_payload *load = msg->bodyptr;
struct wlan_objmgr_psoc *psoc = load->psoc;
struct wlan_objmgr_pdev *pdev = load->pdev;
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_NB_ID);
qdf_mem_free(load);
return QDF_STATUS_SUCCESS;
}
/**
* reg_sched_chan_change_cbks_nb() - Schedule north bound channel change
* callbacks.
* @msg: Pointer to scheduler msg structure.
*/
static QDF_STATUS reg_sched_chan_change_cbks_nb(struct scheduler_msg *msg)
{
struct reg_sched_payload *load = msg->bodyptr;
struct wlan_objmgr_psoc *psoc = load->psoc;
struct wlan_objmgr_pdev *pdev = load->pdev;
reg_call_chan_change_cbks(psoc, pdev);
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_NB_ID);
qdf_mem_free(load);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS reg_send_scheduler_msg_sb(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
{
struct scheduler_msg msg = {0};
struct reg_sched_payload *payload;
QDF_STATUS status;
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
reg_err("error taking psoc ref cnt");
return status;
}
status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_REGULATORY_SB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
reg_err("error taking pdev ref cnt");
return status;
}
reg_alloc_and_fill_payload(psoc, pdev, &payload);
if (!payload) {
reg_err("payload memory alloc failed");
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_SB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
return QDF_STATUS_E_NOMEM;
}
msg.bodyptr = payload;
msg.callback = reg_sched_chan_change_cbks_sb;
msg.flush_callback = reg_chan_change_flush_cbk_sb;
status = scheduler_post_message(QDF_MODULE_ID_REGULATORY,
QDF_MODULE_ID_REGULATORY,
QDF_MODULE_ID_TARGET_IF, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_SB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
reg_err("scheduler msg posting failed");
qdf_mem_free(payload);
}
return status;
}
QDF_STATUS reg_send_scheduler_msg_nb(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
{
struct scheduler_msg msg = {0};
struct reg_sched_payload *payload;
QDF_STATUS status;
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_NB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
reg_err("error taking psoc ref cnt");
return status;
}
status = wlan_objmgr_pdev_try_get_ref(pdev, WLAN_REGULATORY_NB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_NB_ID);
reg_err("error taking pdev ref cnt");
return status;
}
reg_alloc_and_fill_payload(psoc, pdev, &payload);
if (!payload) {
reg_err("payload memory alloc failed");
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_NB_ID);
return QDF_STATUS_E_NOMEM;
}
msg.bodyptr = payload;
msg.callback = reg_sched_chan_change_cbks_nb;
msg.flush_callback = reg_chan_change_flush_cbk_nb;
status = scheduler_post_message(QDF_MODULE_ID_REGULATORY,
QDF_MODULE_ID_REGULATORY,
QDF_MODULE_ID_OS_IF, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_objmgr_pdev_release_ref(pdev, WLAN_REGULATORY_NB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_NB_ID);
reg_err("scheduler msg posting failed");
qdf_mem_free(payload);
}
return status;
}
QDF_STATUS reg_notify_sap_event(struct wlan_objmgr_pdev *pdev,
bool sap_state)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct wlan_objmgr_psoc *psoc;
QDF_STATUS status;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("pdev reg component is NULL");
return QDF_STATUS_E_INVAL;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
reg_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_INVAL;
}
reg_info("sap_state: %d", sap_state);
if (pdev_priv_obj->sap_state == sap_state)
return QDF_STATUS_SUCCESS;
pdev_priv_obj->sap_state = sap_state;
set_disable_channel_state(pdev_priv_obj);
reg_compute_pdev_current_chan_list(pdev_priv_obj);
status = reg_send_scheduler_msg_sb(psoc, pdev);
return status;
}
void reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk, void *arg)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
uint32_t count;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return;
}
qdf_spin_lock_bh(&psoc_priv_obj->cbk_list_lock);
for (count = 0; count < REG_MAX_CHAN_CHANGE_CBKS; count++)
if (!psoc_priv_obj->cbk_list[count].cbk) {
psoc_priv_obj->cbk_list[count].cbk = cbk;
psoc_priv_obj->cbk_list[count].arg = arg;
psoc_priv_obj->num_chan_change_cbks++;
break;
}
qdf_spin_unlock_bh(&psoc_priv_obj->cbk_list_lock);
if (count == REG_MAX_CHAN_CHANGE_CBKS)
reg_err("callback list is full, could not add the cbk");
}
void reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
uint32_t count;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return;
}
qdf_spin_lock_bh(&psoc_priv_obj->cbk_list_lock);
for (count = 0; count < REG_MAX_CHAN_CHANGE_CBKS; count++)
if (psoc_priv_obj->cbk_list[count].cbk == cbk) {
psoc_priv_obj->cbk_list[count].cbk = NULL;
psoc_priv_obj->num_chan_change_cbks--;
break;
}
qdf_spin_unlock_bh(&psoc_priv_obj->cbk_list_lock);
if (count == REG_MAX_CHAN_CHANGE_CBKS)
reg_err("callback not found in the list");
}

98
umac/regulatory/core/src/reg_callbacks.h Звичайний файл
Переглянути файл

@@ -0,0 +1,98 @@
/*
* Copyright (c) 2017-2019 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: reg_callbks.h
* This file provides prototypes of reg callbacks.
*/
#ifndef __REG_CALLBKS_H_
#define __REG_CALLBKS_H_
#ifdef CONFIG_MCL_REGDB
/**
* reg_register_chan_change_callback() - Register channel change callbacks
* @psoc: Pointer to psoc
* @cbk: Pointer to callback function
* @arg: List of arguments
*/
void reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk, void *arg);
/**
* reg_unregister_chan_change_callback() - Unregister channel change callbacks
* @psoc: Pointer to psoc
* @cbk: Pointer to callback function
*/
void reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk);
/**
* reg_notify_sap_event() - Notify regulatory domain for sap event
* @pdev: The physical dev to set the band for
* @sap_state: true for sap start else false
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_notify_sap_event(struct wlan_objmgr_pdev *pdev,
bool sap_state);
/**
* reg_send_scheduler_msg_sb() - Start scheduler to call list of south bound
* callbacks registered whenever current chan list changes.
* @psoc: Pointer to PSOC structure.
* @pdev: Pointer to PDEV structure.
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_send_scheduler_msg_sb(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev);
/**
* reg_send_scheduler_msg_nb() - Start scheduler to call list of north bound
* @psoc: Pointer to global psoc structure.
* @pdev: Pointer to global pdev structure.
*/
QDF_STATUS reg_send_scheduler_msg_nb(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev);
#else
static inline void reg_register_chan_change_callback(
struct wlan_objmgr_psoc *psoc, reg_chan_change_callback cbk,
void *arg)
{
}
static inline void reg_unregister_chan_change_callback(
struct wlan_objmgr_psoc *psoc, reg_chan_change_callback cbk)
{
}
static inline QDF_STATUS reg_send_scheduler_msg_sb(
struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_pdev *pdev)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS reg_send_scheduler_msg_nb(
struct wlan_objmgr_psoc *psoc, struct wlan_objmgr_pdev *pdev)
{
return QDF_STATUS_SUCCESS;
}
#endif
#endif

873
umac/regulatory/core/src/reg_getset.c Звичайний файл
Переглянути файл

@@ -0,0 +1,873 @@
/*
* Copyright (c) 2014-2019 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: reg_getset.c
* This file defines the APIs to set and get the regulatory variables.
*/
#include <wlan_cmn.h>
#include <reg_services_public_struct.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include "reg_priv_objs.h"
#include "reg_getset.h"
#include "reg_callbacks.h"
#include "reg_db.h"
#include "reg_db_parser.h"
#include "reg_host_11d.h"
#include <scheduler_api.h>
#include <wlan_reg_services_api.h>
#include <qdf_platform.h>
#include "reg_services_common.h"
#include "reg_build_chan_list.h"
#define DEFAULT_WORLD_REGDMN 0x60
#define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (psoc_priv_obj)
#define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (pdev_priv_obj)
bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch)
{
enum channel_enum ch_idx;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
ch_idx = reg_get_chan_enum(ch);
if (ch_idx == INVALID_CHANNEL)
return false;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("pdev reg obj is NULL");
return false;
}
if (pdev_priv_obj->cur_chan_list[ch_idx].chan_flags &
REGULATORY_CHAN_RADAR)
return true;
return false;
}
/**
* reg_is_world_ctry_code() - Check if the given country code is WORLD regdomain
* @ctry_code: Country code value.
*/
static bool reg_is_world_ctry_code(uint16_t ctry_code)
{
if ((ctry_code & 0xFFF0) == DEFAULT_WORLD_REGDMN)
return true;
return false;
}
QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country_code)
{
struct wlan_regulatory_psoc_priv_obj *psoc_reg;
if (!country_code) {
reg_err("country_code is NULL");
return QDF_STATUS_E_INVAL;
}
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;
}
qdf_mem_copy(country_code, psoc_reg->cur_country, REG_ALPHA2_LEN + 1);
return QDF_STATUS_SUCCESS;
}
/**
* reg_set_default_country() - Read the default country for the regdomain
* @country: country code.
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_default_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country)
{
struct wlan_regulatory_psoc_priv_obj *psoc_reg;
if (!country) {
reg_err("country is NULL");
return QDF_STATUS_E_INVAL;
}
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;
}
reg_info("setting default_country: %s", country);
qdf_mem_copy(psoc_reg->def_country, country, REG_ALPHA2_LEN + 1);
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)
{
struct wlan_regulatory_psoc_priv_obj *psoc_reg;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct wlan_lmac_if_reg_tx_ops *tx_ops;
struct set_country country_code;
struct wlan_objmgr_psoc *psoc;
struct cc_regdmn_s rd;
uint8_t pdev_id;
if (!pdev) {
reg_err("pdev is NULL");
return QDF_STATUS_E_INVAL;
}
if (!country) {
reg_err("country code is NULL");
return QDF_STATUS_E_INVAL;
}
pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
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_err("country is not different");
return QDF_STATUS_SUCCESS;
}
reg_debug("programming new country:%s to firmware", country);
qdf_mem_copy(country_code.country, country, REG_ALPHA2_LEN + 1);
country_code.pdev_id = pdev_id;
if (reg_is_world_alpha2(country))
psoc_reg->world_country_pending[pdev_id] = true;
else
psoc_reg->new_user_ctry_pending[pdev_id] = true;
if (psoc_reg->offload_enabled) {
tx_ops = reg_get_psoc_tx_ops(psoc);
if (tx_ops->set_country_code) {
tx_ops->set_country_code(psoc, &country_code);
} else {
reg_err("country set fw handler not present");
psoc_reg->new_user_ctry_pending[pdev_id] = false;
return QDF_STATUS_E_FAULT;
}
} else {
if (reg_is_world_alpha2(country)) {
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("reg component pdev priv is NULL");
psoc_reg->new_user_ctry_pending[pdev_id] =
false;
return QDF_STATUS_E_INVAL;
}
if (reg_is_world_ctry_code(
pdev_priv_obj->def_region_domain))
rd.cc.regdmn_id =
pdev_priv_obj->def_region_domain;
else
rd.cc.regdmn_id = DEFAULT_WORLD_REGDMN;
rd.flags = REGDMN_IS_SET;
} else {
qdf_mem_copy(rd.cc.alpha, country, REG_ALPHA2_LEN + 1);
rd.flags = ALPHA_IS_SET;
}
reg_program_chan_list(pdev, &rd);
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_reg;
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;
}
reg_info("re-setting user country to default");
qdf_mem_copy(psoc_reg->cur_country,
psoc_reg->def_country,
REG_ALPHA2_LEN + 1);
reg_debug("set cur_country %.2s", psoc_reg->cur_country);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
const uint8_t *country_alpha2,
enum country_src source)
{
if (!reg_domain_ptr) {
reg_err("Invalid reg domain pointer");
return QDF_STATUS_E_FAULT;
}
*reg_domain_ptr = 0;
if (!country_alpha2) {
reg_err("Country code array is NULL");
return QDF_STATUS_E_FAULT;
}
return QDF_STATUS_SUCCESS;
}
bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
enum channel_state ch_state;
ch_state = reg_get_channel_state(pdev, chan);
return (ch_state == CHANNEL_STATE_DFS) ||
(ch_state == CHANNEL_STATE_DISABLE);
}
#ifdef WLAN_FEATURE_DSRC
bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
uint32_t freq = 0;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("reg pdev priv obj is NULL");
return false;
}
if (!REG_IS_5GHZ_CH(chan))
return false;
freq = reg_chan_to_freq(pdev, chan);
if (!(freq >= REG_DSRC_START_FREQ && freq <= REG_DSRC_END_FREQ))
return false;
return true;
}
#else
bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
{
struct cur_regdmn_info cur_reg_dmn;
QDF_STATUS status;
status = reg_get_curr_regdomain(pdev, &cur_reg_dmn);
if (status != QDF_STATUS_SUCCESS) {
reg_err("Failed to get reg domain");
return false;
}
return reg_etsi13_regdmn(cur_reg_dmn.dmn_id_5g);
}
bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
uint32_t freq = 0;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("reg pdev priv obj is NULL");
return false;
}
if (!REG_IS_5GHZ_CH(chan))
return false;
freq = reg_chan_to_freq(pdev, chan);
if (!(freq >= REG_ETSI13_SRD_START_FREQ &&
freq <= REG_ETSI13_SRD_END_FREQ))
return false;
return reg_is_etsi13_regdmn(pdev);
}
bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
{
struct wlan_objmgr_psoc *psoc;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
if (!pdev) {
reg_alert("pdev is NULL");
return true;
}
psoc = wlan_pdev_get_psoc(pdev);
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
reg_alert("psoc reg component is NULL");
return true;
}
return psoc_priv_obj->enable_srd_chan_in_master_mode &&
reg_is_etsi13_regdmn(pdev);
}
#endif
QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev,
enum band_info band)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct wlan_objmgr_psoc *psoc;
QDF_STATUS status;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("pdev reg component is NULL");
return QDF_STATUS_E_INVAL;
}
if (pdev_priv_obj->band_capability == band) {
reg_info("band is already set to %d", band);
return QDF_STATUS_SUCCESS;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
reg_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_INVAL;
}
reg_info("setting band_info: %d", band);
pdev_priv_obj->band_capability = band;
reg_compute_pdev_current_chan_list(pdev_priv_obj);
status = reg_send_scheduler_msg_sb(psoc, pdev);
return status;
}
#ifdef DISABLE_CHANNEL_LIST
QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct wlan_objmgr_psoc *psoc;
QDF_STATUS status;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("pdev reg component is NULL");
return QDF_STATUS_E_INVAL;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
reg_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_INVAL;
}
pdev_priv_obj->disable_cached_channels = false;
reg_compute_pdev_current_chan_list(pdev_priv_obj);
status = reg_send_scheduler_msg_sb(psoc, pdev);
return status;
}
QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev,
uint32_t *channel_list,
uint32_t num_channels)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct wlan_objmgr_psoc *psoc;
uint8_t i, j;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("pdev reg component is NULL");
return QDF_STATUS_E_INVAL;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
reg_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_INVAL;
}
if (pdev_priv_obj->num_cache_channels > 0) {
pdev_priv_obj->num_cache_channels = 0;
qdf_mem_set(&pdev_priv_obj->cache_disable_chan_list,
sizeof(pdev_priv_obj->cache_disable_chan_list), 0);
}
for (i = 0; i < num_channels; i++) {
for (j = 0; j < NUM_CHANNELS; j++) {
if (channel_list[i] == pdev_priv_obj->
cur_chan_list[j].chan_num) {
pdev_priv_obj->
cache_disable_chan_list[i].chan_num =
channel_list[i];
pdev_priv_obj->
cache_disable_chan_list[i].state =
pdev_priv_obj->cur_chan_list[j].state;
pdev_priv_obj->
cache_disable_chan_list[i].chan_flags =
pdev_priv_obj->
cur_chan_list[j].chan_flags;
}
}
}
pdev_priv_obj->num_cache_channels = num_channels;
return QDF_STATUS_SUCCESS;
}
void set_disable_channel_state(
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
{
pdev_priv_obj->disable_cached_channels = pdev_priv_obj->sap_state;
}
#endif
QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev,
bool fcc_constraint)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_objmgr_psoc *psoc;
QDF_STATUS status;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("pdev reg component is NULL");
return QDF_STATUS_E_INVAL;
}
if (pdev_priv_obj->set_fcc_channel == fcc_constraint) {
reg_info("fcc_constraint is already set to %d", fcc_constraint);
return QDF_STATUS_SUCCESS;
}
reg_info("setting set_fcc_channel: %d", fcc_constraint);
pdev_priv_obj->set_fcc_channel = fcc_constraint;
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
reg_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_INVAL;
}
reg_compute_pdev_current_chan_list(pdev_priv_obj);
status = reg_send_scheduler_msg_sb(psoc, pdev);
return status;
}
QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev,
bool enable)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_objmgr_psoc *psoc;
QDF_STATUS status;
struct wlan_lmac_if_reg_tx_ops *reg_tx_ops;
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("pdev reg component is NULL");
return QDF_STATUS_E_INVAL;
}
if (pdev_priv_obj->dfs_enabled == enable) {
reg_info("dfs_enabled is already set to %d", enable);
return QDF_STATUS_SUCCESS;
}
psoc = wlan_pdev_get_psoc(pdev);
if (!psoc) {
reg_err("psoc is NULL");
return QDF_STATUS_E_INVAL;
}
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!IS_VALID_PSOC_REG_OBJ(psoc_priv_obj)) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_INVAL;
}
reg_info("setting dfs_enabled: %d", enable);
pdev_priv_obj->dfs_enabled = enable;
reg_compute_pdev_current_chan_list(pdev_priv_obj);
reg_tx_ops = reg_get_psoc_tx_ops(psoc);
/* Fill the ic channel list with the updated current channel
* chan list.
*/
if (reg_tx_ops->fill_umac_legacy_chanlist)
reg_tx_ops->fill_umac_legacy_chanlist(pdev,
pdev_priv_obj->cur_chan_list);
status = reg_send_scheduler_msg_sb(psoc, pdev);
return status;
}
/**
* reg_change_pdev_for_config() - Update user configuration in pdev private obj.
* @psoc: Pointer to global psoc structure.
* @object: Pointer to global pdev structure.
* @arg: Pointer to argument list.
*/
static void reg_change_pdev_for_config(struct wlan_objmgr_psoc *psoc,
void *object, void *arg)
{
struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("psoc priv obj is NULL");
return;
}
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("reg pdev private obj is NULL");
return;
}
pdev_priv_obj->dfs_enabled = psoc_priv_obj->dfs_enabled;
pdev_priv_obj->indoor_chan_enabled = psoc_priv_obj->indoor_chan_enabled;
pdev_priv_obj->force_ssc_disable_indoor_channel =
psoc_priv_obj->force_ssc_disable_indoor_channel;
pdev_priv_obj->band_capability = psoc_priv_obj->band_capability;
reg_compute_pdev_current_chan_list(pdev_priv_obj);
reg_send_scheduler_msg_sb(psoc, pdev);
}
QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
struct reg_config_vars config_vars)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
QDF_STATUS status;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("psoc priv obj is NULL");
return QDF_STATUS_E_FAILURE;
}
psoc_priv_obj->enable_11d_supp_original =
config_vars.enable_11d_support;
psoc_priv_obj->scan_11d_interval = config_vars.scan_11d_interval;
psoc_priv_obj->user_ctry_priority = config_vars.userspace_ctry_priority;
psoc_priv_obj->dfs_enabled = config_vars.dfs_enabled;
psoc_priv_obj->indoor_chan_enabled = config_vars.indoor_chan_enabled;
psoc_priv_obj->force_ssc_disable_indoor_channel =
config_vars.force_ssc_disable_indoor_channel;
psoc_priv_obj->band_capability = config_vars.band_capability;
psoc_priv_obj->restart_beaconing = config_vars.restart_beaconing;
psoc_priv_obj->enable_srd_chan_in_master_mode =
config_vars.enable_srd_chan_in_master_mode;
psoc_priv_obj->enable_11d_in_world_mode =
config_vars.enable_11d_in_world_mode;
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
reg_err("error taking psoc ref cnt");
return status;
}
status = wlan_objmgr_iterate_obj_list(psoc, WLAN_PDEV_OP,
reg_change_pdev_for_config,
NULL, 1, WLAN_REGULATORY_SB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
return status;
}
bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan)
{
enum channel_state ch_state;
ch_state = reg_get_channel_state(pdev, chan);
return ch_state == CHANNEL_STATE_DISABLE;
}
bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return false;
}
return psoc_priv_obj->offload_enabled;
}
void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
struct regulatory_channel *reg_channels,
uint8_t *alpha2,
enum dfs_reg dfs_region)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
QDF_STATUS status;
uint32_t count;
enum direction dir;
uint32_t pdev_cnt;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return;
}
qdf_mem_copy(psoc_priv_obj->cur_country, alpha2,
REG_ALPHA2_LEN);
reg_debug("set cur_country %.2s", psoc_priv_obj->cur_country);
for (count = 0; count < NUM_CHANNELS; count++) {
reg_channels[count].chan_num = channel_map[count].chan_num;
reg_channels[count].center_freq =
channel_map[count].center_freq;
reg_channels[count].nol_chan = false;
}
for (pdev_cnt = 0; pdev_cnt < PSOC_MAX_PHY_REG_CAP; pdev_cnt++) {
qdf_mem_copy(psoc_priv_obj->mas_chan_params[pdev_cnt].
mas_chan_list, reg_channels,
NUM_CHANNELS * sizeof(struct regulatory_channel));
psoc_priv_obj->mas_chan_params[pdev_cnt].dfs_region =
dfs_region;
}
dir = SOUTHBOUND;
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
reg_err("error taking psoc ref cnt");
return;
}
status = wlan_objmgr_iterate_obj_list(
psoc, WLAN_PDEV_OP, reg_propagate_mas_chan_list_to_pdev,
&dir, 1, WLAN_REGULATORY_SB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
}
enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
uint8_t *alpha2)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return SOURCE_UNKNOWN;
}
qdf_mem_copy(alpha2, psoc_priv_obj->cur_country, REG_ALPHA2_LEN + 1);
return psoc_priv_obj->cc_src;
}
QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
struct reg_rule_info *reg_rules)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
if (!pdev) {
reg_err("pdev is NULL");
return QDF_STATUS_E_FAILURE;
}
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!pdev_priv_obj) {
reg_err("pdev priv obj is NULL");
return QDF_STATUS_E_FAILURE;
}
qdf_spin_lock_bh(&pdev_priv_obj->reg_rules_lock);
qdf_mem_copy(reg_rules, &pdev_priv_obj->reg_rules,
sizeof(struct reg_rule_info));
qdf_spin_unlock_bh(&pdev_priv_obj->reg_rules_lock);
return QDF_STATUS_SUCCESS;
}
void reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj
*soc_reg)
{
uint8_t ctr;
if (!soc_reg->offload_enabled)
return;
for (ctr = 0; ctr < PSOC_MAX_PHY_REG_CAP; ctr++) {
soc_reg->new_user_ctry_pending[ctr] = false;
soc_reg->new_init_ctry_pending[ctr] = false;
soc_reg->new_11d_ctry_pending[ctr] = false;
soc_reg->world_country_pending[ctr] = false;
}
}
QDF_STATUS reg_set_curr_country(
struct wlan_regulatory_psoc_priv_obj *soc_reg,
struct cur_regulatory_info *regulat_info,
struct wlan_lmac_if_reg_tx_ops *tx_ops)
{
struct wlan_objmgr_psoc *psoc = regulat_info->psoc;
uint8_t pdev_id;
struct set_country country_code;
QDF_STATUS status;
/*
* During SSR/WLAN restart ignore master channel list
* for all events and in the last event handling if
* current country and default country is different, send the last
* configured (soc_reg->cur_country) country.
*/
if ((regulat_info->num_phy != regulat_info->phy_id + 1) ||
(!qdf_mem_cmp(soc_reg->cur_country, regulat_info->alpha2,
REG_ALPHA2_LEN)))
return QDF_STATUS_SUCCESS;
pdev_id = soc_reg->def_pdev_id;
if (soc_reg->cc_src == SOURCE_USERSPACE)
soc_reg->new_user_ctry_pending[pdev_id] = true;
else if (soc_reg->cc_src == SOURCE_11D)
soc_reg->new_11d_ctry_pending[pdev_id] = true;
else
soc_reg->world_country_pending[pdev_id] = true;
qdf_mem_zero(&country_code, sizeof(country_code));
qdf_mem_copy(country_code.country, soc_reg->cur_country,
sizeof(soc_reg->cur_country));
country_code.pdev_id = pdev_id;
if (!tx_ops || !tx_ops->set_country_code) {
reg_err("No regulatory tx_ops for set_country_code");
status = QDF_STATUS_E_FAULT;
goto error;
}
status = tx_ops->set_country_code(psoc, &country_code);
if (QDF_IS_STATUS_ERROR(status)) {
reg_err("Failed to send country code to firmware");
goto error;
}
reg_debug("Target CC: %.2s, Restore to Previous CC: %.2s",
regulat_info->alpha2, soc_reg->cur_country);
return status;
error:
reg_reset_ctry_pending_hints(soc_reg);
return status;
}
bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
struct cur_regulatory_info *regulat_info)
{
uint8_t pdev_id;
if (!soc_reg->offload_enabled)
return false;
if (soc_reg->cc_src == SOURCE_UNKNOWN)
return false;
pdev_id = regulat_info->phy_id;
if (soc_reg->new_user_ctry_pending[pdev_id] ||
soc_reg->new_init_ctry_pending[pdev_id] ||
soc_reg->new_11d_ctry_pending[pdev_id] ||
soc_reg->world_country_pending[pdev_id])
return false;
return true;
}

499
umac/regulatory/core/src/reg_getset.h Звичайний файл
Переглянути файл

@@ -0,0 +1,499 @@
/*
* Copyright (c) 2017-2019 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: reg_getset.h
* This file provides prototypes for setting and getting regulatory variables.
*/
#ifndef __REG_GETSET_H_
#define __REG_GETSET_H_
#ifdef WLAN_FEATURE_DSRC
#define REG_DSRC_START_FREQ channel_map[MIN_DSRC_CHANNEL].center_freq
#define REG_DSRC_END_FREQ channel_map[MAX_DSRC_CHANNEL].center_freq
#endif
#define REG_ETSI13_SRD_START_FREQ 5745
#define REG_ETSI13_SRD_END_FREQ 5865
#define REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \
((curchan) > (newchan) ? \
REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \
- REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \
> REG_SBS_SEPARATION_THRESHOLD : \
REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \
- REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \
> REG_SBS_SEPARATION_THRESHOLD)
#ifdef CONFIG_MCL_REGDB
/**
* reg_chan_has_dfs_attribute() - check channel has dfs attribue or not
* @ch: channel number.
*
* This API get chan initial dfs attribue flag from regdomain
*
* Return: true if chan is dfs, otherwise false
*/
bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch);
/**
* reg_set_band() - Sets the band information for the PDEV
* @pdev: The physical dev to set the band for
* @band: The set band parameters to configure for the pysical device
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, enum band_info band);
#ifdef DISABLE_CHANNEL_LIST
/**
* reg_restore_cached_channels() - Cache the current state of the channles
* @pdev: The physical dev to cache the channels for
*/
QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev);
/**
* reg_cache_channel_state() - Cache the current state of the channles
* @pdev: The physical dev to cache the channels for
* @channel_list: List of the channels for which states needs to be cached
* @num_channels: Number of channels in the list
*
*/
QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev,
uint32_t *channel_list,
uint32_t num_channels);
#else
static inline
QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev)
{
return QDF_STATUS_SUCCESS;
}
static inline
QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev,
uint32_t *channel_list,
uint32_t num_channels)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
* reg_set_fcc_constraint() - Apply fcc constraints on channels 12/13
* @pdev: The physical dev to set the band for
*
* This function reduces the transmit power on channels 12 and 13, to comply
* with FCC regulations in the USA.
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev,
bool fcc_constraint);
/**
* reg_read_current_country() - Get the current regulatory country
* @psoc: The physical SoC to get current country from
* @country_code: the buffer to populate the country code into
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country_code);
/**
* reg_set_default_country() - Set the default regulatory country
* @psoc: The physical SoC to set default country for
* @req: The country information to configure
*
* Return: QDF_STATUS
*/
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
* @country: country value
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_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
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc);
/**
* reg_enable_dfs_channels() - Enable the use of DFS channels
* @pdev: The physical dev to enable/disable DFS channels for
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev, bool enable);
/**
* reg_get_domain_from_country_code() - Get regdomain from country code
* @reg_domain_ptr: Pointer to save regdomain
* @country_alpha2: country string
* @source: Country code source
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
const uint8_t *country_alpha2,
enum country_src source);
/**
* reg_is_passive_or_disable_ch() - Check if the given channel is passive or
* disabled.
* @pdev: Pointer to physical dev
* @chan: Channel number
*
* Return: true if channel is passive or disabled, else false.
*/
bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan);
/**
* reg_is_disable_ch() - Check if the given channel in disable state
* @pdev: Pointer to pdev
* @chan: channel number
*
* Return: True if channel state is disabled, else false
*/
bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan);
/**
* reg_set_config_vars () - set configration variables
* @psoc: psoc ptr
* @config_vars: configuration struct
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
struct reg_config_vars config_vars);
/**
* reg_is_regdb_offloaded() - is regdb offloaded
* @psoc: Pointer to psoc object
*
* Return: true if regdb is offloaded, else false
*/
bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc);
/**
* reg_program_mas_chan_list() - Program the master channel list
* @psoc: Pointer to psoc structure
* @reg_channels: Pointer to reg channels
* @alpha2: country string
* @dfs_region: DFS region
*/
void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
struct regulatory_channel *reg_channels,
uint8_t *alpha2, enum dfs_reg dfs_region);
/**
* reg_get_regd_rules() - provides the reg domain rules info
* @pdev: pdev pointer
* @reg_rules: regulatory rules
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
struct reg_rule_info *reg_rules);
/**
* reg_get_cc_and_src() - Get country string and country source
* @psoc: Pointer to psoc
* @alpha2: Pointer to save country string
*
* Return: country_src
*/
enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
uint8_t *alpha2);
/**
* reg_reset_ctry_pending_hints() - Reset all country pending hints
* @soc_reg: regulatory private object
*
* Return: None
*/
void
reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj *soc_reg);
/**
* reg_set_curr_country() - Set current country update
* @soc_reg: regulatory private object
* @regulat_info: regulatory info from firmware
* @tx_ops: send operations for regulatory component
*
* During SSR or restart of wlan modules after interface change timer phase,
* this function is used to send the recent user/11d country code to firmware.
*
* Return: QDF_STATUS_SUCCESS if correct country is configured
* else return failure
* error code.
*/
QDF_STATUS reg_set_curr_country(
struct wlan_regulatory_psoc_priv_obj *soc_reg,
struct cur_regulatory_info *regulat_info,
struct wlan_lmac_if_reg_tx_ops *tx_ops);
/**
* reg_ignore_default_country() - Ignore default country update
* @soc_reg: regulatory private object
* @regulat_info: regulatory info from firmware
*
* During SSR or restart of wlan modules after interface change timer phase,
* this function is used to ignore default country code from firmware.
*
* Return: If default country needs to be ignored return true else false.
*/
bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
struct cur_regulatory_info *regulat_info);
#else
static inline bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev,
uint32_t ch)
{
return false;
}
static inline QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country_code)
{
return QDF_STATUS_SUCCESS;
}
static inline bool reg_is_world_alpha2(uint8_t *alpha2)
{
return false;
}
static inline bool reg_is_us_alpha2(uint8_t *alpha2)
{
return false;
}
static inline QDF_STATUS reg_set_country(struct wlan_objmgr_pdev *pdev,
uint8_t *country)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev,
bool enable)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS reg_get_domain_from_country_code(
v_REGDOMAIN_t *reg_domain_ptr, const uint8_t *country_alpha2,
enum country_src source)
{
return QDF_STATUS_SUCCESS;
}
static inline bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return false;
}
static inline bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return false;
}
static inline QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
struct reg_config_vars config_vars)
{
return QDF_STATUS_SUCCESS;
}
static inline bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc)
{
return false;
}
static inline void reg_program_mas_chan_list(
struct wlan_objmgr_psoc *psoc,
struct regulatory_channel *reg_channels,
uint8_t *alpha2, enum dfs_reg dfs_region)
{
}
static inline QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
struct reg_rule_info *reg_rules)
{
return QDF_STATUS_SUCCESS;
}
static inline enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
uint8_t *alpha2)
{
return SOURCE_UNKNOWN;
}
static inline void
reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj *soc_reg)
{
}
static inline QDF_STATUS reg_set_curr_country(
struct wlan_regulatory_psoc_priv_obj *soc_reg,
struct cur_regulatory_info *regulat_info,
struct wlan_lmac_if_reg_tx_ops *tx_ops)
{
return QDF_STATUS_SUCCESS;
}
static inline
bool reg_ignore_default_country(struct wlan_regulatory_psoc_priv_obj *soc_reg,
struct cur_regulatory_info *regulat_info)
{
return false;
}
#endif
#if defined(WLAN_FEATURE_DSRC) && defined(CONFIG_MCL_REGDB)
/**
* reg_is_dsrc_chan () - Checks the channel for DSRC or not
* @chan: channel
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan);
static inline bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return false;
}
static inline bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
{
return false;
}
static inline bool
reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
{
return true;
}
#elif defined(CONFIG_MCL_REGDB)
static inline bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return false;
}
/**
* reg_is_etsi13_regdmn () - Checks if the current reg domain is ETSI13 or not
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev);
/**
* reg_is_etsi13_srd_chan () - Checks the channel for ETSI13 srd ch or not
* @chan: channel
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan);
/**
* reg_is_etsi13_srd_chan_allowed_master_mode() - Checks if regdmn is ETSI13
* and SRD channels are allowed in master mode or not.
*
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev);
#else
static inline bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return false;
}
static inline bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
{
return false;
}
static inline bool
reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
{
return false;
}
static inline bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return false;
}
#endif
#if defined(DISABLE_CHANNEL_LIST) && defined(CONFIG_MCL_REGDB)
/**
* set_disable_channel_state() - Set disable channel state flag
* @pdev_priv_obj: Pointer to pdev object
*/
void set_disable_channel_state(
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj);
#else
static inline void set_disable_channel_state(
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj)
{
}
#endif
#endif

Переглянути файл

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2019 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
@@ -20,11 +20,15 @@
* DOC: Add host 11d scan utility functions
*/
#include <wlan_cmn.h>
#include <reg_services_public_struct.h>
#include <wlan_scan_public_structs.h>
#include <wlan_scan_ucfg_api.h>
#include "reg_services.h"
#include "reg_priv.h"
#include <wlan_objmgr_psoc_obj.h>
#include "reg_priv_objs.h"
#include "reg_getset.h"
#include "reg_host_11d.h"
#include "reg_services_common.h"
static QDF_STATUS reg_11d_scan_trigger_handler(
struct wlan_regulatory_psoc_priv_obj *soc_reg)
@@ -170,3 +174,388 @@ QDF_STATUS reg_11d_host_scan_deinit(struct wlan_objmgr_psoc *psoc)
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_priv_obj;
struct set_country country_code;
struct wlan_objmgr_psoc *psoc;
struct cc_regdmn_s rd;
QDF_STATUS status;
struct wlan_lmac_if_reg_tx_ops *tx_ops;
uint8_t pdev_id;
if (!country) {
reg_err("country code is NULL");
return QDF_STATUS_E_INVAL;
}
pdev_id = wlan_objmgr_pdev_get_pdev_id(pdev);
psoc = wlan_pdev_get_psoc(pdev);
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_INVAL;
}
if (!qdf_mem_cmp(psoc_priv_obj->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 = pdev_id;
psoc_priv_obj->new_11d_ctry_pending[pdev_id] = true;
if (psoc_priv_obj->offload_enabled) {
tx_ops = reg_get_psoc_tx_ops(psoc);
if (tx_ops->set_country_code) {
tx_ops->set_country_code(psoc, &country_code);
} else {
reg_err("country set fw handler not present");
psoc_priv_obj->new_11d_ctry_pending[pdev_id] = false;
return QDF_STATUS_E_FAULT;
}
status = QDF_STATUS_SUCCESS;
} 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;
}
/**
* reg_send_11d_flush_cbk() - release 11d psoc reference
* @msg: Pointer to scheduler message.
*
* Return: QDF_STATUS
*/
static QDF_STATUS reg_send_11d_flush_cbk(struct scheduler_msg *msg)
{
struct wlan_objmgr_psoc *psoc = msg->bodyptr;
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
return QDF_STATUS_SUCCESS;
}
/**
* reg_send_11d_msg_cbk() - Send start/stop 11d scan message.
* @msg: Pointer to scheduler message.
*
* Return: QDF_STATUS
*/
static QDF_STATUS reg_send_11d_msg_cbk(struct scheduler_msg *msg)
{
struct wlan_objmgr_psoc *psoc = msg->bodyptr;
struct wlan_lmac_if_reg_tx_ops *tx_ops;
struct reg_start_11d_scan_req start_req;
struct reg_stop_11d_scan_req stop_req;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
tx_ops = reg_get_psoc_tx_ops(psoc);
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("psoc priv obj is NULL");
return QDF_STATUS_E_FAILURE;
}
if (psoc_priv_obj->enable_11d_supp) {
start_req.vdev_id = psoc_priv_obj->vdev_id_for_11d_scan;
start_req.scan_period_msec = psoc_priv_obj->scan_11d_interval;
start_req.start_interval_msec = 0;
reg_debug("sending start msg");
tx_ops->start_11d_scan(psoc, &start_req);
} else {
stop_req.vdev_id = psoc_priv_obj->vdev_id_for_11d_scan;
reg_debug("sending stop msg");
tx_ops->stop_11d_scan(psoc, &stop_req);
}
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
return QDF_STATUS_SUCCESS;
}
/**
* reg_sched_11d_msg() - Schedules 11d scan message.
* @psoc: soc context
*/
static QDF_STATUS reg_sched_11d_msg(struct wlan_objmgr_psoc *psoc)
{
struct scheduler_msg msg = {0};
QDF_STATUS status;
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_SB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
reg_err("error taking psoc ref cnt");
return status;
}
msg.bodyptr = psoc;
msg.callback = reg_send_11d_msg_cbk;
msg.flush_callback = reg_send_11d_flush_cbk;
status = scheduler_post_message(QDF_MODULE_ID_REGULATORY,
QDF_MODULE_ID_REGULATORY,
QDF_MODULE_ID_TARGET_IF, &msg);
if (QDF_IS_STATUS_ERROR(status)) {
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_SB_ID);
reg_err("scheduler msg posting failed");
}
return status;
}
void reg_run_11d_state_machine(struct wlan_objmgr_psoc *psoc)
{
bool temp_11d_support;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
bool world_mode;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return;
}
world_mode = reg_is_world_alpha2(psoc_priv_obj->cur_country);
temp_11d_support = psoc_priv_obj->enable_11d_supp;
if ((psoc_priv_obj->enable_11d_in_world_mode) && (world_mode))
psoc_priv_obj->enable_11d_supp = true;
else if (((psoc_priv_obj->user_ctry_set) &&
(psoc_priv_obj->user_ctry_priority)) ||
(psoc_priv_obj->master_vdev_cnt))
psoc_priv_obj->enable_11d_supp = false;
else
psoc_priv_obj->enable_11d_supp =
psoc_priv_obj->enable_11d_supp_original;
reg_debug("inside 11d state machine:tmp %d 11d_supp %d org %d set %d pri %d cnt %d vdev %d",
temp_11d_support,
psoc_priv_obj->enable_11d_supp,
psoc_priv_obj->enable_11d_supp_original,
psoc_priv_obj->user_ctry_set,
psoc_priv_obj->user_ctry_priority,
psoc_priv_obj->master_vdev_cnt,
psoc_priv_obj->vdev_id_for_11d_scan);
if (temp_11d_support != psoc_priv_obj->enable_11d_supp) {
if (psoc_priv_obj->is_11d_offloaded)
reg_sched_11d_msg(psoc);
else
reg_11d_host_scan(psoc_priv_obj);
}
}
QDF_STATUS reg_11d_vdev_created_update(struct wlan_objmgr_vdev *vdev)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_objmgr_pdev *parent_pdev;
struct wlan_objmgr_psoc *parent_psoc;
uint32_t vdev_id;
enum QDF_OPMODE op_mode;
uint8_t i;
op_mode = wlan_vdev_mlme_get_opmode(vdev);
parent_pdev = wlan_vdev_get_pdev(vdev);
parent_psoc = wlan_pdev_get_psoc(parent_pdev);
psoc_priv_obj = reg_get_psoc_obj(parent_psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return QDF_STATUS_E_FAULT;
}
if ((op_mode == QDF_STA_MODE) ||
(op_mode == QDF_P2P_DEVICE_MODE) ||
(op_mode == QDF_P2P_CLIENT_MODE)) {
vdev_id = wlan_vdev_get_id(vdev);
if (!psoc_priv_obj->vdev_cnt_11d) {
psoc_priv_obj->vdev_id_for_11d_scan = vdev_id;
reg_debug("running 11d state machine, opmode %d",
op_mode);
reg_run_11d_state_machine(parent_psoc);
}
for (i = 0; i < MAX_STA_VDEV_CNT; i++) {
if (psoc_priv_obj->vdev_ids_11d[i] == INVALID_VDEV_ID) {
psoc_priv_obj->vdev_ids_11d[i] = vdev_id;
break;
}
}
psoc_priv_obj->vdev_cnt_11d++;
}
if ((op_mode == QDF_P2P_GO_MODE) || (op_mode == QDF_SAP_MODE)) {
reg_debug("running 11d state machine, opmode %d", op_mode);
psoc_priv_obj->master_vdev_cnt++;
reg_run_11d_state_machine(parent_psoc);
}
return QDF_STATUS_SUCCESS;
}
QDF_STATUS reg_11d_vdev_delete_update(struct wlan_objmgr_vdev *vdev)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_objmgr_pdev *parent_pdev;
struct wlan_objmgr_psoc *parent_psoc;
enum QDF_OPMODE op_mode;
uint32_t vdev_id;
uint8_t i;
if (!vdev) {
reg_err("vdev is NULL");
return QDF_STATUS_E_INVAL;
}
op_mode = wlan_vdev_mlme_get_opmode(vdev);
parent_pdev = wlan_vdev_get_pdev(vdev);
parent_psoc = wlan_pdev_get_psoc(parent_pdev);
psoc_priv_obj = reg_get_psoc_obj(parent_psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return QDF_STATUS_E_FAULT;
}
if ((op_mode == QDF_P2P_GO_MODE) || (op_mode == QDF_SAP_MODE)) {
psoc_priv_obj->master_vdev_cnt--;
reg_debug("run 11d state machine, deleted opmode %d",
op_mode);
reg_run_11d_state_machine(parent_psoc);
return QDF_STATUS_SUCCESS;
}
if ((op_mode == QDF_STA_MODE) || (op_mode == QDF_P2P_DEVICE_MODE) ||
(op_mode == QDF_P2P_CLIENT_MODE)) {
vdev_id = wlan_vdev_get_id(vdev);
for (i = 0; i < MAX_STA_VDEV_CNT; i++) {
if (psoc_priv_obj->vdev_ids_11d[i] == vdev_id) {
psoc_priv_obj->vdev_ids_11d[i] =
INVALID_VDEV_ID;
psoc_priv_obj->vdev_cnt_11d--;
break;
}
}
if ((psoc_priv_obj->vdev_id_for_11d_scan != vdev_id) ||
!psoc_priv_obj->vdev_cnt_11d)
return QDF_STATUS_SUCCESS;
for (i = 0; i < MAX_STA_VDEV_CNT; i++) {
if (psoc_priv_obj->vdev_ids_11d[i] == INVALID_VDEV_ID)
continue;
psoc_priv_obj->vdev_id_for_11d_scan =
psoc_priv_obj->vdev_ids_11d[i];
psoc_priv_obj->enable_11d_supp = false;
reg_debug("running 11d state machine, vdev %d",
psoc_priv_obj->vdev_id_for_11d_scan);
reg_run_11d_state_machine(parent_psoc);
break;
}
}
return QDF_STATUS_SUCCESS;
}
bool reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return false;
}
return psoc_priv_obj->enable_11d_supp;
}
QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_lmac_if_reg_tx_ops *tx_ops;
struct set_country country_code;
uint8_t pdev_id;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return QDF_STATUS_E_FAILURE;
}
pdev_id = psoc_priv_obj->def_pdev_id;
psoc_priv_obj->new_11d_ctry_pending[pdev_id] = true;
qdf_mem_copy(country_code.country, country, REG_ALPHA2_LEN + 1);
country_code.pdev_id = pdev_id;
if (psoc_priv_obj->offload_enabled) {
tx_ops = reg_get_psoc_tx_ops(psoc);
if (tx_ops->set_country_code) {
tx_ops->set_country_code(psoc, &country_code);
} else {
reg_err("country set handler is not present");
psoc_priv_obj->new_11d_ctry_pending[pdev_id] = false;
return QDF_STATUS_E_FAULT;
}
}
return QDF_STATUS_SUCCESS;
}
bool reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return QDF_STATUS_E_FAILURE;
}
return (psoc_priv_obj->enable_11d_supp &&
!psoc_priv_obj->is_11d_offloaded);
}
QDF_STATUS reg_set_11d_offloaded(struct wlan_objmgr_psoc *psoc, bool val)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("psoc reg component is NULL");
return QDF_STATUS_E_FAILURE;
}
psoc_priv_obj->is_11d_offloaded = val;
reg_debug("set is_11d_offloaded %d", val);
return QDF_STATUS_SUCCESS;
}
bool reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc)
{
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return false;
}
return psoc_priv_obj->is_11d_offloaded;
}

Переглянути файл

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2018 The Linux Foundation. All rights reserved.
* Copyright (c) 2018-2019 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
@@ -31,15 +31,14 @@
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS reg_11d_host_scan(
struct wlan_regulatory_psoc_priv_obj *soc_reg);
QDF_STATUS reg_11d_host_scan(struct wlan_regulatory_psoc_priv_obj *soc_reg);
/**
* reg_11d_host_scan_init() - Inid 11d host scan resource
* reg_11d_host_scan_init() - Init 11d host scan resource
* @psoc: soc context
*
* This function gets called during pdev create notification callback to
* init the 11d scan related resouce.
* init the 11d scan related resource.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
@@ -50,12 +49,89 @@ QDF_STATUS reg_11d_host_scan_init(struct wlan_objmgr_psoc *psoc);
* @psoc: soc context
*
* This function gets called during pdev destroy notification callback to
* deinit the 11d scan related resouce.
* deinit the 11d scan related resource.
*
* Return: QDF_STATUS_SUCCESS - in case of success
*/
QDF_STATUS reg_11d_host_scan_deinit(struct wlan_objmgr_psoc *psoc);
/**
* reg_run_11d_state_machine() - 11d state machine function.
* @psoc: soc context
*/
void reg_run_11d_state_machine(struct wlan_objmgr_psoc *psoc);
/**
* 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_is_11d_scan_inprogress() - Check 11d scan is supported
* @psoc: psoc ptr
*
* Return: true if 11d scan supported, else false.
*/
bool reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc);
/**
* reg_save_new_11d_country() - Save the 11d new country
* @psoc: psoc for country information
* @country: country value
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country);
/**
* reg_is_11d_offloaded() - whether 11d offloaded supported or not
* @psoc: psoc ptr
*
* Return: bool
*/
bool reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc);
/**
* reg_11d_enabled_on_host() - know whether 11d enabled on host
* @psoc: psoc ptr
*
* Return: bool
*/
bool reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc);
/**
* reg_11d_vdev_created_update() - vdev obj create callback
* @vdev: vdev pointer
*
* updates 11d state when a vdev is created.
*
* Return: Success or Failure
*/
QDF_STATUS reg_11d_vdev_created_update(struct wlan_objmgr_vdev *vdev);
/**
* reg_11d_vdev_delete_update() - update 11d state upon vdev delete
* @vdev: vdev pointer
*
* Return: Success or Failure
*/
QDF_STATUS reg_11d_vdev_delete_update(struct wlan_objmgr_vdev *vdev);
/**
* reg_set_11d_offloaded() - Set 11d offloaded flag
* @psoc: psoc ptr
* @val: 11d offloaded value
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_11d_offloaded(struct wlan_objmgr_psoc *psoc, bool val);
#else
static inline QDF_STATUS reg_11d_host_scan(
struct wlan_regulatory_psoc_priv_obj *soc_reg)
{
@@ -67,8 +143,56 @@ static inline QDF_STATUS reg_11d_host_scan_init(struct wlan_objmgr_psoc *psoc)
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS reg_11d_host_scan_deinit(
struct wlan_objmgr_psoc *psoc)
static inline QDF_STATUS reg_11d_host_scan_deinit(struct wlan_objmgr_psoc *psoc)
{
return QDF_STATUS_SUCCESS;
}
static inline void reg_run_11d_state_machine(struct wlan_objmgr_psoc *psoc)
{
}
static inline QDF_STATUS reg_set_11d_country(struct wlan_objmgr_pdev *pdev,
uint8_t *country)
{
return QDF_STATUS_SUCCESS;
}
static inline bool reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc)
{
return false;
}
static inline QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country)
{
return QDF_STATUS_SUCCESS;
}
static inline bool reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc)
{
return false;
}
static inline bool reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc)
{
return false;
}
static inline QDF_STATUS reg_11d_vdev_delete_update(
struct wlan_objmgr_vdev *vdev)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS reg_11d_vdev_created_update(
struct wlan_objmgr_vdev *vdev)
{
return QDF_STATUS_SUCCESS;
}
static inline QDF_STATUS reg_set_11d_offloaded(struct wlan_objmgr_psoc *psoc,
bool val)
{
return QDF_STATUS_SUCCESS;
}

236
umac/regulatory/core/src/reg_lte.c Звичайний файл
Переглянути файл

@@ -0,0 +1,236 @@
/*
* Copyright (c) 2014-2019 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: reg_lte.c
* This file contains the LTE feature APIs.
*/
#include <qdf_status.h>
#include <qdf_types.h>
#include <wlan_cmn.h>
#include "reg_services_public_struct.h"
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include "reg_services_common.h"
#include "reg_priv_objs.h"
#include "reg_build_chan_list.h"
#include "reg_callbacks.h"
#include "reg_lte.h"
#ifdef CONFIG_LTE_COEX
/**
* reg_process_ch_avoid_freq() - Update unsafe frequencies in psoc_priv_obj
* @psoc: pointer to psoc object
* @pdev: pointer to pdev object
*
* Return: QDF_STATUS
*/
static QDF_STATUS reg_process_ch_avoid_freq(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev)
{
enum channel_enum ch_loop;
enum channel_enum start_ch_idx;
enum channel_enum end_ch_idx;
uint16_t start_channel;
uint16_t end_channel;
uint32_t i;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct ch_avoid_freq_type *range;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return QDF_STATUS_E_FAILURE;
}
for (i = 0; i < psoc_priv_obj->avoid_freq_list.ch_avoid_range_cnt;
i++) {
if (psoc_priv_obj->unsafe_chan_list.ch_cnt >= NUM_CHANNELS) {
reg_warn("LTE Coex unsafe channel list full");
break;
}
start_ch_idx = INVALID_CHANNEL;
end_ch_idx = INVALID_CHANNEL;
range = &psoc_priv_obj->avoid_freq_list.avoid_freq_range[i];
start_channel = reg_freq_to_chan(pdev, range->start_freq);
end_channel = reg_freq_to_chan(pdev, range->end_freq);
reg_debug("start: freq %d, ch %d, end: freq %d, ch %d",
range->start_freq, start_channel, range->end_freq,
end_channel);
/* do not process frequency bands that are not mapped to
* predefined channels
*/
if (start_channel == 0 || end_channel == 0)
continue;
for (ch_loop = 0; ch_loop < NUM_CHANNELS;
ch_loop++) {
if (REG_CH_TO_FREQ(ch_loop) >= range->start_freq) {
start_ch_idx = ch_loop;
break;
}
}
for (ch_loop = 0; ch_loop < NUM_CHANNELS;
ch_loop++) {
if (REG_CH_TO_FREQ(ch_loop) >= range->end_freq) {
end_ch_idx = ch_loop;
if (REG_CH_TO_FREQ(ch_loop) > range->end_freq)
end_ch_idx--;
break;
}
}
if (start_ch_idx == INVALID_CHANNEL ||
end_ch_idx == INVALID_CHANNEL)
continue;
for (ch_loop = start_ch_idx; ch_loop <= end_ch_idx;
ch_loop++) {
psoc_priv_obj->unsafe_chan_list.ch_list[
psoc_priv_obj->unsafe_chan_list.ch_cnt++] =
REG_CH_NUM(ch_loop);
if (psoc_priv_obj->unsafe_chan_list.ch_cnt >=
NUM_CHANNELS) {
reg_warn("LTECoex unsafe ch list full");
break;
}
}
}
reg_debug("number of unsafe channels is %d ",
psoc_priv_obj->unsafe_chan_list.ch_cnt);
if (!psoc_priv_obj->unsafe_chan_list.ch_cnt) {
reg_debug("No valid ch are present in avoid freq event");
return QDF_STATUS_SUCCESS;
}
for (ch_loop = 0; ch_loop < psoc_priv_obj->unsafe_chan_list.ch_cnt;
ch_loop++) {
if (ch_loop >= NUM_CHANNELS)
break;
reg_debug("channel %d is not safe",
psoc_priv_obj->unsafe_chan_list.ch_list[ch_loop]);
}
return QDF_STATUS_SUCCESS;
}
/**
* reg_update_unsafe_ch() - Updates unsafe channels in current channel list
* @psoc: Pointer to psoc structure
* @object: Pointer to pdev structure
* @arg: List of arguments
*
* Return: None
*/
static void reg_update_unsafe_ch(struct wlan_objmgr_psoc *psoc,
void *object, void *arg)
{
struct wlan_objmgr_pdev *pdev = (struct wlan_objmgr_pdev *)object;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
QDF_STATUS status;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return;
}
pdev_priv_obj = reg_get_pdev_obj(pdev);
if (!IS_VALID_PDEV_REG_OBJ(pdev_priv_obj)) {
reg_err("reg pdev priv obj is NULL");
return;
}
if (psoc_priv_obj->ch_avoid_ind) {
status = reg_process_ch_avoid_freq(psoc, pdev);
if (QDF_IS_STATUS_ERROR(status))
psoc_priv_obj->ch_avoid_ind = false;
}
reg_compute_pdev_current_chan_list(pdev_priv_obj);
status = reg_send_scheduler_msg_nb(psoc, pdev);
if (QDF_IS_STATUS_ERROR(status))
reg_err("channel change msg schedule failed");
}
QDF_STATUS reg_process_ch_avoid_event(struct wlan_objmgr_psoc *psoc,
struct ch_avoid_ind_type *ch_avoid_event)
{
uint32_t i;
struct wlan_regulatory_psoc_priv_obj *psoc_priv_obj;
QDF_STATUS status;
psoc_priv_obj = reg_get_psoc_obj(psoc);
if (!psoc_priv_obj) {
reg_err("reg psoc private obj is NULL");
return QDF_STATUS_E_FAILURE;
}
/* Make unsafe channel list */
reg_debug("band count %d", ch_avoid_event->ch_avoid_range_cnt);
/* generate vendor specific event */
qdf_mem_zero(&psoc_priv_obj->avoid_freq_list,
sizeof(struct ch_avoid_ind_type));
qdf_mem_zero(&psoc_priv_obj->unsafe_chan_list,
sizeof(struct unsafe_ch_list));
for (i = 0; i < ch_avoid_event->ch_avoid_range_cnt; i++) {
if ((CH_AVOID_RULE_RESTART_24G_ONLY ==
psoc_priv_obj->restart_beaconing) &&
REG_IS_5GHZ_FREQ(ch_avoid_event->
avoid_freq_range[i].start_freq)) {
reg_debug(
"skipping 5Ghz LTE Coex unsafe channel range");
continue;
}
psoc_priv_obj->avoid_freq_list.avoid_freq_range[i].start_freq =
ch_avoid_event->avoid_freq_range[i].start_freq;
psoc_priv_obj->avoid_freq_list.avoid_freq_range[i].end_freq =
ch_avoid_event->avoid_freq_range[i].end_freq;
}
psoc_priv_obj->avoid_freq_list.ch_avoid_range_cnt =
ch_avoid_event->ch_avoid_range_cnt;
psoc_priv_obj->ch_avoid_ind = true;
status = wlan_objmgr_psoc_try_get_ref(psoc, WLAN_REGULATORY_NB_ID);
if (QDF_IS_STATUS_ERROR(status)) {
reg_err("error taking psoc ref cnt");
return status;
}
status = wlan_objmgr_iterate_obj_list(
psoc, WLAN_PDEV_OP, reg_update_unsafe_ch, NULL, 1,
WLAN_REGULATORY_NB_ID);
wlan_objmgr_psoc_release_ref(psoc, WLAN_REGULATORY_NB_ID);
return status;
}
#endif

44
umac/regulatory/core/src/reg_lte.h Звичайний файл
Переглянути файл

@@ -0,0 +1,44 @@
/*
* Copyright (c) 2017-2019 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: reg_db_lte.h
* This file provides prototypes of the regulatory component
* LTE functions
*/
#ifdef CONFIG_LTE_COEX
/**
* reg_process_ch_avoid_event() - Process channel avoid event
* @psoc: psoc for country information
* @ch_avoid_event: channel avoid event buffer
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_process_ch_avoid_event(
struct wlan_objmgr_psoc *psoc,
struct ch_avoid_ind_type *ch_avoid_event);
#else
static inline QDF_STATUS reg_process_ch_avoid_event(
struct wlan_objmgr_psoc *psoc,
struct ch_avoid_ind_type *ch_avoid_event)
{
return QDF_STATUS_SUCCESS;
}
#endif

217
umac/regulatory/core/src/reg_opclass.c Звичайний файл
Переглянути файл

@@ -0,0 +1,217 @@
/*
* Copyright (c) 2014-2019 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: reg_opclass.c
* This file defines regulatory opclass functions.
*/
#include <qdf_types.h>
#include <wlan_cmn.h>
#include <reg_services_public_struct.h>
#include <wlan_objmgr_psoc_obj.h>
#include "reg_priv_objs.h"
#include "reg_getset.h"
#include "reg_db.h"
#include "reg_db_parser.h"
#include "reg_host_11d.h"
#include <scheduler_api.h>
#include "reg_build_chan_list.h"
#include "reg_opclass.h"
#ifdef HOST_OPCLASS
static struct reg_dmn_supp_op_classes reg_dmn_curr_supp_opp_classes = { 0 };
#endif
static const struct reg_dmn_op_class_map_t global_op_class[] = {
{81, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} },
{82, 25, BW20, {14} },
{83, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7, 8, 9} },
{84, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11, 12, 13} },
{115, 20, BW20, {36, 40, 44, 48} },
{116, 40, BW40_LOW_PRIMARY, {36, 44} },
{117, 40, BW40_HIGH_PRIMARY, {40, 48} },
{118, 20, BW20, {52, 56, 60, 64} },
{119, 40, BW40_LOW_PRIMARY, {52, 60} },
{120, 40, BW40_HIGH_PRIMARY, {56, 64} },
{121, 20, BW20,
{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} },
{122, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} },
{123, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} },
{125, 20, BW20, {149, 153, 157, 161, 165, 169} },
{126, 40, BW40_LOW_PRIMARY, {149, 157} },
{127, 40, BW40_HIGH_PRIMARY, {153, 161} },
{128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108,
112, 116, 120, 124, 128, 132, 136, 140, 144,
149, 153, 157, 161} },
{0, 0, 0, {0} },
};
static const struct reg_dmn_op_class_map_t us_op_class[] = {
{1, 20, BW20, {36, 40, 44, 48} },
{2, 20, BW20, {52, 56, 60, 64} },
{4, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140,
144} },
{5, 20, BW20, {149, 153, 157, 161, 165} },
{12, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11} },
{22, 40, BW40_LOW_PRIMARY, {36, 44} },
{23, 40, BW40_LOW_PRIMARY, {52, 60} },
{24, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} },
{26, 40, BW40_LOW_PRIMARY, {149, 157} },
{27, 40, BW40_HIGH_PRIMARY, {40, 48} },
{28, 40, BW40_HIGH_PRIMARY, {56, 64} },
{29, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} },
{31, 40, BW40_HIGH_PRIMARY, {153, 161} },
{32, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7} },
{33, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11} },
{128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108,
112, 116, 120, 124, 128, 132, 136, 140, 144,
149, 153, 157, 161} },
{0, 0, 0, {0} },
};
static const struct reg_dmn_op_class_map_t euro_op_class[] = {
{1, 20, BW20, {36, 40, 44, 48} },
{2, 20, BW20, {52, 56, 60, 64} },
{3, 20, BW20, {100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} },
{4, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} },
{5, 40, BW40_LOW_PRIMARY, {36, 44} },
{6, 40, BW40_LOW_PRIMARY, {52, 60} },
{7, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} },
{8, 40, BW40_HIGH_PRIMARY, {40, 48} },
{9, 40, BW40_HIGH_PRIMARY, {56, 64} },
{10, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} },
{11, 40, BW40_LOW_PRIMARY, {1, 2, 3, 4, 5, 6, 7, 8, 9} },
{12, 40, BW40_HIGH_PRIMARY, {5, 6, 7, 8, 9, 10, 11, 12, 13} },
{17, 20, BW20, {149, 153, 157, 161, 165, 169} },
{128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
116, 120, 124, 128} },
{0, 0, 0, {0} },
};
static const struct reg_dmn_op_class_map_t japan_op_class[] = {
{1, 20, BW20, {36, 40, 44, 48} },
{30, 25, BW20, {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13} },
{31, 25, BW20, {14} },
{32, 20, BW20, {52, 56, 60, 64} },
{34, 20, BW20,
{100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140} },
{36, 40, BW40_LOW_PRIMARY, {36, 44} },
{37, 40, BW40_LOW_PRIMARY, {52, 60} },
{39, 40, BW40_LOW_PRIMARY, {100, 108, 116, 124, 132} },
{41, 40, BW40_HIGH_PRIMARY, {40, 48} },
{42, 40, BW40_HIGH_PRIMARY, {56, 64} },
{44, 40, BW40_HIGH_PRIMARY, {104, 112, 120, 128, 136} },
{128, 80, BW80, {36, 40, 44, 48, 52, 56, 60, 64, 100, 104, 108, 112,
116, 120, 124, 128} },
{0, 0, 0, {0} },
};
#ifdef HOST_OPCLASS
uint16_t reg_dmn_get_chanwidth_from_opclass(uint8_t *country, uint8_t channel,
uint8_t opclass)
{
const struct reg_dmn_op_class_map_t *class;
uint16_t i;
if (!qdf_mem_cmp(country, "US", 2))
class = us_op_class;
else if (!qdf_mem_cmp(country, "EU", 2))
class = euro_op_class;
else if (!qdf_mem_cmp(country, "JP", 2))
class = japan_op_class;
else
class = global_op_class;
while (class->op_class) {
if (opclass == class->op_class) {
for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS &&
class->channels[i]); i++) {
if (channel == class->channels[i])
return class->ch_spacing;
}
}
class++;
}
return 0;
}
uint16_t reg_dmn_get_opclass_from_channel(uint8_t *country, uint8_t channel,
uint8_t offset)
{
const struct reg_dmn_op_class_map_t *class = NULL;
uint16_t i = 0;
if (!qdf_mem_cmp(country, "US", 2))
class = us_op_class;
else if (!qdf_mem_cmp(country, "EU", 2))
class = euro_op_class;
else if (!qdf_mem_cmp(country, "JP", 2))
class = japan_op_class;
else
class = global_op_class;
while (class->op_class) {
if ((offset == class->offset) || (offset == BWALL)) {
for (i = 0; (i < REG_MAX_CHANNELS_PER_OPERATING_CLASS &&
class->channels[i]); i++) {
if (channel == class->channels[i])
return class->op_class;
}
}
class++;
}
return 0;
}
uint16_t reg_dmn_set_curr_opclasses(uint8_t num_classes, uint8_t *class)
{
uint8_t i;
if (num_classes > REG_MAX_SUPP_OPER_CLASSES) {
reg_err("invalid num classes %d", num_classes);
return 0;
}
for (i = 0; i < num_classes; i++)
reg_dmn_curr_supp_opp_classes.classes[i] = class[i];
reg_dmn_curr_supp_opp_classes.num_classes = num_classes;
return 0;
}
uint16_t reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class)
{
uint8_t i;
if (!num_classes || !class) {
reg_err("either num_classes or class is null");
return 0;
}
for (i = 0; i < reg_dmn_curr_supp_opp_classes.num_classes; i++)
class[i] = reg_dmn_curr_supp_opp_classes.classes[i];
*num_classes = reg_dmn_curr_supp_opp_classes.num_classes;
return 0;
}
#endif

95
umac/regulatory/core/src/reg_opclass.h Звичайний файл
Переглянути файл

@@ -0,0 +1,95 @@
/*
* Copyright (c) 2017-2019 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: reg_opclass.h
* This file provides prototypes of the regulatory opclass functions
*/
#ifndef __REG_OPCLASS_H__
#define __REG_OPCLASS_H__
#ifdef HOST_OPCLASS
/**
* reg_dmn_get_chanwidth_from_opclass() - Get channel width from opclass.
* @country: Country code
* @channel: Channel number
* @opclass: Operating class
*
* Return: Channel width
*/
uint16_t reg_dmn_get_chanwidth_from_opclass(uint8_t *country, uint8_t channel,
uint8_t opclass);
/**
* reg_dmn_get_opclass_from_channel() - Get operating class from channel.
* @country: Country code.
* @channel: Channel number.
* @offset: Operating class offset.
*
* Return: Error code.
*/
uint16_t reg_dmn_get_opclass_from_channel(uint8_t *country, uint8_t channel,
uint8_t offset);
/**
* reg_dmn_set_curr_opclasses() - Set current operating class
* @num_classes: Number of classes
* @class: Pointer to operating class.
*
* Return: Error code.
*/
uint16_t reg_dmn_set_curr_opclasses(uint8_t num_classes, uint8_t *class);
/**
* reg_dmn_get_curr_opclasses() - Get current supported operating classes.
* @num_classes: Number of classes.
* @class: Pointer to operating class.
*
* Return: Error code.
*/
uint16_t reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class);
#else
static inline uint16_t reg_dmn_get_chanwidth_from_opclass(
uint8_t *country, uint8_t channel, uint8_t opclass)
{
return 0;
}
static inline uint16_t reg_dmn_set_curr_opclasses(
uint8_t num_classes, uint8_t *class)
{
return 0;
}
static inline uint16_t reg_dmn_get_curr_opclasses(
uint8_t *num_classes, uint8_t *class)
{
return 0;
}
static inline uint16_t reg_dmn_get_opclass_from_channel(
uint8_t *country, uint8_t channel, uint8_t offset)
{
return 0;
}
#endif
#endif

Різницю між файлами не показано, бо вона завелика Завантажити різницю

Переглянути файл

@@ -1,687 +0,0 @@
/*
* Copyright (c) 2017-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: reg_services.h
* This file provides prototypes of the regulatory component
* service functions
*/
#ifndef __REG_SERVICES_H_
#define __REG_SERVICES_H_
#include <qdf_types.h>
#include <qdf_status.h>
#include <wlan_objmgr_cmn.h>
#include <wlan_objmgr_global_obj.h>
#include <wlan_objmgr_psoc_obj.h>
#include <wlan_objmgr_pdev_obj.h>
#include <wlan_objmgr_vdev_obj.h>
#include "reg_db.h"
#include <reg_services_public_struct.h>
#define REG_MIN_24GHZ_CH_NUM channel_map[MIN_24GHZ_CHANNEL].chan_num
#define REG_MAX_24GHZ_CH_NUM channel_map[MAX_24GHZ_CHANNEL].chan_num
#define REG_MIN_5GHZ_CH_NUM channel_map[MIN_5GHZ_CHANNEL].chan_num
#define REG_MAX_5GHZ_CH_NUM channel_map[MAX_5GHZ_CHANNEL].chan_num
#ifdef WLAN_FEATURE_DSRC
#define REG_DSRC_START_FREQ channel_map[MIN_DSRC_CHANNEL].center_freq
#define REG_DSRC_END_FREQ channel_map[MAX_DSRC_CHANNEL].center_freq
#endif
#define REG_ETSI13_SRD_START_FREQ 5745
#define REG_ETSI13_SRD_END_FREQ 5865
#define REG_IS_24GHZ_CH(chan_num) \
((chan_num >= REG_MIN_24GHZ_CH_NUM) && \
(chan_num <= REG_MAX_24GHZ_CH_NUM))
#define REG_MIN_24GHZ_CH_FREQ channel_map[MIN_24GHZ_CHANNEL].center_freq
#define REG_MAX_24GHZ_CH_FREQ channel_map[MAX_24GHZ_CHANNEL].center_freq
#define REG_IS_24GHZ_CH_FREQ(freq) \
((freq >= REG_MIN_24GHZ_CH_FREQ) && \
(freq <= REG_MAX_24GHZ_CH_FREQ))
#ifndef CONFIG_LEGACY_CHAN_ENUM
#define REG_MIN_49GHZ_CH_FREQ channel_map[MIN_49GHZ_CHANNEL].center_freq
#define REG_MAX_49GHZ_CH_FREQ channel_map[MAX_49GHZ_CHANNEL].center_freq
#define REG_IS_49GHZ_FREQ(freq) \
((freq >= REG_MIN_49GHZ_CH_FREQ) && \
(freq <= REG_MAX_49GHZ_CH_FREQ))
#endif
#define REG_IS_5GHZ_CH(chan_num) \
((chan_num >= REG_MIN_5GHZ_CH_NUM) && \
(chan_num <= REG_MAX_5GHZ_CH_NUM))
#define REG_IS_5GHZ_FREQ(freq) \
((freq >= channel_map[MIN_5GHZ_CHANNEL].center_freq) && \
(freq <= channel_map[MAX_5GHZ_CHANNEL].center_freq))
#define REG_CH_NUM(ch_enum) channel_map[ch_enum].chan_num
#define REG_CH_TO_FREQ(ch_enum) channel_map[ch_enum].center_freq
#define REG_IS_CHANNEL_VALID_5G_SBS(curchan, newchan) \
(curchan > newchan ? \
REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \
- REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \
> REG_SBS_SEPARATION_THRESHOLD : \
REG_CH_TO_FREQ(reg_get_chan_enum(newchan)) \
- REG_CH_TO_FREQ(reg_get_chan_enum(curchan)) \
> REG_SBS_SEPARATION_THRESHOLD)
#define IS_VALID_PSOC_REG_OBJ(psoc_priv_obj) (NULL != psoc_priv_obj)
#define IS_VALID_PDEV_REG_OBJ(pdev_priv_obj) (NULL != pdev_priv_obj)
/* EEPROM setting is a country code */
#define COUNTRY_ERD_FLAG 0x8000
extern const struct chan_map *channel_map;
enum channel_enum reg_get_chan_enum(uint32_t chan_num);
QDF_STATUS reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev,
struct channel_power *ch_list,
uint8_t *num_chan);
enum channel_state reg_get_channel_state(struct wlan_objmgr_pdev *pdev,
uint32_t ch);
/**
* reg_chan_has_dfs_attribute() - check channel has dfs attribue or not
* @ch: channel number.
*
* This API get chan initial dfs attribue flag from regdomain
*
* Return: true if chan is dfs, otherwise false
*/
bool reg_chan_has_dfs_attribute(struct wlan_objmgr_pdev *pdev, uint32_t ch);
enum channel_state reg_get_5g_bonded_channel_state(struct wlan_objmgr_pdev
*pdev,
uint8_t ch,
enum phy_ch_width bw);
enum channel_state reg_get_2g_bonded_channel_state(struct wlan_objmgr_pdev
*pdev,
uint8_t oper_ch,
uint8_t sec_ch,
enum phy_ch_width bw);
void reg_set_channel_params(struct wlan_objmgr_pdev *pdev,
uint8_t ch, uint8_t sec_ch_2g,
struct ch_params *ch_params);
/**
* reg_set_band() - Sets the band information for the PDEV
* @pdev: The physical dev to set the band for
* @band: The set band parameters to configure for the pysical device
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_band(struct wlan_objmgr_pdev *pdev, enum band_info band);
/**
* reg_restore_cached_channels() - Cache the current state of the channles
* @pdev: The physical dev to cache the channels for
*/
#ifdef DISABLE_CHANNEL_LIST
QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev);
#else
static inline
QDF_STATUS reg_restore_cached_channels(struct wlan_objmgr_pdev *pdev)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
* reg_cache_channel_state() - Cache the current state of the channles
* @pdev: The physical dev to cache the channels for
* @channel_list: List of the channels for which states needs to be cached
* @num_channels: Number of channels in the list
*
*/
#ifdef DISABLE_CHANNEL_LIST
QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev,
uint32_t *channel_list,
uint32_t num_channels);
#else
static inline
QDF_STATUS reg_cache_channel_state(struct wlan_objmgr_pdev *pdev,
uint32_t *channel_list,
uint32_t num_channels)
{
return QDF_STATUS_SUCCESS;
}
#endif
/**
* reg_notify_sap_event() - Notify regulatory domain for sap event
* @pdev: The physical dev to set the band for
* @sap_state: true for sap start else false
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_notify_sap_event(struct wlan_objmgr_pdev *pdev,
bool sap_state);
/**
* reg_set_fcc_constraint() - Apply fcc constraints on channels 12/13
* @pdev: The physical dev to set the band for
*
* This function reduces the transmit power on channels 12 and 13, to comply
* with FCC regulations in the USA.
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_fcc_constraint(struct wlan_objmgr_pdev *pdev,
bool fcc_constraint);
/**
* reg_read_default_country() - Get the default regulatory country
* @psoc: The physical SoC to get default country from
* @country_code: the buffer to populate the country code into
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_read_default_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country_code);
/**
* reg_read_current_country() - Get the current regulatory country
* @psoc: The physical SoC to get current country from
* @country_code: the buffer to populate the country code into
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_read_current_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country_code);
/**
* reg_set_default_country() - Set the default regulatory country
* @psoc: The physical SoC to set default country for
* @req: The country information to configure
*
* Return: QDF_STATUS
*/
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
* @country: country value
*
* Return: QDF_STATUS
*/
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
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_reset_country(struct wlan_objmgr_psoc *psoc);
/**
* reg_enable_dfs_channels() - Enable the use of DFS channels
* @pdev: The physical dev to enable/disable DFS channels for
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_enable_dfs_channels(struct wlan_objmgr_pdev *pdev, bool enable);
void reg_get_current_dfs_region(struct wlan_objmgr_pdev *pdev,
enum dfs_reg *dfs_reg);
uint32_t reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev,
uint32_t chan_num);
uint32_t reg_get_channel_freq(struct wlan_objmgr_pdev *pdev,
uint32_t chan_num);
uint16_t reg_get_bw_value(enum phy_ch_width bw);
void reg_set_dfs_region(struct wlan_objmgr_pdev *pdev,
enum dfs_reg dfs_reg);
QDF_STATUS reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
const uint8_t *country_alpha2,
enum country_src source);
enum band_info reg_chan_to_band(uint32_t chan_num);
uint16_t reg_dmn_get_chanwidth_from_opclass(uint8_t *country,
uint8_t channel,
uint8_t opclass);
uint16_t reg_dmn_get_opclass_from_channel(uint8_t *country,
uint8_t channel,
uint8_t offset);
uint16_t reg_dmn_set_curr_opclasses(uint8_t num_classes, uint8_t *class);
uint16_t reg_dmn_get_curr_opclasses(uint8_t *num_classes, uint8_t *class);
QDF_STATUS reg_process_master_chan_list(struct cur_regulatory_info *reg_info);
QDF_STATUS wlan_regulatory_psoc_obj_created_notification(
struct wlan_objmgr_psoc *psoc,
void *arg_list);
QDF_STATUS wlan_regulatory_psoc_obj_destroyed_notification(
struct wlan_objmgr_psoc *psoc,
void *arg_list);
QDF_STATUS wlan_regulatory_pdev_obj_created_notification(
struct wlan_objmgr_pdev *pdev,
void *arg_list);
QDF_STATUS wlan_regulatory_pdev_obj_destroyed_notification(
struct wlan_objmgr_pdev *pdev,
void *arg_list);
static inline struct wlan_lmac_if_reg_tx_ops *
reg_get_psoc_tx_ops(struct wlan_objmgr_psoc *psoc)
{
return &((psoc->soc_cb.tx_ops.reg_ops));
}
QDF_STATUS reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
struct regulatory_channel
*chan_list);
QDF_STATUS reg_program_chan_list(struct wlan_objmgr_pdev *pdev,
struct cc_regdmn_s *rd);
void reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list,
uint8_t num_ch, bool nol_ch);
/**
* reg_is_dfs_ch () - Checks the channel state for DFS
* @chan: channel
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan);
#ifdef WLAN_FEATURE_DSRC
/**
* reg_is_dsrc_chan () - Checks the channel for DSRC or not
* @chan: channel
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan);
static inline bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return false;
}
static inline bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev)
{
return false;
}
static inline bool
reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev)
{
return true;
}
#else
/**
* reg_is_etsi13_regdmn () - Checks if the current reg domain is ETSI13 or not
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_etsi13_regdmn(struct wlan_objmgr_pdev *pdev);
/**
* reg_is_etsi13_srd_chan () - Checks the channel for ETSI13 srd ch or not
* @chan: channel
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_etsi13_srd_chan(struct wlan_objmgr_pdev *pdev, uint32_t chan);
/**
* reg_is_etsi13_srd_chan_allowed_master_mode() - Checks if regdmn is ETSI13
* and SRD channels are allowed in master mode or not.
*
* @pdev: pdev ptr
*
* Return: true or false
*/
bool reg_is_etsi13_srd_chan_allowed_master_mode(struct wlan_objmgr_pdev *pdev);
static inline bool reg_is_dsrc_chan(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return false;
}
#endif
bool reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev,
uint32_t chan);
bool reg_is_disable_ch(struct wlan_objmgr_pdev *pdev, uint32_t chan);
uint32_t reg_freq_to_chan(struct wlan_objmgr_pdev *pdev, uint32_t freq);
uint32_t reg_chan_to_freq(struct wlan_objmgr_pdev *pdev, uint32_t chan_num);
/**
* reg_chan_is_49ghz() - Check if the input channel number is 4.9GHz
* @pdev: Pdev pointer
* @chan_num: Input channel number
*
* Return: true if the channel is 4.9GHz else false.
*/
bool reg_chan_is_49ghz(struct wlan_objmgr_pdev *pdev,
uint8_t chan_num);
/**
* reg_set_config_vars () - set configration variables
* @psoc: psoc ptr
* @config_vars: configuration struct
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_set_config_vars(struct wlan_objmgr_psoc *psoc,
struct reg_config_vars config_vars);
bool reg_is_regdb_offloaded(struct wlan_objmgr_psoc *psoc);
void reg_program_mas_chan_list(struct wlan_objmgr_psoc *psoc,
struct regulatory_channel *reg_channels,
uint8_t *alpha2,
enum dfs_reg dfs_region);
/**
* reg_get_regd_rules() - provides the reg domain rules info
* @pdev: pdev pointer
* @reg_rules: regulatory rules
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_get_regd_rules(struct wlan_objmgr_pdev *pdev,
struct reg_rule_info *reg_rules);
/**
* reg_reset_reg_rules() - provides the reg domain rules info
* @reg_rules: reg rules pointer
*
* Return: None
*/
void reg_reset_reg_rules(struct reg_rule_info *reg_rules);
QDF_STATUS reg_program_default_cc(struct wlan_objmgr_pdev *pdev,
uint16_t regdmn);
QDF_STATUS reg_get_current_cc(struct wlan_objmgr_pdev *pdev,
struct cc_regdmn_s *rd);
QDF_STATUS reg_get_curr_band(struct wlan_objmgr_pdev *pdev,
enum band_info *band);
typedef void (*reg_chan_change_callback)(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev,
struct regulatory_channel *chan_list,
struct avoid_freq_ind_data *avoid_freq_ind,
void *arg);
void reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk,
void *arg);
void reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk);
struct chan_change_cbk_entry {
reg_chan_change_callback cbk;
void *arg;
};
bool reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc);
enum country_src reg_get_cc_and_src(struct wlan_objmgr_psoc *psoc,
uint8_t *alpha2);
/**
* reg_save_new_11d_country() - Save the 11d new country
* @psoc: psoc for country information
* @country: country value
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_save_new_11d_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country);
/**
* reg_is_11d_offloaded() - whether 11d offloaded supported or not
* @psoc: psoc ptr
*
* Return: bool
*/
bool reg_is_11d_offloaded(struct wlan_objmgr_psoc *psoc);
/**
* reg_11d_enabled_on_host() - know whether 11d enabled on host
* @psoc: psoc ptr
*
* Return: bool
*/
bool reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc);
/**
* reg_11d_vdev_delete_update() - update 11d state upon vdev delete
* @vdev: vdev pointer
*
* Return: Success or Failure
*/
QDF_STATUS reg_11d_vdev_delete_update(struct wlan_objmgr_vdev *vdev);
/**
* reg_11d_vdev_created_update() - update 11d state upon vdev create
* @vdev: vdev pointer
*
* Return: Success or Failure
*/
QDF_STATUS reg_11d_vdev_created_update(struct wlan_objmgr_vdev *vdev);
/**
* reg_get_psoc_obj() - Provides the reg component object pointer
* @psoc: pointer to psoc object.
*
* Return: reg component object pointer
*/
struct wlan_regulatory_psoc_priv_obj *reg_get_psoc_obj(
struct wlan_objmgr_psoc *psoc);
/**
* reg_reset_ctry_pending_hints() - Reset all country pending hints
* @soc_reg: regulatory private object
*
* Return: None
*/
void
reg_reset_ctry_pending_hints(struct wlan_regulatory_psoc_priv_obj *soc_reg);
/**
* reg_set_regdb_offloaded() - set/clear regulatory offloaded flag
*
* @psoc: psoc pointer
* Return: Success or Failure
*/
QDF_STATUS reg_set_regdb_offloaded(struct wlan_objmgr_psoc *psoc,
bool val);
/**
* reg_set_11d_offloaded() - set/clear 11d offloaded flag
*
* @psoc: psoc pointer
* Return: Success or Failure
*/
QDF_STATUS reg_set_11d_offloaded(struct wlan_objmgr_psoc *psoc,
bool val);
/**
* reg_get_curr_regdomain() - Get current regdomain in use
* @pdev: pdev pointer
* @cur_regdmn: Current regdomain info
*
* Return: QDF status
*/
QDF_STATUS reg_get_curr_regdomain(struct wlan_objmgr_pdev *pdev,
struct cur_regdmn_info *cur_regdmn);
/**
* reg_modify_chan_144() - Enable/Disable channel 144
* @pdev: pdev pointer
* @enable_chan_144: flag to disable/enable channel 144
*
* Return: Success or Failure
*/
QDF_STATUS reg_modify_chan_144(struct wlan_objmgr_pdev *pdev,
bool en_chan_144);
/**
* reg_get_en_chan_144() - get en_chan_144 flag value
* @pdev: pdev pointer
*
* Return: en_chan_144 flag value
*/
bool reg_get_en_chan_144(struct wlan_objmgr_pdev *pdev);
/**
* reg_process_ch_avoid_event() - Process channel avoid event
* @psoc: psoc for country information
* @ch_avoid_event: channel avoid event buffer
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_process_ch_avoid_event(struct wlan_objmgr_psoc *psoc,
struct ch_avoid_ind_type *ch_avoid_event);
/**
* reg_send_scheduler_msg_sb() - Start scheduler to call list of callbacks
* registered whenever current chan list changes.
* @psoc: Pointer to PSOC structure.
* @pdev: Pointer to PDEV structure.
*
* Return: QDF_STATUS
*/
QDF_STATUS reg_send_scheduler_msg_sb(struct wlan_objmgr_psoc *psoc,
struct wlan_objmgr_pdev *pdev);
/**
* reg_get_hal_reg_cap() - Get HAL REG capabilities
* @psoc: psoc for country information
*
* Return: hal reg cap pointer
*/
struct wlan_psoc_host_hal_reg_capabilities_ext *reg_get_hal_reg_cap(
struct wlan_objmgr_psoc *psoc);
/**
* reg_set_hal_reg_cap() - Set HAL REG capabilities
* @psoc: psoc for country information
* @reg_cap: Regulatory caps pointer
* @phy_cnt: number of phy
*
* Return: hal reg cap pointer
*/
QDF_STATUS reg_set_hal_reg_cap(struct wlan_objmgr_psoc *psoc,
struct wlan_psoc_host_hal_reg_capabilities_ext *reg_cap,
uint16_t phy_cnt);
/**
* reg_chan_in_range() - Check if the given channel is in pdev's channel range
* @chan_list: Pointer to regulatory channel list.
* @low_freq_2g: Low frequency 2G.
* @high_freq_2g: High frequency 2G.
* @low_freq_5g: Low frequency 5G.
* @high_freq_5g: High frequency 5G.
* @ch_enum: Channel enum.
*
* Return: true if ch_enum is with in pdev's channel range, else false.
*/
bool reg_chan_in_range(struct regulatory_channel *chan_list,
uint32_t low_freq_2g,
uint32_t high_freq_2g,
uint32_t low_freq_5g,
uint32_t high_freq_5g,
enum channel_enum ch_enum);
/**
* reg_update_nol_history_ch() - Set nol-history flag for the channels in the
* list.
*
* @pdev: Pdev ptr.
* @ch_list: Input channel list.
* @num_ch: Number of channels.
* @nol_history_ch: NOL-History flag.
*
* Return: void
*/
void reg_update_nol_history_ch(struct wlan_objmgr_pdev *pdev,
uint8_t *chan_list,
uint8_t num_chan,
bool nol_history_chan);
#endif