15b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 25b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Copyright (c) 2010 Broadcom Corporation 35b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * 45b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Permission to use, copy, modify, and/or distribute this software for any 55b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * purpose with or without fee is hereby granted, provided that the above 65b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * copyright notice and this permission notice appear in all copies. 75b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * 85b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 95b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <linux/types.h> 185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <net/mac80211.h> 195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <defs.h> 215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "pub.h" 225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "phy/phy_hal.h" 235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "main.h" 245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "stf.h" 255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "channel.h" 265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* QDB() macro takes a dB value and converts to a quarter dB value */ 285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) 295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_01_11 (1<<0) 315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_12_13 (1<<1) 325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_14 (1<<2) 335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */ 345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */ 355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */ 365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */ 375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */ 385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */ 395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */ 405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */ 415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */ 425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */ 435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */ 445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_52_140_ALL (1<<14) 455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ 465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | \ 485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_SET_5G_LOW2 | \ 495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_SET_5G_LOW3) 505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) 515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) 525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_100_140 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \ 535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) 545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) 555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | \ 585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_CHAN_12_13 | \ 595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_CHAN_14) 605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RADAR_SET_NONE 0 625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RADAR_SET_1 1 635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_NONE 0 655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_SET_2G_SHORT 1 665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_CHAN_165 2 675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_ALL_5G 3 685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_JAPAN_LEGACY 4 695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_11D_2G 5 705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_11D_5G 6 715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_LOW_HI 7 725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_12_13_14 8 735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_2G_IDX_i 0 755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_5G_IDX_11 0 765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_MIMO_IDX_bn 0 775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_MIMO_IDX_11n 0 785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ 805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define BRCMS_MAXPWR_TBL_SIZE 6 815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ 825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define BRCMS_MAXPWR_MIMO_TBL_SIZE 14 835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* power level in group of 2.4GHz band channels: 855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[0] - CCK channels [1] 865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[1] - CCK channels [2-10] 875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[2] - CCK channels [11-14] 885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[3] - OFDM channels [1] 895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[4] - OFDM channels [2-10] 905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[5] - OFDM channels [11-14] 915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* maxpwr mapping to 5GHz band channels: 945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[0] - channels [34-48] 955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[1] - channels [52-60] 965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[2] - channels [62-64] 975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[3] - channels [100-140] 985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[4] - channels [149-165] 995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 1005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */ 1015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LC(id) LOCALE_MIMO_IDX_ ## id 1035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LC_2G(id) LOCALE_2G_IDX_ ## id 1055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LC_5G(id) LOCALE_5G_IDX_ ## id 1075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALES(band2, band5, mimo2, mimo5) \ 1095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} 1105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* macro to get 2.4 GHz channel group index for tx power */ 1125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) 1135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) 1145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* macro to get 5 GHz channel group index for tx power */ 1165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \ 1175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (((c) < 62) ? 1 : \ 1185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (((c) < 100) ? 2 : \ 1195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (((c) < 149) ? 3 : 4)))) 1205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define ISDFS_EU(fl) (((fl) & BRCMS_DFS_EU) == BRCMS_DFS_EU) 1225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1235b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct brcms_cm_band { 1245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* struct locale_info flags */ 1255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 locale_flags; 1265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* List of valid channels in the country */ 1275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_chanvec valid_channels; 1285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* List of restricted use channels */ 1295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct brcms_chanvec *restricted_channels; 1305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* List of radar sensitive channels */ 1315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct brcms_chanvec *radar_channels; 1325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 PAD[8]; 1335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* locale per-channel tx power limits for MIMO frames 1365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr arrays are index by channel for 2.4 GHz limits, and 1375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel) 1385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 1395b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct locale_mimo_info { 1405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* tx 20 MHz power limits, qdBm units */ 1415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE]; 1425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* tx 40 MHz power limits, qdBm units */ 1435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE]; 1445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 flags; 1455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Country names and abbreviations with locale defined from ISO 3166 */ 1485b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct country_info { 1495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const u8 locale_2G; /* 2.4G band locale */ 1505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const u8 locale_5G; /* 5G band locale */ 1515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const u8 locale_mimo_2G; /* 2.4G mimo info */ 1525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const u8 locale_mimo_5G; /* 5G mimo info */ 1535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1555b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct brcms_cm_info { 1565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_pub *pub; 1575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc; 1585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char srom_ccode[BRCM_CNTRY_BUF_SZ]; /* Country Code in SROM */ 1595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint srom_regrev; /* Regulatory Rev for the SROM ccode */ 1605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country; /* current country def */ 1615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char ccode[BRCM_CNTRY_BUF_SZ]; /* current internal Country Code */ 1625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint regrev; /* current Regulatory Revision */ 1635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char country_abbrev[BRCM_CNTRY_BUF_SZ]; /* current advertised ccode */ 1645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* per-band state (one per phy/radio) */ 1655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_cm_band bandstate[MAXBANDS]; 1665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* quiet channels currently for radar sensitivity or 11h support */ 1675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* channels on which we cannot transmit */ 1685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_chanvec quiet_channels; 1695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* locale channel and power info. */ 1725b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct locale_info { 1735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u32 valid_channels; 1745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* List of radar sensitive channels */ 1755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 radar_channels; 1765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* List of channels used only if APs are detected */ 1775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 restricted_channels; 1785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Max tx pwr in qdBm for each sub-band */ 1795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE]; 1805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Country IE advertised max tx pwr in dBm per sub-band */ 1815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel s8 pub_maxpwr[BAND_5G_PWR_LVLS]; 1825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 flags; 1835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ 1865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 1885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Some common channel sets 1895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 1905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* No channels */ 1925b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec chanvec_none = { 1935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 1975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* All 2.4 GHz HW channels */ 2005b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec chanvec_all_2G = { 2015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0xfe, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* All 5 GHz HW channels */ 2085b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec chanvec_all_5G = { 2095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x11, 0x11, 2105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, 2115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x20, 0x22, 0x22, 0x00, 0x00, 0x11, 2125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x11, 0x01} 2135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 2165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Radar channel sets 2175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 2185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Channels 52 - 64, 100 - 140 */ 2205b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec radar_set1 = { 2215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, /* 52 - 60 */ 2225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x01, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x11, /* 64, 100 - 124 */ 2235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 128 - 140 */ 2245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 2285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Restricted channel sets 2295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 2305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Channels 34, 38, 42, 46 */ 2325b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec restricted_set_japan_legacy = { 2335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 2345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Channels 12, 13 */ 2405b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec restricted_set_2g_short = { 2415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Channel 165 */ 2485b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec restricted_chan_165 = { 2495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 2525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Channels 36 - 48 & 149 - 165 */ 2565b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec restricted_low_hi = { 2575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, 2585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x20, 0x22, 0x22, 0x00, 0x00, 0x00, 2605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Channels 12 - 14 */ 2645b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec restricted_set_12_13_14 = { 2655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* global memory to provide working buffer for expanded locale */ 2725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2735b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec *g_table_radar_set[] = { 2745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &chanvec_none, 2755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &radar_set1 2765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2785b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec *g_table_restricted_chan[] = { 2795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &chanvec_none, /* restricted_set_none */ 2805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &restricted_set_2g_short, 2815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &restricted_chan_165, 2825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &chanvec_all_5G, 2835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &restricted_set_japan_legacy, 2845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &chanvec_all_2G, /* restricted_set_11d_2G */ 2855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &chanvec_all_5G, /* restricted_set_11d_5G */ 2865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &restricted_low_hi, 2875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &restricted_set_12_13_14 2885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2905b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_2g_01_11 = { 2915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2975b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_2g_12_13 = { 2985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3045b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_2g_14 = { 3055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3115b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW_JP1 = { 3125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 3135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3185b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW_JP2 = { 3195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 3205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3255b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW1 = { 3265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, 3275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3325b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW2 = { 3335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 3345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3395b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW3 = { 3405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 3415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3465b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_MID1 = { 3475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, 3495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3535b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_MID2 = { 3545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 3565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3605b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_MID3 = { 3615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3675b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_HIGH1 = { 3685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3745b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_HIGH2 = { 3755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, 3785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3815b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_HIGH3 = { 3825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 3855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3885b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_52_140_ALL = { 3895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 3905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 3915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 3925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3955b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_HIGH4 = { 3965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 3995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x11, 0x11} 4005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4025b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec *g_table_locale_base[] = { 4035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_2g_01_11, 4045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_2g_12_13, 4055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_2g_14, 4065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW_JP1, 4075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW_JP2, 4085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW1, 4095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW2, 4105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW3, 4115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_MID1, 4125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_MID2, 4135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_MID3, 4145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_HIGH1, 4155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_HIGH2, 4165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_HIGH3, 4175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_52_140_ALL, 4185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_HIGH4 4195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4215b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void brcms_c_locale_add_channels(struct brcms_chanvec *target, 4225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct brcms_chanvec *channels) 4235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 4245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 i; 4255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < sizeof(struct brcms_chanvec); i++) 4265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel target->vec[i] |= channels->vec[i]; 4275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 4285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4295b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void brcms_c_locale_get_channels(const struct locale_info *locale, 4305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_chanvec *channels) 4315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 4325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 i; 4335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel memset(channels, 0, sizeof(struct brcms_chanvec)); 4355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { 4375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale->valid_channels & (1 << i)) 4385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_locale_add_channels(channels, 4395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel g_table_locale_base[i]); 4405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 4415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 4425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 4445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Locale Definitions - 2.4 GHz 4455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 4465b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ 4475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, 4485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_RADAR_SET_NONE, 4495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_RESTRICTED_SET_2G_SHORT, 4505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {QDB(19), QDB(19), QDB(19), 4515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(19), QDB(19), QDB(19)}, 4525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {20, 20, 20, 0}, 4535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel BRCMS_EIRP 4545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 4575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Locale Definitions - 5 GHz 4585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 4595b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info locale_11 = { 4605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ 4615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, 4625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_RADAR_SET_1, 4635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_RESTRICTED_NONE, 4645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, 4655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {23, 23, 23, 30, 30}, 4665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel BRCMS_EIRP | BRCMS_DFS_EU 4675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4695b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info *g_locale_2g_table[] = { 4705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_i 4715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4735b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info *g_locale_5g_table[] = { 4745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_11 4755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 4785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * MIMO Locale Definitions - 2.4 GHz 4795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 4805b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info locale_bn = { 4815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), 4825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), 4835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(13), QDB(13), QDB(13)}, 4845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0, 0, QDB(13), QDB(13), QDB(13), 4855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), 4865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(13), 0, 0}, 4875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0 4885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4905b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info *g_mimo_2g_table[] = { 4915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_bn 4925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 4955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * MIMO Locale Definitions - 5 GHz 4965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 4975b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info locale_11n = { 4985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, 4995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, 5005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0 5015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 5025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5035b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info *g_mimo_5g_table[] = { 5045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_11n 5055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 5065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5075b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct { 5085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char abbrev[BRCM_CNTRY_BUF_SZ]; /* country abbreviation */ 5095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct country_info country; 5105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} cntry_locales[] = { 5115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel { 5125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel "X2", LOCALES(i, 11, bn, 11n)}, /* Worldwide RoW 2 */ 5135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 5145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#ifdef SUPPORT_40MHZ 5165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 20MHz channel info for 40MHz pairing support */ 5175b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct chan20_info { 5185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 sb; 5195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 adj_sbs; 5205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 5215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* indicates adjacent channels that are allowed for a 40 Mhz channel and 5235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * those that permitted by the HT 5245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 5255b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct chan20_info chan20_info[] = { 5265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 11b/11g */ 5275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 0 */ {1, (CH_UPPER_SB | CH_EWA_VALID)}, 5285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 1 */ {2, (CH_UPPER_SB | CH_EWA_VALID)}, 5295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 2 */ {3, (CH_UPPER_SB | CH_EWA_VALID)}, 5305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 3 */ {4, (CH_UPPER_SB | CH_EWA_VALID)}, 5315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 4 */ {5, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, 5325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 5 */ {6, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, 5335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 6 */ {7, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, 5345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 7 */ {8, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, 5355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 8 */ {9, (CH_UPPER_SB | CH_LOWER_SB | CH_EWA_VALID)}, 5365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 9 */ {10, (CH_LOWER_SB | CH_EWA_VALID)}, 5375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 10 */ {11, (CH_LOWER_SB | CH_EWA_VALID)}, 5385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 11 */ {12, (CH_LOWER_SB)}, 5395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 12 */ {13, (CH_LOWER_SB)}, 5405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 13 */ {14, (CH_LOWER_SB)}, 5415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 11a japan high */ 5435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 14 */ {34, (CH_UPPER_SB)}, 5445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 15 */ {38, (CH_LOWER_SB)}, 5455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 16 */ {42, (CH_LOWER_SB)}, 5465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 17 */ {46, (CH_LOWER_SB)}, 5475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 11a usa low */ 5495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 18 */ {36, (CH_UPPER_SB | CH_EWA_VALID)}, 5505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 19 */ {40, (CH_LOWER_SB | CH_EWA_VALID)}, 5515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 20 */ {44, (CH_UPPER_SB | CH_EWA_VALID)}, 5525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 21 */ {48, (CH_LOWER_SB | CH_EWA_VALID)}, 5535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 22 */ {52, (CH_UPPER_SB | CH_EWA_VALID)}, 5545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 23 */ {56, (CH_LOWER_SB | CH_EWA_VALID)}, 5555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 24 */ {60, (CH_UPPER_SB | CH_EWA_VALID)}, 5565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 25 */ {64, (CH_LOWER_SB | CH_EWA_VALID)}, 5575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 11a Europe */ 5595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 26 */ {100, (CH_UPPER_SB | CH_EWA_VALID)}, 5605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 27 */ {104, (CH_LOWER_SB | CH_EWA_VALID)}, 5615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 28 */ {108, (CH_UPPER_SB | CH_EWA_VALID)}, 5625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 29 */ {112, (CH_LOWER_SB | CH_EWA_VALID)}, 5635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 30 */ {116, (CH_UPPER_SB | CH_EWA_VALID)}, 5645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 31 */ {120, (CH_LOWER_SB | CH_EWA_VALID)}, 5655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 32 */ {124, (CH_UPPER_SB | CH_EWA_VALID)}, 5665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 33 */ {128, (CH_LOWER_SB | CH_EWA_VALID)}, 5675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 34 */ {132, (CH_UPPER_SB | CH_EWA_VALID)}, 5685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 35 */ {136, (CH_LOWER_SB | CH_EWA_VALID)}, 5695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 36 */ {140, (CH_LOWER_SB)}, 5705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 11a usa high, ref5 only */ 5725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* The 0x80 bit in pdiv means these are REF5, other entries are REF20 */ 5735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 37 */ {149, (CH_UPPER_SB | CH_EWA_VALID)}, 5745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 38 */ {153, (CH_LOWER_SB | CH_EWA_VALID)}, 5755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 39 */ {157, (CH_UPPER_SB | CH_EWA_VALID)}, 5765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 40 */ {161, (CH_LOWER_SB | CH_EWA_VALID)}, 5775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 41 */ {165, (CH_LOWER_SB)}, 5785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 11a japan */ 5805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 42 */ {184, (CH_UPPER_SB)}, 5815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 43 */ {188, (CH_LOWER_SB)}, 5825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 44 */ {192, (CH_UPPER_SB)}, 5835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 45 */ {196, (CH_LOWER_SB)}, 5845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 46 */ {200, (CH_UPPER_SB)}, 5855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 47 */ {204, (CH_LOWER_SB)}, 5865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 48 */ {208, (CH_UPPER_SB)}, 5875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 49 */ {212, (CH_LOWER_SB)}, 5885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 50 */ {216, (CH_LOWER_SB)} 5895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 5905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#endif /* SUPPORT_40MHZ */ 5915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5925b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx) 5935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 5945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) 5955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; /* error condition */ 5965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return g_locale_2g_table[locale_idx]; 5985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 5995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6005b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx) 6015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) 6035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; /* error condition */ 6045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return g_locale_5g_table[locale_idx]; 6065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 6075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6085b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx) 6095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) 6115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 6125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return g_mimo_2g_table[locale_idx]; 6145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 6155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6165b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx) 6175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) 6195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 6205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return g_mimo_5g_table[locale_idx]; 6225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 6235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6245b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic int 6255b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode, 6265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char *mapped_ccode, uint *mapped_regrev) 6275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 6295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 6305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Lookup a country info structure from a null terminated country 6325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * abbreviation and regrev directly with no translation. 6335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 6345b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct country_info * 6355b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_country_lookup_direct(const char *ccode, uint regrev) 6365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint size, i; 6385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Should just return 0 for single locale driver. */ 6405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Keep it this way in case we add more locales. (for now anyway) */ 6415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 6435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * all other country def arrays are for regrev == 0, so if 6445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * regrev is non-zero, fail 6455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 6465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (regrev > 0) 6475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 6485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* find matched table entry from country code */ 6505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel size = ARRAY_SIZE(cntry_locales); 6515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < size; i++) { 6525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (strcmp(ccode, cntry_locales[i].abbrev) == 0) 6535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return &cntry_locales[i].country; 6545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 6555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 6565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 6575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6585b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct country_info * 6595b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_countrycode_map(struct brcms_cm_info *wlc_cm, const char *ccode, 6605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char *mapped_ccode, uint *mapped_regrev) 6615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 6635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country; 6645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint srom_regrev = wlc_cm->srom_regrev; 6655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const char *srom_ccode = wlc_cm->srom_ccode; 6665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int mapped; 6675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* check for currently supported ccode size */ 6695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (strlen(ccode) > (BRCM_CNTRY_BUF_SZ - 1)) { 6705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wiphy_err(wlc->wiphy, "wl%d: %s: ccode \"%s\" too long for " 6715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel "match\n", wlc->pub->unit, __func__, ccode); 6725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 6735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 6745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* default mapping is the given ccode and regrev 0 */ 6765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); 6775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel *mapped_regrev = 0; 6785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* If the desired country code matches the srom country code, 6805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * then the mapped country is the srom regulatory rev. 6815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Otherwise look for an aggregate mapping. 6825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 6835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (!strcmp(srom_ccode, ccode)) { 6845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel *mapped_regrev = srom_regrev; 6855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mapped = 0; 6865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wiphy_err(wlc->wiphy, "srom_code == ccode %s\n", __func__); 6875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else { 6885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mapped = 6895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_country_aggregate_map(wlc_cm, ccode, mapped_ccode, 6905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mapped_regrev); 6915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 6925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* find the matching built-in country definition */ 6945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel country = brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev); 6955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* if there is not an exact rev match, default to rev zero */ 6975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (country == NULL && *mapped_regrev != 0) { 6985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel *mapped_regrev = 0; 6995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel country = 7005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_country_lookup_direct(mapped_ccode, *mapped_regrev); 7015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 7025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return country; 7045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Lookup a country info structure from a null terminated country code 7075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * The lookup is case sensitive. 7085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7095b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct country_info * 7105b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_country_lookup(struct brcms_c_info *wlc, const char *ccode) 7115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 7125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country; 7135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char mapped_ccode[BRCM_CNTRY_BUF_SZ]; 7145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint mapped_regrev; 7155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 7175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * map the country code to a built-in country code, regrev, and 7185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * country_info struct 7195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel country = brcms_c_countrycode_map(wlc->cmi, ccode, mapped_ccode, 7215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &mapped_regrev); 7225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return country; 7245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 7275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * reset the quiet channels vector to the union 7285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * of the restricted and radar channel sets 7295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7305b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm) 7315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 7325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 7335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint i, j; 7345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_band *band; 7355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct brcms_chanvec *chanvec; 7365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec)); 7385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel band = wlc->band; 7405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < wlc->pub->_nbands; 7415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { 7425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* initialize quiet channels for restricted channels */ 7445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; 7455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < sizeof(struct brcms_chanvec); j++) 7465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; 7475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 7495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Is the channel valid for the current locale and current band? */ 7525b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val) 7535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 7545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 7555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return ((val < MAXCHANNEL) && 7575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, 7585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel val)); 7595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Is the channel valid for the current locale and specified band? */ 7625b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm, 7635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint bandunit, uint val) 7645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 7655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return ((val < MAXCHANNEL) 7665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); 7675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Is the channel valid for the current locale? (but don't consider channels not 7705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * available due to bandlocking) 7715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7725b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val) 7735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 7745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 7755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_valid_channel20(wlc->cmi, val) || 7775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (!wlc->bandlocked 7785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel && brcms_c_valid_channel20_in_band(wlc->cmi, 7795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel OTHERBANDUNIT(wlc), val)); 7805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* JP, J1 - J10 are Japan ccodes */ 7835b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_japan_ccode(const char *ccode) 7845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 7855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return (ccode[0] == 'J' && 7865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); 7875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Returns true if currently set country is Japan or variant */ 7905b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_japan(struct brcms_c_info *wlc) 7915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 7925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_japan_ccode(wlc->cmi->country_abbrev); 7935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7955b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void 7965b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channel_min_txpower_limits_with_local_constraint( 7975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr, 7985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 local_constraint_qdbm) 7995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 8005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int j; 8015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* CCK Rates */ 8035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) 8045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm); 8055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20 MHz Legacy OFDM SISO */ 8075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) 8085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm); 8095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20 MHz Legacy OFDM CDD */ 8115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) 8125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_cdd[j] = 8135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->ofdm_cdd[j], local_constraint_qdbm); 8145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40 MHz Legacy OFDM SISO */ 8165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) 8175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_siso[j] = 8185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); 8195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40 MHz Legacy OFDM CDD */ 8215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) 8225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_cdd[j] = 8235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm); 8245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20MHz MCS 0-7 SISO */ 8265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 8275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_siso[j] = 8285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_20_siso[j], local_constraint_qdbm); 8295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20MHz MCS 0-7 CDD */ 8315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 8325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_cdd[j] = 8335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); 8345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20MHz MCS 0-7 STBC */ 8365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 8375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_stbc[j] = 8385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); 8395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20MHz MCS 8-15 MIMO */ 8415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) 8425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_mimo[j] = 8435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_20_mimo[j], local_constraint_qdbm); 8445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 0-7 SISO */ 8465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 8475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_siso[j] = 8485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_40_siso[j], local_constraint_qdbm); 8495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 0-7 CDD */ 8515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 8525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_cdd[j] = 8535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_40_cdd[j], local_constraint_qdbm); 8545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 0-7 STBC */ 8565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 8575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_stbc[j] = 8585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_40_stbc[j], local_constraint_qdbm); 8595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 8-15 MIMO */ 8615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) 8625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_mimo[j] = 8635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_40_mimo[j], local_constraint_qdbm); 8645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 32 */ 8665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm); 8675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 8695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Update the radio state (enable/disable) and tx power targets 8715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * based on a new set of channel/regulatory information 8725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 8735b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) 8745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 8755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 8765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint chan; 8775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct txpwr_limits txpwr; 8785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* search for the existence of any valid channel */ 8805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (chan = 0; chan < MAXCHANNEL; chan++) { 8815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (brcms_c_valid_channel20_db(wlc->cmi, chan)) 8825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel break; 8835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 8845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (chan == MAXCHANNEL) 8855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel chan = INVCHANNEL; 8865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 8885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * based on the channel search above, set or 8895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * clear WL_RADIO_COUNTRY_DISABLE. 8905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 8915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (chan == INVCHANNEL) { 8925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 8935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * country/locale with no valid channels, set 8945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * the radio disable bit 8955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 8965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); 8975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" " 8985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel "nbands %d bandlocked %d\n", wlc->pub->unit, 8995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel __func__, wlc_cm->country_abbrev, wlc->pub->_nbands, 9005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc->bandlocked); 9015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else if (mboolisset(wlc->pub->radio_disabled, 9025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel WL_RADIO_COUNTRY_DISABLE)) { 9035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 9045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * country/locale with valid channel, clear 9055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * the radio disable bit 9065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 9075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); 9085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 9095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 9115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Now that the country abbreviation is set, if the radio supports 2G, 9125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * then set channel 14 restrictions based on the new locale. 9135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 9145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) 9155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, 9165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_japan(wlc) ? true : 9175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel false); 9185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (wlc->pub->up && chan != INVCHANNEL) { 9205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); 9215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channel_min_txpower_limits_with_local_constraint(wlc_cm, 9225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &txpwr, BRCMS_TXPWR_MAX); 9235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_phy_txpower_limit_set(wlc->band->pi, &txpwr, wlc->chanspec); 9245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 9255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 9265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9275b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic int 9285b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channels_init(struct brcms_cm_info *wlc_cm, 9295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country) 9305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 9315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 9325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint i, j; 9335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_band *band; 9345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_info *li; 9355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_chanvec sup_chan; 9365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_mimo_info *li_mimo; 9375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel band = wlc->band; 9395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < wlc->pub->_nbands; 9405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { 9415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li = (band->bandtype == BRCM_BAND_5G) ? 9435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_locale_5g(country->locale_5G) : 9445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_locale_2g(country->locale_2G); 9455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; 9465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li_mimo = (band->bandtype == BRCM_BAND_5G) ? 9475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_mimo_5g(country->locale_mimo_5G) : 9485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_mimo_2g(country->locale_mimo_2G); 9495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* merge the mimo non-mimo locale flags */ 9515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].locale_flags |= 9525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li_mimo->flags; 9535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].restricted_channels = 9555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel g_table_restricted_chan[li->restricted_channels]; 9565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].radar_channels = 9575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel g_table_radar_set[li->radar_channels]; 9585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 9605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * set the channel availability, masking out the channels 9615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * that may not be supported on this phy. 9625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 9635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_phy_chanspec_band_validch(band->pi, band->bandtype, 9645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &sup_chan); 9655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_locale_get_channels(li, 9665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &wlc_cm->bandstate[band->bandunit]. 9675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel valid_channels); 9685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < sizeof(struct brcms_chanvec); j++) 9695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].valid_channels. 9705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel vec[j] &= sup_chan.vec[j]; 9715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 9725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_quiet_channels_reset(wlc_cm); 9745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channels_commit(wlc_cm); 9755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return 0; 9775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 9785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 9805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * set the driver's current country and regulatory information 9815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * using a country code as the source. Look up built in country 9825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * information found with the country code. 9835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 9845b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void 9855b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_set_country_common(struct brcms_cm_info *wlc_cm, 9865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const char *country_abbrev, 9875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const char *ccode, uint regrev, 9885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country) 9895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 9905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_info *locale; 9915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 9925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char prev_country_abbrev[BRCM_CNTRY_BUF_SZ]; 9935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* save current country state */ 9955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->country = country; 9965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel memset(&prev_country_abbrev, 0, BRCM_CNTRY_BUF_SZ); 9985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(prev_country_abbrev, wlc_cm->country_abbrev, 9995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel BRCM_CNTRY_BUF_SZ - 1); 10005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(wlc_cm->country_abbrev, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); 10025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(wlc_cm->ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); 10035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->regrev = regrev; 10045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if ((wlc->pub->_n_enab & SUPPORT_11N) != 10065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc->protection->nmode_user) 10075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_set_nmode(wlc); 10085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); 10105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); 10115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* set or restore gmode as required by regulatory */ 10125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel locale = brcms_c_get_locale_2g(country->locale_2G); 10135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale && (locale->flags & BRCMS_NO_OFDM)) 10145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); 10155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel else 10165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); 10175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channels_init(wlc_cm, country); 10195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return; 10215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 10225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10235b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic int 10245b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_set_countrycode_rev(struct brcms_cm_info *wlc_cm, 10255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const char *country_abbrev, 10265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const char *ccode, int regrev) 10275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 10285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country; 10295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char mapped_ccode[BRCM_CNTRY_BUF_SZ]; 10305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint mapped_regrev; 10315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* if regrev is -1, lookup the mapped country code, 10335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * otherwise use the ccode and regrev directly 10345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 10355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (regrev == -1) { 10365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 10375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * map the country code to a built-in country 10385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * code, regrev, and country_info 10395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 10405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel country = 10415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_countrycode_map(wlc_cm, ccode, mapped_ccode, 10425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &mapped_regrev); 10435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else { 10445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* find the matching built-in country definition */ 10455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel country = brcms_c_country_lookup_direct(ccode, regrev); 10465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(mapped_ccode, ccode, BRCM_CNTRY_BUF_SZ); 10475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mapped_regrev = regrev; 10485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (country == NULL) 10515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return -EINVAL; 10525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* set the driver state for the country */ 10545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_set_country_common(wlc_cm, country_abbrev, mapped_ccode, 10555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mapped_regrev, country); 10565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return 0; 10585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 10595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 10615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * set the driver's current country and regulatory information using 10625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * a country code as the source. Lookup built in country information 10635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * found with the country code. 10645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 10655b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic int 10665b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_set_countrycode(struct brcms_cm_info *wlc_cm, const char *ccode) 10675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 10685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char country_abbrev[BRCM_CNTRY_BUF_SZ]; 10695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(country_abbrev, ccode, BRCM_CNTRY_BUF_SZ); 10705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_set_countrycode_rev(wlc_cm, country_abbrev, ccode, -1); 10715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 10725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10735b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) 10745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 10755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_cm_info *wlc_cm; 10765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char country_abbrev[BRCM_CNTRY_BUF_SZ]; 10775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country; 10785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_pub *pub = wlc->pub; 10795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel char *ccode; 10805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); 10825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); 10845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (wlc_cm == NULL) 10855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 10865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->pub = pub; 10875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->wlc = wlc; 10885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc->cmi = wlc_cm; 10895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* store the country code for passing up as a regulatory hint */ 10915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel ccode = getvar(wlc->hw->sih, BRCMS_SROM_CCODE); 10925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (ccode) 10935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); 10945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 10965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * internal country information which must match 10975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * regulatory constraints in firmware 10985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 10995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel memset(country_abbrev, 0, BRCM_CNTRY_BUF_SZ); 11005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); 11015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel country = brcms_c_country_lookup(wlc, country_abbrev); 11025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* save default country for exiting 11d regulatory mode */ 11045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(wlc->country_default, country_abbrev, BRCM_CNTRY_BUF_SZ - 1); 11055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* initialize autocountry_default to driver default */ 11075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel strncpy(wlc->autocountry_default, "X2", BRCM_CNTRY_BUF_SZ - 1); 11085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_set_countrycode(wlc_cm, country_abbrev); 11105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return wlc_cm; 11125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 11135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11145b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm) 11155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 11165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel kfree(wlc_cm); 11175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 11185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11195b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu8 11205b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, 11215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint bandunit) 11225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 11235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return wlc_cm->bandstate[bandunit].locale_flags; 11245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 11255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11265b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool 11275b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec) 11285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 11295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return (wlc_cm->wlc->pub->_n_enab & SUPPORT_11N) && 11305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel CHSPEC_IS40(chspec) ? 11315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (isset(wlc_cm->quiet_channels.vec, 11325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel lower_20_sb(CHSPEC_CHANNEL(chspec))) || 11335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel isset(wlc_cm->quiet_channels.vec, 11345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel upper_20_sb(CHSPEC_CHANNEL(chspec)))) : 11355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec)); 11365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 11375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11385b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid 11395b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, 11405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 local_constraint_qdbm) 11415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 11425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 11435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct txpwr_limits txpwr; 11445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); 11465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channel_min_txpower_limits_with_local_constraint( 11485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm, &txpwr, local_constraint_qdbm 11495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel ); 11505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_b_set_chanspec(wlc->hw, chanspec, 11525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0), 11535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &txpwr); 11545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 11555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11565b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid 11575b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, 11585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct txpwr_limits *txpwr) 11595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 11605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 11615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint i; 11625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint chan; 11635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int maxpwr; 11645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int delta; 11655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country; 11665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_band *band; 11675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_info *li; 11685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int conducted_max = BRCMS_TXPWR_MAX; 11695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int conducted_ofdm_max = BRCMS_TXPWR_MAX; 11705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_mimo_info *li_mimo; 11715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int maxpwr20, maxpwr40; 11725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int maxpwr_idx; 11735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint j; 11745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel memset(txpwr, 0, sizeof(struct txpwr_limits)); 11765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (!brcms_c_valid_chanspec_db(wlc_cm, chanspec)) { 11785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel country = brcms_c_country_lookup(wlc, wlc->autocountry_default); 11795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (country == NULL) 11805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return; 11815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else { 11825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel country = wlc_cm->country; 11835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 11845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel chan = CHSPEC_CHANNEL(chanspec); 11865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel band = wlc->bandstate[chspec_bandunit(chanspec)]; 11875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li = (band->bandtype == BRCM_BAND_5G) ? 11885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_locale_5g(country->locale_5G) : 11895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_locale_2g(country->locale_2G); 11905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li_mimo = (band->bandtype == BRCM_BAND_5G) ? 11925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_mimo_5g(country->locale_mimo_5G) : 11935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_mimo_2g(country->locale_mimo_2G); 11945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li->flags & BRCMS_EIRP) { 11965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = band->antgain; 11975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else { 11985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = 0; 11995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->antgain > QDB(6)) 12005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = band->antgain - QDB(6); /* Excess over 6 dB */ 12015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 12025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li == &locale_i) { 12045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel conducted_max = QDB(22); 12055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel conducted_ofdm_max = QDB(22); 12065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 12075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* CCK txpwr limits for 2.4G band */ 12095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->bandtype == BRCM_BAND_2G) { 12105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)]; 12115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = maxpwr - delta; 12135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = max(maxpwr, 0); 12145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = min(maxpwr, conducted_max); 12155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) 12175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->cck[i] = (u8) maxpwr; 12185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 12195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* OFDM txpwr limits for 2.4G or 5G bands */ 12215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->bandtype == BRCM_BAND_2G) 12225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; 12235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel else 12245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; 12255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = maxpwr - delta; 12275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = max(maxpwr, 0); 12285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = min(maxpwr, conducted_ofdm_max); 12295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Keep OFDM lmit below CCK limit */ 12315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->bandtype == BRCM_BAND_2G) 12325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = min_t(int, maxpwr, txpwr->cck[0]); 12335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) 12355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm[i] = (u8) maxpwr; 12365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { 12385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 12395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * OFDM 40 MHz SISO has the same power as the corresponding 12405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * MCS0-7 rate unless overriden by the locale specific code. 12415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * We set this value to 0 as a flag (presumably 0 dBm isn't 12425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * a possibility) and then copy the MCS0-7 value to the 40 MHz 12435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * value if it wasn't explicitly set. 12445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 12455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_siso[i] = 0; 12465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_cdd[i] = (u8) maxpwr; 12485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_cdd[i] = 0; 12505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 12515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* MIMO/HT specific limits */ 12535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li_mimo->flags & BRCMS_EIRP) { 12545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = band->antgain; 12555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else { 12565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = 0; 12575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->antgain > QDB(6)) 12585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = band->antgain - QDB(6); /* Excess over 6 dB */ 12595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 12605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->bandtype == BRCM_BAND_2G) 12625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr_idx = (chan - 1); 12635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel else 12645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr_idx = CHANNEL_POWER_IDX_5G(chan); 12655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr20 = li_mimo->maxpwr20[maxpwr_idx]; 12675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = li_mimo->maxpwr40[maxpwr_idx]; 12685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr20 = maxpwr20 - delta; 12705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr20 = max(maxpwr20, 0); 12715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = maxpwr40 - delta; 12725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = max(maxpwr40, 0); 12735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in the MCS 0-7 (SISO) rates */ 12755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 12765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 12785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * 20 MHz has the same power as the corresponding OFDM rate 12795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * unless overriden by the locale specific code. 12805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 12815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_siso[i] = txpwr->ofdm[i]; 12825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_siso[i] = 0; 12835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 12845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in the MCS 0-7 CDD rates */ 12865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 12875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_cdd[i] = (u8) maxpwr20; 12885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_cdd[i] = (u8) maxpwr40; 12895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 12905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 12915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 12925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * These locales have SISO expressed in the 12935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * table and override CDD later 12945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 12955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li_mimo == &locale_bn) { 12965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li_mimo == &locale_bn) { 12975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr20 = QDB(16); 12985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = 0; 12995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (chan >= 3 && chan <= 11) 13015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = QDB(16); 13025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 13055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_siso[i] = (u8) maxpwr20; 13065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_siso[i] = (u8) maxpwr40; 13075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in the MCS 0-7 STBC rates */ 13115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 13125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_stbc[i] = 0; 13135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_stbc[i] = 0; 13145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in the MCS 8-15 SDM rates */ 13175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) { 13185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_mimo[i] = (u8) maxpwr20; 13195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_mimo[i] = (u8) maxpwr40; 13205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in MCS32 */ 13235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs32 = (u8) maxpwr40; 13245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) { 13265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->ofdm_40_cdd[i] == 0) 13275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; 13285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (i == 0) { 13295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel i = i + 1; 13305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->ofdm_40_cdd[i] == 0) 13315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; 13325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 13365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO 13375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * value if it wasn't provided explicitly. 13385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 13395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 13405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->mcs_40_siso[i] == 0) 13415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i]; 13425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) { 13455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->ofdm_40_siso[i] == 0) 13465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; 13475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (i == 0) { 13485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel i = i + 1; 13495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->ofdm_40_siso[i] == 0) 13505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; 13515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 13555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding 13565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * STBC values if they weren't provided explicitly. 13575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 13585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 13595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->mcs_20_stbc[i] == 0) 13605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i]; 13615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->mcs_40_stbc[i] == 0) 13635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; 13645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 13655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return; 13675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 13685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 13695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 13703de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers * Verify the chanspec is using a legal set of parameters, i.e. that the 13713de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers * chanspec specified a band, bw, ctl_sb and channel and that the 13723de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers * combination could be legal given any set of circumstances. 13733de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers * RETURNS: true is the chanspec is malformed, false if it looks good. 13743de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers */ 13753de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukersstatic bool brcms_c_chspec_malformed(u16 chanspec) 13763de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers{ 13773de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers /* must be 2G or 5G band */ 13783de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec)) 13793de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return true; 13803de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers /* must be 20 or 40 bandwidth */ 13813de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec)) 13823de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return true; 13833de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers 13843de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */ 13853de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (CHSPEC_IS20(chanspec)) { 13863de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (!CHSPEC_SB_NONE(chanspec)) 13873de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return true; 13883de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers } else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) { 13893de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return true; 13903de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers } 13913de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers 13923de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return false; 13933de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers} 13943de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers 13953de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers/* 13965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Validate the chanspec for this locale, for 40MHZ we need to also 13975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * check that the sidebands are valid 20MZH channels in this locale 13985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * and they are also a legal HT combination 13995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 14005b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool 14015b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec, 14025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel bool dualband) 14035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 14045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 14055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 channel = CHSPEC_CHANNEL(chspec); 14065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 14075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* check the chanspec */ 14083de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (brcms_c_chspec_malformed(chspec)) { 14095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", 14105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc->pub->unit, chspec); 14115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 14125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 14135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 14145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) != 14155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel chspec_bandunit(chspec)) 14165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 14175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 14185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Check a 20Mhz channel */ 14195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (CHSPEC_IS20(chspec)) { 14205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (dualband) 14215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_valid_channel20_db(wlc_cm->wlc->cmi, 14225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel channel); 14235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel else 14245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_valid_channel20(wlc_cm->wlc->cmi, 14255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel channel); 14265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 14275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#ifdef SUPPORT_40MHZ 14285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 14295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * We know we are now checking a 40MHZ channel, so we should 14305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * only be here for NPHYS 14315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 14325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (BRCMS_ISNPHY(wlc->band) || BRCMS_ISSSLPNPHY(wlc->band)) { 14335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 upper_sideband = 0, idx; 14345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 num_ch20_entries = 14355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel sizeof(chan20_info) / sizeof(struct chan20_info); 14365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 14375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (!VALID_40CHANSPEC_IN_BAND(wlc, chspec_bandunit(chspec))) 14385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 14395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 14405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (dualband) { 14415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (!brcms_c_valid_channel20_db(wlc->cmi, 14425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel lower_20_sb(channel)) || 14435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel !brcms_c_valid_channel20_db(wlc->cmi, 14445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel upper_20_sb(channel))) 14455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 14465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else { 14475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (!brcms_c_valid_channel20(wlc->cmi, 14485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel lower_20_sb(channel)) || 14495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel !brcms_c_valid_channel20(wlc->cmi, 14505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel upper_20_sb(channel))) 14515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 14525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 14535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 14545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* find the lower sideband info in the sideband array */ 14555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (idx = 0; idx < num_ch20_entries; idx++) { 14565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (chan20_info[idx].sb == lower_20_sb(channel)) 14575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel upper_sideband = chan20_info[idx].adj_sbs; 14585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 14595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* check that the lower sideband allows an upper sideband */ 14605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if ((upper_sideband & (CH_UPPER_SB | CH_EWA_VALID)) == 14615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (CH_UPPER_SB | CH_EWA_VALID)) 14625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return true; 14635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 14645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 14655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#endif /* 40 MHZ */ 14665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 14675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 14685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 14695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 14705b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec) 14715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 14725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true); 14735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 1474