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