mirror of
https://github.com/proski/madwifi
synced 2024-11-25 07:49:43 +03:00
5890429464
git-svn-id: http://madwifi-project.org/svn/madwifi/trunk@4166 0192ed92-7a03-0410-a25b-9323aeb14dbd
2871 lines
100 KiB
C
2871 lines
100 KiB
C
/*
|
|
* Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
|
|
* Copyright (c) 2005-2006 Atheros Communications, Inc.
|
|
* 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.
|
|
*
|
|
* $FreeBSD$
|
|
*/
|
|
#include "opt_ah.h"
|
|
|
|
#include "ah.h"
|
|
#include "ah_internal.h"
|
|
#include "ah_eeprom.h"
|
|
#include "ah_devid.h"
|
|
|
|
/*
|
|
* XXX this code needs a audit+review
|
|
*/
|
|
|
|
/* used throughout this file... */
|
|
#define N(a) (sizeof (a) / sizeof (a[0]))
|
|
|
|
#define HAL_MODE_11A_TURBO HAL_MODE_108A
|
|
#define HAL_MODE_11G_TURBO HAL_MODE_108G
|
|
|
|
/* 10MHz is half the 11A bandwidth used to determine upper edge freq
|
|
of the outdoor channel */
|
|
#define HALF_MAXCHANBW 10
|
|
|
|
/*
|
|
* BMLEN defines the size of the bitmask used to hold frequency
|
|
* band specifications. Note this must agree with the BM macro
|
|
* definition that's used to setup initializers. See also further
|
|
* comments below.
|
|
*/
|
|
#define BMLEN 2 /* 2 x 64 bits in each channel bitmask */
|
|
typedef uint64_t chanbmask_t[BMLEN];
|
|
|
|
#define W0(_a) \
|
|
(((_a) >= 0 && (_a) < 64 ? (((uint64_t) 1)<<(_a)) : (uint64_t) 0))
|
|
#define W1(_a) \
|
|
(((_a) > 63 && (_a) < 128 ? (((uint64_t) 1)<<((_a)-64)) : (uint64_t) 0))
|
|
#define BM1(_fa) { W0(_fa), W1(_fa) }
|
|
#define BM2(_fa, _fb) { W0(_fa) | W0(_fb), W1(_fa) | W1(_fb) }
|
|
#define BM3(_fa, _fb, _fc) \
|
|
{ W0(_fa) | W0(_fb) | W0(_fc), W1(_fa) | W1(_fb) | W1(_fc) }
|
|
#define BM4(_fa, _fb, _fc, _fd) \
|
|
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd), \
|
|
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) }
|
|
#define BM5(_fa, _fb, _fc, _fd, _fe) \
|
|
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe), \
|
|
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) }
|
|
#define BM6(_fa, _fb, _fc, _fd, _fe, _ff) \
|
|
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff), \
|
|
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) }
|
|
#define BM7(_fa, _fb, _fc, _fd, _fe, _ff, _fg) \
|
|
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
|
|
W0(_fg),\
|
|
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
|
|
W1(_fg) }
|
|
#define BM8(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh) \
|
|
{ W0(_fa) | W0(_fb) | W0(_fc) | W0(_fd) | W0(_fe) | W0(_ff) | \
|
|
W0(_fg) | W0(_fh) , \
|
|
W1(_fa) | W1(_fb) | W1(_fc) | W1(_fd) | W1(_fe) | W1(_ff) | \
|
|
W1(_fg) | W1(_fh) }
|
|
|
|
/*
|
|
* Country/Region Codes
|
|
* Numbering from ISO 3166
|
|
*/
|
|
enum {
|
|
CTRY_ALBANIA = 8, /* Albania */
|
|
CTRY_ALGERIA = 12, /* Algeria */
|
|
CTRY_ARGENTINA = 32, /* Argentina */
|
|
CTRY_ARMENIA = 51, /* Armenia */
|
|
CTRY_AUSTRALIA = 36, /* Australia */
|
|
CTRY_AUSTRIA = 40, /* Austria */
|
|
CTRY_AZERBAIJAN = 31, /* Azerbaijan */
|
|
CTRY_BAHRAIN = 48, /* Bahrain */
|
|
CTRY_BELARUS = 112, /* Belarus */
|
|
CTRY_BELGIUM = 56, /* Belgium */
|
|
CTRY_BELIZE = 84, /* Belize */
|
|
CTRY_BOLIVIA = 68, /* Bolivia */
|
|
CTRY_BRAZIL = 76, /* Brazil */
|
|
CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */
|
|
CTRY_BULGARIA = 100, /* Bulgaria */
|
|
CTRY_CANADA = 124, /* Canada */
|
|
CTRY_CHILE = 152, /* Chile */
|
|
CTRY_CHINA = 156, /* People's Republic of China */
|
|
CTRY_COLOMBIA = 170, /* Colombia */
|
|
CTRY_COSTA_RICA = 188, /* Costa Rica */
|
|
CTRY_CROATIA = 191, /* Croatia */
|
|
CTRY_CYPRUS = 196,
|
|
CTRY_CZECH = 203, /* Czech Republic */
|
|
CTRY_DENMARK = 208, /* Denmark */
|
|
CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */
|
|
CTRY_ECUADOR = 218, /* Ecuador */
|
|
CTRY_EGYPT = 818, /* Egypt */
|
|
CTRY_EL_SALVADOR = 222, /* El Salvador */
|
|
CTRY_ESTONIA = 233, /* Estonia */
|
|
CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */
|
|
CTRY_FINLAND = 246, /* Finland */
|
|
CTRY_FRANCE = 250, /* France */
|
|
CTRY_FRANCE2 = 255, /* France2 */
|
|
CTRY_GEORGIA = 268, /* Georgia */
|
|
CTRY_GERMANY = 276, /* Germany */
|
|
CTRY_GREECE = 300, /* Greece */
|
|
CTRY_GUATEMALA = 320, /* Guatemala */
|
|
CTRY_HONDURAS = 340, /* Honduras */
|
|
CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */
|
|
CTRY_HUNGARY = 348, /* Hungary */
|
|
CTRY_ICELAND = 352, /* Iceland */
|
|
CTRY_INDIA = 356, /* India */
|
|
CTRY_INDONESIA = 360, /* Indonesia */
|
|
CTRY_IRAN = 364, /* Iran */
|
|
CTRY_IRAQ = 368, /* Iraq */
|
|
CTRY_IRELAND = 372, /* Ireland */
|
|
CTRY_ISRAEL = 376, /* Israel */
|
|
CTRY_ITALY = 380, /* Italy */
|
|
CTRY_JAMAICA = 388, /* Jamaica */
|
|
CTRY_JAPAN = 392, /* Japan */
|
|
CTRY_JAPAN1 = 393, /* Japan (JP1) */
|
|
CTRY_JAPAN2 = 394, /* Japan (JP0) */
|
|
CTRY_JAPAN3 = 395, /* Japan (JP1-1) */
|
|
CTRY_JAPAN4 = 396, /* Japan (JE1) */
|
|
CTRY_JAPAN5 = 397, /* Japan (JE2) */
|
|
CTRY_JAPAN6 = 399, /* Japan (JP6) */
|
|
|
|
CTRY_JAPAN7 = 4007, /* Japan (J7) */
|
|
CTRY_JAPAN8 = 4008, /* Japan (J8) */
|
|
CTRY_JAPAN9 = 4009, /* Japan (J9) */
|
|
|
|
CTRY_JAPAN10 = 4010, /* Japan (J10) */
|
|
CTRY_JAPAN11 = 4011, /* Japan (J11) */
|
|
CTRY_JAPAN12 = 4012, /* Japan (J12) */
|
|
|
|
CTRY_JAPAN13 = 4013, /* Japan (J13) */
|
|
CTRY_JAPAN14 = 4014, /* Japan (J14) */
|
|
CTRY_JAPAN15 = 4015, /* Japan (J15) */
|
|
|
|
CTRY_JAPAN16 = 4016, /* Japan (J16) */
|
|
CTRY_JAPAN17 = 4017, /* Japan (J17) */
|
|
CTRY_JAPAN18 = 4018, /* Japan (J18) */
|
|
|
|
CTRY_JAPAN19 = 4019, /* Japan (J19) */
|
|
CTRY_JAPAN20 = 4020, /* Japan (J20) */
|
|
CTRY_JAPAN21 = 4021, /* Japan (J21) */
|
|
|
|
CTRY_JAPAN22 = 4022, /* Japan (J22) */
|
|
CTRY_JAPAN23 = 4023, /* Japan (J23) */
|
|
CTRY_JAPAN24 = 4024, /* Japan (J24) */
|
|
|
|
CTRY_JORDAN = 400, /* Jordan */
|
|
CTRY_KAZAKHSTAN = 398, /* Kazakhstan */
|
|
CTRY_KENYA = 404, /* Kenya */
|
|
CTRY_KOREA_NORTH = 408, /* North Korea */
|
|
CTRY_KOREA_ROC = 410, /* South Korea */
|
|
CTRY_KOREA_ROC2 = 411, /* South Korea */
|
|
CTRY_KOREA_ROC3 = 412, /* South Korea */
|
|
CTRY_KUWAIT = 414, /* Kuwait */
|
|
CTRY_LATVIA = 428, /* Latvia */
|
|
CTRY_LEBANON = 422, /* Lebanon */
|
|
CTRY_LIBYA = 434, /* Libya */
|
|
CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */
|
|
CTRY_LITHUANIA = 440, /* Lithuania */
|
|
CTRY_LUXEMBOURG = 442, /* Luxembourg */
|
|
CTRY_MACAU = 446, /* Macau */
|
|
CTRY_MACEDONIA = 807, /* the Former Yugoslav Republic of Macedonia */
|
|
CTRY_MALAYSIA = 458, /* Malaysia */
|
|
CTRY_MALTA = 470, /* Malta */
|
|
CTRY_MEXICO = 484, /* Mexico */
|
|
CTRY_MONACO = 492, /* Principality of Monaco */
|
|
CTRY_MOROCCO = 504, /* Morocco */
|
|
CTRY_NETHERLANDS = 528, /* Netherlands */
|
|
CTRY_NEW_ZEALAND = 554, /* New Zealand */
|
|
CTRY_NICARAGUA = 558, /* Nicaragua */
|
|
CTRY_NORWAY = 578, /* Norway */
|
|
CTRY_OMAN = 512, /* Oman */
|
|
CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */
|
|
CTRY_PANAMA = 591, /* Panama */
|
|
CTRY_PARAGUAY = 600, /* Paraguay */
|
|
CTRY_PERU = 604, /* Peru */
|
|
CTRY_PHILIPPINES = 608, /* Republic of the Philippines */
|
|
CTRY_POLAND = 616, /* Poland */
|
|
CTRY_PORTUGAL = 620, /* Portugal */
|
|
CTRY_PUERTO_RICO = 630, /* Puerto Rico */
|
|
CTRY_QATAR = 634, /* Qatar */
|
|
CTRY_ROMANIA = 642, /* Romania */
|
|
CTRY_RUSSIA = 643, /* Russia */
|
|
CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */
|
|
CTRY_SINGAPORE = 702, /* Singapore */
|
|
CTRY_SLOVAKIA = 703, /* Slovak Republic */
|
|
CTRY_SLOVENIA = 705, /* Slovenia */
|
|
CTRY_SOUTH_AFRICA = 710, /* South Africa */
|
|
CTRY_SPAIN = 724, /* Spain */
|
|
CTRY_SR9 = 5000, /* Ubiquiti SR9 (900MHz/GSM) */
|
|
CTRY_SWEDEN = 752, /* Sweden */
|
|
CTRY_SWITZERLAND = 756, /* Switzerland */
|
|
CTRY_SYRIA = 760, /* Syria */
|
|
CTRY_TAIWAN = 158, /* Taiwan */
|
|
CTRY_THAILAND = 764, /* Thailand */
|
|
CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */
|
|
CTRY_TUNISIA = 788, /* Tunisia */
|
|
CTRY_TURKEY = 792, /* Turkey */
|
|
CTRY_UAE = 784, /* U.A.E. */
|
|
CTRY_UKRAINE = 804, /* Ukraine */
|
|
CTRY_UNITED_KINGDOM = 826, /* United Kingdom */
|
|
CTRY_UNITED_STATES = 840, /* United States */
|
|
CTRY_UNITED_STATES_FCC49 = 842, /* United States (Public Safety)*/
|
|
CTRY_URUGUAY = 858, /* Uruguay */
|
|
CTRY_UZBEKISTAN = 860, /* Uzbekistan */
|
|
CTRY_VENEZUELA = 862, /* Venezuela */
|
|
CTRY_VIET_NAM = 704, /* Viet Nam */
|
|
CTRY_XR9 = 5001, /* Ubiquiti XR9 (900MHz/GSM) */
|
|
CTRY_GZ901 = 5002, /* Zcomax GZ-901 (900MHz/GSM) */
|
|
CTRY_YEMEN = 887, /* Yemen */
|
|
CTRY_ZIMBABWE = 716 /* Zimbabwe */
|
|
};
|
|
|
|
|
|
/*
|
|
* Mask to check whether a domain is a multidomain or a single domain
|
|
*/
|
|
#define MULTI_DOMAIN_MASK 0xFF00
|
|
|
|
/*
|
|
* Enumerated Regulatory Domain Information 8 bit values indicate that
|
|
* the regdomain is really a pair of unitary regdomains. 12 bit values
|
|
* are the real unitary regdomains and are the only ones which have the
|
|
* frequency bitmasks and flags set.
|
|
*/
|
|
enum {
|
|
/*
|
|
* The following regulatory domain definitions are
|
|
* found in the EEPROM. Each regulatory domain
|
|
* can operate in either a 5GHz or 2.4GHz wireless mode or
|
|
* both 5GHz and 2.4GHz wireless modes.
|
|
* In general, the value holds no special
|
|
* meaning and is used to decode into either specific
|
|
* 2.4GHz or 5GHz wireless mode for that particular
|
|
* regulatory domain.
|
|
*/
|
|
NO_ENUMRD = 0x00,
|
|
NULL1_WORLD = 0x03, /* For 11b-only countries (no 11a allowed) */
|
|
NULL1_ETSIB = 0x07, /* Israel */
|
|
NULL1_ETSIC = 0x08,
|
|
FCC1_FCCA = 0x10, /* USA */
|
|
FCC1_WORLD = 0x11, /* Hong Kong */
|
|
FCC4_FCCA = 0x12, /* USA - Public Safety */
|
|
FCC5_FCCB = 0x13, /* USA w/ 1/2 and 1/4 width channels */
|
|
|
|
FCC2_FCCA = 0x20, /* Canada */
|
|
FCC2_WORLD = 0x21, /* Australia & HK */
|
|
FCC2_ETSIC = 0x22,
|
|
FRANCE_RES = 0x31, /* Legacy France for OEM */
|
|
FCC3_FCCA = 0x3A, /* USA & Canada w/5470 band, 11h, DFS enabled */
|
|
FCC3_WORLD = 0x3B, /* USA & Canada w/5470 band, 11h, DFS enabled */
|
|
|
|
ETSI1_WORLD = 0x37,
|
|
ETSI3_ETSIA = 0x32, /* France (optional) */
|
|
ETSI2_WORLD = 0x35, /* Hungary & others */
|
|
ETSI3_WORLD = 0x36, /* France & others */
|
|
ETSI4_WORLD = 0x30,
|
|
ETSI4_ETSIC = 0x38,
|
|
ETSI5_WORLD = 0x39,
|
|
ETSI6_WORLD = 0x34, /* Bulgaria */
|
|
ETSI_RESERVED = 0x33, /* Reserved (Do not used) */
|
|
|
|
MKK1_MKKA = 0x40, /* Japan (JP1) */
|
|
MKK1_MKKB = 0x41, /* Japan (JP0) */
|
|
APL4_WORLD = 0x42, /* Singapore */
|
|
MKK2_MKKA = 0x43, /* Japan with 4.9G channels */
|
|
APL_RESERVED = 0x44, /* Reserved (Do not used) */
|
|
APL2_WORLD = 0x45, /* Korea */
|
|
APL2_APLC = 0x46,
|
|
APL3_WORLD = 0x47,
|
|
MKK1_FCCA = 0x48, /* Japan (JP1-1) */
|
|
APL2_APLD = 0x49, /* Korea with 2.3G channels */
|
|
MKK1_MKKA1 = 0x4A, /* Japan (JE1) */
|
|
MKK1_MKKA2 = 0x4B, /* Japan (JE2) */
|
|
MKK1_MKKC = 0x4C, /* Japan (MKK1_MKKA,except Ch14) */
|
|
|
|
APL3_FCCA = 0x50,
|
|
APL1_WORLD = 0x52, /* Latin America */
|
|
APL1_FCCA = 0x53,
|
|
APL1_APLA = 0x54,
|
|
APL1_ETSIC = 0x55,
|
|
APL2_ETSIC = 0x56, /* Venezuela */
|
|
APL5_WORLD = 0x58, /* Chile */
|
|
APL6_WORLD = 0x5B, /* Singapore */
|
|
APL7_FCCA = 0x5C, /* Taiwan 5.47 Band */
|
|
APL8_WORLD = 0x5D, /* Malaysia 5GHz */
|
|
APL9_WORLD = 0x5E, /* Korea 5GHz */
|
|
|
|
/*
|
|
* World mode SKUs
|
|
*/
|
|
WOR0_WORLD = 0x60, /* World0 (WO0 SKU) */
|
|
WOR1_WORLD = 0x61, /* World1 (WO1 SKU) */
|
|
WOR2_WORLD = 0x62, /* World2 (WO2 SKU) */
|
|
WOR3_WORLD = 0x63, /* World3 (WO3 SKU) */
|
|
WOR4_WORLD = 0x64, /* World4 (WO4 SKU) */
|
|
WOR5_ETSIC = 0x65, /* World5 (WO5 SKU) */
|
|
|
|
WOR01_WORLD = 0x66, /* World0-1 (WW0-1 SKU) */
|
|
WOR02_WORLD = 0x67, /* World0-2 (WW0-2 SKU) */
|
|
EU1_WORLD = 0x68, /* Same as World0-2 (WW0-2 SKU), except active scan ch1-13. No ch14 */
|
|
|
|
WOR9_WORLD = 0x69, /* World9 (WO9 SKU) */
|
|
WORA_WORLD = 0x6A, /* WorldA (WOA SKU) */
|
|
|
|
MKK3_MKKB = 0x80, /* Japan UNI-1 even + MKKB */
|
|
MKK3_MKKA2 = 0x81, /* Japan UNI-1 even + MKKA2 */
|
|
MKK3_MKKC = 0x82, /* Japan UNI-1 even + MKKC */
|
|
|
|
MKK4_MKKB = 0x83, /* Japan UNI-1 even + UNI-2 + MKKB */
|
|
MKK4_MKKA2 = 0x84, /* Japan UNI-1 even + UNI-2 + MKKA2 */
|
|
MKK4_MKKC = 0x85, /* Japan UNI-1 even + UNI-2 + MKKC */
|
|
|
|
MKK5_MKKB = 0x86, /* Japan UNI-1 even + UNI-2 + mid-band + MKKB */
|
|
MKK5_MKKA2 = 0x87, /* Japan UNI-1 even + UNI-2 + mid-band + MKKA2 */
|
|
MKK5_MKKC = 0x88, /* Japan UNI-1 even + UNI-2 + mid-band + MKKC */
|
|
|
|
MKK6_MKKB = 0x89, /* Japan UNI-1 even + UNI-1 odd MKKB */
|
|
MKK6_MKKA2 = 0x8A, /* Japan UNI-1 even + UNI-1 odd + MKKA2 */
|
|
MKK6_MKKC = 0x8B, /* Japan UNI-1 even + UNI-1 odd + MKKC */
|
|
|
|
MKK7_MKKB = 0x8C, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKB */
|
|
MKK7_MKKA2 = 0x8D, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKA2 */
|
|
MKK7_MKKC = 0x8E, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + MKKC */
|
|
|
|
MKK8_MKKB = 0x8F, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKB */
|
|
MKK8_MKKA2 = 0x90, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKA2 */
|
|
MKK8_MKKC = 0x91, /* Japan UNI-1 even + UNI-1 odd + UNI-2 + mid-band + MKKC */
|
|
|
|
/* Following definitions are used only by s/w to map old
|
|
* Japan SKUs.
|
|
*/
|
|
MKK3_MKKA = 0xF0, /* Japan UNI-1 even + MKKA */
|
|
MKK3_MKKA1 = 0xF1, /* Japan UNI-1 even + MKKA1 */
|
|
MKK3_FCCA = 0xF2, /* Japan UNI-1 even + FCCA */
|
|
MKK4_MKKA = 0xF3, /* Japan UNI-1 even + UNI-2 + MKKA */
|
|
MKK4_MKKA1 = 0xF4, /* Japan UNI-1 even + UNI-2 + MKKA1 */
|
|
MKK4_FCCA = 0xF5, /* Japan UNI-1 even + UNI-2 + FCCA */
|
|
MKK9_MKKA = 0xF6, /* Japan UNI-1 even + 4.9GHz */
|
|
MKK10_MKKA = 0xF7, /* Japan UNI-1 even + UNI-2 + 4.9GHz */
|
|
|
|
/*
|
|
* Regulator domains ending in a number (e.g. APL1,
|
|
* MK1, ETSI4, etc) apply to 5GHz channel and power
|
|
* information. Regulator domains ending in a letter
|
|
* (e.g. APLA, FCCA, etc) apply to 2.4GHz channel and
|
|
* power information.
|
|
*/
|
|
APL1 = 0x0150, /* LAT & Asia */
|
|
APL2 = 0x0250, /* LAT & Asia */
|
|
APL3 = 0x0350, /* Taiwan */
|
|
APL4 = 0x0450, /* Jordan */
|
|
APL5 = 0x0550, /* Chile */
|
|
APL6 = 0x0650, /* Singapore */
|
|
APL8 = 0x0850, /* Malaysia */
|
|
APL9 = 0x0950, /* Korea (South) ROC 3 */
|
|
|
|
ETSI1 = 0x0130, /* Europe & others */
|
|
ETSI2 = 0x0230, /* Europe & others */
|
|
ETSI3 = 0x0330, /* Europe & others */
|
|
ETSI4 = 0x0430, /* Europe & others */
|
|
ETSI5 = 0x0530, /* Europe & others */
|
|
ETSI6 = 0x0630, /* Europe & others */
|
|
ETSIA = 0x0A30, /* France */
|
|
ETSIB = 0x0B30, /* Israel */
|
|
ETSIC = 0x0C30, /* Latin America */
|
|
|
|
FCC1 = 0x0110, /* US & others */
|
|
FCC2 = 0x0120, /* Canada, Australia & New Zealand */
|
|
FCC3 = 0x0160, /* US w/new middle band & DFS */
|
|
FCC4 = 0x0165, /* US Public Safety */
|
|
FCC5 = 0x0166, /* US w/ 1/2 and 1/4 width channels */
|
|
FCCA = 0x0A10,
|
|
FCCB = 0x0A11, /* US w/ 1/2 and 1/4 width channels */
|
|
|
|
APLD = 0x0D50, /* South Korea */
|
|
|
|
MKK1 = 0x0140, /* Japan (UNI-1 odd)*/
|
|
MKK2 = 0x0240, /* Japan (4.9 GHz + UNI-1 odd) */
|
|
MKK3 = 0x0340, /* Japan (UNI-1 even) */
|
|
MKK4 = 0x0440, /* Japan (UNI-1 even + UNI-2) */
|
|
MKK5 = 0x0540, /* Japan (UNI-1 even + UNI-2 + mid-band) */
|
|
MKK6 = 0x0640, /* Japan (UNI-1 odd + UNI-1 even) */
|
|
MKK7 = 0x0740, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 */
|
|
MKK8 = 0x0840, /* Japan (UNI-1 odd + UNI-1 even + UNI-2 + mid-band) */
|
|
MKK9 = 0x0940, /* Japan (UNI-1 even + 4.9 GHZ) */
|
|
MKK10 = 0x0B40, /* Japan (UNI-1 even + UNI-2 + 4.9 GHZ) */
|
|
MKKA = 0x0A40, /* Japan */
|
|
MKKC = 0x0A50,
|
|
|
|
NULL1 = 0x0198,
|
|
WORLD = 0x0199,
|
|
SR9_WORLD = 0x0298,
|
|
XR9_WORLD = 0x0299,
|
|
GZ901_WORLD = 0x029a,
|
|
DEBUG_REG_DMN = 0x01ff,
|
|
};
|
|
|
|
#define WORLD_SKU_MASK 0x00F0
|
|
#define WORLD_SKU_PREFIX 0x0060
|
|
|
|
enum { /* conformance test limits */
|
|
FCC = 0x10,
|
|
MKK = 0x40,
|
|
ETSI = 0x30,
|
|
};
|
|
|
|
/*
|
|
* The following are flags for different requirements per reg domain.
|
|
* These requirements are either inhereted from the reg domain pair or
|
|
* from the unitary reg domain if the reg domain pair flags value is 0
|
|
*/
|
|
enum {
|
|
NO_REQ = 0x00000000, /* NB: must be zero */
|
|
DISALLOW_ADHOC_11A = 0x00000001,
|
|
DISALLOW_ADHOC_11A_TURB = 0x00000002,
|
|
NEED_NFC = 0x00000004,
|
|
ADHOC_PER_11D = 0x00000008, /* Start Ad-Hoc mode */
|
|
ADHOC_NO_11A = 0x00000010,
|
|
LIMIT_FRAME_4MS = 0x00000020, /* 4msec limit on frame length*/
|
|
NO_HOSTAP = 0x00000040, /* No HOSTAP mode opereation */
|
|
};
|
|
|
|
/*
|
|
* The following describe the bit masks for different passive scan
|
|
* capability/requirements per regdomain.
|
|
*/
|
|
#define NO_PSCAN 0x0ULL /* NB: must be zero */
|
|
#define PSCAN_FCC 0x0000000000000001ULL
|
|
#define PSCAN_FCC_T 0x0000000000000002ULL
|
|
#define PSCAN_ETSI 0x0000000000000004ULL
|
|
#define PSCAN_MKK1 0x0000000000000008ULL
|
|
#define PSCAN_MKK2 0x0000000000000010ULL
|
|
#define PSCAN_MKKA 0x0000000000000020ULL
|
|
#define PSCAN_MKKA_G 0x0000000000000040ULL
|
|
#define PSCAN_ETSIA 0x0000000000000080ULL
|
|
#define PSCAN_ETSIB 0x0000000000000100ULL
|
|
#define PSCAN_ETSIC 0x0000000000000200ULL
|
|
#define PSCAN_WWR 0x0000000000000400ULL
|
|
#define PSCAN_MKKA1 0x0000000000000800ULL
|
|
#define PSCAN_MKKA1_G 0x0000000000001000ULL
|
|
#define PSCAN_MKKA2 0x0000000000002000ULL
|
|
#define PSCAN_MKKA2_G 0x0000000000004000ULL
|
|
#define PSCAN_MKK3 0x0000000000008000ULL
|
|
#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
|
|
#define IS_ECM_CHAN 0x8000000000000000ULL
|
|
|
|
/*
|
|
* THE following table is the mapping of regdomain pairs specified by
|
|
* an 8 bit regdomain value to the individual unitary reg domains
|
|
*/
|
|
typedef struct {
|
|
HAL_REG_DOMAIN regDmnEnum; /* 16 bit reg domain pair */
|
|
HAL_REG_DOMAIN regDmn5GHz; /* 5GHz reg domain */
|
|
HAL_REG_DOMAIN regDmn2GHz; /* 2GHz reg domain */
|
|
uint32_t flags5GHz; /* Requirements flags (AdHoc
|
|
disallow, noise floor cal needed,
|
|
etc) */
|
|
uint32_t flags2GHz; /* Requirements flags (AdHoc
|
|
disallow, noise floor cal needed,
|
|
etc) */
|
|
uint64_t pscanMask; /* Passive Scan flags which
|
|
can override unitary domain
|
|
passive scan flags. This
|
|
value is used as a mask on
|
|
the unitary flags*/
|
|
uint16_t singleCC; /* Country code of single country if
|
|
a one-on-one mapping exists */
|
|
} REG_DMN_PAIR_MAPPING;
|
|
|
|
static REG_DMN_PAIR_MAPPING regDomainPairs[] = {
|
|
{NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
|
|
{FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{FCC4_FCCA, FCC4, FCCA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{FCC5_FCCB, FCC5, FCCB, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
|
|
{ETSI1_WORLD, ETSI1, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{ETSI2_WORLD, ETSI2, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{ETSI3_WORLD, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{ETSI4_WORLD, ETSI4, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{ETSI5_WORLD, ETSI5, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{ETSI6_WORLD, ETSI6, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
|
|
{ETSI3_ETSIA, ETSI3, WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
|
|
{FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
|
|
{APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER, },
|
|
|
|
{MKK1_MKKA, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN },
|
|
{MKK1_MKKB, MKK1, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN1 },
|
|
{MKK1_FCCA, MKK1, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN2 },
|
|
{MKK1_MKKA1, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4 },
|
|
{MKK1_MKKA2, MKK1, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5 },
|
|
{MKK1_MKKC, MKK1, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN6 },
|
|
|
|
/* MKK2 */
|
|
{MKK2_MKKA, MKK2, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC| LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN3 },
|
|
|
|
/* MKK3 */
|
|
{MKK3_MKKA, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC , PSCAN_MKKA, 0 },
|
|
{MKK3_MKKB, MKK3, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN7 },
|
|
{MKK3_MKKA1, MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 },
|
|
{MKK3_MKKA2,MKK3, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8 },
|
|
{MKK3_MKKC, MKK3, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, CTRY_JAPAN9 },
|
|
{MKK3_FCCA, MKK3, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, NO_PSCAN, 0 },
|
|
|
|
/* MKK4 */
|
|
{MKK4_MKKB, MKK4, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN10 },
|
|
{MKK4_MKKA1, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, 0 },
|
|
{MKK4_MKKA2, MKK4, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 |PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11 },
|
|
{MKK4_MKKC, MKK4, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN12 },
|
|
{MKK4_FCCA, MKK4, FCCA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, 0 },
|
|
|
|
/* MKK5 */
|
|
{MKK5_MKKB, MKK5, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN13 },
|
|
{MKK5_MKKA2,MKK5, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14 },
|
|
{MKK5_MKKC, MKK5, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3, CTRY_JAPAN15 },
|
|
|
|
/* MKK6 */
|
|
{MKK6_MKKB, MKK6, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16 },
|
|
{MKK6_MKKA2, MKK6, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17 },
|
|
{MKK6_MKKC, MKK6, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1, CTRY_JAPAN18 },
|
|
|
|
/* MKK7 */
|
|
{MKK7_MKKB, MKK7, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN19 },
|
|
{MKK7_MKKA2, MKK7, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN20 },
|
|
{MKK7_MKKC, MKK7, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21 },
|
|
|
|
/* MKK8 */
|
|
{MKK8_MKKB, MKK8, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN22 },
|
|
{MKK8_MKKA2,MKK8, MKKA, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN23 },
|
|
{MKK8_MKKC, MKK8, MKKC, DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKK3 , CTRY_JAPAN24 },
|
|
|
|
{MKK9_MKKA, MKK9, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, 0 },
|
|
{MKK10_MKKA, MKK10, MKKA, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G, 0 },
|
|
|
|
/* These are super domains */
|
|
{WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WOR1_WORLD, WOR1_WORLD, WOR1_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WOR4_WORLD, WOR4_WORLD, WOR4_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WOR9_WORLD, WOR9_WORLD, WOR9_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{WORA_WORLD, WORA_WORLD, WORA_WORLD, DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, 0 },
|
|
{SR9_WORLD, NULL1, SR9_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_SR9 },
|
|
{XR9_WORLD, NULL1, XR9_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_XR9 },
|
|
{GZ901_WORLD, NULL1, GZ901_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, CTRY_GZ901 },
|
|
};
|
|
|
|
/*
|
|
* The following tables are the master list for all different freqeuncy
|
|
* bands with the complete matrix of all possible flags and settings
|
|
* for each band if it is used in ANY reg domain.
|
|
*/
|
|
|
|
#define DEF_REGDMN FCC1_FCCA
|
|
#define DEF_DMN_5 FCC1
|
|
#define DEF_DMN_2 FCCA
|
|
#define COUNTRY_ERD_FLAG 0x8000
|
|
#define WORLDWIDE_ROAMING_FLAG 0x4000
|
|
#define SUPER_DOMAIN_MASK 0x0fff
|
|
#define COUNTRY_CODE_MASK 0x3fff
|
|
|
|
#define YES AH_TRUE
|
|
#define NO AH_FALSE
|
|
|
|
typedef struct {
|
|
HAL_CTRY_CODE countryCode;
|
|
HAL_REG_DOMAIN regDmnEnum;
|
|
HAL_BOOL allow11g;
|
|
HAL_BOOL allow11aTurbo;
|
|
HAL_BOOL allow11gTurbo;
|
|
HAL_BOOL allow11ng20;
|
|
HAL_BOOL allow11ng40;
|
|
HAL_BOOL allow11na20;
|
|
HAL_BOOL allow11na40;
|
|
uint16_t outdoorChanStart;
|
|
} COUNTRY_CODE_TO_ENUM_RD;
|
|
|
|
static COUNTRY_CODE_TO_ENUM_RD allCountries[] = {
|
|
{CTRY_DEBUG, NO_ENUMRD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_DEFAULT, DEF_REGDMN, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_ALBANIA, NULL1_WORLD, YES, NO, YES, YES, NO, NO, NO, 7000 },
|
|
{CTRY_ALGERIA, NULL1_WORLD, YES, NO, YES, YES, NO, NO, NO, 7000 },
|
|
{CTRY_ARGENTINA, APL3_WORLD, NO, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_ARMENIA, ETSI4_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_AUSTRALIA, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_AUSTRIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_AZERBAIJAN, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_BAHRAIN, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_BELARUS, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_BELGIUM, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_BELIZE, APL1_ETSIC, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_BOLIVIA, APL1_ETSIC, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_BRAZIL, FCC3_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
|
|
{CTRY_BRUNEI_DARUSSALAM,APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_BULGARIA, ETSI6_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_CANADA, FCC2_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_CHILE, APL6_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_CHINA, APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_COLOMBIA, FCC1_FCCA, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_COSTA_RICA, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_CROATIA, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_CYPRUS, ETSI1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_CZECH, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_DENMARK, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_DOMINICAN_REPUBLIC,FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_ECUADOR, NULL1_WORLD, NO, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_EGYPT, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_EL_SALVADOR, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_ESTONIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_FINLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_FRANCE, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_FRANCE2, ETSI3_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_GEORGIA, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_GERMANY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_GREECE, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_GUATEMALA, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_GZ901, GZ901_WORLD, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_HONDURAS, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_HONG_KONG, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_HUNGARY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_ICELAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_INDIA, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_INDONESIA, APL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_IRAN, APL1_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_IRELAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_ISRAEL, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_ITALY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_JAPAN, MKK1_MKKA, YES, NO, NO, YES, NO, YES, NO, 7000 },
|
|
{CTRY_JAPAN1, MKK1_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN2, MKK1_FCCA, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN3, MKK2_MKKA, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN4, MKK1_MKKA1, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN5, MKK1_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN6, MKK1_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
|
|
{CTRY_JAPAN7, MKK3_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN8, MKK3_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN9, MKK3_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
|
|
{CTRY_JAPAN10, MKK4_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN11, MKK4_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN12, MKK4_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
|
|
{CTRY_JAPAN13, MKK5_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN14, MKK5_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN15, MKK5_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
|
|
{CTRY_JAPAN16, MKK6_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN17, MKK6_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN18, MKK6_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
|
|
{CTRY_JAPAN19, MKK7_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN20, MKK7_MKKA2, YES, NO, NO, YES, NO, YES, NO, 7000 },
|
|
{CTRY_JAPAN21, MKK7_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
|
|
{CTRY_JAPAN22, MKK8_MKKB, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN23, MKK8_MKKA2, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_JAPAN24, MKK8_MKKC, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
|
|
{CTRY_JORDAN, APL4_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_KAZAKHSTAN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_KOREA_NORTH, APL2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_KOREA_ROC, APL2_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
|
|
{CTRY_KOREA_ROC2, APL2_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
|
|
{CTRY_KOREA_ROC3, APL9_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
|
|
{CTRY_KUWAIT, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_LATVIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_LEBANON, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_LIECHTENSTEIN,ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_LITHUANIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_LUXEMBOURG, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_MACAU, FCC2_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_MACEDONIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_MALAYSIA, APL8_WORLD, YES, NO, NO, YES, NO, YES, NO, 7000 },
|
|
{CTRY_MALTA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_MEXICO, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_MONACO, ETSI4_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_MOROCCO, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_NETHERLANDS, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_NEW_ZEALAND, FCC2_ETSIC, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_NORWAY, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_OMAN, APL6_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_PAKISTAN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_PANAMA, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_PERU, APL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_PHILIPPINES, FCC3_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_POLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_PORTUGAL, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_PUERTO_RICO, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_QATAR, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_ROMANIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_RUSSIA, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_SAUDI_ARABIA,FCC2_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_SINGAPORE, APL6_WORLD, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_SLOVAKIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_SLOVENIA, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_SOUTH_AFRICA,FCC3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_SPAIN, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_SR9, SR9_WORLD, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_SWEDEN, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_SWITZERLAND, ETSI1_WORLD, YES, NO, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_SYRIA, NULL1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_TAIWAN, APL3_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_THAILAND, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_TRINIDAD_Y_TOBAGO,ETSI4_WORLD,YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_TUNISIA, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_TURKEY, ETSI3_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_UKRAINE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_UAE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_UNITED_KINGDOM, ETSI1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_UNITED_STATES, FCC1_FCCA, YES, YES, YES, YES,YES, YES,YES, 5825 },
|
|
{CTRY_UNITED_STATES_FCC49,FCC4_FCCA,YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_URUGUAY, FCC1_WORLD, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_UZBEKISTAN, FCC3_FCCA, YES, YES, YES, YES,YES, YES,YES, 7000 },
|
|
{CTRY_VENEZUELA, APL2_ETSIC, YES, NO, YES, YES,YES, YES, NO, 7000 },
|
|
{CTRY_VIET_NAM, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_XR9, XR9_WORLD, YES, NO, NO, NO, NO, NO, NO, 7000 },
|
|
{CTRY_YEMEN, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 },
|
|
{CTRY_ZIMBABWE, NULL1_WORLD, YES, NO, YES, YES,YES, NO, NO, 7000 }
|
|
};
|
|
|
|
/* Bit masks for DFS per regdomain */
|
|
enum {
|
|
NO_DFS = 0x0000000000000000ULL, /* NB: must be zero */
|
|
DFS_FCC3 = 0x0000000000000001ULL,
|
|
DFS_ETSI = 0x0000000000000002ULL,
|
|
DFS_MKK4 = 0x0000000000000004ULL,
|
|
};
|
|
|
|
#define AFTER(x) ((x)+1)
|
|
|
|
/*
|
|
* Frequency band collections are defined using bitmasks. Each bit
|
|
* in a mask is the index of an entry in one of the following tables.
|
|
* Bitmasks are BMLEN*64 bits so if a table grows beyond that the bit
|
|
* vectors must be enlarged or the tables split somehow (e.g. split
|
|
* 1/2 and 1/4 rate channels into a separate table).
|
|
*
|
|
* Beware of ordering; the indices are defined relative to the preceding
|
|
* entry so if things get off there will be confusion. A good way to
|
|
* check the indices is to collect them in a switch statement in a stub
|
|
* function so the compiler checks for duplicates.
|
|
*/
|
|
|
|
typedef struct {
|
|
uint16_t lowChannel; /* Low channel center in MHz */
|
|
uint16_t highChannel; /* High Channel center in MHz */
|
|
uint8_t powerDfs; /* Max power (dBm) for channel
|
|
range when using DFS */
|
|
uint8_t antennaMax; /* Max allowed antenna gain */
|
|
uint8_t channelBW; /* Bandwidth of the channel */
|
|
uint8_t channelSep; /* Channel separation within
|
|
the band */
|
|
uint64_t useDfs; /* Use DFS in the RegDomain
|
|
if corresponding bit is set */
|
|
uint64_t usePassScan; /* Use Passive Scan in the RegDomain
|
|
if corresponding bit is set */
|
|
uint8_t regClassId; /* Regulatory class id */
|
|
} REG_DMN_FREQ_BAND;
|
|
|
|
/*
|
|
* 5GHz 11A channel tags
|
|
*/
|
|
static REG_DMN_FREQ_BAND regDmn5GhzFreq[] = {
|
|
{ 4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 },
|
|
#define F1_4915_4925 0
|
|
{ 4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16 },
|
|
#define F1_4935_4945 AFTER(F1_4915_4925)
|
|
{ 4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7 },
|
|
#define F1_4920_4980 AFTER(F1_4935_4945)
|
|
{ 4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define F1_4942_4987 AFTER(F1_4920_4980)
|
|
{ 4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define F1_4945_4985 AFTER(F1_4942_4987)
|
|
{ 4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define F1_4950_4980 AFTER(F1_4945_4985)
|
|
{ 5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 },
|
|
#define F1_5035_5040 AFTER(F1_4950_4980)
|
|
{ 5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2 },
|
|
#define F1_5040_5080 AFTER(F1_5035_5040)
|
|
{ 5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12 },
|
|
#define F1_5055_5055 AFTER(F1_5040_5080)
|
|
|
|
{ 5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F1_5120_5240 AFTER(F1_5055_5055)
|
|
{ 5120, 5240, 5, 6, 10, 10, NO_DFS, NO_PSCAN, 0 },
|
|
#define F2_5120_5240 AFTER(F1_5120_5240)
|
|
{ 5120, 5240, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0 },
|
|
#define F3_5120_5240 AFTER(F2_5120_5240)
|
|
|
|
{ 5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 },
|
|
#define F1_5170_5230 AFTER(F3_5120_5240)
|
|
{ 5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1 },
|
|
#define F2_5170_5230 AFTER(F1_5170_5230)
|
|
|
|
{ 5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F1_5180_5240 AFTER(F2_5170_5230)
|
|
{ 5180, 5240, 17, 6, 20, 20, NO_DFS, PSCAN_FCC, 1 },
|
|
#define F2_5180_5240 AFTER(F1_5180_5240)
|
|
{ 5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F3_5180_5240 AFTER(F2_5180_5240)
|
|
{ 5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F4_5180_5240 AFTER(F3_5180_5240)
|
|
{ 5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F5_5180_5240 AFTER(F4_5180_5240)
|
|
{ 5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0 },
|
|
#define F6_5180_5240 AFTER(F5_5180_5240)
|
|
{ 5180, 5240, 17, 6, 20, 10, NO_DFS, PSCAN_FCC, 1 },
|
|
#define F7_5180_5240 AFTER(F6_5180_5240)
|
|
{ 5180, 5240, 17, 6, 20, 5, NO_DFS, PSCAN_FCC, 1 },
|
|
#define F8_5180_5240 AFTER(F7_5180_5240)
|
|
|
|
{ 5180, 5320, 20, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
|
|
#define F1_5180_5320 AFTER(F8_5180_5240)
|
|
|
|
{ 5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F1_5240_5280 AFTER(F1_5180_5320)
|
|
|
|
{ 5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F1_5260_5280 AFTER(F1_5240_5280)
|
|
|
|
{ 5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F1_5260_5320 AFTER(F1_5260_5280)
|
|
|
|
{ 5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3 , 0 },
|
|
#define F2_5260_5320 AFTER(F1_5260_5320)
|
|
|
|
{ 5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
|
|
#define F3_5260_5320 AFTER(F2_5260_5320)
|
|
{ 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
|
|
#define F4_5260_5320 AFTER(F3_5260_5320)
|
|
{ 5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 },
|
|
#define F5_5260_5320 AFTER(F4_5260_5320)
|
|
{ 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F6_5260_5320 AFTER(F5_5260_5320)
|
|
{ 5260, 5320, 23, 6, 20, 10, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
|
|
#define F7_5260_5320 AFTER(F6_5260_5320)
|
|
{ 5260, 5320, 23, 6, 20, 5, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2 },
|
|
#define F8_5260_5320 AFTER(F7_5260_5320)
|
|
|
|
{ 5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
|
|
#define F1_5260_5700 AFTER(F8_5260_5320)
|
|
{ 5260, 5700, 5, 6, 10, 10, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
|
|
#define F2_5260_5700 AFTER(F1_5260_5700)
|
|
{ 5260, 5700, 5, 6, 5, 5, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0 },
|
|
#define F3_5260_5700 AFTER(F2_5260_5700)
|
|
|
|
{ 5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0 },
|
|
#define F1_5280_5320 AFTER(F3_5260_5700)
|
|
|
|
{ 5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
|
|
#define F1_5500_5620 AFTER(F1_5280_5320)
|
|
|
|
{ 5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4 },
|
|
#define F1_5500_5700 AFTER(F1_5500_5620)
|
|
{ 5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F2_5500_5700 AFTER(F1_5500_5700)
|
|
{ 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC | PSCAN_ETSI, 0 },
|
|
#define F3_5500_5700 AFTER(F2_5500_5700)
|
|
{ 5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4, PSCAN_MKK3 | PSCAN_FCC, 0 },
|
|
#define F4_5500_5700 AFTER(F3_5500_5700)
|
|
|
|
{ 5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F1_5745_5805 AFTER(F4_5500_5700)
|
|
{ 5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F2_5745_5805 AFTER(F1_5745_5805)
|
|
{ 5745, 5805, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0 },
|
|
#define F3_5745_5805 AFTER(F2_5745_5805)
|
|
{ 5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F1_5745_5825 AFTER(F3_5745_5805)
|
|
{ 5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F2_5745_5825 AFTER(F1_5745_5825)
|
|
{ 5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F3_5745_5825 AFTER(F2_5745_5825)
|
|
{ 5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F4_5745_5825 AFTER(F3_5745_5825)
|
|
{ 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3 },
|
|
#define F5_5745_5825 AFTER(F4_5745_5825)
|
|
{ 5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define F6_5745_5825 AFTER(F5_5745_5825)
|
|
{ 5745, 5825, 5, 6, 10, 10, NO_DFS, NO_PSCAN, 0 },
|
|
#define F7_5745_5825 AFTER(F6_5745_5825)
|
|
{ 5745, 5825, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0 },
|
|
#define F8_5745_5825 AFTER(F7_5745_5825)
|
|
{ 5745, 5825, 30, 6, 20, 10, NO_DFS, NO_PSCAN, 3 },
|
|
#define F9_5745_5825 AFTER(F8_5745_5825)
|
|
{ 5745, 5825, 30, 6, 20, 5, NO_DFS, NO_PSCAN, 3 },
|
|
#define F10_5745_5825 AFTER(F9_5745_5825)
|
|
|
|
/*
|
|
* Below are the world roaming channels
|
|
* All WWR domains have no power limit, instead use the card's CTL
|
|
* or max power settings.
|
|
*/
|
|
{ 4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
|
|
#define W1_4920_4980 AFTER(F10_5745_5825)
|
|
{ 5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
|
|
#define W1_5040_5080 AFTER(W1_4920_4980)
|
|
{ 5170, 5230, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
|
|
#define W1_5170_5230 AFTER(W1_5040_5080)
|
|
{ 5180, 5240, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
|
|
#define W1_5180_5240 AFTER(W1_5170_5230)
|
|
{ 5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
|
|
#define W1_5260_5320 AFTER(W1_5180_5240)
|
|
{ 5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
|
|
#define W1_5745_5825 AFTER(W1_5260_5320)
|
|
{ 5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0 },
|
|
#define W1_5500_5700 AFTER(W1_5745_5825)
|
|
{ 5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define W2_5260_5320 AFTER(W1_5500_5700)
|
|
{ 5180, 5240, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0 },
|
|
#define W2_5180_5240 AFTER(W2_5260_5320)
|
|
{ 5825, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0 },
|
|
#define W2_5825_5825 AFTER(W2_5180_5240)
|
|
};
|
|
|
|
/*
|
|
* 5GHz Turbo (dynamic & static) tags
|
|
*/
|
|
static REG_DMN_FREQ_BAND regDmn5GhzTurboFreq[] = {
|
|
{ 5130, 5210, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_5130_5210 0
|
|
{ 5250, 5330, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
|
|
#define T1_5250_5330 AFTER(T1_5130_5210)
|
|
{ 5370, 5490, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_5370_5490 AFTER(T1_5250_5330)
|
|
{ 5530, 5650, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
|
|
#define T1_5530_5650 AFTER(T1_5370_5490)
|
|
|
|
{ 5150, 5190, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_5150_5190 AFTER(T1_5530_5650)
|
|
{ 5230, 5310, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
|
|
#define T1_5230_5310 AFTER(T1_5150_5190)
|
|
{ 5350, 5470, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_5350_5470 AFTER(T1_5230_5310)
|
|
{ 5510, 5670, 5, 6, 40, 40, DFS_FCC3, NO_PSCAN, 0},
|
|
#define T1_5510_5670 AFTER(T1_5350_5470)
|
|
|
|
{ 5200, 5240, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_5200_5240 AFTER(T1_5510_5670)
|
|
{ 5200, 5240, 23, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T2_5200_5240 AFTER(T1_5200_5240)
|
|
{ 5210, 5210, 17, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_5210_5210 AFTER(T2_5200_5240)
|
|
{ 5210, 5210, 23, 0, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T2_5210_5210 AFTER(T1_5210_5210)
|
|
|
|
{ 5280, 5280, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
|
|
#define T1_5280_5280 AFTER(T2_5210_5210)
|
|
{ 5280, 5280, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
|
|
#define T2_5280_5280 AFTER(T1_5280_5280)
|
|
{ 5250, 5250, 17, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
|
|
#define T1_5250_5250 AFTER(T2_5280_5280)
|
|
{ 5290, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
|
|
#define T1_5290_5290 AFTER(T1_5250_5250)
|
|
{ 5250, 5290, 20, 0, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
|
|
#define T1_5250_5290 AFTER(T1_5290_5290)
|
|
{ 5250, 5290, 23, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
|
|
#define T2_5250_5290 AFTER(T1_5250_5290)
|
|
|
|
{ 5540, 5660, 20, 6, 40, 40, DFS_FCC3, PSCAN_FCC_T, 0},
|
|
#define T1_5540_5660 AFTER(T2_5250_5290)
|
|
{ 5760, 5800, 20, 0, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_5760_5800 AFTER(T1_5540_5660)
|
|
{ 5760, 5800, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T2_5760_5800 AFTER(T1_5760_5800)
|
|
|
|
{ 5765, 5805, 30, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_5765_5805 AFTER(T2_5760_5800)
|
|
|
|
/*
|
|
* Below are the WWR frequencies
|
|
*/
|
|
{ 5210, 5250, 15, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
|
|
#define WT1_5210_5250 AFTER(T1_5765_5805)
|
|
{ 5290, 5290, 18, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
|
|
#define WT1_5290_5290 AFTER(WT1_5210_5250)
|
|
{ 5540, 5660, 20, 0, 40, 40, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
|
|
#define WT1_5540_5660 AFTER(WT1_5290_5290)
|
|
{ 5760, 5800, 20, 0, 40, 40, NO_DFS, PSCAN_WWR, 0},
|
|
#define WT1_5760_5800 AFTER(WT1_5540_5660)
|
|
};
|
|
|
|
/*
|
|
* 2GHz 11b channel tags
|
|
*/
|
|
static REG_DMN_FREQ_BAND regDmn2GhzFreq[] = {
|
|
{ 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F1_2312_2372 0
|
|
{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F2_2312_2372 AFTER(F1_2312_2372)
|
|
|
|
{ 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F1_2412_2472 AFTER(F2_2312_2372)
|
|
{ 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
|
|
#define F2_2412_2472 AFTER(F1_2412_2472)
|
|
{ 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F3_2412_2472 AFTER(F2_2412_2472)
|
|
|
|
{ 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F1_2412_2462 AFTER(F3_2412_2472)
|
|
{ 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
|
|
#define F2_2412_2462 AFTER(F1_2412_2462)
|
|
|
|
{ 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F1_2432_2442 AFTER(F2_2412_2462)
|
|
|
|
{ 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F1_2457_2472 AFTER(F1_2432_2442)
|
|
|
|
{ 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
|
|
#define F1_2467_2472 AFTER(F1_2457_2472)
|
|
|
|
{ 2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F1_2484_2484 AFTER(F1_2467_2472)
|
|
{ 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
|
|
#define F2_2484_2484 AFTER(F1_2484_2484)
|
|
|
|
{ 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define F1_2512_2732 AFTER(F2_2484_2484)
|
|
|
|
/*
|
|
* WWR have powers opened up to 20dBm.
|
|
* Limits should often come from CTL/Max powers
|
|
*/
|
|
{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define W1_2312_2372 AFTER(F1_2512_2732)
|
|
{ 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define W1_2412_2412 AFTER(W1_2312_2372)
|
|
{ 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define W1_2417_2432 AFTER(W1_2412_2412)
|
|
{ 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define W1_2437_2442 AFTER(W1_2417_2432)
|
|
{ 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define W1_2447_2457 AFTER(W1_2437_2442)
|
|
{ 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define W1_2462_2462 AFTER(W1_2447_2457)
|
|
{ 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
|
|
#define W1_2467_2467 AFTER(W1_2462_2462)
|
|
{ 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
|
|
#define W2_2467_2467 AFTER(W1_2467_2467)
|
|
{ 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
|
|
#define W1_2472_2472 AFTER(W2_2467_2467)
|
|
{ 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
|
|
#define W2_2472_2472 AFTER(W1_2472_2472)
|
|
{ 2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
|
|
#define W1_2484_2484 AFTER(W2_2472_2472)
|
|
{ 2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
|
|
#define W2_2484_2484 AFTER(W1_2484_2484)
|
|
};
|
|
|
|
/*
|
|
* 2GHz 11g channel tags
|
|
*/
|
|
static REG_DMN_FREQ_BAND regDmn2Ghz11gFreq[] = {
|
|
{ 2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G1_2312_2372 0
|
|
{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G2_2312_2372 AFTER(G1_2312_2372)
|
|
{ 2312, 2372, 5, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G3_2312_2372 AFTER(G2_2312_2372)
|
|
{ 2312, 2372, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G4_2312_2372 AFTER(G3_2312_2372)
|
|
|
|
{ 2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G1_2412_2472 AFTER(G4_2312_2372)
|
|
{ 2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
|
|
#define G2_2412_2472 AFTER(G1_2412_2472)
|
|
{ 2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G3_2412_2472 AFTER(G2_2412_2472)
|
|
{ 2412, 2472, 5, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G4_2412_2472 AFTER(G3_2412_2472)
|
|
{ 2412, 2472, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G5_2412_2472 AFTER(G4_2412_2472)
|
|
|
|
{ 2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G1_2412_2462 AFTER(G5_2412_2472)
|
|
{ 2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
|
|
#define G2_2412_2462 AFTER(G1_2412_2462)
|
|
{ 2412, 2462, 27, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G3_2412_2462 AFTER(G2_2412_2462)
|
|
{ 2412, 2462, 27, 6, 5, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G4_2412_2462 AFTER(G3_2412_2462)
|
|
|
|
{ 2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G1_2432_2442 AFTER(G4_2412_2462)
|
|
|
|
{ 2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G1_2457_2472 AFTER(G1_2432_2442)
|
|
|
|
{ 2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G1_2512_2732 AFTER(G1_2457_2472)
|
|
{ 2512, 2732, 5, 6, 10, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G2_2512_2732 AFTER(G1_2512_2732)
|
|
{ 2512, 2732, 5, 6, 5, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define G3_2512_2732 AFTER(G2_2512_2732)
|
|
|
|
{ 2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0 },
|
|
#define G1_2467_2472 AFTER(G3_2512_2732)
|
|
|
|
/*
|
|
* WWR open up the power to 20dBm
|
|
*/
|
|
{ 2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define WG1_2312_2372 AFTER(G1_2467_2472)
|
|
{ 2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define WG1_2412_2412 AFTER(WG1_2312_2372)
|
|
{ 2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define WG1_2417_2432 AFTER(WG1_2412_2412)
|
|
{ 2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define WG1_2437_2442 AFTER(WG1_2417_2432)
|
|
{ 2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define WG1_2447_2457 AFTER(WG1_2437_2442)
|
|
{ 2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
|
|
#define WG1_2462_2462 AFTER(WG1_2447_2457)
|
|
{ 2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
|
|
#define WG1_2467_2467 AFTER(WG1_2462_2462)
|
|
{ 2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
|
|
#define WG2_2467_2467 AFTER(WG1_2467_2467)
|
|
{ 2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
|
|
#define WG1_2472_2472 AFTER(WG2_2467_2467)
|
|
{ 2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
|
|
#define WG2_2472_2472 AFTER(WG1_2472_2472)
|
|
|
|
/*
|
|
* Mapping for 900MHz cards like Ubiquiti SR9 and XR9
|
|
* and ZComax GZ-901.
|
|
*/
|
|
{ 2422, 2437, 30, 0, 5, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S1_907_922_5 AFTER(WG2_2472_2472)
|
|
{ 2422, 2437, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S1_907_922_10 AFTER(S1_907_922_5)
|
|
{ 2427, 2432, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S1_912_917 AFTER(S1_907_922_10)
|
|
{ 2427, 2442, 30, 0, 5, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S2_907_922_5 AFTER(S1_912_917)
|
|
{ 2427, 2442, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S2_907_922_10 AFTER(S2_907_922_5)
|
|
{ 2432, 2437, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S2_912_917 AFTER(S2_907_922_10)
|
|
{ 2452, 2467, 30, 0, 5, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S1_908_923_5 AFTER(S2_912_917)
|
|
{ 2457, 2467, 30, 0, 10, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S1_913_918_10 AFTER(S1_908_923_5)
|
|
{ 2457, 2467, 30, 0, 20, 5, NO_DFS, PSCAN_FCC, 0 },
|
|
#define S1_913_918 AFTER(S1_913_918_10)
|
|
};
|
|
|
|
/*
|
|
* 2GHz Dynamic turbo tags
|
|
*/
|
|
static REG_DMN_FREQ_BAND regDmn2Ghz11gTurboFreq[] = {
|
|
{ 2312, 2372, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_2312_2372 0
|
|
{ 2437, 2437, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_2437_2437 AFTER(T1_2312_2372)
|
|
{ 2437, 2437, 20, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T2_2437_2437 AFTER(T1_2437_2437)
|
|
{ 2437, 2437, 18, 6, 40, 40, NO_DFS, PSCAN_WWR, 0},
|
|
#define T3_2437_2437 AFTER(T2_2437_2437)
|
|
{ 2512, 2732, 5, 6, 40, 40, NO_DFS, NO_PSCAN, 0},
|
|
#define T1_2512_2732 AFTER(T3_2437_2437)
|
|
};
|
|
|
|
typedef struct regDomain {
|
|
uint16_t regDmnEnum; /* value from EnumRd table */
|
|
uint8_t conformanceTestLimit;
|
|
uint32_t flags; /* Requirement flags (AdHoc disallow,
|
|
noise floor cal needed, etc) */
|
|
uint64_t dfsMask; /* DFS bitmask for 5Ghz tables */
|
|
uint64_t pscan; /* Bitmask for passive scan */
|
|
chanbmask_t chan11a; /* 11a channels */
|
|
chanbmask_t chan11a_turbo; /* 11a static turbo channels */
|
|
chanbmask_t chan11a_dyn_turbo; /* 11a dynamic turbo channels */
|
|
chanbmask_t chan11a_half; /* 11a 1/2 width channels */
|
|
chanbmask_t chan11a_quarter; /* 11a 1/4 width channels */
|
|
chanbmask_t chan11b; /* 11b channels */
|
|
chanbmask_t chan11g; /* 11g channels */
|
|
chanbmask_t chan11g_turbo; /* 11g dynamic turbo channels */
|
|
chanbmask_t chan11g_half; /* 11g 1/2 width channels */
|
|
chanbmask_t chan11g_quarter; /* 11g 1/4 width channels */
|
|
} REG_DOMAIN;
|
|
|
|
static REG_DOMAIN regDomains[] = {
|
|
|
|
{.regDmnEnum = DEBUG_REG_DMN,
|
|
.conformanceTestLimit = FCC,
|
|
.dfsMask = DFS_FCC3,
|
|
.chan11a = BM4(F1_4950_4980,
|
|
F1_5120_5240,
|
|
F1_5260_5700,
|
|
F1_5745_5825),
|
|
.chan11a_half = BM4(F1_4945_4985,
|
|
F2_5120_5240,
|
|
F2_5260_5700,
|
|
F7_5745_5825),
|
|
.chan11a_quarter = BM4(F1_4942_4987,
|
|
F3_5120_5240,
|
|
F3_5260_5700,
|
|
F8_5745_5825),
|
|
.chan11a_turbo = BM8(T1_5130_5210,
|
|
T1_5250_5330,
|
|
T1_5370_5490,
|
|
T1_5530_5650,
|
|
T1_5150_5190,
|
|
T1_5230_5310,
|
|
T1_5350_5470,
|
|
T1_5510_5670),
|
|
.chan11a_dyn_turbo = BM4(T1_5200_5240,
|
|
T1_5280_5280,
|
|
T1_5540_5660,
|
|
T1_5765_5805),
|
|
.chan11b = BM4(F1_2312_2372,
|
|
F1_2412_2472,
|
|
F1_2484_2484,
|
|
F1_2512_2732),
|
|
.chan11g = BM3(G1_2312_2372, G1_2412_2472, G1_2512_2732),
|
|
.chan11g_turbo = BM3(T1_2312_2372, T1_2437_2437, T1_2512_2732),
|
|
.chan11g_half = BM3(G2_2312_2372, G4_2412_2472, G2_2512_2732),
|
|
.chan11g_quarter = BM3(G3_2312_2372, G5_2412_2472, G3_2512_2732),
|
|
},
|
|
|
|
{.regDmnEnum = APL1,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11a = BM1(F4_5745_5825),
|
|
},
|
|
|
|
{.regDmnEnum = APL2,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11a = BM1(F1_5745_5805),
|
|
},
|
|
|
|
{.regDmnEnum = APL3,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11a = BM2(F1_5280_5320, F2_5745_5805),
|
|
},
|
|
|
|
{.regDmnEnum = APL4,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11a = BM2(F4_5180_5240, F3_5745_5825),
|
|
},
|
|
|
|
{.regDmnEnum = APL5,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11a = BM1(F2_5745_5825),
|
|
},
|
|
|
|
{.regDmnEnum = APL6,
|
|
.conformanceTestLimit = ETSI,
|
|
.dfsMask = DFS_ETSI,
|
|
.pscan = PSCAN_FCC_T | PSCAN_FCC,
|
|
.chan11a = BM3(F4_5180_5240, F2_5260_5320, F3_5745_5825),
|
|
.chan11a_turbo = BM3(T2_5210_5210, T1_5250_5290, T1_5760_5800),
|
|
},
|
|
|
|
{.regDmnEnum = APL8,
|
|
.conformanceTestLimit = ETSI,
|
|
.flags = DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM2(F6_5260_5320, F4_5745_5825),
|
|
},
|
|
|
|
{.regDmnEnum = APL9,
|
|
.conformanceTestLimit = ETSI,
|
|
.dfsMask = DFS_ETSI,
|
|
.pscan = PSCAN_ETSI,
|
|
.flags = DISALLOW_ADHOC_11A|DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM3(F1_5180_5320, F1_5500_5620, F3_5745_5805),
|
|
},
|
|
|
|
{.regDmnEnum = ETSI1,
|
|
.conformanceTestLimit = ETSI,
|
|
.dfsMask = DFS_ETSI,
|
|
.pscan = PSCAN_ETSI,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM3(W2_5180_5240, F2_5260_5320, F2_5500_5700),
|
|
},
|
|
|
|
{.regDmnEnum = ETSI2,
|
|
.conformanceTestLimit = ETSI,
|
|
.dfsMask = DFS_ETSI,
|
|
.pscan = PSCAN_ETSI,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM1(F3_5180_5240),
|
|
},
|
|
|
|
{.regDmnEnum = ETSI3,
|
|
.conformanceTestLimit = ETSI,
|
|
.dfsMask = DFS_ETSI,
|
|
.pscan = PSCAN_ETSI,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM2(W2_5180_5240, F2_5260_5320),
|
|
},
|
|
|
|
{.regDmnEnum = ETSI4,
|
|
.conformanceTestLimit = ETSI,
|
|
.dfsMask = DFS_ETSI,
|
|
.pscan = PSCAN_ETSI,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM2(F3_5180_5240, F1_5260_5320),
|
|
},
|
|
|
|
{.regDmnEnum = ETSI5,
|
|
.conformanceTestLimit = ETSI,
|
|
.dfsMask = DFS_ETSI,
|
|
.pscan = PSCAN_ETSI,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM1(F1_5180_5240),
|
|
},
|
|
|
|
{.regDmnEnum = ETSI6,
|
|
.conformanceTestLimit = ETSI,
|
|
.dfsMask = DFS_ETSI,
|
|
.pscan = PSCAN_ETSI,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM3(F5_5180_5240, F1_5260_5280, F3_5500_5700),
|
|
},
|
|
|
|
{.regDmnEnum = FCC1,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11a = BM3(F2_5180_5240, F4_5260_5320, F5_5745_5825),
|
|
.chan11a_turbo = BM3(T1_5210_5210, T2_5250_5290, T2_5760_5800),
|
|
.chan11a_dyn_turbo = BM3(T1_5200_5240, T1_5280_5280, T1_5765_5805),
|
|
},
|
|
|
|
{.regDmnEnum = FCC2,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11a = BM3(F6_5180_5240, F5_5260_5320, F6_5745_5825),
|
|
.chan11a_dyn_turbo = BM3(T2_5200_5240, T1_5280_5280, T1_5765_5805),
|
|
},
|
|
|
|
{.regDmnEnum = FCC3,
|
|
.conformanceTestLimit = FCC,
|
|
.dfsMask = DFS_FCC3,
|
|
.pscan = PSCAN_FCC | PSCAN_FCC_T,
|
|
.chan11a = BM4(F2_5180_5240,
|
|
F3_5260_5320,
|
|
F1_5500_5700,
|
|
F5_5745_5825),
|
|
.chan11a_turbo = BM4(T1_5210_5210,
|
|
T1_5250_5250,
|
|
T1_5290_5290,
|
|
T2_5760_5800),
|
|
.chan11a_dyn_turbo = BM3(T1_5200_5240, T2_5280_5280, T1_5540_5660),
|
|
},
|
|
|
|
{.regDmnEnum = FCC4,
|
|
.conformanceTestLimit = FCC,
|
|
.dfsMask = DFS_FCC3,
|
|
.pscan = PSCAN_FCC | PSCAN_FCC_T,
|
|
.chan11a = BM1(F1_4950_4980),
|
|
.chan11a_half = BM1(F1_4945_4985),
|
|
.chan11a_quarter = BM1(F1_4942_4987),
|
|
},
|
|
|
|
/* FCC1 w/ 1/2 and 1/4 width channels */
|
|
{.regDmnEnum = FCC5,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11a = BM3(F2_5180_5240, F4_5260_5320, F5_5745_5825),
|
|
.chan11a_turbo = BM3(T1_5210_5210, T2_5250_5290, T2_5760_5800),
|
|
.chan11a_dyn_turbo = BM3(T1_5200_5240, T1_5280_5280, T1_5765_5805),
|
|
.chan11a_half = BM3(F7_5180_5240, F7_5260_5320, F9_5745_5825),
|
|
.chan11a_quarter = BM3(F8_5180_5240, F8_5260_5320,F10_5745_5825),
|
|
},
|
|
|
|
{.regDmnEnum = MKK1,
|
|
.conformanceTestLimit = MKK,
|
|
.pscan = PSCAN_MKK1,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM1(F1_5170_5230),
|
|
},
|
|
|
|
{.regDmnEnum = MKK2,
|
|
.conformanceTestLimit = MKK,
|
|
.pscan = PSCAN_MKK2,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM3(F1_4920_4980, F1_5040_5080, F1_5170_5230),
|
|
.chan11a_half = BM4(F1_4915_4925,
|
|
F1_4935_4945,
|
|
F1_5035_5040,
|
|
F1_5055_5055),
|
|
},
|
|
|
|
/* UNI-1 even */
|
|
{.regDmnEnum = MKK3,
|
|
.conformanceTestLimit = MKK,
|
|
.pscan = PSCAN_MKK3,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM1(F4_5180_5240),
|
|
},
|
|
|
|
/* UNI-1 even + UNI-2 */
|
|
{.regDmnEnum = MKK4,
|
|
.conformanceTestLimit = MKK,
|
|
.dfsMask = DFS_MKK4,
|
|
.pscan = PSCAN_MKK3,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM2(F4_5180_5240, F2_5260_5320),
|
|
},
|
|
|
|
/* UNI-1 even + UNI-2 + mid-band */
|
|
{.regDmnEnum = MKK5,
|
|
.conformanceTestLimit = MKK,
|
|
.dfsMask = DFS_MKK4,
|
|
.pscan = PSCAN_MKK3,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM3(F4_5180_5240, F2_5260_5320, F4_5500_5700),
|
|
},
|
|
|
|
/* UNI-1 odd + even */
|
|
{.regDmnEnum = MKK6,
|
|
.conformanceTestLimit = MKK,
|
|
.pscan = PSCAN_MKK1,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM2(F2_5170_5230, F4_5180_5240),
|
|
},
|
|
|
|
/* UNI-1 odd + UNI-1 even + UNI-2 */
|
|
{.regDmnEnum = MKK7,
|
|
.conformanceTestLimit = MKK,
|
|
.dfsMask = DFS_MKK4,
|
|
.pscan = PSCAN_MKK1 | PSCAN_MKK3,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM3(F1_5170_5230, F4_5180_5240, F2_5260_5320),
|
|
},
|
|
|
|
/* UNI-1 odd + UNI-1 even + UNI-2 + mid-band */
|
|
{.regDmnEnum = MKK8,
|
|
.conformanceTestLimit = MKK,
|
|
.dfsMask = DFS_MKK4,
|
|
.pscan = PSCAN_MKK1 | PSCAN_MKK3,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM4(F1_5170_5230,
|
|
F4_5180_5240,
|
|
F2_5260_5320,
|
|
F4_5500_5700),
|
|
},
|
|
|
|
/* UNI-1 even + 4.9 GHZ */
|
|
{.regDmnEnum = MKK9,
|
|
.conformanceTestLimit = MKK,
|
|
.pscan = PSCAN_MKK3,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM7(F1_4915_4925,
|
|
F1_4935_4945,
|
|
F1_4920_4980,
|
|
F1_5035_5040,
|
|
F1_5055_5055,
|
|
F1_5040_5080,
|
|
F4_5180_5240),
|
|
},
|
|
|
|
/* UNI-1 even + UNI-2 + 4.9 GHZ */
|
|
{.regDmnEnum = MKK10,
|
|
.conformanceTestLimit = MKK,
|
|
.dfsMask = DFS_MKK4,
|
|
.pscan = PSCAN_MKK3,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11a = BM8(F1_4915_4925,
|
|
F1_4935_4945,
|
|
F1_4920_4980,
|
|
F1_5035_5040,
|
|
F1_5055_5055,
|
|
F1_5040_5080,
|
|
F4_5180_5240,
|
|
F2_5260_5320),
|
|
},
|
|
|
|
/* Defined here to use when 2G channels are authorised for country K2 */
|
|
{.regDmnEnum = APLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.chan11b = BM2(F2_2312_2372,F2_2412_2472),
|
|
.chan11g = BM2(G2_2312_2372,G2_2412_2472),
|
|
},
|
|
|
|
{.regDmnEnum = ETSIA,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.pscan = PSCAN_ETSIA,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11b = BM1(F1_2457_2472),
|
|
.chan11g = BM1(G1_2457_2472),
|
|
.chan11g_turbo = BM1(T2_2437_2437)
|
|
},
|
|
|
|
{.regDmnEnum = ETSIB,
|
|
.conformanceTestLimit = ETSI,
|
|
.pscan = PSCAN_ETSIB,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11b = BM1(F1_2432_2442),
|
|
.chan11g = BM1(G1_2432_2442),
|
|
.chan11g_turbo = BM1(T2_2437_2437)
|
|
},
|
|
|
|
{.regDmnEnum = ETSIC,
|
|
.conformanceTestLimit = ETSI,
|
|
.pscan = PSCAN_ETSIC,
|
|
.flags = DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
|
|
.chan11b = BM1(F3_2412_2472),
|
|
.chan11g = BM1(G3_2412_2472),
|
|
.chan11g_turbo = BM1(T2_2437_2437)
|
|
},
|
|
|
|
{.regDmnEnum = FCCA,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11b = BM1(F1_2412_2462),
|
|
.chan11g = BM1(G1_2412_2462),
|
|
.chan11g_turbo = BM1(T2_2437_2437),
|
|
},
|
|
|
|
/* FCCA w/ 1/2 and 1/4 width channels */
|
|
{.regDmnEnum = FCCB,
|
|
.conformanceTestLimit = FCC,
|
|
.chan11b = BM1(F1_2412_2462),
|
|
.chan11g = BM1(G1_2412_2462),
|
|
.chan11g_turbo = BM1(T2_2437_2437),
|
|
.chan11g_half = BM1(G3_2412_2462),
|
|
.chan11g_quarter = BM1(G4_2412_2462),
|
|
},
|
|
|
|
{.regDmnEnum = MKKA,
|
|
.conformanceTestLimit = MKK,
|
|
.pscan = PSCAN_MKKA | PSCAN_MKKA_G
|
|
| PSCAN_MKKA1 | PSCAN_MKKA1_G
|
|
| PSCAN_MKKA2 | PSCAN_MKKA2_G,
|
|
.flags = DISALLOW_ADHOC_11A_TURB,
|
|
.chan11b = BM3(F2_2412_2462, F1_2467_2472, F2_2484_2484),
|
|
.chan11g = BM2(G2_2412_2462, G1_2467_2472),
|
|
.chan11g_turbo = BM1(T2_2437_2437)
|
|
},
|
|
|
|
{.regDmnEnum = MKKC,
|
|
.conformanceTestLimit = MKK,
|
|
.chan11b = BM1(F2_2412_2472),
|
|
.chan11g = BM1(G2_2412_2472),
|
|
.chan11g_turbo = BM1(T2_2437_2437)
|
|
},
|
|
|
|
{.regDmnEnum = WORLD,
|
|
.conformanceTestLimit = ETSI,
|
|
.chan11b = BM1(F2_2412_2472),
|
|
.chan11g = BM1(G2_2412_2472),
|
|
.chan11g_turbo = BM1(T2_2437_2437)
|
|
},
|
|
|
|
{.regDmnEnum = WOR0_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_PER_11D,
|
|
.chan11a = BM5(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5170_5230,
|
|
W1_5745_5825,
|
|
W1_5500_5700),
|
|
.chan11a_turbo = BM3(WT1_5210_5250,
|
|
WT1_5290_5290,
|
|
WT1_5760_5800),
|
|
.chan11b = BM8(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2472_2472,
|
|
W1_2417_2432,
|
|
W1_2447_2457,
|
|
W1_2467_2467,
|
|
W1_2484_2484),
|
|
.chan11g = BM7(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2472_2472,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457,
|
|
WG1_2467_2467),
|
|
.chan11g_turbo = BM1(T3_2437_2437)
|
|
},
|
|
|
|
{.regDmnEnum = WOR01_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_PER_11D,
|
|
.chan11a = BM5(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5170_5230,
|
|
W1_5745_5825,
|
|
W1_5500_5700),
|
|
.chan11a_turbo = BM3(WT1_5210_5250,
|
|
WT1_5290_5290,
|
|
WT1_5760_5800),
|
|
.chan11b = BM5(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2417_2432,
|
|
W1_2447_2457),
|
|
.chan11g = BM5(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = WOR02_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_PER_11D,
|
|
.chan11a = BM5(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5170_5230,
|
|
W1_5745_5825,
|
|
W1_5500_5700),
|
|
.chan11a_turbo = BM3(WT1_5210_5250,
|
|
WT1_5290_5290,
|
|
WT1_5760_5800),
|
|
.chan11b = BM7(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2472_2472,
|
|
W1_2417_2432,
|
|
W1_2447_2457,
|
|
W1_2467_2467),
|
|
.chan11g = BM7(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2472_2472,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457,
|
|
WG1_2467_2467),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = EU1_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_PER_11D,
|
|
.chan11a = BM5(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5170_5230,
|
|
W1_5745_5825,
|
|
W1_5500_5700),
|
|
.chan11a_turbo = BM3(WT1_5210_5250,
|
|
WT1_5290_5290,
|
|
WT1_5760_5800),
|
|
.chan11b = BM7(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W2_2472_2472,
|
|
W1_2417_2432,
|
|
W1_2447_2457,
|
|
W2_2467_2467),
|
|
.chan11g = BM7(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG2_2472_2472,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457,
|
|
WG2_2467_2467),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = WOR1_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_NO_11A,
|
|
.chan11a = BM5(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5170_5230,
|
|
W1_5745_5825,
|
|
W1_5500_5700),
|
|
.chan11b = BM8(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2472_2472,
|
|
W1_2417_2432,
|
|
W1_2447_2457,
|
|
W1_2467_2467,
|
|
W1_2484_2484),
|
|
.chan11g = BM7(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2472_2472,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457,
|
|
WG1_2467_2467),
|
|
.chan11g_turbo = BM1(T3_2437_2437)
|
|
},
|
|
|
|
{.regDmnEnum = WOR2_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_NO_11A,
|
|
.chan11a = BM5(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5170_5230,
|
|
W1_5745_5825,
|
|
W1_5500_5700),
|
|
.chan11a_turbo = BM3(WT1_5210_5250,
|
|
WT1_5290_5290,
|
|
WT1_5760_5800),
|
|
.chan11b = BM8(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2472_2472,
|
|
W1_2417_2432,
|
|
W1_2447_2457,
|
|
W1_2467_2467,
|
|
W1_2484_2484),
|
|
.chan11g = BM7(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2472_2472,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457,
|
|
WG1_2467_2467),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = WOR3_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_PER_11D,
|
|
.chan11a = BM4(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5170_5230,
|
|
W1_5745_5825),
|
|
.chan11a_turbo = BM3(WT1_5210_5250,
|
|
WT1_5290_5290,
|
|
WT1_5760_5800),
|
|
.chan11b = BM7(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2472_2472,
|
|
W1_2417_2432,
|
|
W1_2447_2457,
|
|
W1_2467_2467),
|
|
.chan11g = BM7(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2472_2472,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457,
|
|
WG1_2467_2467),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = WOR4_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_NO_11A,
|
|
.chan11a = BM4(W2_5260_5320,
|
|
W2_5180_5240,
|
|
F2_5745_5805,
|
|
W2_5825_5825),
|
|
.chan11a_turbo = BM3(WT1_5210_5250,
|
|
WT1_5290_5290,
|
|
WT1_5760_5800),
|
|
.chan11b = BM5(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2417_2432,
|
|
W1_2447_2457),
|
|
.chan11g = BM5(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = WOR5_ETSIC,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_NO_11A,
|
|
.chan11a = BM3(W1_5260_5320, W2_5180_5240, F6_5745_5825),
|
|
.chan11b = BM7(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W2_2472_2472,
|
|
W1_2417_2432,
|
|
W1_2447_2457,
|
|
W2_2467_2467),
|
|
.chan11g = BM7(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG2_2472_2472,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457,
|
|
WG2_2467_2467),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = WOR9_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_NO_11A,
|
|
.chan11a = BM4(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5745_5825,
|
|
W1_5500_5700),
|
|
.chan11a_turbo = BM3(WT1_5210_5250,
|
|
WT1_5290_5290,
|
|
WT1_5760_5800),
|
|
.chan11b = BM5(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2417_2432,
|
|
W1_2447_2457),
|
|
.chan11g = BM5(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = WORA_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.dfsMask = DFS_FCC3 | DFS_ETSI,
|
|
.pscan = PSCAN_WWR,
|
|
.flags = ADHOC_NO_11A,
|
|
.chan11a = BM4(W1_5260_5320,
|
|
W1_5180_5240,
|
|
W1_5745_5825,
|
|
W1_5500_5700),
|
|
.chan11b = BM7(W1_2412_2412,
|
|
W1_2437_2442,
|
|
W1_2462_2462,
|
|
W1_2472_2472,
|
|
W1_2417_2432,
|
|
W1_2447_2457,
|
|
W1_2467_2467),
|
|
.chan11g = BM7(WG1_2412_2412,
|
|
WG1_2437_2442,
|
|
WG1_2462_2462,
|
|
WG1_2472_2472,
|
|
WG1_2417_2432,
|
|
WG1_2447_2457,
|
|
WG1_2467_2467),
|
|
.chan11g_turbo = BM1(T3_2437_2437)},
|
|
|
|
{.regDmnEnum = SR9_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.pscan = PSCAN_FCC | PSCAN_FCC_T,
|
|
.chan11g = BM1(S1_912_917),
|
|
.chan11g_half = BM1(S1_907_922_10),
|
|
.chan11g_quarter = BM1(S1_907_922_5),
|
|
},
|
|
|
|
{.regDmnEnum = XR9_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.pscan = PSCAN_FCC | PSCAN_FCC_T,
|
|
.chan11g = BM1(S2_912_917),
|
|
.chan11g_half = BM1(S2_907_922_10),
|
|
.chan11g_quarter = BM1(S2_907_922_5),
|
|
},
|
|
|
|
{.regDmnEnum = GZ901_WORLD,
|
|
.conformanceTestLimit = NO_CTL,
|
|
.pscan = PSCAN_FCC | PSCAN_FCC_T,
|
|
.chan11g = BM1(S1_913_918),
|
|
.chan11g_half = BM1(S1_913_918_10),
|
|
.chan11g_quarter = BM1(S1_908_923_5),
|
|
},
|
|
|
|
{.regDmnEnum = NULL1,
|
|
.conformanceTestLimit = NO_CTL,
|
|
}
|
|
};
|
|
|
|
struct cmode {
|
|
u_int mode;
|
|
u_int flags;
|
|
};
|
|
|
|
static const struct cmode modes[] = {
|
|
{ HAL_MODE_TURBO, CHANNEL_ST}, /* NB: 11a Static Turbo */
|
|
{ HAL_MODE_11A, CHANNEL_A},
|
|
{ HAL_MODE_11B, CHANNEL_B},
|
|
{ HAL_MODE_11G, CHANNEL_G},
|
|
{ HAL_MODE_11G_TURBO, CHANNEL_108G},
|
|
{ HAL_MODE_11A_TURBO, CHANNEL_108A},
|
|
{ HAL_MODE_11A_QUARTER_RATE, CHANNEL_A | CHANNEL_QUARTER},
|
|
{ HAL_MODE_11A_HALF_RATE, CHANNEL_A | CHANNEL_HALF},
|
|
{ HAL_MODE_11G_QUARTER_RATE, CHANNEL_G | CHANNEL_QUARTER},
|
|
{ HAL_MODE_11G_HALF_RATE, CHANNEL_G | CHANNEL_HALF},
|
|
{ HAL_MODE_11NG_HT20, CHANNEL_G_HT20},
|
|
{ HAL_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
|
|
{ HAL_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
|
|
{ HAL_MODE_11NA_HT20, CHANNEL_A_HT20},
|
|
{ HAL_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
|
|
{ HAL_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
|
|
};
|
|
|
|
static int
|
|
chansort(const void *a, const void *b)
|
|
{
|
|
#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
|
|
const HAL_CHANNEL_INTERNAL *ca = a;
|
|
const HAL_CHANNEL_INTERNAL *cb = b;
|
|
|
|
return (ca->channel == cb->channel) ?
|
|
(ca->channelFlags & CHAN_FLAGS) -
|
|
(cb->channelFlags & CHAN_FLAGS) :
|
|
ca->channel - cb->channel;
|
|
#undef CHAN_FLAGS
|
|
}
|
|
typedef int ath_hal_cmp_t(const void *, const void *);
|
|
static void ath_hal_sort(void *a, size_t n, size_t es, ath_hal_cmp_t *cmp);
|
|
static COUNTRY_CODE_TO_ENUM_RD* findCountry(HAL_CTRY_CODE countryCode);
|
|
static HAL_BOOL getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country, uint16_t channelFlag, REG_DOMAIN *rd);
|
|
|
|
|
|
static uint16_t
|
|
getEepromRD(struct ath_hal *ah)
|
|
{
|
|
return AH_PRIVATE(ah)->ah_currentRD &~ WORLDWIDE_ROAMING_FLAG;
|
|
}
|
|
|
|
/*
|
|
* Test to see if the bitmask array is all zeros
|
|
*/
|
|
static HAL_BOOL
|
|
isChanBitMaskZero(const uint64_t *bitmask)
|
|
{
|
|
#if BMLEN > 2
|
|
#error "add more cases"
|
|
#endif
|
|
#if BMLEN > 1
|
|
if (bitmask[1] != 0)
|
|
return AH_FALSE;
|
|
#endif
|
|
return (bitmask[0] == 0);
|
|
}
|
|
|
|
/*
|
|
* Return whether or not the regulatory domain/country in EEPROM
|
|
* is acceptable.
|
|
*/
|
|
static HAL_BOOL
|
|
isEepromValid(struct ath_hal *ah)
|
|
{
|
|
uint16_t rd = getEepromRD(ah);
|
|
int i;
|
|
|
|
if (rd & COUNTRY_ERD_FLAG) {
|
|
uint16_t cc = rd &~ COUNTRY_ERD_FLAG;
|
|
for (i = 0; i < N(allCountries); i++)
|
|
if (allCountries[i].countryCode == cc)
|
|
return AH_TRUE;
|
|
} else {
|
|
for (i = 0; i < N(regDomainPairs); i++)
|
|
if (regDomainPairs[i].regDmnEnum == rd)
|
|
return AH_TRUE;
|
|
}
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: invalid regulatory domain/country code 0x%x\n", __func__, rd);
|
|
return AH_FALSE;
|
|
}
|
|
|
|
/*
|
|
* Returns whether or not the specified country code
|
|
* is allowed by the EEPROM setting
|
|
*/
|
|
static HAL_BOOL
|
|
isCountryCodeValid(struct ath_hal *ah, HAL_CTRY_CODE cc)
|
|
{
|
|
uint16_t rd;
|
|
|
|
/* Default setting requires no checks */
|
|
if (cc == CTRY_DEFAULT)
|
|
return AH_TRUE;
|
|
#ifdef AH_DEBUG_COUNTRY
|
|
if (cc == CTRY_DEBUG)
|
|
return AH_TRUE;
|
|
#endif
|
|
rd = getEepromRD(ah);
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: EEPROM regdomain 0x%x\n",
|
|
__func__, rd);
|
|
|
|
if (rd & COUNTRY_ERD_FLAG) {
|
|
/* EEP setting is a country - config shall match */
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: EEPROM setting is country code %u\n", __func__,
|
|
rd &~ COUNTRY_ERD_FLAG);
|
|
return (cc == (rd & ~COUNTRY_ERD_FLAG));
|
|
} else if (rd == DEBUG_REG_DMN || rd == NO_ENUMRD) {
|
|
/* Set to Debug or AllowAnyCountry mode - allow any setting */
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: rd %d allowed\n",
|
|
__func__, rd);
|
|
return AH_TRUE;
|
|
#ifdef AH_SUPPORT_11D
|
|
} else if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) {
|
|
int i;
|
|
for (i=0; i < N(allCountries); i++) {
|
|
if (cc == allCountries[i].countryCode)
|
|
return AH_TRUE;
|
|
}
|
|
#endif
|
|
} else {
|
|
int i;
|
|
for (i = 0; i < N(allCountries); i++) {
|
|
if (cc == allCountries[i].countryCode &&
|
|
allCountries[i].regDmnEnum == rd)
|
|
return AH_TRUE;
|
|
}
|
|
}
|
|
return AH_FALSE;
|
|
}
|
|
|
|
/*
|
|
* Return the mask of available modes based on the hardware
|
|
* capabilities and the specified country code and reg domain.
|
|
*/
|
|
static u_int
|
|
ath_hal_getwmodesnreg(struct ath_hal *ah,
|
|
const COUNTRY_CODE_TO_ENUM_RD *country, const REG_DOMAIN *rd5GHz)
|
|
{
|
|
#define HAL_MODE_11G_ALL \
|
|
(HAL_MODE_11G | HAL_MODE_11G_TURBO | HAL_MODE_11G_QUARTER_RATE | \
|
|
HAL_MODE_11G_HALF_RATE)
|
|
#define HAL_MODE_11A_ALL \
|
|
(HAL_MODE_11A | HAL_MODE_11A_TURBO | HAL_MODE_TURBO | \
|
|
HAL_MODE_11A_QUARTER_RATE | HAL_MODE_11A_HALF_RATE)
|
|
u_int modesAvail;
|
|
|
|
/* Get modes that HW is capable of */
|
|
modesAvail = ath_hal_getWirelessModes(ah);
|
|
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: wireless modes 0x%x cc %u rd %u\n",
|
|
__func__, modesAvail, country->countryCode, country->regDmnEnum);
|
|
|
|
/* Check country regulations for allowed modes */
|
|
if (!country->allow11g && (modesAvail & HAL_MODE_11G_ALL)) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow all 11g\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11G_ALL;
|
|
}
|
|
if (isChanBitMaskZero(rd5GHz->chan11a) &&
|
|
(modesAvail & HAL_MODE_11A_ALL)) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow all 11a\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11A_ALL;
|
|
}
|
|
if ((modesAvail & (HAL_MODE_11A_TURBO | HAL_MODE_TURBO)) &&
|
|
!country->allow11aTurbo) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow 11aTurbo\n", __func__);
|
|
modesAvail &= ~(HAL_MODE_11A_TURBO | HAL_MODE_TURBO);
|
|
}
|
|
if ((modesAvail & HAL_MODE_11G_TURBO) && !country->allow11gTurbo) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow 11gTurbo\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11G_TURBO;
|
|
}
|
|
|
|
/* Check 11n operation */
|
|
if ((modesAvail & HAL_MODE_11NG_HT20) && !country->allow11ng20) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow 11g HT20\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11NG_HT20;
|
|
}
|
|
if ((modesAvail & HAL_MODE_11NA_HT20) && !country->allow11na20) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow 11a HT20\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11NA_HT20;
|
|
}
|
|
if ((modesAvail & HAL_MODE_11NG_HT40PLUS) && !country->allow11ng40) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow 11g HT40+\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11NG_HT40PLUS;
|
|
}
|
|
if ((modesAvail & HAL_MODE_11NG_HT40MINUS) && !country->allow11ng40) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow 11g HT40-\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11NG_HT40MINUS;
|
|
}
|
|
if ((modesAvail & HAL_MODE_11NA_HT40PLUS) && !country->allow11na40) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow 11a HT40+\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11NA_HT40PLUS;
|
|
}
|
|
if ((modesAvail & HAL_MODE_11NA_HT40MINUS) && !country->allow11na40) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: disallow 11a HT40-\n", __func__);
|
|
modesAvail &= ~HAL_MODE_11NA_HT40MINUS;
|
|
}
|
|
|
|
return modesAvail;
|
|
#undef HAL_MODE_11A_ALL
|
|
#undef HAL_MODE_11G_ALL
|
|
}
|
|
|
|
/*
|
|
* Return the mask of available modes based on the hardware
|
|
* capabilities and the specified country code.
|
|
*/
|
|
|
|
u_int
|
|
ath_hal_getwirelessmodes(struct ath_hal *ah, HAL_CTRY_CODE cc)
|
|
{
|
|
COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
|
|
u_int mode = 0;
|
|
REG_DOMAIN rd;
|
|
|
|
country = findCountry(cc);
|
|
if (country != AH_NULL) {
|
|
if (getWmRD(ah, country, ~CHANNEL_2GHZ, &rd))
|
|
mode = ath_hal_getwmodesnreg(ah, country, &rd);
|
|
}
|
|
return mode;
|
|
}
|
|
|
|
/*
|
|
* Return if device is public safety.
|
|
*/
|
|
HAL_BOOL
|
|
ath_hal_ispublicsafetysku(struct ath_hal *ah)
|
|
{
|
|
uint16_t rd = getEepromRD(ah);
|
|
|
|
switch (rd) {
|
|
case FCC4_FCCA:
|
|
case CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG:
|
|
return AH_TRUE;
|
|
case DEBUG_REG_DMN:
|
|
case NO_ENUMRD:
|
|
if (AH_PRIVATE(ah)->ah_countryCode == CTRY_UNITED_STATES_FCC49)
|
|
return AH_TRUE;
|
|
break;
|
|
}
|
|
return AH_FALSE;
|
|
}
|
|
|
|
/*
|
|
* Return if device is actually operating in 900 MHz band.
|
|
*/
|
|
HAL_BOOL
|
|
ath_hal_isgsmsku(struct ath_hal *ah)
|
|
{
|
|
uint16_t rd = getEepromRD(ah);
|
|
|
|
switch (rd) {
|
|
case SR9_WORLD:
|
|
case XR9_WORLD:
|
|
case GZ901_WORLD:
|
|
case CTRY_SR9 | COUNTRY_ERD_FLAG:
|
|
case CTRY_XR9 | COUNTRY_ERD_FLAG:
|
|
case CTRY_GZ901 | COUNTRY_ERD_FLAG:
|
|
return AH_TRUE;
|
|
case DEBUG_REG_DMN:
|
|
case NO_ENUMRD:
|
|
return AH_PRIVATE(ah)->ah_countryCode == CTRY_SR9
|
|
|| AH_PRIVATE(ah)->ah_countryCode == CTRY_XR9
|
|
|| AH_PRIVATE(ah)->ah_countryCode == CTRY_GZ901
|
|
;
|
|
}
|
|
return AH_FALSE;
|
|
}
|
|
|
|
/*
|
|
* Find the pointer to the country element in the country table
|
|
* corresponding to the country code
|
|
*/
|
|
static COUNTRY_CODE_TO_ENUM_RD*
|
|
findCountry(HAL_CTRY_CODE countryCode)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < N(allCountries); i++) {
|
|
if (allCountries[i].countryCode == countryCode)
|
|
return &allCountries[i];
|
|
}
|
|
return AH_NULL; /* Not found */
|
|
}
|
|
|
|
/*
|
|
* Calculate a default country based on the EEPROM setting.
|
|
*/
|
|
static HAL_CTRY_CODE
|
|
getDefaultCountry(struct ath_hal *ah)
|
|
{
|
|
uint16_t rd;
|
|
int i;
|
|
|
|
rd = getEepromRD(ah);
|
|
if (rd & COUNTRY_ERD_FLAG) {
|
|
COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
|
|
uint16_t cc = rd & ~COUNTRY_ERD_FLAG;
|
|
|
|
country = findCountry(cc);
|
|
if (country != AH_NULL)
|
|
return cc;
|
|
}
|
|
/*
|
|
* Check reg domains that have only one country
|
|
*/
|
|
for (i = 0; i < N(regDomainPairs); i++)
|
|
if (regDomainPairs[i].regDmnEnum == rd) {
|
|
if (regDomainPairs[i].singleCC != 0)
|
|
return regDomainPairs[i].singleCC;
|
|
else
|
|
i = N(regDomainPairs);
|
|
}
|
|
return CTRY_DEFAULT;
|
|
}
|
|
|
|
static HAL_BOOL
|
|
isValidRegDmn(int regDmn, REG_DOMAIN *rd)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < N(regDomains); i++) {
|
|
if (regDomains[i].regDmnEnum == regDmn) {
|
|
if (rd != AH_NULL) {
|
|
OS_MEMCPY(rd, ®Domains[i],
|
|
sizeof(REG_DOMAIN));
|
|
}
|
|
return AH_TRUE;
|
|
}
|
|
}
|
|
return AH_FALSE;
|
|
}
|
|
|
|
static HAL_BOOL
|
|
isValidRegDmnPair(int regDmnPair)
|
|
{
|
|
int i;
|
|
|
|
if (regDmnPair == NO_ENUMRD)
|
|
return AH_FALSE;
|
|
for (i = 0; i < N(regDomainPairs); i++) {
|
|
if (regDomainPairs[i].regDmnEnum == regDmnPair)
|
|
return AH_TRUE;
|
|
}
|
|
return AH_FALSE;
|
|
}
|
|
|
|
/*
|
|
* Return the Wireless Mode Regulatory Domain based
|
|
* on the country code and the wireless mode.
|
|
*/
|
|
static HAL_BOOL
|
|
getWmRD(struct ath_hal *ah, COUNTRY_CODE_TO_ENUM_RD *country,
|
|
uint16_t channelFlag, REG_DOMAIN *rd)
|
|
{
|
|
int regDmn;
|
|
REG_DMN_PAIR_MAPPING *regPair;
|
|
uint64_t flags;
|
|
|
|
if (country->countryCode == CTRY_DEFAULT) {
|
|
uint16_t rdnum = getEepromRD(ah);
|
|
|
|
if ((rdnum & COUNTRY_ERD_FLAG) == 0) {
|
|
if (isValidRegDmn(rdnum, AH_NULL) ||
|
|
isValidRegDmnPair(rdnum))
|
|
regDmn = rdnum;
|
|
else
|
|
regDmn = country->regDmnEnum;
|
|
} else
|
|
regDmn = country->regDmnEnum;
|
|
} else
|
|
regDmn = country->regDmnEnum;
|
|
regPair = AH_NULL;
|
|
flags = NO_REQ;
|
|
if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
|
|
int i;
|
|
|
|
for (i = 0; i < N(regDomainPairs); i++) {
|
|
if (regDomainPairs[i].regDmnEnum == regDmn) {
|
|
regPair = ®DomainPairs[i];
|
|
break;
|
|
}
|
|
}
|
|
if (regPair == AH_NULL) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: Failed to find reg domain pair %u\n",
|
|
__func__, regDmn);
|
|
return AH_FALSE;
|
|
}
|
|
if (channelFlag & CHANNEL_2GHZ) {
|
|
regDmn = regPair->regDmn2GHz;
|
|
flags = regPair->flags2GHz;
|
|
} else {
|
|
regDmn = regPair->regDmn5GHz;
|
|
flags = regPair->flags5GHz;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* We either started with a unitary reg domain or we've found the
|
|
* unitary reg domain of the pair
|
|
*/
|
|
if (isValidRegDmn(regDmn, rd)) {
|
|
if (regPair != AH_NULL)
|
|
rd->pscan &= regPair->pscanMask;
|
|
if ((country->regDmnEnum & MULTI_DOMAIN_MASK) == 0 &&
|
|
flags != NO_REQ)
|
|
rd->flags = flags;
|
|
return AH_TRUE;
|
|
} else {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: Failed to find unitary reg domain %u\n", __func__,
|
|
country->regDmnEnum);
|
|
return AH_FALSE;
|
|
}
|
|
}
|
|
|
|
static HAL_BOOL
|
|
IS_BIT_SET(int bit, const uint64_t bitmask[])
|
|
{
|
|
int byteOffset, bitnum;
|
|
uint64_t val;
|
|
|
|
byteOffset = bit/64;
|
|
bitnum = bit - byteOffset*64;
|
|
val = ((uint64_t) 1) << bitnum;
|
|
return (bitmask[byteOffset] & val) != 0;
|
|
}
|
|
|
|
/* Add given regclassid into regclassids array up to max of maxregids */
|
|
static void
|
|
ath_add_regclassid(uint8_t *regclassids, u_int maxregids,
|
|
u_int *nregids, uint8_t regclassid)
|
|
{
|
|
int i;
|
|
|
|
/* Is regclassid valid? */
|
|
if (regclassid == 0)
|
|
return;
|
|
|
|
for (i = 0; i < maxregids; i++) {
|
|
if (regclassids[i] == regclassid) /* already present */
|
|
return;
|
|
if (regclassids[i] == 0) { /* free slot */
|
|
regclassids[i] = regclassid;
|
|
(*nregids)++;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Setup the channel list based on the information in the EEPROM and
|
|
* any supplied country code. Note that we also do a bunch of EEPROM
|
|
* verification here and setup certain regulatory-related access
|
|
* control data used later on.
|
|
*/
|
|
|
|
HAL_BOOL
|
|
ath_hal_init_channels(struct ath_hal *ah,
|
|
HAL_CHANNEL *chans, u_int maxchans, u_int *nchans,
|
|
uint8_t *regclassids, u_int maxregids, u_int *nregids,
|
|
HAL_CTRY_CODE cc, u_int modeSelect,
|
|
HAL_BOOL enableOutdoor, HAL_BOOL enableExtendedChannels)
|
|
{
|
|
#define CHANNEL_HALF_BW 10
|
|
#define CHANNEL_QUARTER_BW 5
|
|
u_int modesAvail;
|
|
uint16_t maxChan;
|
|
COUNTRY_CODE_TO_ENUM_RD *country = AH_NULL;
|
|
REG_DOMAIN rd5GHz, rd2GHz;
|
|
const struct cmode *cm;
|
|
HAL_CHANNEL_INTERNAL *ichans = &AH_PRIVATE(ah)->ah_channels[0];
|
|
int next, b;
|
|
uint8_t ctl;
|
|
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: cc %u mode 0x%x%s%s\n",
|
|
__func__, cc, modeSelect, enableOutdoor? " Enable outdoor" : " ",
|
|
enableExtendedChannels ? " Enable ecm" : "");
|
|
|
|
/*
|
|
* Validate the EEPROM setting and setup defaults
|
|
*/
|
|
if (!isEepromValid(ah)) {
|
|
/*
|
|
* Don't return any channels if the EEPROM has an
|
|
* invalid regulatory domain/country code setting.
|
|
*/
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: invalid EEPROM contents\n",__func__);
|
|
return AH_FALSE;
|
|
}
|
|
|
|
AH_PRIVATE(ah)->ah_countryCode = getDefaultCountry(ah);
|
|
|
|
#ifndef AH_SUPPORT_11D
|
|
if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT) {
|
|
#endif
|
|
/*
|
|
* We now have enough state to validate any country code
|
|
* passed in by the caller.
|
|
*/
|
|
if (!isCountryCodeValid(ah, cc)) {
|
|
/* NB: Atheros silently ignores invalid country codes */
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: invalid country code %d\n", __func__, cc);
|
|
return AH_FALSE;
|
|
}
|
|
AH_PRIVATE(ah)->ah_countryCode = cc & COUNTRY_CODE_MASK;
|
|
#ifndef AH_SUPPORT_11D
|
|
}
|
|
#endif
|
|
|
|
/* Get pointers to the country element and the reg domain elements */
|
|
country = findCountry(AH_PRIVATE(ah)->ah_countryCode);
|
|
|
|
if (country == AH_NULL) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "NULL Country!, cc= %d\n",
|
|
AH_PRIVATE(ah)->ah_countryCode);
|
|
return AH_FALSE;
|
|
}
|
|
|
|
if (!getWmRD(ah, country, ~CHANNEL_2GHZ, &rd5GHz)) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: no unitary 5GHz regdomain for country %u\n",
|
|
__func__, AH_PRIVATE(ah)->ah_countryCode);
|
|
return AH_FALSE;
|
|
}
|
|
if (!getWmRD(ah, country, CHANNEL_2GHZ, &rd2GHz)) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: no unitary 2GHz regdomain for country %u\n",
|
|
__func__, AH_PRIVATE(ah)->ah_countryCode);
|
|
return AH_FALSE;
|
|
}
|
|
|
|
modesAvail = ath_hal_getwmodesnreg(ah, country, &rd5GHz);
|
|
maxChan = !enableOutdoor ? country->outdoorChanStart : 7000;
|
|
|
|
if (maxchans > N(AH_PRIVATE(ah)->ah_channels))
|
|
maxchans = N(AH_PRIVATE(ah)->ah_channels);
|
|
next = 0;
|
|
for (cm = modes; cm < &modes[N(modes)]; cm++) {
|
|
uint16_t c, c_hi, c_lo;
|
|
uint64_t *channelBM = AH_NULL;
|
|
REG_DOMAIN *rd = AH_NULL;
|
|
REG_DMN_FREQ_BAND *fband = AH_NULL,*freqs;
|
|
int low_adj, hi_adj, channelSep, lastc;
|
|
|
|
if ((cm->mode & modeSelect) == 0) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: skip mode 0x%x flags 0x%x\n",
|
|
__func__, cm->mode, cm->flags);
|
|
continue;
|
|
}
|
|
if ((cm->mode & modesAvail) == 0) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: !avail mode 0x%x (0x%x) flags 0x%x\n",
|
|
__func__, modesAvail, cm->mode, cm->flags);
|
|
continue;
|
|
}
|
|
if (!ath_hal_getChannelEdges(ah, cm->flags, &c_lo, &c_hi)) {
|
|
/* channel not supported by hardware, skip it */
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: channels 0x%x not supported by hardware\n",
|
|
__func__,cm->flags);
|
|
continue;
|
|
}
|
|
switch (cm->mode) {
|
|
case HAL_MODE_TURBO:
|
|
rd = &rd5GHz;
|
|
channelBM = rd->chan11a_turbo;
|
|
freqs = ®Dmn5GhzTurboFreq[0];
|
|
ctl = rd->conformanceTestLimit | CTL_TURBO;
|
|
break;
|
|
case HAL_MODE_11A:
|
|
case HAL_MODE_11A_HALF_RATE:
|
|
case HAL_MODE_11A_QUARTER_RATE:
|
|
case HAL_MODE_11NA_HT20:
|
|
case HAL_MODE_11NA_HT40PLUS:
|
|
case HAL_MODE_11NA_HT40MINUS:
|
|
rd = &rd5GHz;
|
|
if (cm->mode == HAL_MODE_11A_HALF_RATE)
|
|
channelBM = rd->chan11a_half;
|
|
else if (cm->mode == HAL_MODE_11A_QUARTER_RATE)
|
|
channelBM = rd->chan11a_quarter;
|
|
else
|
|
channelBM = rd->chan11a;
|
|
freqs = ®Dmn5GhzFreq[0];
|
|
ctl = rd->conformanceTestLimit;
|
|
break;
|
|
case HAL_MODE_11B:
|
|
rd = &rd2GHz;
|
|
channelBM = rd->chan11b;
|
|
freqs = ®Dmn2GhzFreq[0];
|
|
ctl = rd->conformanceTestLimit | CTL_11B;
|
|
break;
|
|
case HAL_MODE_11G:
|
|
case HAL_MODE_11G_HALF_RATE:
|
|
case HAL_MODE_11G_QUARTER_RATE:
|
|
case HAL_MODE_11NG_HT20:
|
|
case HAL_MODE_11NG_HT40PLUS:
|
|
case HAL_MODE_11NG_HT40MINUS:
|
|
rd = &rd2GHz;
|
|
if (cm->mode == HAL_MODE_11G_HALF_RATE)
|
|
channelBM = rd->chan11g_half;
|
|
else if (cm->mode == HAL_MODE_11G_QUARTER_RATE)
|
|
channelBM = rd->chan11g_quarter;
|
|
else
|
|
channelBM = rd->chan11g;
|
|
freqs = ®Dmn2Ghz11gFreq[0];
|
|
ctl = rd->conformanceTestLimit | CTL_11G;
|
|
break;
|
|
case HAL_MODE_11G_TURBO:
|
|
rd = &rd2GHz;
|
|
channelBM = rd->chan11g_turbo;
|
|
freqs = ®Dmn2Ghz11gTurboFreq[0];
|
|
ctl = rd->conformanceTestLimit | CTL_108G;
|
|
break;
|
|
case HAL_MODE_11A_TURBO:
|
|
rd = &rd5GHz;
|
|
channelBM = rd->chan11a_dyn_turbo;
|
|
freqs = ®Dmn5GhzTurboFreq[0];
|
|
ctl = rd->conformanceTestLimit | CTL_108G;
|
|
break;
|
|
default:
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: Unkonwn HAL mode 0x%x\n", __func__, cm->mode);
|
|
continue;
|
|
}
|
|
if (isChanBitMaskZero(channelBM))
|
|
continue;
|
|
/*
|
|
* Setup special handling for HT40 channels; e.g.
|
|
* 5G HT40 channels require 40Mhz channel separation.
|
|
*/
|
|
hi_adj = (cm->mode == HAL_MODE_11NA_HT40PLUS ||
|
|
cm->mode == HAL_MODE_11NG_HT40PLUS) ? -20 : 0;
|
|
low_adj = (cm->mode == HAL_MODE_11NA_HT40MINUS ||
|
|
cm->mode == HAL_MODE_11NG_HT40MINUS) ? 20 : 0;
|
|
channelSep = (cm->mode == HAL_MODE_11NA_HT40PLUS ||
|
|
cm->mode == HAL_MODE_11NA_HT40MINUS) ? 40 : 0;
|
|
|
|
for (b = 0; b < 64*BMLEN; b++) {
|
|
if (!IS_BIT_SET(b, channelBM))
|
|
continue;
|
|
fband = &freqs[b];
|
|
lastc = 0;
|
|
|
|
ath_add_regclassid(regclassids, maxregids,
|
|
nregids, fband->regClassId);
|
|
|
|
for (c = fband->lowChannel + low_adj;
|
|
c <= fband->highChannel + hi_adj;
|
|
c += fband->channelSep) {
|
|
HAL_CHANNEL_INTERNAL icv;
|
|
|
|
if (!(c_lo <= c && c <= c_hi)) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: c %u out of range [%u..%u]\n",
|
|
__func__, c, c_lo, c_hi);
|
|
continue;
|
|
}
|
|
if (((c+fband->channelSep)/2) > (maxChan+HALF_MAXCHANBW)) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: c %u > maxChan %u\n",
|
|
__func__, c, maxChan);
|
|
continue;
|
|
}
|
|
if (next >= maxchans){
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: too many channels for channel table\n",
|
|
__func__);
|
|
goto done;
|
|
}
|
|
if ((fband->usePassScan & IS_ECM_CHAN) &&
|
|
!enableExtendedChannels) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"Skipping ecm channel\n");
|
|
continue;
|
|
}
|
|
/* XXX needs to be in ath_hal_checkchannel */
|
|
if ((rd->flags & NO_HOSTAP) &&
|
|
(AH_PRIVATE(ah)->ah_opmode == HAL_M_HOSTAP)) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"Skipping HOSTAP channel\n");
|
|
continue;
|
|
}
|
|
/*
|
|
* Make sure that channel separation
|
|
* meets the requirement.
|
|
*/
|
|
if (lastc && channelSep &&
|
|
(c-lastc) < channelSep)
|
|
continue;
|
|
|
|
OS_MEMZERO(&icv, sizeof(icv));
|
|
icv.channel = c;
|
|
icv.channelFlags = cm->flags;
|
|
icv.maxRegTxPower = fband->powerDfs;
|
|
icv.antennaMax = fband->antennaMax;
|
|
icv.regDmnFlags = rd->flags;
|
|
icv.conformanceTestLimit = ctl;
|
|
if (fband->usePassScan & rd->pscan)
|
|
icv.channelFlags |= CHANNEL_PASSIVE;
|
|
else
|
|
icv.channelFlags &= ~CHANNEL_PASSIVE;
|
|
lastc = c;
|
|
if (fband->useDfs & rd->dfsMask) {
|
|
/* DFS and HT40 don't mix */
|
|
if (cm->mode == HAL_MODE_11NA_HT40PLUS ||
|
|
cm->mode == HAL_MODE_11NA_HT40MINUS)
|
|
continue;
|
|
icv.privFlags = CHANNEL_DFS;
|
|
} else
|
|
icv.privFlags = 0;
|
|
if (rd->flags & LIMIT_FRAME_4MS)
|
|
icv.privFlags |= CHANNEL_4MS_LIMIT;
|
|
|
|
ichans[next++] = icv;
|
|
}
|
|
}
|
|
}
|
|
done:
|
|
if (next != 0) {
|
|
int i;
|
|
|
|
/* XXX maxchans set above so this cannot happen? */
|
|
if (next > N(AH_PRIVATE(ah)->ah_channels)) {
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN,
|
|
"%s: too many channels %u; truncating to %u\n",
|
|
__func__, next,
|
|
(int) N(AH_PRIVATE(ah)->ah_channels));
|
|
next = N(AH_PRIVATE(ah)->ah_channels);
|
|
}
|
|
|
|
/*
|
|
* Keep a private copy of the channel list so we can
|
|
* constrain future requests to only these channels
|
|
*/
|
|
ath_hal_sort(ichans, next, sizeof(HAL_CHANNEL_INTERNAL),
|
|
chansort);
|
|
AH_PRIVATE(ah)->ah_nchan = next;
|
|
|
|
/*
|
|
* Copy the channel list to the public channel list
|
|
*/
|
|
for (i = 0; i < next; i++) {
|
|
chans[i].channel = ichans[i].channel;
|
|
chans[i].channelFlags = ichans[i].channelFlags;
|
|
chans[i].privFlags = ichans[i].privFlags;
|
|
chans[i].maxRegTxPower = ichans[i].maxRegTxPower;
|
|
}
|
|
/*
|
|
* Retrieve power limits.
|
|
*/
|
|
ath_hal_getpowerlimits(ah, chans, next);
|
|
for (i = 0; i < next; i++) {
|
|
ichans[i].maxTxPower = chans[i].maxTxPower;
|
|
ichans[i].minTxPower = chans[i].minTxPower;
|
|
}
|
|
}
|
|
*nchans = next;
|
|
/* XXX copy private setting to public area */
|
|
ah->ah_countryCode = AH_PRIVATE(ah)->ah_countryCode;
|
|
return (next != 0);
|
|
#undef CHANNEL_HALF_BW
|
|
#undef CHANNEL_QUARTER_BW
|
|
}
|
|
|
|
/*
|
|
* Return whether or not the specified channel is ok to use
|
|
* based on the current regulatory domain constraints and
|
|
* DFS interference.
|
|
*/
|
|
HAL_CHANNEL_INTERNAL *
|
|
ath_hal_checkchannel(struct ath_hal *ah, const HAL_CHANNEL *c)
|
|
{
|
|
#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
|
|
HAL_CHANNEL_INTERNAL *base, *cc;
|
|
/* NB: be wary of user-specified channel flags */
|
|
int flags = c->channelFlags & CHAN_FLAGS;
|
|
int n, lim, d;
|
|
|
|
/*
|
|
* Check current channel to avoid the lookup.
|
|
*/
|
|
cc = AH_PRIVATE(ah)->ah_curchan;
|
|
if (cc != AH_NULL && cc->channel == c->channel &&
|
|
(cc->channelFlags & CHAN_FLAGS) == flags) {
|
|
if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
|
|
(cc->channelFlags & CHANNEL_DFS))
|
|
return AH_NULL;
|
|
else
|
|
return cc;
|
|
}
|
|
|
|
/* binary search based on known sorting order */
|
|
base = AH_PRIVATE(ah)->ah_channels;
|
|
n = AH_PRIVATE(ah)->ah_nchan;
|
|
/* binary search based on known sorting order */
|
|
for (lim = n; lim != 0; lim >>= 1) {
|
|
cc = &base[lim>>1];
|
|
d = c->channel - cc->channel;
|
|
if (d == 0) {
|
|
if ((cc->channelFlags & CHAN_FLAGS) == flags) {
|
|
if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
|
|
(cc->channelFlags & CHANNEL_DFS))
|
|
return AH_NULL;
|
|
else
|
|
return cc;
|
|
}
|
|
d = flags - (cc->channelFlags & CHAN_FLAGS);
|
|
}
|
|
if (d > 0) {
|
|
base = cc + 1;
|
|
lim--;
|
|
}
|
|
}
|
|
HALDEBUG(ah, HAL_DEBUG_REGDOMAIN, "%s: no match for %u/0x%x\n",
|
|
__func__, c->channel, c->channelFlags);
|
|
return AH_NULL;
|
|
#undef CHAN_FLAGS
|
|
}
|
|
|
|
/*
|
|
* Return the max allowed antenna gain and apply any regulatory
|
|
* domain specific changes.
|
|
*
|
|
* NOTE: a negative reduction is possible in RD's that only
|
|
* measure radiated power (e.g., ETSI) which would increase
|
|
* that actual conducted output power (though never beyond
|
|
* the calibrated target power).
|
|
*/
|
|
u_int
|
|
ath_hal_getantennareduction(struct ath_hal *ah, HAL_CHANNEL *chan, u_int twiceGain)
|
|
{
|
|
HAL_CHANNEL_INTERNAL *ichan=AH_NULL;
|
|
int8_t antennaMax;
|
|
|
|
if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
|
|
antennaMax = twiceGain - ichan->antennaMax*2;
|
|
return (antennaMax < 0) ? 0 : antennaMax;
|
|
} else {
|
|
/* Failed to find the correct index - may be a debug channel */
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
/* XXX - maybe move ctl decision into channel set area or
|
|
into the tables so no decision is needed in the code */
|
|
|
|
#define isWwrSKU(_ah) \
|
|
((getEepromRD((_ah)) & WORLD_SKU_MASK) == WORLD_SKU_PREFIX || \
|
|
getEepromRD(_ah) == WORLD)
|
|
|
|
|
|
/*
|
|
* Return the test group from the specified channel from
|
|
* the regulatory table.
|
|
*
|
|
* TODO: CTL for 11B CommonMode when regulatory domain is unknown
|
|
*/
|
|
u_int
|
|
ath_hal_getctl(struct ath_hal *ah, HAL_CHANNEL *chan)
|
|
{
|
|
u_int ctl = NO_CTL;
|
|
HAL_CHANNEL_INTERNAL *ichan;
|
|
|
|
/* Special CTL to signify WWR SKU without a known country */
|
|
if (AH_PRIVATE(ah)->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
|
|
if (IS_CHAN_B(chan)) {
|
|
ctl = SD_NO_CTL | CTL_11B;
|
|
} else if (IS_CHAN_G(chan)) {
|
|
ctl = SD_NO_CTL | CTL_11G;
|
|
} else if (IS_CHAN_108G(chan)) {
|
|
ctl = SD_NO_CTL | CTL_108G;
|
|
} else if (IS_CHAN_T(chan)) {
|
|
ctl = SD_NO_CTL | CTL_TURBO;
|
|
} else {
|
|
ctl = SD_NO_CTL | CTL_11A;
|
|
}
|
|
} else {
|
|
if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL) {
|
|
ctl = ichan->conformanceTestLimit;
|
|
/* limit 11G OFDM power */
|
|
if (IS_CHAN_PUREG(chan) &&
|
|
(ctl & CTL_MODE_M) == CTL_11B)
|
|
ctl = (ctl &~ CTL_MODE_M) | CTL_11G;
|
|
}
|
|
}
|
|
return ctl;
|
|
}
|
|
|
|
/*
|
|
* Return whether or not a noise floor check is required in
|
|
* the current regulatory domain for the specified channel.
|
|
*/
|
|
HAL_BOOL
|
|
ath_hal_getnfcheckrequired(struct ath_hal *ah, HAL_CHANNEL *chan)
|
|
{
|
|
HAL_CHANNEL_INTERNAL *ichan;
|
|
|
|
if ((ichan = ath_hal_checkchannel(ah, chan)) != AH_NULL)
|
|
return ((ichan->regDmnFlags & NEED_NFC) ? AH_TRUE : AH_FALSE);
|
|
return AH_FALSE;
|
|
}
|
|
|
|
/*
|
|
* Insertion sort.
|
|
*/
|
|
#define swap(_a, _b, _size) { \
|
|
uint8_t *s = _b; \
|
|
int i = _size; \
|
|
do { \
|
|
uint8_t tmp = *_a; \
|
|
*_a++ = *s; \
|
|
*s++ = tmp; \
|
|
} while (--i); \
|
|
_a -= _size; \
|
|
}
|
|
|
|
static void
|
|
ath_hal_sort(void *a, size_t n, size_t size, ath_hal_cmp_t *cmp)
|
|
{
|
|
uint8_t *aa = a;
|
|
uint8_t *ai, *t;
|
|
|
|
for (ai = aa+size; --n >= 1; ai += size)
|
|
for (t = ai; t > aa; t -= size) {
|
|
uint8_t *u = t - size;
|
|
if (cmp(u, t) <= 0)
|
|
break;
|
|
swap(u, t, size);
|
|
}
|
|
}
|