Path: blob/master/ALFA-W1F1/RTL8814AU/os_dep/linux/wifi_regd.c
1307 views
/******************************************************************************1*2* Copyright(c) 2009-2010 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/1415#include <drv_types.h>1617#ifdef CONFIG_IOCTL_CFG802111819#include <rtw_wifi_regd.h>2021/*22*Only these channels all allow active23*scan on all world regulatory domains24*/2526/* 2G chan 01 - chan 11 */27#define RTW_2GHZ_CH01_11 \28REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)2930/*31*We enable active scan on these a case32*by case basis by regulatory domain33*/3435/* 2G chan 12 - chan 13, PASSIV SCAN */36#define RTW_2GHZ_CH12_13 \37REG_RULE(2467-10, 2472+10, 40, 0, 20, \38NL80211_RRF_PASSIVE_SCAN)3940/* 5G chan 36 - chan 165 */41#define RTW_5GHZ_5150_5850 \42REG_RULE(5150-10, 5850+10, 40, 0, 30, \43NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)4445static const struct ieee80211_regdomain rtw_regdom_rd = {46.n_reg_rules = 3,47.alpha2 = "99",48.reg_rules = {49RTW_2GHZ_CH01_11,50RTW_2GHZ_CH12_13,51RTW_5GHZ_5150_5850,52}53};5455#if 056/*57* REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags)58*/5960static struct country_code_to_enum_rd allCountries[] = {61{COUNTRY_CODE_USER, "RD"},62};6364/* 2G chan 14, PASSIVS SCAN, NO OFDM (B only) */65#define RTW_2GHZ_CH14 \66REG_RULE(2484-10, 2484+10, 40, 0, 20, \67NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)6869/* 5G chan 36 - chan 64 */70#define RTW_5GHZ_5150_5350 \71REG_RULE(5150-10, 5350+10, 40, 0, 30, \72NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)7374/* 5G chan 100 - chan 165 */75#define RTW_5GHZ_5470_5850 \76REG_RULE(5470-10, 5850+10, 40, 0, 30, \77NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)7879/* 5G chan 149 - chan 165 */80#define RTW_5GHZ_5725_5850 \81REG_RULE(5725-10, 5850+10, 40, 0, 30, \82NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)838485static const struct ieee80211_regdomain rtw_regdom_11 = {86.n_reg_rules = 1,87.alpha2 = "99",88.reg_rules = {89RTW_2GHZ_CH01_11,90}91};9293static const struct ieee80211_regdomain rtw_regdom_12_13 = {94.n_reg_rules = 2,95.alpha2 = "99",96.reg_rules = {97RTW_2GHZ_CH01_11,98RTW_2GHZ_CH12_13,99}100};101102static const struct ieee80211_regdomain rtw_regdom_no_midband = {103.n_reg_rules = 3,104.alpha2 = "99",105.reg_rules = {106RTW_2GHZ_CH01_11,107RTW_5GHZ_5150_5350,108RTW_5GHZ_5725_5850,109}110};111112static const struct ieee80211_regdomain rtw_regdom_60_64 = {113.n_reg_rules = 3,114.alpha2 = "99",115.reg_rules = {116RTW_2GHZ_CH01_11,117RTW_2GHZ_CH12_13,118RTW_5GHZ_5725_5850,119}120};121122static const struct ieee80211_regdomain rtw_regdom_14_60_64 = {123.n_reg_rules = 4,124.alpha2 = "99",125.reg_rules = {126RTW_2GHZ_CH01_11,127RTW_2GHZ_CH12_13,128RTW_2GHZ_CH14,129RTW_5GHZ_5725_5850,130}131};132133static const struct ieee80211_regdomain rtw_regdom_14 = {134.n_reg_rules = 3,135.alpha2 = "99",136.reg_rules = {137RTW_2GHZ_CH01_11,138RTW_2GHZ_CH12_13,139RTW_2GHZ_CH14,140}141};142143144static struct rtw_regulatory *rtw_regd;145#endif146147#if 0 /* not_yet */148static void _rtw_reg_apply_beaconing_flags(struct wiphy *wiphy,149enum nl80211_reg_initiator initiator)150{151enum nl80211_band band;152struct ieee80211_supported_band *sband;153const struct ieee80211_reg_rule *reg_rule;154struct ieee80211_channel *ch;155unsigned int i;156u32 bandwidth = 0;157int r;158159for (band = 0; band < NUM_NL80211_BANDS; band++) {160161if (!wiphy->bands[band])162continue;163164sband = wiphy->bands[band];165166for (i = 0; i < sband->n_channels; i++) {167ch = &sband->channels[i];168if (rtw_is_dfs_ch(ch->hw_value) ||169(ch->flags & IEEE80211_CHAN_RADAR))170continue;171if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {172r = freq_reg_info(wiphy, ch->center_freq,173bandwidth, ®_rule);174if (r)175continue;176177/*178*If 11d had a rule for this channel ensure179*we enable adhoc/beaconing if it allows us to180*use it. Note that we would have disabled it181*by applying our static world regdomain by182*default during init, prior to calling our183*regulatory_hint().184*/185186if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))187ch->flags &= ~IEEE80211_CHAN_NO_IBSS;188if (!189(reg_rule->flags &190NL80211_RRF_PASSIVE_SCAN))191ch->flags &=192~IEEE80211_CHAN_PASSIVE_SCAN;193} else {194if (ch->beacon_found)195ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |196IEEE80211_CHAN_PASSIVE_SCAN);197}198}199}200}201202/* Allows active scan scan on Ch 12 and 13 */203static void _rtw_reg_apply_active_scan_flags(struct wiphy *wiphy,204enum nl80211_reg_initiator205initiator)206{207struct ieee80211_supported_band *sband;208struct ieee80211_channel *ch;209const struct ieee80211_reg_rule *reg_rule;210u32 bandwidth = 0;211int r;212213if (!wiphy->bands[NL80211_BAND_2GHZ])214return;215sband = wiphy->bands[NL80211_BAND_2GHZ];216217/*218* If no country IE has been received always enable active scan219* on these channels. This is only done for specific regulatory SKUs220*/221if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {222ch = &sband->channels[11]; /* CH 12 */223if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)224ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;225ch = &sband->channels[12]; /* CH 13 */226if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)227ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;228return;229}230231/*232* If a country IE has been received check its rule for this233* channel first before enabling active scan. The passive scan234* would have been enforced by the initial processing of our235* custom regulatory domain.236*/237238ch = &sband->channels[11]; /* CH 12 */239r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule);240if (!r) {241if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))242if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)243ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;244}245246ch = &sband->channels[12]; /* CH 13 */247r = freq_reg_info(wiphy, ch->center_freq, bandwidth, ®_rule);248if (!r) {249if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))250if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)251ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;252}253}254#endif255256void rtw_regd_apply_flags(struct wiphy *wiphy)257{258struct dvobj_priv *dvobj = wiphy_to_dvobj(wiphy);259struct rf_ctl_t *rfctl = dvobj_to_rfctl(dvobj);260RT_CHANNEL_INFO *channel_set = rfctl->channel_set;261u8 max_chan_nums = rfctl->max_chan_nums;262263struct ieee80211_supported_band *sband;264struct ieee80211_channel *ch;265unsigned int i, j;266u16 channel;267u32 freq;268269/* all channels disable */270for (i = 0; i < NUM_NL80211_BANDS; i++) {271sband = wiphy->bands[i];272273if (sband) {274for (j = 0; j < sband->n_channels; j++) {275ch = &sband->channels[j];276277if (ch)278ch->flags = IEEE80211_CHAN_DISABLED;279}280}281}282283/* channels apply by channel plans. */284for (i = 0; i < max_chan_nums; i++) {285channel = channel_set[i].ChannelNum;286freq = rtw_ch2freq(channel);287288ch = ieee80211_get_channel(wiphy, freq);289if (!ch)290continue;291292if (channel_set[i].ScanType == SCAN_PASSIVE293#if defined(CONFIG_DFS_MASTER)294&& rtw_odm_dfs_domain_unknown(dvobj)295#endif296) {297#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))298ch->flags = (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN);299#else300ch->flags = IEEE80211_CHAN_NO_IR;301#endif302} else303ch->flags = 0;304305#ifdef CONFIG_DFS306if (rtw_is_dfs_ch(ch->hw_value)307#if defined(CONFIG_DFS_MASTER)308&& rtw_odm_dfs_domain_unknown(dvobj)309#endif310) {311ch->flags |= IEEE80211_CHAN_RADAR;312#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))313ch->flags |= (IEEE80211_CHAN_NO_IBSS | IEEE80211_CHAN_PASSIVE_SCAN);314#else315ch->flags |= IEEE80211_CHAN_NO_IR;316#endif317}318#endif /* CONFIG_DFS */319}320}321322static const struct ieee80211_regdomain *_rtw_regdomain_select(struct323rtw_regulatory324*reg)325{326#if 0327switch (reg->country_code) {328case COUNTRY_CODE_USER:329default:330return &rtw_regdom_rd;331}332#else333return &rtw_regdom_rd;334#endif335}336337static void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)338{339switch (request->initiator) {340case NL80211_REGDOM_SET_BY_DRIVER:341RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_DRIVER");342break;343case NL80211_REGDOM_SET_BY_CORE:344RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_CORE");345break;346case NL80211_REGDOM_SET_BY_USER:347RTW_INFO("%s: %s alpha2:%c%c\n", __func__, "NL80211_REGDOM_SET_BY_USER"348, request->alpha2[0], request->alpha2[1]);349rtw_set_country(wiphy_to_adapter(wiphy), request->alpha2);350break;351case NL80211_REGDOM_SET_BY_COUNTRY_IE:352RTW_INFO("%s: %s\n", __func__, "NL80211_REGDOM_SET_BY_COUNTRY_IE");353break;354}355356rtw_regd_apply_flags(wiphy);357}358359#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))360static int rtw_reg_notifier_return(struct wiphy *wiphy, struct regulatory_request *request)361{362rtw_reg_notifier(wiphy, request);363return 0;364}365#endif366367static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg, struct wiphy *wiphy)368{369const struct ieee80211_regdomain *regd;370371#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 9, 0))372wiphy->reg_notifier = rtw_reg_notifier_return;373#else374wiphy->reg_notifier = rtw_reg_notifier;375#endif376377#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0))378wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;379wiphy->flags &= ~WIPHY_FLAG_STRICT_REGULATORY;380wiphy->flags &= ~WIPHY_FLAG_DISABLE_BEACON_HINTS;381#else382wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;383wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;384wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;385#endif386387regd = _rtw_regdomain_select(reg);388wiphy_apply_custom_regulatory(wiphy, regd);389390rtw_regd_apply_flags(wiphy);391}392393int rtw_regd_init(struct wiphy *wiphy)394{395#if 0396if (rtw_regd == NULL) {397rtw_regd = (struct rtw_regulatory *)398rtw_malloc(sizeof(struct rtw_regulatory));399400rtw_regd->alpha2[0] = '9';401rtw_regd->alpha2[1] = '9';402403rtw_regd->country_code = COUNTRY_CODE_USER;404}405406RTW_INFO("%s: Country alpha2 being used: %c%c\n",407__func__, rtw_regd->alpha2[0], rtw_regd->alpha2[1]);408#endif409410_rtw_regd_init_wiphy(NULL, wiphy);411412return 0;413}414#endif /* CONFIG_IOCTL_CFG80211 */415416417