blob: 6a6351f8fd6c28112028aa0bee37e802f73af94c [file] [log] [blame]
/*
* Copyright (c) 2017 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.
*/
/**
* @file wlan_reg_services_api.c
* @brief contains regulatory service functions
*/
#include <qdf_status.h>
#include <qdf_types.h>
#include <wlan_reg_services_api.h>
#include "../../core/src/reg_services.h"
#include "../../core/src/reg_priv.h"
/**
* wlan_reg_get_channel_list_with_power() - Provide the channel list with power
* @ch_list: pointer to the channel list.
*
* Return: QDF_STATUS
*/
QDF_STATUS wlan_reg_get_channel_list_with_power(struct wlan_objmgr_pdev *pdev,
struct channel_power *ch_list,
uint8_t *num_chan)
{
/*
* Update the channel list with channel information with power.
*/
return reg_get_channel_list_with_power(pdev, ch_list, num_chan);
}
/**
* wlan_reg_read_default_country() - Read the default country for the regdomain
* @country: pointer to the country code.
*
* Return: None
*/
QDF_STATUS wlan_reg_read_default_country(struct wlan_objmgr_psoc *psoc,
uint8_t *country)
{
/*
* Get the default country information
*/
return reg_read_default_country(psoc, country);
}
/**
* wlan_reg_get_channel_state() - Get channel state from regulatory
* @ch: channel number.
*
* Return: channel state
*/
enum channel_state wlan_reg_get_channel_state(struct wlan_objmgr_pdev *pdev,
uint32_t ch)
{
/*
* Get channel state from regulatory
*/
return reg_get_channel_state(pdev, ch);
}
/**
* wlan_reg_get_5g_bonded_channel_state() - Get 5G bonded channel state
* @ch: channel number.
* @bw: channel band width
*
* Return: channel state
*/
enum channel_state wlan_reg_get_5g_bonded_channel_state(
struct wlan_objmgr_pdev *pdev, uint8_t ch,
enum phy_ch_width bw)
{
/*
* Get channel state from regulatory
*/
return reg_get_5g_bonded_channel_state(pdev, ch, bw);
}
/**
* wlan_reg_get_2g_bonded_channel_state() - Get 2G bonded channel state
* @ch: channel number.
* @bw: channel band width
*
* Return: channel state
*/
enum channel_state wlan_reg_get_2g_bonded_channel_state(
struct wlan_objmgr_pdev *pdev, uint8_t ch,
uint8_t sec_ch, enum phy_ch_width bw)
{
/*
* Get channel state from regulatory
*/
return reg_get_2g_bonded_channel_state(pdev, ch, sec_ch, bw);
}
/**
* wlan_reg_set_channel_params() - Sets channel parameteres for given bandwidth
* @ch: channel number.
* @ch_params: pointer to the channel parameters.
*
* Return: None
*/
void wlan_reg_set_channel_params(struct wlan_objmgr_pdev *pdev, uint8_t ch,
uint8_t sec_ch_2g,
struct ch_params *ch_params)
{
/*
* Set channel parameters like center frequency for a bonded channel
* state. Also return the maximum bandwidth supported by the channel.
*/
reg_set_channel_params(pdev, ch, sec_ch_2g, ch_params);
}
/**
* wlan_reg_get_dfs_region () - Get the current dfs region
* @dfs_reg: pointer to dfs region
*
* Return: Status
*/
QDF_STATUS wlan_reg_get_dfs_region(struct wlan_objmgr_pdev *pdev,
enum dfs_reg *dfs_reg)
{
/*
* Get the current dfs region
*/
reg_get_dfs_region(pdev, dfs_reg);
return QDF_STATUS_SUCCESS;
}
uint32_t wlan_reg_get_channel_reg_power(struct wlan_objmgr_pdev *pdev,
uint32_t chan_num)
{
return reg_get_channel_reg_power(pdev, chan_num);
}
/**
* wlan_reg_get_channel_freq() - get regulatory power for channel
* @chan_num: channel number
*
* Return: int
*/
uint32_t wlan_reg_get_channel_freq(struct wlan_objmgr_pdev *pdev,
uint32_t chan_num)
{
return reg_get_channel_freq(pdev, chan_num);
}
QDF_STATUS wlan_reg_get_current_chan_list(struct wlan_objmgr_pdev *pdev,
struct regulatory_channel *chan_list)
{
return reg_get_current_chan_list(pdev, chan_list);
}
/**
* wlan_reg_get_bw_value() - give bandwidth value
* bw: bandwidth enum
*
* Return: uint16_t
*/
uint16_t wlan_reg_get_bw_value(enum phy_ch_width bw)
{
return reg_get_bw_value(bw);
}
/**
* wlan_reg_get_bonded_channel_state() - Get 2G bonded channel state
* @ch: channel number.
* @bw: channel band width
*
* Return: channel state
*/
enum channel_state wlan_reg_get_bonded_channel_state(
struct wlan_objmgr_pdev *pdev, uint8_t ch,
enum phy_ch_width bw, uint8_t sec_ch)
{
if (WLAN_REG_IS_24GHZ_CH(ch))
return reg_get_2g_bonded_channel_state(pdev, ch,
sec_ch, bw);
else
return reg_get_5g_bonded_channel_state(pdev, ch,
bw);
}
/**
* wlan_reg_set_dfs_region () - Get the current dfs region
* @dfs_reg: pointer to dfs region
*
* Return: None
*/
void wlan_reg_set_dfs_region(struct wlan_objmgr_pdev *pdev,
enum dfs_reg dfs_reg)
{
reg_set_dfs_region(pdev, dfs_reg);
}
QDF_STATUS wlan_reg_get_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr,
const uint8_t *country_alpha2, enum country_src source)
{
return reg_get_domain_from_country_code(reg_domain_ptr,
country_alpha2, source);
}
uint16_t wlan_reg_dmn_get_opclass_from_channel(uint8_t *country,
uint8_t channel,
uint8_t offset)
{
return reg_dmn_get_opclass_from_channel(country, channel,
offset);
}
uint16_t wlan_reg_dmn_get_chanwidth_from_opclass(uint8_t *country,
uint8_t channel,
uint8_t opclass)
{
return reg_dmn_get_chanwidth_from_opclass(country, channel,
opclass);
}
uint16_t wlan_reg_dmn_set_curr_opclasses(uint8_t num_classes,
uint8_t *class)
{
return reg_dmn_set_curr_opclasses(num_classes, class);
}
uint16_t wlan_reg_dmn_get_curr_opclasses(uint8_t *num_classes,
uint8_t *class)
{
return reg_dmn_get_curr_opclasses(num_classes, class);
}
QDF_STATUS wlan_regulatory_init(void)
{
QDF_STATUS status;
status = wlan_objmgr_register_psoc_create_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_psoc_obj_created_notification, NULL);
if (status != QDF_STATUS_SUCCESS) {
reg_err("failed to register reg psoc obj create handler");
return status;
}
status = wlan_objmgr_register_psoc_destroy_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_psoc_obj_destroyed_notification, NULL);
if (status != QDF_STATUS_SUCCESS) {
reg_err("failed to register reg psoc obj create handler");
goto unreg_psoc_create;
}
status = wlan_objmgr_register_pdev_create_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_pdev_obj_created_notification, NULL);
if (status != QDF_STATUS_SUCCESS) {
reg_err("failed to register reg psoc obj create handler");
goto unreg_psoc_destroy;
}
status = wlan_objmgr_register_pdev_destroy_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_pdev_obj_destroyed_notification, NULL);
if (status != QDF_STATUS_SUCCESS) {
reg_err("failed to register reg psoc obj create handler");
goto unreg_pdev_create;
}
reg_debug("regulatory handlers registered with obj mgr");
return status;
unreg_pdev_create:
status = wlan_objmgr_unregister_pdev_create_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_pdev_obj_created_notification,
NULL);
unreg_psoc_destroy:
status = wlan_objmgr_unregister_psoc_destroy_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_psoc_obj_destroyed_notification,
NULL);
unreg_psoc_create:
status = wlan_objmgr_unregister_psoc_create_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_psoc_obj_created_notification,
NULL);
return QDF_STATUS_E_FAILURE;
}
QDF_STATUS wlan_regulatory_deinit(void)
{
QDF_STATUS status, ret_status = QDF_STATUS_SUCCESS;
status = wlan_objmgr_unregister_pdev_destroy_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_pdev_obj_destroyed_notification, NULL);
if (status != QDF_STATUS_SUCCESS) {
reg_err("failed to unregister reg pdev obj destroy handler");
ret_status = status;
}
status = wlan_objmgr_unregister_pdev_create_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_pdev_obj_created_notification, NULL);
if (status != QDF_STATUS_SUCCESS) {
reg_err("failed to unregister reg pdev obj create handler");
ret_status = status;
}
status = wlan_objmgr_unregister_psoc_destroy_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_psoc_obj_destroyed_notification, NULL);
if (status != QDF_STATUS_SUCCESS) {
reg_err("failed to unregister reg psoc obj destroy handler");
ret_status = status;
}
status = wlan_objmgr_unregister_psoc_create_handler(
WLAN_UMAC_COMP_REGULATORY,
wlan_regulatory_psoc_obj_created_notification, NULL);
if (status != QDF_STATUS_SUCCESS) {
reg_err("failed to unregister reg psoc obj create handler");
ret_status = status;
}
reg_debug("deregistered callbacks with obj mgr");
return ret_status;
}
QDF_STATUS regulatory_psoc_open(struct wlan_objmgr_psoc *psoc)
{
struct wlan_lmac_if_reg_tx_ops *tx_ops;
tx_ops = reg_get_psoc_tx_ops(psoc);
if (tx_ops->register_master_handler)
tx_ops->register_master_handler(psoc, NULL);
if (tx_ops->register_11d_new_cc_handler)
tx_ops->register_11d_new_cc_handler(psoc, NULL);
return QDF_STATUS_SUCCESS;
}
QDF_STATUS regulatory_psoc_close(struct wlan_objmgr_psoc *psoc)
{
struct wlan_lmac_if_reg_tx_ops *tx_ops;
tx_ops = reg_get_psoc_tx_ops(psoc);
if (tx_ops->unregister_11d_new_cc_handler)
tx_ops->unregister_11d_new_cc_handler(psoc, NULL);
if (tx_ops->unregister_master_handler)
tx_ops->unregister_master_handler(psoc, NULL);
return QDF_STATUS_SUCCESS;
}
void wlan_reg_update_nol_ch(struct wlan_objmgr_pdev *pdev, uint8_t *ch_list,
uint8_t num_ch, bool nol_ch)
{
reg_update_nol_ch(pdev, ch_list, num_ch, nol_ch);
}
bool wlan_reg_is_dfs_ch(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return reg_is_dfs_ch(pdev, chan);
}
bool wlan_reg_is_passive_or_disable_ch(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return reg_is_passive_or_disable_ch(pdev, chan);
}
bool wlan_reg_is_disable_ch(struct wlan_objmgr_pdev *pdev,
uint32_t chan)
{
return reg_is_disable_ch(pdev, chan);
}
uint32_t wlan_reg_freq_to_chan(struct wlan_objmgr_pdev *pdev,
uint32_t freq)
{
return reg_freq_to_chan(pdev, freq);
}
uint32_t wlan_reg_chan_to_freq(struct wlan_objmgr_pdev *pdev,
uint32_t chan_num)
{
return reg_chan_to_freq(pdev, chan_num);
}
QDF_STATUS wlan_reg_set_country(struct wlan_objmgr_pdev *pdev,
uint8_t *country)
{
return reg_set_country(pdev, country);
}
void wlan_reg_register_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk,
void *arg)
{
reg_register_chan_change_callback(psoc, cbk, arg);
}
void wlan_reg_unregister_chan_change_callback(struct wlan_objmgr_psoc *psoc,
reg_chan_change_callback cbk)
{
reg_unregister_chan_change_callback(psoc, cbk);
}
bool wlan_reg_11d_enabled_on_host(struct wlan_objmgr_psoc *psoc)
{
return reg_11d_enabled_on_host(psoc);
}
QDF_STATUS wlan_reg_get_chip_mode(struct wlan_objmgr_pdev *pdev,
uint32_t *chip_mode)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_REGULATORY);
if (NULL == pdev_priv_obj) {
reg_err("reg pdev private obj is NULL");
return QDF_STATUS_E_FAULT;
}
*chip_mode = pdev_priv_obj->wireless_modes;
return QDF_STATUS_SUCCESS;
}
bool wlan_reg_is_11d_scan_inprogress(struct wlan_objmgr_psoc *psoc)
{
return reg_is_11d_scan_inprogress(psoc);
}
QDF_STATUS wlan_reg_get_freq_range(struct wlan_objmgr_pdev *pdev,
uint32_t *low_2g,
uint32_t *high_2g,
uint32_t *low_5g,
uint32_t *high_5g)
{
struct wlan_regulatory_pdev_priv_obj *pdev_priv_obj;
pdev_priv_obj = wlan_objmgr_pdev_get_comp_private_obj(pdev,
WLAN_UMAC_COMP_REGULATORY);
if (NULL == pdev_priv_obj) {
reg_err("reg pdev private obj is NULL");
return QDF_STATUS_E_FAULT;
}
*low_2g = pdev_priv_obj->range_2g_low;
*high_2g = pdev_priv_obj->range_2g_high;
*low_5g = pdev_priv_obj->range_5g_low;
*high_5g = pdev_priv_obj->range_5g_high;
return QDF_STATUS_SUCCESS;
}
struct wlan_lmac_if_reg_tx_ops *
wlan_reg_get_tx_ops(struct wlan_objmgr_psoc *psoc)
{
return reg_get_psoc_tx_ops(psoc);
}