channel.c revision cf03c5dac83609f09d9f0e9fa3c09d86daed614d
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> 18cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#include <net/cfg80211.h> 195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <net/mac80211.h> 20cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#include <net/regulatory.h> 215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include <defs.h> 235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "pub.h" 245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "phy/phy_hal.h" 255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "main.h" 265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "stf.h" 275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#include "channel.h" 28cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#include "mac80211_if.h" 295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* QDB() macro takes a dB value and converts to a quarter dB value */ 315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define QDB(n) ((n) * BRCMS_TXPWR_DB_FACTOR) 325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_01_11 (1<<0) 345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_12_13 (1<<1) 355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_14 (1<<2) 365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW_JP1 (1<<3) /* 34-48, step 2 */ 375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW_JP2 (1<<4) /* 34-46, step 4 */ 385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW1 (1<<5) /* 36-48, step 4 */ 395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW2 (1<<6) /* 52 */ 405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_LOW3 (1<<7) /* 56-64, step 4 */ 415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_MID1 (1<<8) /* 100-116, step 4 */ 425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_MID2 (1<<9) /* 120-124, step 4 */ 435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_MID3 (1<<10) /* 128 */ 445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_HIGH1 (1<<11) /* 132-140, step 4 */ 455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_HIGH2 (1<<12) /* 149-161, step 4 */ 465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_HIGH3 (1<<13) /* 165 */ 475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_52_140_ALL (1<<14) 485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_SET_5G_HIGH4 (1<<15) /* 184-216 */ 495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_36_64 (LOCALE_SET_5G_LOW1 | \ 515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_SET_5G_LOW2 | \ 525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_SET_5G_LOW3) 535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_52_64 (LOCALE_SET_5G_LOW2 | LOCALE_SET_5G_LOW3) 545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_100_124 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2) 555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_100_140 (LOCALE_SET_5G_MID1 | LOCALE_SET_5G_MID2 | \ 565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_SET_5G_MID3 | LOCALE_SET_5G_HIGH1) 575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_149_165 (LOCALE_SET_5G_HIGH2 | LOCALE_SET_5G_HIGH3) 585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_184_216 LOCALE_SET_5G_HIGH4 595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_CHAN_01_14 (LOCALE_CHAN_01_11 | \ 615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_CHAN_12_13 | \ 625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_CHAN_14) 635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_NONE 0 655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_RESTRICTED_SET_2G_SHORT 1 665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_2G_IDX_i 0 685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_5G_IDX_11 0 695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_MIMO_IDX_bn 0 705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALE_MIMO_IDX_11n 0 715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* max of BAND_5G_PWR_LVLS and 6 for 2.4 GHz */ 735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define BRCMS_MAXPWR_TBL_SIZE 6 745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* max of BAND_5G_PWR_LVLS and 14 for 2.4 GHz */ 755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define BRCMS_MAXPWR_MIMO_TBL_SIZE 14 765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* power level in group of 2.4GHz band channels: 785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[0] - CCK channels [1] 795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[1] - CCK channels [2-10] 805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[2] - CCK channels [11-14] 815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[3] - OFDM channels [1] 825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[4] - OFDM channels [2-10] 835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[5] - OFDM channels [11-14] 845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* maxpwr mapping to 5GHz band channels: 875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[0] - channels [34-48] 885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[1] - channels [52-60] 895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[2] - channels [62-64] 905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[3] - channels [100-140] 915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr[4] - channels [149-165] 925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define BAND_5G_PWR_LVLS 5 /* 5 power levels for 5G */ 945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LC(id) LOCALE_MIMO_IDX_ ## id 965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LC_2G(id) LOCALE_2G_IDX_ ## id 985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LC_5G(id) LOCALE_5G_IDX_ ## id 1005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define LOCALES(band2, band5, mimo2, mimo5) \ 1025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {LC_2G(band2), LC_5G(band5), LC(mimo2), LC(mimo5)} 1035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* macro to get 2.4 GHz channel group index for tx power */ 1055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define CHANNEL_POWER_IDX_2G_CCK(c) (((c) < 2) ? 0 : (((c) < 11) ? 1 : 2)) 1065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define CHANNEL_POWER_IDX_2G_OFDM(c) (((c) < 2) ? 3 : (((c) < 11) ? 4 : 5)) 1075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* macro to get 5 GHz channel group index for tx power */ 1095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel#define CHANNEL_POWER_IDX_5G(c) (((c) < 52) ? 0 : \ 1105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (((c) < 62) ? 1 : \ 1115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (((c) < 100) ? 2 : \ 1125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (((c) < 149) ? 3 : 4)))) 1135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 114cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0) 115cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \ 116cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_PASSIVE_SCAN | \ 117cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_NO_IBSS) 118cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 119cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \ 120cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_PASSIVE_SCAN | \ 121cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_NO_IBSS) 122cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \ 123cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_PASSIVE_SCAN | \ 124cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_DFS | \ 125cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_NO_IBSS) 126cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \ 127cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_PASSIVE_SCAN | \ 128cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_DFS | \ 129cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_NO_IBSS) 130cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \ 131cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_PASSIVE_SCAN | \ 132cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee NL80211_RRF_NO_IBSS) 133cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 134cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestatic const struct ieee80211_regdomain brcms_regdom_x2 = { 135cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee .n_reg_rules = 7, 136cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee .alpha2 = "X2", 137cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee .reg_rules = { 138cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee BRCM_2GHZ_2412_2462, 139cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee BRCM_2GHZ_2467_2472, 140cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee BRCM_5GHZ_5180_5240, 141cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee BRCM_5GHZ_5260_5320, 142cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee BRCM_5GHZ_5500_5700, 143cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee BRCM_5GHZ_5745_5825, 144cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 145cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee}; 146cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1475b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct brcms_cm_band { 1485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* struct locale_info flags */ 1495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 locale_flags; 1505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* List of valid channels in the country */ 1515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_chanvec valid_channels; 1525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* List of restricted use channels */ 1535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct brcms_chanvec *restricted_channels; 1545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* locale per-channel tx power limits for MIMO frames 1575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * maxpwr arrays are index by channel for 2.4 GHz limits, and 1585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * by sub-band for 5 GHz limits using CHANNEL_POWER_IDX_5G(channel) 1595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 1605b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct locale_mimo_info { 1615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* tx 20 MHz power limits, qdBm units */ 1625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel s8 maxpwr20[BRCMS_MAXPWR_MIMO_TBL_SIZE]; 1635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* tx 40 MHz power limits, qdBm units */ 1645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel s8 maxpwr40[BRCMS_MAXPWR_MIMO_TBL_SIZE]; 1655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 flags; 1665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Country names and abbreviations with locale defined from ISO 3166 */ 1695b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct country_info { 1705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const u8 locale_2G; /* 2.4G band locale */ 1715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const u8 locale_5G; /* 5G band locale */ 1725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const u8 locale_mimo_2G; /* 2.4G mimo info */ 1735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const u8 locale_mimo_5G; /* 5G mimo info */ 1745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 176cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestruct brcms_regd { 177cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct country_info country; 178cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee const struct ieee80211_regdomain *regdomain; 179cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee}; 180cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1815b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct brcms_cm_info { 1825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_pub *pub; 1835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc; 184cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee const struct brcms_regd *world_regd; 1855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* per-band state (one per phy/radio) */ 1865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_cm_band bandstate[MAXBANDS]; 1875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* quiet channels currently for radar sensitivity or 11h support */ 1885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* channels on which we cannot transmit */ 1895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_chanvec quiet_channels; 1905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 1915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 1925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* locale channel and power info. */ 1935b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct locale_info { 1945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u32 valid_channels; 1955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* List of channels used only if APs are detected */ 1965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 restricted_channels; 1975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Max tx pwr in qdBm for each sub-band */ 1985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel s8 maxpwr[BRCMS_MAXPWR_TBL_SIZE]; 1995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 flags; 2005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Regulatory Matrix Spreadsheet (CLM) MIMO v3.7.9 */ 2035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 2055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Some common channel sets 2065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 2075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* No channels */ 2095b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec chanvec_none = { 2105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 2175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Restricted channel sets 2185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 2195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Channels 12, 13 */ 2215b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec restricted_set_2g_short = { 2225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* global memory to provide working buffer for expanded locale */ 2295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2305b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec *g_table_restricted_chan[] = { 2315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &chanvec_none, /* restricted_set_none */ 2325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &restricted_set_2g_short, 2335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2355b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_2g_01_11 = { 2365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2425b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_2g_12_13 = { 2435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2495b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_2g_14 = { 2505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2565b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW_JP1 = { 2575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x54, 0x55, 0x01, 0x00, 2585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2635b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW_JP2 = { 2645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x44, 0x44, 0x00, 0x00, 2655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2705b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW1 = { 2715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x01, 0x00, 2725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2775b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW2 = { 2785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 2795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2845b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_LOW3 = { 2855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 2865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2915b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_MID1 = { 2925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 0x11, 0x00, 2945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 2955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 2965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 2975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 2985b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_MID2 = { 2995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 3015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3055b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_MID3 = { 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 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3125b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_HIGH1 = { 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 0x10, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 3165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3195b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_HIGH2 = { 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, 0x20, 0x22, 0x02, 0x00, 0x00, 0x00, 3235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3265b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_HIGH3 = { 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, 0x20, 0x00, 0x00, 0x00, 3305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3335b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_52_140_ALL = { 3345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x11, 3355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 3365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 3375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x00, 0x00, 0x00, 0x00} 3385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3405b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec locale_5g_HIGH4 = { 3415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0x00, 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, 0x00, 0x00, 0x00, 0x11, 3445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0x11, 0x11, 0x11, 0x11} 3455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3475b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct brcms_chanvec *g_table_locale_base[] = { 3485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_2g_01_11, 3495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_2g_12_13, 3505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_2g_14, 3515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW_JP1, 3525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW_JP2, 3535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW1, 3545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW2, 3555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_LOW3, 3565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_MID1, 3575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_MID2, 3585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_MID3, 3595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_HIGH1, 3605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_HIGH2, 3615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_HIGH3, 3625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_52_140_ALL, 3635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_5g_HIGH4 3645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3665b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void brcms_c_locale_add_channels(struct brcms_chanvec *target, 3675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct brcms_chanvec *channels) 3685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 3695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 i; 3705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < sizeof(struct brcms_chanvec); i++) 3715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel target->vec[i] |= channels->vec[i]; 3725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 3735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3745b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void brcms_c_locale_get_channels(const struct locale_info *locale, 3755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_chanvec *channels) 3765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 3775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 i; 3785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel memset(channels, 0, sizeof(struct brcms_chanvec)); 3805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { 3825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale->valid_channels & (1 << i)) 3835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_locale_add_channels(channels, 3845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel g_table_locale_base[i]); 3855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 3865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 3875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 3895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Locale Definitions - 2.4 GHz 3905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 3915b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info locale_i = { /* locale i. channel 1 - 13 */ 3925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_CHAN_01_11 | LOCALE_CHAN_12_13, 3935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_RESTRICTED_SET_2G_SHORT, 3945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {QDB(19), QDB(19), QDB(19), 3955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(19), QDB(19), QDB(19)}, 3965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel BRCMS_EIRP 3975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 3985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 3995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 4005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Locale Definitions - 5 GHz 4015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 4025b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info locale_11 = { 4035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* locale 11. channel 36 - 48, 52 - 64, 100 - 140, 149 - 165 */ 4045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_CHAN_36_64 | LOCALE_CHAN_100_140 | LOCALE_CHAN_149_165, 4055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel LOCALE_RESTRICTED_NONE, 4065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {QDB(21), QDB(21), QDB(21), QDB(21), QDB(21)}, 4075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel BRCMS_EIRP | BRCMS_DFS_EU 4085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4105b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info *g_locale_2g_table[] = { 4115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_i 4125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4145b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info *g_locale_5g_table[] = { 4155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_11 4165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 4195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * MIMO Locale Definitions - 2.4 GHz 4205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 4215b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info locale_bn = { 4225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), 4235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), 4245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(13), QDB(13), QDB(13)}, 4255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {0, 0, QDB(13), QDB(13), QDB(13), 4265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(13), QDB(13), QDB(13), QDB(13), QDB(13), 4275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel QDB(13), 0, 0}, 4285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0 4295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4315b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info *g_mimo_2g_table[] = { 4325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_bn 4335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 4365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * MIMO Locale Definitions - 5 GHz 4375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 4385b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info locale_11n = { 4395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel { /* 12.5 dBm */ 50, 50, 50, QDB(15), QDB(15)}, 4405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel {QDB(14), QDB(15), QDB(15), QDB(15), QDB(15)}, 4415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 0 4425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4445b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info *g_mimo_5g_table[] = { 4455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &locale_11n 4465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 448cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestatic const struct brcms_regd cntry_locales[] = { 449cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee /* Worldwide RoW 2, must always be at index 0 */ 4505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel { 451cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee .country = LOCALES(i, 11, bn, 11n), 452cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee .regdomain = &brcms_regdom_x2, 453cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee }, 4545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel}; 4555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4565b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info *brcms_c_get_locale_2g(u8 locale_idx) 4575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 4585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) 4595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; /* error condition */ 4605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return g_locale_2g_table[locale_idx]; 4625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 4635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4645b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_info *brcms_c_get_locale_5g(u8 locale_idx) 4655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 4665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) 4675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; /* error condition */ 4685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return g_locale_5g_table[locale_idx]; 4705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 4715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4725b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info *brcms_c_get_mimo_2g(u8 locale_idx) 4735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 4745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) 4755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 4765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return g_mimo_2g_table[locale_idx]; 4785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 4795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4805b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic const struct locale_mimo_info *brcms_c_get_mimo_5g(u8 locale_idx) 4815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 4825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) 4835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 4845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 4855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return g_mimo_5g_table[locale_idx]; 4865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 4875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 48894a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel/* 48994a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel * Indicates whether the country provided is valid to pass 49094a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel * to cfg80211 or not. 49194a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel * 49294a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel * returns true if valid; false if not. 49394a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel */ 49494a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Sprielstatic bool brcms_c_country_valid(const char *ccode) 49594a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel{ 49694a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel /* 49794a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel * only allow ascii alpha uppercase for the first 2 49894a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel * chars. 49994a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel */ 50094a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A && 50194a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A && 50294a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel ccode[2] == '\0')) 50394a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel return false; 50494a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel 50594a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel /* 50694a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel * do not match ISO 3166-1 user assigned country codes 50794a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel * that may be in the driver table 50894a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel */ 50994a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel if (!strcmp("AA", ccode) || /* AA */ 51094a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel !strcmp("ZZ", ccode) || /* ZZ */ 51194a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel ccode[0] == 'X' || /* XA - XZ */ 51294a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel (ccode[0] == 'Q' && /* QM - QZ */ 51394a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel (ccode[1] >= 'M' && ccode[1] <= 'Z'))) 51494a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel return false; 51594a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel 51694a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel if (!strcmp("NA", ccode)) 51794a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel return false; 51894a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel 51994a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel return true; 52094a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel} 52194a2ca311cf4154c566cf5c49b88c13cd4cdce73Arend van Spriel 522cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestatic const struct brcms_regd *brcms_world_regd(const char *regdom, int len) 5235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 524cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee const struct brcms_regd *regd = NULL; 525cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee int i; 5265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 527cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee for (i = 0; i < ARRAY_SIZE(cntry_locales); i++) { 528cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!strncmp(regdom, cntry_locales[i].regdomain->alpha2, len)) { 529cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee regd = &cntry_locales[i]; 530cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee break; 531cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 5325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 5335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 534cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee return regd; 5355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 5365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 537cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestatic const struct brcms_regd *brcms_default_world_regd(void) 5385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 539cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee return &cntry_locales[0]; 5405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 5415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 5435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * reset the quiet channels vector to the union 5445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * of the restricted and radar channel sets 5455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 5465b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void brcms_c_quiet_channels_reset(struct brcms_cm_info *wlc_cm) 5475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 5485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 5495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint i, j; 5505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_band *band; 5515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct brcms_chanvec *chanvec; 5525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel memset(&wlc_cm->quiet_channels, 0, sizeof(struct brcms_chanvec)); 5545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel band = wlc->band; 5565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < wlc->pub->_nbands; 5575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { 5585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* initialize quiet channels for restricted channels */ 5605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel chanvec = wlc_cm->bandstate[band->bandunit].restricted_channels; 5615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < sizeof(struct brcms_chanvec); j++) 5625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->quiet_channels.vec[j] |= chanvec->vec[j]; 5635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 5655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 5665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Is the channel valid for the current locale and current band? */ 5685b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_valid_channel20(struct brcms_cm_info *wlc_cm, uint val) 5695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 5705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 5715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return ((val < MAXCHANNEL) && 5735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, 5745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel val)); 5755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 5765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Is the channel valid for the current locale and specified band? */ 5785b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_valid_channel20_in_band(struct brcms_cm_info *wlc_cm, 5795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint bandunit, uint val) 5805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 5815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return ((val < MAXCHANNEL) 5825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel && isset(wlc_cm->bandstate[bandunit].valid_channels.vec, val)); 5835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 5845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Is the channel valid for the current locale? (but don't consider channels not 5865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * available due to bandlocking) 5875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 5885b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_valid_channel20_db(struct brcms_cm_info *wlc_cm, uint val) 5895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 5905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 5915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_valid_channel20(wlc->cmi, val) || 5935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (!wlc->bandlocked 5945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel && brcms_c_valid_channel20_in_band(wlc->cmi, 5955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel OTHERBANDUNIT(wlc), val)); 5965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 5975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 5985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* JP, J1 - J10 are Japan ccodes */ 5995b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool brcms_c_japan_ccode(const char *ccode) 6005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return (ccode[0] == 'J' && 6025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (ccode[1] == 'P' || (ccode[1] >= '1' && ccode[1] <= '9'))); 6035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 6045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6055b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void 6065b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channel_min_txpower_limits_with_local_constraint( 6075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_cm_info *wlc_cm, struct txpwr_limits *txpwr, 6085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 local_constraint_qdbm) 6095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int j; 6115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* CCK Rates */ 6135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < WL_TX_POWER_CCK_NUM; j++) 6145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->cck[j] = min(txpwr->cck[j], local_constraint_qdbm); 6155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20 MHz Legacy OFDM SISO */ 6175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < WL_TX_POWER_OFDM_NUM; j++) 6185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm[j] = min(txpwr->ofdm[j], local_constraint_qdbm); 6195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20 MHz Legacy OFDM CDD */ 6215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) 6225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_cdd[j] = 6235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->ofdm_cdd[j], local_constraint_qdbm); 6245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40 MHz Legacy OFDM SISO */ 6265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) 6275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_siso[j] = 6285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->ofdm_40_siso[j], local_constraint_qdbm); 6295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40 MHz Legacy OFDM CDD */ 6315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_OFDM; j++) 6325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_cdd[j] = 6335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->ofdm_40_cdd[j], local_constraint_qdbm); 6345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20MHz MCS 0-7 SISO */ 6365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 6375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_siso[j] = 6385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_20_siso[j], local_constraint_qdbm); 6395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20MHz MCS 0-7 CDD */ 6415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 6425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_cdd[j] = 6435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_20_cdd[j], local_constraint_qdbm); 6445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20MHz MCS 0-7 STBC */ 6465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 6475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_stbc[j] = 6485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_20_stbc[j], local_constraint_qdbm); 6495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 20MHz MCS 8-15 MIMO */ 6515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) 6525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_mimo[j] = 6535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_20_mimo[j], local_constraint_qdbm); 6545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 0-7 SISO */ 6565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 6575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_siso[j] = 6585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_40_siso[j], local_constraint_qdbm); 6595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 0-7 CDD */ 6615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 6625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_cdd[j] = 6635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_40_cdd[j], local_constraint_qdbm); 6645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 0-7 STBC */ 6665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_1_STREAM; j++) 6675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_stbc[j] = 6685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_40_stbc[j], local_constraint_qdbm); 6695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 8-15 MIMO */ 6715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < BRCMS_NUM_RATES_MCS_2_STREAM; j++) 6725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_mimo[j] = 6735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel min(txpwr->mcs_40_mimo[j], local_constraint_qdbm); 6745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 40MHz MCS 32 */ 6765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs32 = min(txpwr->mcs32, local_constraint_qdbm); 6775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 6795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* Update the radio state (enable/disable) and tx power targets 6815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * based on a new set of channel/regulatory information 6825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 6835b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void brcms_c_channels_commit(struct brcms_cm_info *wlc_cm) 6845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 6855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 6865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint chan; 6875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* search for the existence of any valid channel */ 6895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (chan = 0; chan < MAXCHANNEL; chan++) { 6905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (brcms_c_valid_channel20_db(wlc->cmi, chan)) 6915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel break; 6925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 6935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (chan == MAXCHANNEL) 6945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel chan = INVCHANNEL; 6955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 6965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 6975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * based on the channel search above, set or 6985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * clear WL_RADIO_COUNTRY_DISABLE. 6995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (chan == INVCHANNEL) { 7015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 7025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * country/locale with no valid channels, set 7035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * the radio disable bit 7045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); 7065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wiphy_err(wlc->wiphy, "wl%d: %s: no valid channel for \"%s\" " 7075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel "nbands %d bandlocked %d\n", wlc->pub->unit, 708cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee __func__, wlc_cm->world_regd->regdomain->alpha2, 709cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee wlc->pub->_nbands, wlc->bandlocked); 7105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else if (mboolisset(wlc->pub->radio_disabled, 7115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel WL_RADIO_COUNTRY_DISABLE)) { 7125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 7135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * country/locale with valid channel, clear 7145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * the radio disable bit 7155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel mboolclr(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); 7175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 7185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7205b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic int 7215b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channels_init(struct brcms_cm_info *wlc_cm, 7225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country) 7235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 7245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 7255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint i, j; 7265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_band *band; 7275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_info *li; 7285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_chanvec sup_chan; 7295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_mimo_info *li_mimo; 7305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel band = wlc->band; 7325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < wlc->pub->_nbands; 7335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel i++, band = wlc->bandstate[OTHERBANDUNIT(wlc)]) { 7345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li = (band->bandtype == BRCM_BAND_5G) ? 7365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_locale_5g(country->locale_5G) : 7375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_locale_2g(country->locale_2G); 7385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].locale_flags = li->flags; 7395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li_mimo = (band->bandtype == BRCM_BAND_5G) ? 7405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_mimo_5g(country->locale_mimo_5G) : 7415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_mimo_2g(country->locale_mimo_2G); 7425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* merge the mimo non-mimo locale flags */ 7445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].locale_flags |= 7455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li_mimo->flags; 7465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].restricted_channels = 7485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel g_table_restricted_chan[li->restricted_channels]; 7495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 7515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * set the channel availability, masking out the channels 7525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * that may not be supported on this phy. 7535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_phy_chanspec_band_validch(band->pi, band->bandtype, 7555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &sup_chan); 7565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_locale_get_channels(li, 7575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &wlc_cm->bandstate[band->bandunit]. 7585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel valid_channels); 7595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (j = 0; j < sizeof(struct brcms_chanvec); j++) 7605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->bandstate[band->bandunit].valid_channels. 7615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel vec[j] &= sup_chan.vec[j]; 7625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 7635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_quiet_channels_reset(wlc_cm); 7655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channels_commit(wlc_cm); 7665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return 0; 7685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 7695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 7715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * set the driver's current country and regulatory information 7725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * using a country code as the source. Look up built in country 7735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * information found with the country code. 7745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 7755b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic void 776cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheebrcms_c_set_country(struct brcms_cm_info *wlc_cm, 777cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee const struct brcms_regd *regd) 7785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 779cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee const struct country_info *country = ®d->country; 7805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_info *locale; 7815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 7825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if ((wlc->pub->_n_enab & SUPPORT_11N) != 7845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc->protection->nmode_user) 7855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_set_nmode(wlc); 7865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_2G_INDEX]); 7885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_stf_ss_update(wlc, wlc->bandstate[BAND_5G_INDEX]); 7895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* set or restore gmode as required by regulatory */ 7905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel locale = brcms_c_get_locale_2g(country->locale_2G); 7915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (locale && (locale->flags & BRCMS_NO_OFDM)) 7925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_set_gmode(wlc, GMODE_LEGACY_B, false); 7935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel else 7945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_set_gmode(wlc, wlc->protection->gmode_user, false); 7955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channels_init(wlc_cm, country); 7975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 7985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return; 7995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 8005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8015b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstruct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) 8025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 8035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_cm_info *wlc_cm; 8045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_pub *pub = wlc->pub; 805898d3c3b2462cd439edb575f43b732425693aff0Hauke Mehrtens struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; 806cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee const char *ccode = sprom->alpha2; 807cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee int ccode_len = sizeof(sprom->alpha2); 8085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); 8105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm = kzalloc(sizeof(struct brcms_cm_info), GFP_ATOMIC); 8125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (wlc_cm == NULL) 8135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return NULL; 8145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->pub = pub; 8155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm->wlc = wlc; 8165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc->cmi = wlc_cm; 8175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* store the country code for passing up as a regulatory hint */ 819cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee wlc_cm->world_regd = brcms_world_regd(ccode, ccode_len); 820cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (brcms_c_country_valid(ccode)) 821cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee strncpy(wlc->pub->srom_ccode, ccode, ccode_len); 822cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 823cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee /* 824cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee * If no custom world domain is found in the SROM, use the 825cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee * default "X2" domain. 826cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee */ 827cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!wlc_cm->world_regd) { 828cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee wlc_cm->world_regd = brcms_default_world_regd(); 829cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ccode = wlc_cm->world_regd->regdomain->alpha2; 830cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ccode_len = BRCM_CNTRY_BUF_SZ - 1; 831cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 8325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* save default country for exiting 11d regulatory mode */ 834cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee strncpy(wlc->country_default, ccode, ccode_len); 8355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* initialize autocountry_default to driver default */ 837cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee strncpy(wlc->autocountry_default, ccode, ccode_len); 8385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 839cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee brcms_c_set_country(wlc_cm, wlc_cm->world_regd); 8405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return wlc_cm; 8425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 8435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8445b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid brcms_c_channel_mgr_detach(struct brcms_cm_info *wlc_cm) 8455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 8465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel kfree(wlc_cm); 8475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 8485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8495b435de0d786869c95d1962121af0d7df2542009Arend van Sprielu8 8505b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channel_locale_flags_in_band(struct brcms_cm_info *wlc_cm, 8515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint bandunit) 8525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 8535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return wlc_cm->bandstate[bandunit].locale_flags; 8545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 8555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8565b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool 8575b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_quiet_chanspec(struct brcms_cm_info *wlc_cm, u16 chspec) 8585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 8595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return (wlc_cm->wlc->pub->_n_enab & SUPPORT_11N) && 8605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel CHSPEC_IS40(chspec) ? 8615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (isset(wlc_cm->quiet_channels.vec, 8625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel lower_20_sb(CHSPEC_CHANNEL(chspec))) || 8635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel isset(wlc_cm->quiet_channels.vec, 8645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel upper_20_sb(CHSPEC_CHANNEL(chspec)))) : 8655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel isset(wlc_cm->quiet_channels.vec, CHSPEC_CHANNEL(chspec)); 8665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 8675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8685b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid 8695b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channel_set_chanspec(struct brcms_cm_info *wlc_cm, u16 chanspec, 8705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 local_constraint_qdbm) 8715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 8725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 8735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct txpwr_limits txpwr; 8745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channel_reg_limits(wlc_cm, chanspec, &txpwr); 8765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_channel_min_txpower_limits_with_local_constraint( 8785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc_cm, &txpwr, local_constraint_qdbm 8795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel ); 8805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_b_set_chanspec(wlc->hw, chanspec, 8825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel (brcms_c_quiet_chanspec(wlc_cm, chanspec) != 0), 8835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel &txpwr); 8845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 8855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 8865b435de0d786869c95d1962121af0d7df2542009Arend van Sprielvoid 8875b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_channel_reg_limits(struct brcms_cm_info *wlc_cm, u16 chanspec, 8885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct txpwr_limits *txpwr) 8895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 8905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 8915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint i; 8925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint chan; 8935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int maxpwr; 8945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int delta; 8955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct country_info *country; 8965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_band *band; 8975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_info *li; 8985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int conducted_max = BRCMS_TXPWR_MAX; 8995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int conducted_ofdm_max = BRCMS_TXPWR_MAX; 9005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel const struct locale_mimo_info *li_mimo; 9015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int maxpwr20, maxpwr40; 9025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel int maxpwr_idx; 9035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel uint j; 9045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel memset(txpwr, 0, sizeof(struct txpwr_limits)); 9065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 907cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee country = &wlc_cm->world_regd->country; 9085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel chan = CHSPEC_CHANNEL(chanspec); 9105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel band = wlc->bandstate[chspec_bandunit(chanspec)]; 9115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li = (band->bandtype == BRCM_BAND_5G) ? 9125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_locale_5g(country->locale_5G) : 9135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_locale_2g(country->locale_2G); 9145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel li_mimo = (band->bandtype == BRCM_BAND_5G) ? 9165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_mimo_5g(country->locale_mimo_5G) : 9175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel brcms_c_get_mimo_2g(country->locale_mimo_2G); 9185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li->flags & BRCMS_EIRP) { 9205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = band->antgain; 9215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else { 9225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = 0; 9235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->antgain > QDB(6)) 9245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = band->antgain - QDB(6); /* Excess over 6 dB */ 9255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 9265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li == &locale_i) { 9285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel conducted_max = QDB(22); 9295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel conducted_ofdm_max = QDB(22); 9305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 9315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* CCK txpwr limits for 2.4G band */ 9335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->bandtype == BRCM_BAND_2G) { 9345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_CCK(chan)]; 9355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = maxpwr - delta; 9375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = max(maxpwr, 0); 9385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = min(maxpwr, conducted_max); 9395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_CCK; i++) 9415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->cck[i] = (u8) maxpwr; 9425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 9435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* OFDM txpwr limits for 2.4G or 5G bands */ 9455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->bandtype == BRCM_BAND_2G) 9465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = li->maxpwr[CHANNEL_POWER_IDX_2G_OFDM(chan)]; 9475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel else 9485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = li->maxpwr[CHANNEL_POWER_IDX_5G(chan)]; 9495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = maxpwr - delta; 9515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = max(maxpwr, 0); 9525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = min(maxpwr, conducted_ofdm_max); 9535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Keep OFDM lmit below CCK limit */ 9555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->bandtype == BRCM_BAND_2G) 9565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr = min_t(int, maxpwr, txpwr->cck[0]); 9575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) 9595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm[i] = (u8) maxpwr; 9605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_OFDM; i++) { 9625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 9635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * OFDM 40 MHz SISO has the same power as the corresponding 9645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * MCS0-7 rate unless overriden by the locale specific code. 9655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * We set this value to 0 as a flag (presumably 0 dBm isn't 9665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * a possibility) and then copy the MCS0-7 value to the 40 MHz 9675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * value if it wasn't explicitly set. 9685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 9695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_siso[i] = 0; 9705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_cdd[i] = (u8) maxpwr; 9725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_cdd[i] = 0; 9745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 9755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* MIMO/HT specific limits */ 9775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li_mimo->flags & BRCMS_EIRP) { 9785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = band->antgain; 9795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } else { 9805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = 0; 9815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->antgain > QDB(6)) 9825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel delta = band->antgain - QDB(6); /* Excess over 6 dB */ 9835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 9845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (band->bandtype == BRCM_BAND_2G) 9865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr_idx = (chan - 1); 9875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel else 9885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr_idx = CHANNEL_POWER_IDX_5G(chan); 9895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr20 = li_mimo->maxpwr20[maxpwr_idx]; 9915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = li_mimo->maxpwr40[maxpwr_idx]; 9925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr20 = maxpwr20 - delta; 9945b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr20 = max(maxpwr20, 0); 9955b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = maxpwr40 - delta; 9965b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = max(maxpwr40, 0); 9975b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 9985b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in the MCS 0-7 (SISO) rates */ 9995b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 10005b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10015b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 10025b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * 20 MHz has the same power as the corresponding OFDM rate 10035b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * unless overriden by the locale specific code. 10045b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 10055b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_siso[i] = txpwr->ofdm[i]; 10065b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_siso[i] = 0; 10075b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10085b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10095b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in the MCS 0-7 CDD rates */ 10105b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 10115b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_cdd[i] = (u8) maxpwr20; 10125b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_cdd[i] = (u8) maxpwr40; 10135b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10145b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10155b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 10165b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * These locales have SISO expressed in the 10175b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * table and override CDD later 10185b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 10195b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li_mimo == &locale_bn) { 10205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (li_mimo == &locale_bn) { 10215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr20 = QDB(16); 10225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = 0; 10235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10245b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (chan >= 3 && chan <= 11) 10255b435de0d786869c95d1962121af0d7df2542009Arend van Spriel maxpwr40 = QDB(16); 10265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 10295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_siso[i] = (u8) maxpwr20; 10305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_siso[i] = (u8) maxpwr40; 10315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10325b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in the MCS 0-7 STBC rates */ 10355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 10365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_stbc[i] = 0; 10375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_stbc[i] = 0; 10385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in the MCS 8-15 SDM rates */ 10415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_2_STREAM; i++) { 10425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_mimo[i] = (u8) maxpwr20; 10435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_mimo[i] = (u8) maxpwr40; 10445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Fill in MCS32 */ 10475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs32 = (u8) maxpwr40; 10485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) { 10505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->ofdm_40_cdd[i] == 0) 10515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; 10525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (i == 0) { 10535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel i = i + 1; 10545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->ofdm_40_cdd[i] == 0) 10555b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_cdd[i] = txpwr->mcs_40_cdd[j]; 10565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10595b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 10605b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Copy the 40 MHZ MCS 0-7 CDD value to the 40 MHZ MCS 0-7 SISO 10615b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * value if it wasn't provided explicitly. 10625b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 10635b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 10645b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->mcs_40_siso[i] == 0) 10655b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_siso[i] = txpwr->mcs_40_cdd[i]; 10665b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10675b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10685b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0, j = 0; i < BRCMS_NUM_RATES_OFDM; i++, j++) { 10695b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->ofdm_40_siso[i] == 0) 10705b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; 10715b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (i == 0) { 10725b435de0d786869c95d1962121af0d7df2542009Arend van Spriel i = i + 1; 10735b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->ofdm_40_siso[i] == 0) 10745b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->ofdm_40_siso[i] = txpwr->mcs_40_siso[j]; 10755b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10765b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10775b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10785b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* 10795b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Copy the 20 and 40 MHz MCS0-7 CDD values to the corresponding 10805b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * STBC values if they weren't provided explicitly. 10815b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 10825b435de0d786869c95d1962121af0d7df2542009Arend van Spriel for (i = 0; i < BRCMS_NUM_RATES_MCS_1_STREAM; i++) { 10835b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->mcs_20_stbc[i] == 0) 10845b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_20_stbc[i] = txpwr->mcs_20_cdd[i]; 10855b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10865b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (txpwr->mcs_40_stbc[i] == 0) 10875b435de0d786869c95d1962121af0d7df2542009Arend van Spriel txpwr->mcs_40_stbc[i] = txpwr->mcs_40_cdd[i]; 10885b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 10895b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10905b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return; 10915b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 10925b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 10935b435de0d786869c95d1962121af0d7df2542009Arend van Spriel/* 10943de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers * Verify the chanspec is using a legal set of parameters, i.e. that the 10953de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers * chanspec specified a band, bw, ctl_sb and channel and that the 10963de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers * combination could be legal given any set of circumstances. 10973de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers * RETURNS: true is the chanspec is malformed, false if it looks good. 10983de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers */ 10993de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukersstatic bool brcms_c_chspec_malformed(u16 chanspec) 11003de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers{ 11013de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers /* must be 2G or 5G band */ 11023de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (!CHSPEC_IS5G(chanspec) && !CHSPEC_IS2G(chanspec)) 11033de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return true; 11043de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers /* must be 20 or 40 bandwidth */ 11053de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (!CHSPEC_IS40(chanspec) && !CHSPEC_IS20(chanspec)) 11063de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return true; 11073de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers 11083de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers /* 20MHZ b/w must have no ctl sb, 40 must have a ctl sb */ 11093de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (CHSPEC_IS20(chanspec)) { 11103de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (!CHSPEC_SB_NONE(chanspec)) 11113de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return true; 11123de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers } else if (!CHSPEC_SB_UPPER(chanspec) && !CHSPEC_SB_LOWER(chanspec)) { 11133de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return true; 11143de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers } 11153de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers 11163de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers return false; 11173de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers} 11183de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers 11193de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers/* 11205b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * Validate the chanspec for this locale, for 40MHZ we need to also 11215b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * check that the sidebands are valid 20MZH channels in this locale 11225b435de0d786869c95d1962121af0d7df2542009Arend van Spriel * and they are also a legal HT combination 11235b435de0d786869c95d1962121af0d7df2542009Arend van Spriel */ 11245b435de0d786869c95d1962121af0d7df2542009Arend van Sprielstatic bool 11255b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbrcms_c_valid_chanspec_ext(struct brcms_cm_info *wlc_cm, u16 chspec, 11265b435de0d786869c95d1962121af0d7df2542009Arend van Spriel bool dualband) 11275b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 11285b435de0d786869c95d1962121af0d7df2542009Arend van Spriel struct brcms_c_info *wlc = wlc_cm->wlc; 11295b435de0d786869c95d1962121af0d7df2542009Arend van Spriel u8 channel = CHSPEC_CHANNEL(chspec); 11305b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11315b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* check the chanspec */ 11323de67818e7e7ef95c8f7eac665dd29454c07b48bAlwin Beukers if (brcms_c_chspec_malformed(chspec)) { 11335b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wiphy_err(wlc->wiphy, "wl%d: malformed chanspec 0x%x\n", 11345b435de0d786869c95d1962121af0d7df2542009Arend van Spriel wlc->pub->unit, chspec); 11355b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 11365b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 11375b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11385b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (CHANNEL_BANDUNIT(wlc_cm->wlc, channel) != 11395b435de0d786869c95d1962121af0d7df2542009Arend van Spriel chspec_bandunit(chspec)) 11405b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 11415b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11425b435de0d786869c95d1962121af0d7df2542009Arend van Spriel /* Check a 20Mhz channel */ 11435b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (CHSPEC_IS20(chspec)) { 11445b435de0d786869c95d1962121af0d7df2542009Arend van Spriel if (dualband) 11455b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_valid_channel20_db(wlc_cm->wlc->cmi, 11465b435de0d786869c95d1962121af0d7df2542009Arend van Spriel channel); 11475b435de0d786869c95d1962121af0d7df2542009Arend van Spriel else 11485b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_valid_channel20(wlc_cm->wlc->cmi, 11495b435de0d786869c95d1962121af0d7df2542009Arend van Spriel channel); 11505b435de0d786869c95d1962121af0d7df2542009Arend van Spriel } 11515b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11525b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return false; 11535b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 11545b435de0d786869c95d1962121af0d7df2542009Arend van Spriel 11555b435de0d786869c95d1962121af0d7df2542009Arend van Sprielbool brcms_c_valid_chanspec_db(struct brcms_cm_info *wlc_cm, u16 chspec) 11565b435de0d786869c95d1962121af0d7df2542009Arend van Spriel{ 11575b435de0d786869c95d1962121af0d7df2542009Arend van Spriel return brcms_c_valid_chanspec_ext(wlc_cm, chspec, true); 11585b435de0d786869c95d1962121af0d7df2542009Arend van Spriel} 1159cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1160cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestatic bool brcms_is_radar_freq(u16 center_freq) 1161cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee{ 1162cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee return center_freq >= 5260 && center_freq <= 5700; 1163cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee} 1164cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1165cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestatic void brcms_reg_apply_radar_flags(struct wiphy *wiphy) 1166cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee{ 1167cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct ieee80211_supported_band *sband; 1168cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct ieee80211_channel *ch; 1169cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee int i; 1170cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1171cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee sband = wiphy->bands[IEEE80211_BAND_5GHZ]; 1172cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!sband) 1173cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee return; 1174cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1175cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee for (i = 0; i < sband->n_channels; i++) { 1176cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ch = &sband->channels[i]; 1177cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1178cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!brcms_is_radar_freq(ch->center_freq)) 1179cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee continue; 1180cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1181cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee /* 1182cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee * All channels in this range should be passive and have 1183cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee * DFS enabled. 1184cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee */ 1185cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!(ch->flags & IEEE80211_CHAN_DISABLED)) 1186cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ch->flags |= IEEE80211_CHAN_RADAR | 1187cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee IEEE80211_CHAN_NO_IBSS | 1188cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee IEEE80211_CHAN_PASSIVE_SCAN; 1189cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 1190cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee} 1191cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1192cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestatic void 1193cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheebrcms_reg_apply_beaconing_flags(struct wiphy *wiphy, 1194cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee enum nl80211_reg_initiator initiator) 1195cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee{ 1196cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct ieee80211_supported_band *sband; 1197cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct ieee80211_channel *ch; 1198cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee const struct ieee80211_reg_rule *rule; 1199cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee int band, i, ret; 1200cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1201cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1202cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee sband = wiphy->bands[band]; 1203cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!sband) 1204cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee continue; 1205cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1206cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee for (i = 0; i < sband->n_channels; i++) { 1207cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ch = &sband->channels[i]; 1208cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1209cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (ch->flags & 1210cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_RADAR)) 1211cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee continue; 1212cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1213cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { 1214cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ret = freq_reg_info(wiphy, ch->center_freq, 1215cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 0, &rule); 1216cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (ret) 1217cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee continue; 1218cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1219cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!(rule->flags & NL80211_RRF_NO_IBSS)) 1220cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ch->flags &= ~IEEE80211_CHAN_NO_IBSS; 1221cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!(rule->flags & NL80211_RRF_PASSIVE_SCAN)) 1222cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ch->flags &= 1223cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ~IEEE80211_CHAN_PASSIVE_SCAN; 1224cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } else if (ch->beacon_found) { 1225cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | 1226cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee IEEE80211_CHAN_PASSIVE_SCAN); 1227cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 1228cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 1229cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 1230cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee} 1231cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1232cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheestatic int brcms_reg_notifier(struct wiphy *wiphy, 1233cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct regulatory_request *request) 1234cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee{ 1235cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); 1236cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct brcms_info *wl = hw->priv; 1237cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct brcms_c_info *wlc = wl->wlc; 1238cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1239cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee brcms_reg_apply_radar_flags(wiphy); 1240cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1241cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) 1242cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee brcms_reg_apply_beaconing_flags(wiphy, request->initiator); 1243cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1244cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (wlc->pub->_nbands > 1 || wlc->band->bandtype == BRCM_BAND_2G) 1245cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee wlc_phy_chanspec_ch14_widefilter_set(wlc->band->pi, 1246cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee brcms_c_japan_ccode(request->alpha2)); 1247cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1248cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee return 0; 1249cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee} 1250cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1251cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forsheevoid brcms_c_regd_init(struct brcms_c_info *wlc) 1252cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee{ 1253cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct wiphy *wiphy = wlc->wiphy; 1254cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee const struct brcms_regd *regd = wlc->cmi->world_regd; 1255cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct ieee80211_supported_band *sband; 1256cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct ieee80211_channel *ch; 1257cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct brcms_chanvec sup_chan; 1258cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee struct brcms_band *band; 1259cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee int band_idx, i; 1260cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1261cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee /* Disable any channels not supported by the phy */ 1262cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee for (band_idx = 0; band_idx < IEEE80211_NUM_BANDS; band_idx++) { 1263cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (band_idx == IEEE80211_BAND_2GHZ) 1264cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee band = wlc->bandstate[BAND_2G_INDEX]; 1265cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee else 1266cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee band = wlc->bandstate[BAND_5G_INDEX]; 1267cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee wlc_phy_chanspec_band_validch(band->pi, band->bandtype, 1268cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee &sup_chan); 1269cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1270cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee sband = wiphy->bands[band_idx]; 1271cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee for (i = 0; i < sband->n_channels; i++) { 1272cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ch = &sband->channels[i]; 1273cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee if (!isset(sup_chan.vec, ch->hw_value)) 1274cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee ch->flags |= IEEE80211_CHAN_DISABLED; 1275cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 1276cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee } 1277cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee 1278cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee wlc->wiphy->reg_notifier = brcms_reg_notifier; 1279cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee wlc->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 1280cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee WIPHY_FLAG_STRICT_REGULATORY; 1281cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee wiphy_apply_custom_regulatory(wlc->wiphy, regd->regdomain); 1282cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee brcms_reg_apply_beaconing_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER); 1283cf03c5dac83609f09d9f0e9fa3c09d86daed614dSeth Forshee} 1284