提交 5f8e077c 编写于 作者: L Luis R. Rodriguez 提交者: John W. Linville

ath9k: simplify regulatory code

Now that cfg80211 has its own regulatory infrastructure we can
condense ath9k's regulatory code considerably. We only keep data
we need to provide our own regulatory_hint(), reg_notifier() and
information necessary for calibration.

Atheros hardware supports 12 world regulatory domains, since these
are custom we apply them through the the new wiphy_apply_custom_regulatory().
Although we have 12 we can consolidate these into 5 structures based on
frequency and apply a different set of flags that differentiate them on
a case by case basis through the reg_notifier().

If CRDA is not found our own custom world regulatory domain is applied,
this is identical to cfg80211's except we enable passive scan on most
frequencies.
Signed-off-by: NLuis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: NJohn W. Linville <linville@tuxdriver.com>
上级 24ed1da1
...@@ -457,22 +457,12 @@ struct ath9k_channel { ...@@ -457,22 +457,12 @@ struct ath9k_channel {
struct ieee80211_channel *chan; struct ieee80211_channel *chan;
u16 channel; u16 channel;
u32 channelFlags; u32 channelFlags;
u8 privFlags;
int8_t maxRegTxPower;
int8_t maxTxPower;
int8_t minTxPower;
u32 chanmode; u32 chanmode;
int32_t CalValid; int32_t CalValid;
bool oneTimeCalsDone; bool oneTimeCalsDone;
int8_t iCoff; int8_t iCoff;
int8_t qCoff; int8_t qCoff;
int16_t rawNoiseFloor; int16_t rawNoiseFloor;
int8_t antennaMax;
u32 regDmnFlags;
u32 conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */
#ifdef ATH_NF_PER_CHAN
struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
#endif
}; };
#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \ #define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
...@@ -500,7 +490,6 @@ struct ath9k_channel { ...@@ -500,7 +490,6 @@ struct ath9k_channel {
((_c)->chanmode == CHANNEL_G_HT40MINUS)) ((_c)->chanmode == CHANNEL_G_HT40MINUS))
#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c))) #define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)
#define IS_CHAN_A_5MHZ_SPACED(_c) \ #define IS_CHAN_A_5MHZ_SPACED(_c) \
((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \ ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
(((_c)->channel % 20) != 0) && \ (((_c)->channel % 20) != 0) && \
...@@ -790,15 +779,13 @@ struct ath_hal { ...@@ -790,15 +779,13 @@ struct ath_hal {
u16 ah_currentRD; u16 ah_currentRD;
u16 ah_currentRDExt; u16 ah_currentRDExt;
u16 ah_currentRDInUse; u16 ah_currentRDInUse;
u16 ah_currentRD5G; char alpha2[2];
u16 ah_currentRD2G; struct reg_dmn_pair_mapping *regpair;
char ah_iso[4];
enum ath9k_power_mode ah_power_mode; enum ath9k_power_mode ah_power_mode;
enum ath9k_power_mode ah_restore_mode; enum ath9k_power_mode ah_restore_mode;
struct ath9k_channel ah_channels[150]; struct ath9k_channel ah_channels[38];
struct ath9k_channel *ah_curchan; struct ath9k_channel *ah_curchan;
u32 ah_nchan;
bool ah_isPciExpress; bool ah_isPciExpress;
u16 ah_txTrigLevel; u16 ah_txTrigLevel;
...@@ -807,10 +794,7 @@ struct ath_hal { ...@@ -807,10 +794,7 @@ struct ath_hal {
u32 ah_rfkill_polarity; u32 ah_rfkill_polarity;
u32 ah_btactive_gpio; u32 ah_btactive_gpio;
u32 ah_wlanactive_gpio; u32 ah_wlanactive_gpio;
#ifndef ATH_NF_PER_CHAN
struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS]; struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
#endif
bool sw_mgmt_crypto; bool sw_mgmt_crypto;
}; };
...@@ -825,8 +809,6 @@ struct ath_rate_table; ...@@ -825,8 +809,6 @@ struct ath_rate_table;
/* Helpers */ /* Helpers */
enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
const struct ath9k_channel *chan);
bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val); bool ath9k_hw_wait(struct ath_hal *ah, u32 reg, u32 mask, u32 val);
u32 ath9k_hw_reverse_bits(u32 val, u32 n); u32 ath9k_hw_reverse_bits(u32 val, u32 n);
bool ath9k_get_channel_edges(struct ath_hal *ah, bool ath9k_get_channel_edges(struct ath_hal *ah,
...@@ -836,7 +818,6 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah, ...@@ -836,7 +818,6 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah,
struct ath_rate_table *rates, struct ath_rate_table *rates,
u32 frameLen, u16 rateix, u32 frameLen, u16 rateix,
bool shortPreamble); bool shortPreamble);
u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
void ath9k_hw_get_channel_centers(struct ath_hal *ah, void ath9k_hw_get_channel_centers(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
struct chan_centers *centers); struct chan_centers *centers);
...@@ -924,17 +905,18 @@ bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us); ...@@ -924,17 +905,18 @@ bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode); void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
/* Regulatory */ /* Regulatory */
u16 ath9k_regd_get_rd(struct ath_hal *ah);
bool ath9k_is_world_regd(struct ath_hal *ah);
const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah);
const struct ieee80211_regdomain *ath9k_default_world_regdomain(void);
void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby);
void ath9k_reg_apply_radar_flags(struct wiphy *wiphy);
bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah); int ath9k_regd_init(struct ath_hal *ah);
struct ath9k_channel* ath9k_regd_check_channel(struct ath_hal *ah, bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah);
const struct ath9k_channel *c);
u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan); u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah, int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request);
struct ath9k_channel *chan);
bool ath9k_regd_init_channels(struct ath_hal *ah,
u32 maxchans, u32 *nchans, u8 *regclassids,
u32 maxregids, u32 *nregids, u16 cc,
bool enableOutdoor, bool enableExtendedChannels);
/* ANI */ /* ANI */
......
...@@ -625,11 +625,7 @@ void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan) ...@@ -625,11 +625,7 @@ void ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
else else
chainmask = 0x3F; chainmask = 0x3F;
#ifdef ATH_NF_PER_CHAN
h = chan->nfCalHist;
#else
h = ah->nfCalHist; h = ah->nfCalHist;
#endif
for (i = 0; i < NUM_NF_READINGS; i++) { for (i = 0; i < NUM_NF_READINGS; i++) {
if (chainmask & (1 << i)) { if (chainmask & (1 << i)) {
...@@ -697,11 +693,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah, ...@@ -697,11 +693,7 @@ int16_t ath9k_hw_getnf(struct ath_hal *ah,
} }
} }
#ifdef ATH_NF_PER_CHAN
h = chan->nfCalHist;
#else
h = ah->nfCalHist; h = ah->nfCalHist;
#endif
ath9k_hw_update_nfcal_hist_buffer(h, nfarray); ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
chan->rawNoiseFloor = h[0].privNF; chan->rawNoiseFloor = h[0].privNF;
...@@ -728,20 +720,12 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah) ...@@ -728,20 +720,12 @@ void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan) s16 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
{ {
struct ath9k_channel *ichan;
s16 nf; s16 nf;
ichan = ath9k_regd_check_channel(ah, chan); if (chan->rawNoiseFloor == 0)
if (ichan == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
"invalid channel %u/0x%x; no mapping\n",
chan->channel, chan->channelFlags);
return ATH_DEFAULT_NOISE_FLOOR;
}
if (ichan->rawNoiseFloor == 0)
nf = -96; nf = -96;
else else
nf = ichan->rawNoiseFloor; nf = chan->rawNoiseFloor;
if (!ath9k_hw_nf_in_range(ah, nf)) if (!ath9k_hw_nf_in_range(ah, nf))
nf = ATH_DEFAULT_NOISE_FLOOR; nf = ATH_DEFAULT_NOISE_FLOOR;
...@@ -755,21 +739,13 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, ...@@ -755,21 +739,13 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
struct hal_cal_list *currCal = ahp->ah_cal_list_curr; struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
*isCalDone = true; *isCalDone = true;
if (ichan == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"invalid channel %u/0x%x; no mapping\n",
chan->channel, chan->channelFlags);
return false;
}
if (currCal && if (currCal &&
(currCal->calState == CAL_RUNNING || (currCal->calState == CAL_RUNNING ||
currCal->calState == CAL_WAITING)) { currCal->calState == CAL_WAITING)) {
ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal, ath9k_hw_per_calibration(ah, chan, rxchainmask, currCal,
isCalDone); isCalDone);
if (*isCalDone) { if (*isCalDone) {
ahp->ah_cal_list_curr = currCal = currCal->calNext; ahp->ah_cal_list_curr = currCal = currCal->calNext;
...@@ -782,14 +758,12 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan, ...@@ -782,14 +758,12 @@ bool ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
} }
if (longcal) { if (longcal) {
ath9k_hw_getnf(ah, ichan); ath9k_hw_getnf(ah, chan);
ath9k_hw_loadnf(ah, ah->ah_curchan); ath9k_hw_loadnf(ah, ah->ah_curchan);
ath9k_hw_start_nfcal(ah); ath9k_hw_start_nfcal(ah);
if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) { if (chan->channelFlags & CHANNEL_CW_INT)
chan->channelFlags |= CHANNEL_CW_INT; chan->channelFlags &= ~CHANNEL_CW_INT;
ichan->channelFlags &= ~CHANNEL_CW_INT;
}
} }
return true; return true;
...@@ -894,7 +868,6 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, ...@@ -894,7 +868,6 @@ bool ath9k_hw_init_cal(struct ath_hal *ah,
struct ath9k_channel *chan) struct ath9k_channel *chan)
{ {
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
struct ath9k_channel *ichan = ath9k_regd_check_channel(ah, chan);
REG_WRITE(ah, AR_PHY_AGC_CONTROL, REG_WRITE(ah, AR_PHY_AGC_CONTROL,
REG_READ(ah, AR_PHY_AGC_CONTROL) | REG_READ(ah, AR_PHY_AGC_CONTROL) |
...@@ -942,7 +915,7 @@ bool ath9k_hw_init_cal(struct ath_hal *ah, ...@@ -942,7 +915,7 @@ bool ath9k_hw_init_cal(struct ath_hal *ah,
ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr); ath9k_hw_reset_calibration(ah, ahp->ah_cal_list_curr);
} }
ichan->CalValid = 0; chan->CalValid = 0;
return true; return true;
} }
......
...@@ -724,7 +724,6 @@ struct ath_softc { ...@@ -724,7 +724,6 @@ struct ath_softc {
struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX]; struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX]; struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
struct ath_rate_table *cur_rate_table; struct ath_rate_table *cur_rate_table;
struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
struct ath_led radio_led; struct ath_led radio_led;
struct ath_led assoc_led; struct ath_led assoc_led;
......
...@@ -187,46 +187,6 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah, ...@@ -187,46 +187,6 @@ u16 ath9k_hw_computetxtime(struct ath_hal *ah,
return txTime; return txTime;
} }
u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
{
if (flags & CHANNEL_2GHZ) {
if (freq == 2484)
return 14;
if (freq < 2484)
return (freq - 2407) / 5;
else
return 15 + ((freq - 2512) / 20);
} else if (flags & CHANNEL_5GHZ) {
if (ath9k_regd_is_public_safety_sku(ah) &&
IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
return ((freq * 10) +
(((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
} else if ((flags & CHANNEL_A) && (freq <= 5000)) {
return (freq - 4000) / 5;
} else {
return (freq - 5000) / 5;
}
} else {
if (freq == 2484)
return 14;
if (freq < 2484)
return (freq - 2407) / 5;
if (freq < 5000) {
if (ath9k_regd_is_public_safety_sku(ah)
&& IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
return ((freq * 10) +
(((freq % 5) ==
2) ? 5 : 0) - 49400) / 5;
} else if (freq > 4900) {
return (freq - 4000) / 5;
} else {
return 15 + ((freq - 2512) / 20);
}
}
return (freq - 5000) / 5;
}
}
void ath9k_hw_get_channel_centers(struct ath_hal *ah, void ath9k_hw_get_channel_centers(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
struct chan_centers *centers) struct chan_centers *centers)
...@@ -1270,6 +1230,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, ...@@ -1270,6 +1230,7 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
{ {
int i, regWrites = 0; int i, regWrites = 0;
struct ath_hal_5416 *ahp = AH5416(ah); struct ath_hal_5416 *ahp = AH5416(ah);
struct ieee80211_channel *channel = chan->chan;
u32 modesIndex, freqIndex; u32 modesIndex, freqIndex;
int status; int status;
...@@ -1374,9 +1335,8 @@ static int ath9k_hw_process_ini(struct ath_hal *ah, ...@@ -1374,9 +1335,8 @@ static int ath9k_hw_process_ini(struct ath_hal *ah,
status = ath9k_hw_set_txpower(ah, chan, status = ath9k_hw_set_txpower(ah, chan,
ath9k_regd_get_ctl(ah, chan), ath9k_regd_get_ctl(ah, chan),
ath9k_regd_get_antenna_allowed(ah, channel->max_antenna_gain * 2,
chan), channel->max_power * 2,
chan->maxRegTxPower * 2,
min((u32) MAX_RATE_POWER, min((u32) MAX_RATE_POWER,
(u32) ah->ah_powerLimit)); (u32) ah->ah_powerLimit));
if (status != 0) { if (status != 0) {
...@@ -1669,6 +1629,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, ...@@ -1669,6 +1629,7 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
struct ath9k_channel *chan, struct ath9k_channel *chan,
enum ath9k_ht_macmode macmode) enum ath9k_ht_macmode macmode)
{ {
struct ieee80211_channel *channel = chan->chan;
u32 synthDelay, qnum; u32 synthDelay, qnum;
for (qnum = 0; qnum < AR_NUM_QCU; qnum++) { for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
...@@ -1705,8 +1666,8 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah, ...@@ -1705,8 +1666,8 @@ static bool ath9k_hw_channel_change(struct ath_hal *ah,
if (ath9k_hw_set_txpower(ah, chan, if (ath9k_hw_set_txpower(ah, chan,
ath9k_regd_get_ctl(ah, chan), ath9k_regd_get_ctl(ah, chan),
ath9k_regd_get_antenna_allowed(ah, chan), channel->max_antenna_gain * 2,
chan->maxRegTxPower * 2, channel->max_power * 2,
min((u32) MAX_RATE_POWER, min((u32) MAX_RATE_POWER,
(u32) ah->ah_powerLimit)) != 0) { (u32) ah->ah_powerLimit)) != 0) {
DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
...@@ -2209,13 +2170,6 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan, ...@@ -2209,13 +2170,6 @@ int ath9k_hw_reset(struct ath_hal *ah, struct ath9k_channel *chan,
ahp->ah_rxchainmask &= 0x3; ahp->ah_rxchainmask &= 0x3;
} }
if (ath9k_regd_check_channel(ah, chan) == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
"invalid channel %u/0x%x; no mapping\n",
chan->channel, chan->channelFlags);
return -EINVAL;
}
if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
return -EIO; return -EIO;
...@@ -3718,13 +3672,14 @@ bool ath9k_hw_disable(struct ath_hal *ah) ...@@ -3718,13 +3672,14 @@ bool ath9k_hw_disable(struct ath_hal *ah)
bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit) bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
{ {
struct ath9k_channel *chan = ah->ah_curchan; struct ath9k_channel *chan = ah->ah_curchan;
struct ieee80211_channel *channel = chan->chan;
ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER); ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
if (ath9k_hw_set_txpower(ah, chan, if (ath9k_hw_set_txpower(ah, chan,
ath9k_regd_get_ctl(ah, chan), ath9k_regd_get_ctl(ah, chan),
ath9k_regd_get_antenna_allowed(ah, chan), channel->max_antenna_gain * 2,
chan->maxRegTxPower * 2, channel->max_power * 2,
min((u32) MAX_RATE_POWER, min((u32) MAX_RATE_POWER,
(u32) ah->ah_powerLimit)) != 0) (u32) ah->ah_powerLimit)) != 0)
return false; return false;
......
...@@ -28,6 +28,77 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards."); ...@@ -28,6 +28,77 @@ MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards"); MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
/* We use the hw_value as an index into our private channel structure */
#define CHAN2G(_freq, _idx) { \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 30, \
}
#define CHAN5G(_freq, _idx) { \
.band = IEEE80211_BAND_5GHZ, \
.center_freq = (_freq), \
.hw_value = (_idx), \
.max_power = 30, \
}
/* Some 2 GHz radios are actually tunable on 2312-2732
* on 5 MHz steps, we support the channels which we know
* we have calibration data for all cards though to make
* this static */
static struct ieee80211_channel ath9k_2ghz_chantable[] = {
CHAN2G(2412, 0), /* Channel 1 */
CHAN2G(2417, 1), /* Channel 2 */
CHAN2G(2422, 2), /* Channel 3 */
CHAN2G(2427, 3), /* Channel 4 */
CHAN2G(2432, 4), /* Channel 5 */
CHAN2G(2437, 5), /* Channel 6 */
CHAN2G(2442, 6), /* Channel 7 */
CHAN2G(2447, 7), /* Channel 8 */
CHAN2G(2452, 8), /* Channel 9 */
CHAN2G(2457, 9), /* Channel 10 */
CHAN2G(2462, 10), /* Channel 11 */
CHAN2G(2467, 11), /* Channel 12 */
CHAN2G(2472, 12), /* Channel 13 */
CHAN2G(2484, 13), /* Channel 14 */
};
/* Some 5 GHz radios are actually tunable on XXXX-YYYY
* on 5 MHz steps, we support the channels which we know
* we have calibration data for all cards though to make
* this static */
static struct ieee80211_channel ath9k_5ghz_chantable[] = {
/* _We_ call this UNII 1 */
CHAN5G(5180, 14), /* Channel 36 */
CHAN5G(5200, 15), /* Channel 40 */
CHAN5G(5220, 16), /* Channel 44 */
CHAN5G(5240, 17), /* Channel 48 */
/* _We_ call this UNII 2 */
CHAN5G(5260, 18), /* Channel 52 */
CHAN5G(5280, 19), /* Channel 56 */
CHAN5G(5300, 20), /* Channel 60 */
CHAN5G(5320, 21), /* Channel 64 */
/* _We_ call this "Middle band" */
CHAN5G(5500, 22), /* Channel 100 */
CHAN5G(5520, 23), /* Channel 104 */
CHAN5G(5540, 24), /* Channel 108 */
CHAN5G(5560, 25), /* Channel 112 */
CHAN5G(5580, 26), /* Channel 116 */
CHAN5G(5600, 27), /* Channel 120 */
CHAN5G(5620, 28), /* Channel 124 */
CHAN5G(5640, 29), /* Channel 128 */
CHAN5G(5660, 30), /* Channel 132 */
CHAN5G(5680, 31), /* Channel 136 */
CHAN5G(5700, 32), /* Channel 140 */
/* _We_ call this UNII 3 */
CHAN5G(5745, 33), /* Channel 149 */
CHAN5G(5765, 34), /* Channel 153 */
CHAN5G(5785, 35), /* Channel 157 */
CHAN5G(5805, 36), /* Channel 161 */
CHAN5G(5825, 37), /* Channel 165 */
};
static void ath_cache_conf_rate(struct ath_softc *sc, static void ath_cache_conf_rate(struct ath_softc *sc,
struct ieee80211_conf *conf) struct ieee80211_conf *conf)
{ {
...@@ -152,75 +223,6 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band) ...@@ -152,75 +223,6 @@ static void ath_setup_rates(struct ath_softc *sc, enum ieee80211_band band)
} }
} }
static int ath_setup_channels(struct ath_softc *sc)
{
struct ath_hal *ah = sc->sc_ah;
int nchan, i, a = 0, b = 0;
u8 regclassids[ATH_REGCLASSIDS_MAX];
u32 nregclass = 0;
struct ieee80211_supported_band *band_2ghz;
struct ieee80211_supported_band *band_5ghz;
struct ieee80211_channel *chan_2ghz;
struct ieee80211_channel *chan_5ghz;
struct ath9k_channel *c;
/* Fill in ah->ah_channels */
if (!ath9k_regd_init_channels(ah, ATH_CHAN_MAX, (u32 *)&nchan,
regclassids, ATH_REGCLASSIDS_MAX,
&nregclass, CTRY_DEFAULT, false, 1)) {
u32 rd = ah->ah_currentRD;
DPRINTF(sc, ATH_DBG_FATAL,
"Unable to collect channel list; "
"regdomain likely %u country code %u\n",
rd, CTRY_DEFAULT);
return -EINVAL;
}
band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ];
chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ];
for (i = 0; i < nchan; i++) {
c = &ah->ah_channels[i];
if (IS_CHAN_2GHZ(c)) {
chan_2ghz[a].band = IEEE80211_BAND_2GHZ;
chan_2ghz[a].center_freq = c->channel;
chan_2ghz[a].max_power = c->maxTxPower;
c->chan = &chan_2ghz[a];
if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
chan_2ghz[a].flags |= IEEE80211_CHAN_NO_IBSS;
if (c->channelFlags & CHANNEL_PASSIVE)
chan_2ghz[a].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
band_2ghz->n_channels = ++a;
DPRINTF(sc, ATH_DBG_CONFIG, "2MHz channel: %d, "
"channelFlags: 0x%x\n",
c->channel, c->channelFlags);
} else if (IS_CHAN_5GHZ(c)) {
chan_5ghz[b].band = IEEE80211_BAND_5GHZ;
chan_5ghz[b].center_freq = c->channel;
chan_5ghz[b].max_power = c->maxTxPower;
c->chan = &chan_5ghz[a];
if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
chan_5ghz[b].flags |= IEEE80211_CHAN_NO_IBSS;
if (c->channelFlags & CHANNEL_PASSIVE)
chan_5ghz[b].flags |= IEEE80211_CHAN_PASSIVE_SCAN;
band_5ghz->n_channels = ++b;
DPRINTF(sc, ATH_DBG_CONFIG, "5MHz channel: %d, "
"channelFlags: 0x%x\n",
c->channel, c->channelFlags);
}
}
return 0;
}
/* /*
* Set/change channels. If the channel is really being changed, it's done * Set/change channels. If the channel is really being changed, it's done
* by reseting the chip. To accomplish this we must first cleanup any pending * by reseting the chip. To accomplish this we must first cleanup any pending
...@@ -582,19 +584,6 @@ irqreturn_t ath_isr(int irq, void *dev) ...@@ -582,19 +584,6 @@ irqreturn_t ath_isr(int irq, void *dev)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
static int ath_get_channel(struct ath_softc *sc,
struct ieee80211_channel *chan)
{
int i;
for (i = 0; i < sc->sc_ah->ah_nchan; i++) {
if (sc->sc_ah->ah_channels[i].channel == chan->center_freq)
return i;
}
return -1;
}
static u32 ath_get_extchanmode(struct ath_softc *sc, static u32 ath_get_extchanmode(struct ath_softc *sc,
struct ieee80211_channel *chan, struct ieee80211_channel *chan,
enum nl80211_channel_type channel_type) enum nl80211_channel_type channel_type)
...@@ -1349,16 +1338,12 @@ static int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1349,16 +1338,12 @@ static int ath_init(u16 devid, struct ath_softc *sc)
for (i = 0; i < sc->sc_keymax; i++) for (i = 0; i < sc->sc_keymax; i++)
ath9k_hw_keyreset(ah, (u16) i); ath9k_hw_keyreset(ah, (u16) i);
/* Collect the channel list using the default country code */ if (ath9k_regd_init(sc->sc_ah))
error = ath_setup_channels(sc);
if (error)
goto bad; goto bad;
/* default to MONITOR mode */ /* default to MONITOR mode */
sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR; sc->sc_ah->ah_opmode = NL80211_IFTYPE_MONITOR;
/* Setup rate tables */ /* Setup rate tables */
ath_rate_attach(sc); ath_rate_attach(sc);
...@@ -1490,18 +1475,20 @@ static int ath_init(u16 devid, struct ath_softc *sc) ...@@ -1490,18 +1475,20 @@ static int ath_init(u16 devid, struct ath_softc *sc)
/* setup channels and rates */ /* setup channels and rates */
sc->sbands[IEEE80211_BAND_2GHZ].channels = sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
sc->channels[IEEE80211_BAND_2GHZ];
sc->sbands[IEEE80211_BAND_2GHZ].bitrates = sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
sc->rates[IEEE80211_BAND_2GHZ]; sc->rates[IEEE80211_BAND_2GHZ];
sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ; sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
ARRAY_SIZE(ath9k_2ghz_chantable);
if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) { if (test_bit(ATH9K_MODE_11A, sc->sc_ah->ah_caps.wireless_modes)) {
sc->sbands[IEEE80211_BAND_5GHZ].channels = sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
sc->channels[IEEE80211_BAND_5GHZ];
sc->sbands[IEEE80211_BAND_5GHZ].bitrates = sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
sc->rates[IEEE80211_BAND_5GHZ]; sc->rates[IEEE80211_BAND_5GHZ];
sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ; sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
ARRAY_SIZE(ath9k_5ghz_chantable);
} }
if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX) if (sc->sc_ah->ah_caps.hw_caps & ATH9K_HW_CAP_BT_COEX)
...@@ -1550,6 +1537,9 @@ int ath_attach(u16 devid, struct ath_softc *sc) ...@@ -1550,6 +1537,9 @@ int ath_attach(u16 devid, struct ath_softc *sc)
BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC); BIT(NL80211_IFTYPE_ADHOC);
hw->wiphy->reg_notifier = ath9k_reg_notifier;
hw->wiphy->strict_regulatory = true;
hw->queues = 4; hw->queues = 4;
hw->max_rates = 4; hw->max_rates = 4;
hw->max_rate_tries = ATH_11N_TXMAXTRY; hw->max_rate_tries = ATH_11N_TXMAXTRY;
...@@ -1588,11 +1578,36 @@ int ath_attach(u16 devid, struct ath_softc *sc) ...@@ -1588,11 +1578,36 @@ int ath_attach(u16 devid, struct ath_softc *sc)
goto detach; goto detach;
#endif #endif
if (ath9k_is_world_regd(sc->sc_ah)) {
/* Anything applied here (prior to wiphy registratoin) gets
* saved on the wiphy orig_* parameters */
const struct ieee80211_regdomain *regd =
ath9k_world_regdomain(sc->sc_ah);
hw->wiphy->custom_regulatory = true;
hw->wiphy->strict_regulatory = false;
wiphy_apply_custom_regulatory(sc->hw->wiphy, regd);
ath9k_reg_apply_radar_flags(hw->wiphy);
ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT);
} else {
/* This gets applied in the case of the absense of CRDA,
* its our own custom world regulatory domain, similar to
* cfg80211's but we enable passive scanning */
const struct ieee80211_regdomain *regd =
ath9k_default_world_regdomain();
wiphy_apply_custom_regulatory(sc->hw->wiphy, regd);
ath9k_reg_apply_radar_flags(hw->wiphy);
ath9k_reg_apply_world_flags(hw->wiphy, REGDOM_SET_BY_INIT);
}
error = ieee80211_register_hw(hw); error = ieee80211_register_hw(hw);
if (!ath9k_is_world_regd(sc->sc_ah))
regulatory_hint(hw->wiphy, sc->sc_ah->alpha2);
/* Initialize LED control */ /* Initialize LED control */
ath_init_leds(sc); ath_init_leds(sc);
return 0; return 0;
detach: detach:
ath_detach(sc); ath_detach(sc);
...@@ -1818,6 +1833,37 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc) ...@@ -1818,6 +1833,37 @@ int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
return qnum; return qnum;
} }
/* XXX: Remove me once we don't depend on ath9k_channel for all
* this redundant data */
static void ath9k_update_ichannel(struct ath_softc *sc,
struct ath9k_channel *ichan)
{
struct ieee80211_hw *hw = sc->hw;
struct ieee80211_channel *chan = hw->conf.channel;
struct ieee80211_conf *conf = &hw->conf;
ichan->channel = chan->center_freq;
ichan->chan = chan;
if (chan->band == IEEE80211_BAND_2GHZ) {
ichan->chanmode = CHANNEL_G;
ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
} else {
ichan->chanmode = CHANNEL_A;
ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
}
sc->tx_chan_width = ATH9K_HT_MACMODE_20;
if (conf_is_ht(conf)) {
if (conf_is_ht40(conf))
sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
ichan->chanmode = ath_get_extchanmode(sc, chan,
conf->channel_type);
}
}
/**********************/ /**********************/
/* mac80211 callbacks */ /* mac80211 callbacks */
/**********************/ /**********************/
...@@ -1834,16 +1880,10 @@ static int ath9k_start(struct ieee80211_hw *hw) ...@@ -1834,16 +1880,10 @@ static int ath9k_start(struct ieee80211_hw *hw)
/* setup initial channel */ /* setup initial channel */
pos = ath_get_channel(sc, curchan); pos = curchan->hw_value;
if (pos == -1) {
DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n", curchan->center_freq);
return -EINVAL;
}
sc->tx_chan_width = ATH9K_HT_MACMODE_20;
sc->sc_ah->ah_channels[pos].chanmode =
(curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
init_channel = &sc->sc_ah->ah_channels[pos]; init_channel = &sc->sc_ah->ah_channels[pos];
ath9k_update_ichannel(sc, init_channel);
/* Reset SERDES registers */ /* Reset SERDES registers */
ath9k_hw_configpcipowersave(sc->sc_ah, 0); ath9k_hw_configpcipowersave(sc->sc_ah, 0);
...@@ -2127,32 +2167,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed) ...@@ -2127,32 +2167,13 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
struct ieee80211_channel *curchan = hw->conf.channel; struct ieee80211_channel *curchan = hw->conf.channel;
int pos; int pos = curchan->hw_value;
DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n", DPRINTF(sc, ATH_DBG_CONFIG, "Set channel: %d MHz\n",
curchan->center_freq); curchan->center_freq);
pos = ath_get_channel(sc, curchan); /* XXX: remove me eventualy */
if (pos == -1) { ath9k_update_ichannel(sc, &sc->sc_ah->ah_channels[pos]);
DPRINTF(sc, ATH_DBG_FATAL, "Invalid channel: %d\n",
curchan->center_freq);
mutex_unlock(&sc->mutex);
return -EINVAL;
}
sc->tx_chan_width = ATH9K_HT_MACMODE_20;
sc->sc_ah->ah_channels[pos].chanmode =
(curchan->band == IEEE80211_BAND_2GHZ) ?
CHANNEL_G : CHANNEL_A;
if (conf_is_ht(conf)) {
if (conf_is_ht40(conf))
sc->tx_chan_width = ATH9K_HT_MACMODE_2040;
sc->sc_ah->ah_channels[pos].chanmode =
ath_get_extchanmode(sc, curchan,
conf->channel_type);
}
ath_update_chainmask(sc, conf_is_ht(conf)); ath_update_chainmask(sc, conf_is_ht(conf));
......
...@@ -21,174 +21,323 @@ ...@@ -21,174 +21,323 @@
#include "regd.h" #include "regd.h"
#include "regd_common.h" #include "regd_common.h"
static int ath9k_regd_chansort(const void *a, const void *b) /*
{ * This is a set of common rules used by our world regulatory domains.
const struct ath9k_channel *ca = a; * We have 12 world regulatory domains. To save space we consolidate
const struct ath9k_channel *cb = b; * the regulatory domains in 5 structures by frequency and change
* the flags on our reg_notifier() on a case by case basis.
return (ca->channel == cb->channel) ? */
(ca->channelFlags & CHAN_FLAGS) -
(cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel;
}
static void /* Only these channels all allow active scan on all world regulatory domains */
ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp) #define ATH9K_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
{
u8 *aa = a; /* We enable active scan on these a case by case basis by regulatory domain */
u8 *ai, *t; #define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\
NL80211_RRF_PASSIVE_SCAN)
for (ai = aa + size; --n >= 1; ai += size) #define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\
for (t = ai; t > aa; t -= size) { NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
u8 *u = t - size;
if (cmp(u, t) <= 0) /* We allow IBSS on these on a case by case basis by regulatory domain */
break; #define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 40, 0, 30,\
swap_array(u, t, size); NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
} #define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\
} NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 40, 0, 30,\
NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \
ATH9K_2GHZ_CH12_13, \
ATH9K_2GHZ_CH14
#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \
ATH9K_5GHZ_5470_5850
/* This one skips what we call "mid band" */
#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
ATH9K_5GHZ_5725_5850
/* Can be used for:
* 0x60, 0x61, 0x62 */
static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = {
.n_reg_rules = 5,
.alpha2 = "99",
.reg_rules = {
ATH9K_2GHZ_ALL,
ATH9K_5GHZ_ALL,
}
};
/* Can be used by 0x63 and 0x65 */
static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
ATH9K_2GHZ_CH01_11,
ATH9K_2GHZ_CH12_13,
ATH9K_5GHZ_NO_MIDBAND,
}
};
/* Can be used by 0x64 only */
static const struct ieee80211_regdomain ath9k_world_regdom_64 = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
ATH9K_2GHZ_CH01_11,
ATH9K_5GHZ_NO_MIDBAND,
}
};
/* Can be used by 0x66 and 0x69 */
static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = {
.n_reg_rules = 3,
.alpha2 = "99",
.reg_rules = {
ATH9K_2GHZ_CH01_11,
ATH9K_5GHZ_ALL,
}
};
/* Can be used by 0x67, 0x6A and 0x68 */
static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = {
.n_reg_rules = 4,
.alpha2 = "99",
.reg_rules = {
ATH9K_2GHZ_CH01_11,
ATH9K_2GHZ_CH12_13,
ATH9K_5GHZ_ALL,
}
};
static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah) static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah)
{ {
return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG; return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG;
} }
static bool ath9k_regd_is_chan_bm_zero(u64 *bitmask) u16 ath9k_regd_get_rd(struct ath_hal *ah)
{ {
int i; return ath9k_regd_get_eepromRD(ah);
}
for (i = 0; i < BMLEN; i++) { bool ath9k_is_world_regd(struct ath_hal *ah)
if (bitmask[i] != 0) {
return false; return isWwrSKU(ah);
}
return true;
} }
static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
{ {
u16 rd = ath9k_regd_get_eepromRD(ah); /* this is the most restrictive */
int i; return &ath9k_world_regdom_64;
}
if (rd & COUNTRY_ERD_FLAG) { const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah)
u16 cc = rd & ~COUNTRY_ERD_FLAG; {
for (i = 0; i < ARRAY_SIZE(allCountries); i++) switch (ah->regpair->regDmnEnum) {
if (allCountries[i].countryCode == cc) case 0x60:
return true; case 0x61:
} else { case 0x62:
for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) return &ath9k_world_regdom_60_61_62;
if (regDomainPairs[i].regDmnEnum == rd) case 0x63:
return true; case 0x65:
return &ath9k_world_regdom_63_65;
case 0x64:
return &ath9k_world_regdom_64;
case 0x66:
case 0x69:
return &ath9k_world_regdom_66_69;
case 0x67:
case 0x68:
case 0x6A:
return &ath9k_world_regdom_67_68_6A;
default:
WARN_ON(1);
return ath9k_default_world_regdomain();
} }
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"invalid regulatory domain/country code 0x%x\n", rd);
return false;
} }
static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah) /* Enable adhoc on 5 GHz if allowed by 11d */
static void ath9k_reg_apply_5ghz_adhoc_flags(struct wiphy *wiphy,
enum reg_set_by setby)
{ {
u32 regcap; struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath_softc *sc = hw->priv;
regcap = ah->ah_caps.reg_cap; struct ieee80211_supported_band *sband;
const struct ieee80211_reg_rule *reg_rule;
struct ieee80211_channel *ch;
unsigned int i;
u32 bandwidth = 0;
int r;
if (setby != REGDOM_SET_BY_COUNTRY_IE)
return;
if (!test_bit(ATH9K_MODE_11A,
sc->sc_ah->ah_caps.wireless_modes))
return;
if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND) sband = wiphy->bands[IEEE80211_BAND_5GHZ];
return true; for (i = 0; i < sband->n_channels; i++) {
else ch = &sband->channels[i];
return false; r = freq_reg_info(wiphy, ch->center_freq,
&bandwidth, &reg_rule);
if (r)
continue;
/* If 11d had a rule for this channel ensure we enable adhoc
* if it allows us to use it. Note that we would have disabled
* it by applying our static world regdomain by default during
* probe */
if (!(reg_rule->flags & NL80211_RRF_NO_IBSS))
ch->flags &= ~NL80211_RRF_NO_IBSS;
}
} }
static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, /* Allows active scan scan on Ch 12 and 13 */
u16 cc) static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy,
enum reg_set_by setby)
{ {
u16 rd; struct ieee80211_supported_band *sband;
int i; struct ieee80211_channel *ch;
const struct ieee80211_reg_rule *reg_rule;
if (cc == CTRY_DEFAULT) u32 bandwidth = 0;
return true; int r;
if (cc == CTRY_DEBUG)
return true; /* Force passive scan on Channels 12-13 */
sband = wiphy->bands[IEEE80211_BAND_2GHZ];
/* If no country IE has been received always enable active scan
* on these channels */
if (setby != REGDOM_SET_BY_COUNTRY_IE) {
ch = &sband->channels[11]; /* CH 12 */
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
ch = &sband->channels[12]; /* CH 13 */
if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
return;
}
rd = ath9k_regd_get_eepromRD(ah); /* If a country IE has been recieved check its rule for this
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd); * channel first before enabling active scan. The passive scan
* would have been enforced by the initial probe processing on
* our custom regulatory domain. */
if (rd & COUNTRY_ERD_FLAG) { ch = &sband->channels[11]; /* CH 12 */
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
"EEPROM setting is country code %u\n", if (!r) {
rd & ~COUNTRY_ERD_FLAG); if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
return cc == (rd & ~COUNTRY_ERD_FLAG); if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
} }
for (i = 0; i < ARRAY_SIZE(allCountries); i++) { ch = &sband->channels[12]; /* CH 13 */
if (cc == allCountries[i].countryCode) { r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, &reg_rule);
#ifdef AH_SUPPORT_11D if (!r) {
if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
return true; if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
#endif ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
if (allCountries[i].regDmnEnum == rd ||
rd == DEBUG_REG_DMN || rd == NO_ENUMRD)
return true;
}
} }
return false;
} }
static void /* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, void ath9k_reg_apply_radar_flags(struct wiphy *wiphy)
struct country_code_to_enum_rd *country,
struct regDomain *rd5GHz,
unsigned long *modes_allowed)
{ {
bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX); struct ieee80211_supported_band *sband;
struct ieee80211_channel *ch;
unsigned int i;
if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) && if (!wiphy->bands[IEEE80211_BAND_5GHZ])
(!country->allow11g)) return;
clear_bit(ATH9K_MODE_11G, modes_allowed);
if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) && sband = wiphy->bands[IEEE80211_BAND_5GHZ];
(ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a)))
clear_bit(ATH9K_MODE_11A, modes_allowed);
if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes) for (i = 0; i < sband->n_channels; i++) {
&& (!country->allow11ng20)) ch = &sband->channels[i];
clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed); if (ch->center_freq < 5260)
continue;
if (ch->center_freq > 5700)
continue;
/* We always enable radar detection/DFS on this
* frequency range. Additionally we also apply on
* this frequency range:
* - If STA mode does not yet have DFS supports disable
* active scanning
* - If adhoc mode does not support DFS yet then
* disable adhoc in the frequency.
* - If AP mode does not yet support radar detection/DFS
* do not allow AP mode
*/
if (!(ch->flags & IEEE80211_CHAN_DISABLED))
ch->flags |= IEEE80211_CHAN_RADAR |
IEEE80211_CHAN_NO_IBSS |
IEEE80211_CHAN_PASSIVE_SCAN;
}
}
if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes) void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby)
&& (!country->allow11na20)) {
clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed); struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath_softc *sc = hw->priv;
struct ath_hal *ah = sc->sc_ah;
switch (ah->regpair->regDmnEnum) {
case 0x60:
case 0x63:
case 0x66:
case 0x67:
ath9k_reg_apply_5ghz_adhoc_flags(wiphy, setby);
break;
case 0x68:
ath9k_reg_apply_5ghz_adhoc_flags(wiphy, setby);
ath9k_reg_apply_active_scan_flags(wiphy, setby);
break;
}
return;
}
if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) && int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
(!country->allow11ng40)) {
clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed); struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
struct ath_softc *sc = hw->priv;
if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) && /* We always apply this */
(!country->allow11ng40)) ath9k_reg_apply_radar_flags(wiphy);
clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed);
if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) && switch (request->initiator) {
(!country->allow11na40)) case REGDOM_SET_BY_DRIVER:
clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed); case REGDOM_SET_BY_INIT:
case REGDOM_SET_BY_CORE:
case REGDOM_SET_BY_USER:
break;
case REGDOM_SET_BY_COUNTRY_IE:
if (ath9k_is_world_regd(sc->sc_ah))
ath9k_reg_apply_world_flags(wiphy, request->initiator);
break;
}
if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) && return 0;
(!country->allow11na40))
clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed);
} }
bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah)
{ {
u16 rd; u16 rd = ath9k_regd_get_eepromRD(ah);
int i;
rd = ath9k_regd_get_eepromRD(ah);
switch (rd) { if (rd & COUNTRY_ERD_FLAG) {
case FCC4_FCCA: /* EEPROM value is a country code */
case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG): u16 cc = rd & ~COUNTRY_ERD_FLAG;
return true; for (i = 0; i < ARRAY_SIZE(allCountries); i++)
case DEBUG_REG_DMN: if (allCountries[i].countryCode == cc)
case NO_ENUMRD: return true;
if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49) } else {
return true; /* EEPROM value is a regpair value */
break; for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
if (regDomainPairs[i].regDmnEnum == rd)
return true;
} }
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"invalid regulatory domain/country code 0x%x\n", rd);
return false; return false;
} }
/* EEPROM country code to regpair mapping */
static struct country_code_to_enum_rd* static struct country_code_to_enum_rd*
ath9k_regd_find_country(u16 countryCode) ath9k_regd_find_country(u16 countryCode)
{ {
...@@ -201,10 +350,23 @@ ath9k_regd_find_country(u16 countryCode) ...@@ -201,10 +350,23 @@ ath9k_regd_find_country(u16 countryCode)
return NULL; return NULL;
} }
/* EEPROM rd code to regpair mapping */
static struct country_code_to_enum_rd*
ath9k_regd_find_country_by_rd(int regdmn)
{
int i;
for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
if (allCountries[i].regDmnEnum == regdmn)
return &allCountries[i];
}
return NULL;
}
/* Returns the map of the EEPROM set RD to a country code */
static u16 ath9k_regd_get_default_country(struct ath_hal *ah) static u16 ath9k_regd_get_default_country(struct ath_hal *ah)
{ {
u16 rd; u16 rd;
int i;
rd = ath9k_regd_get_eepromRD(ah); rd = ath9k_regd_get_eepromRD(ah);
if (rd & COUNTRY_ERD_FLAG) { if (rd & COUNTRY_ERD_FLAG) {
...@@ -216,798 +378,104 @@ static u16 ath9k_regd_get_default_country(struct ath_hal *ah) ...@@ -216,798 +378,104 @@ static u16 ath9k_regd_get_default_country(struct ath_hal *ah)
return cc; return cc;
} }
for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
if (regDomainPairs[i].regDmnEnum == rd) {
if (regDomainPairs[i].singleCC != 0)
return regDomainPairs[i].singleCC;
else
i = ARRAY_SIZE(regDomainPairs);
}
return CTRY_DEFAULT; return CTRY_DEFAULT;
} }
static bool ath9k_regd_is_valid_reg_domain(int regDmn, static struct reg_dmn_pair_mapping*
struct regDomain *rd) ath9k_get_regpair(int regdmn)
{
int i;
for (i = 0; i < ARRAY_SIZE(regDomains); i++) {
if (regDomains[i].regDmnEnum == regDmn) {
if (rd != NULL) {
memcpy(rd, &regDomains[i],
sizeof(struct regDomain));
}
return true;
}
}
return false;
}
static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair)
{ {
int i; int i;
if (regDmnPair == NO_ENUMRD) if (regdmn == NO_ENUMRD)
return false; return NULL;
for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
if (regDomainPairs[i].regDmnEnum == regDmnPair) if (regDomainPairs[i].regDmnEnum == regdmn)
return true; return &regDomainPairs[i];
} }
return false; return NULL;
}
static bool
ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
u16 channelFlag, struct regDomain *rd)
{
int i, found;
u64 flags = NO_REQ;
struct reg_dmn_pair_mapping *regPair = NULL;
int regOrg;
regOrg = regDmn;
if (regDmn == CTRY_DEFAULT) {
u16 rdnum;
rdnum = ath9k_regd_get_eepromRD(ah);
if (!(rdnum & COUNTRY_ERD_FLAG)) {
if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) ||
ath9k_regd_is_valid_reg_domainPair(rdnum)) {
regDmn = rdnum;
}
}
}
if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
for (i = 0, found = 0;
(i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) {
if (regDomainPairs[i].regDmnEnum == regDmn) {
regPair = &regDomainPairs[i];
found = 1;
}
}
if (!found) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Failed to find reg domain pair %u\n", regDmn);
return false;
}
if (!(channelFlag & CHANNEL_2GHZ)) {
regDmn = regPair->regDmn5GHz;
flags = regPair->flags5GHz;
}
if (channelFlag & CHANNEL_2GHZ) {
regDmn = regPair->regDmn2GHz;
flags = regPair->flags2GHz;
}
}
found = ath9k_regd_is_valid_reg_domain(regDmn, rd);
if (!found) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Failed to find unitary reg domain %u\n", regDmn);
return false;
} else {
rd->pscan &= regPair->pscanMask;
if (((regOrg & MULTI_DOMAIN_MASK) == 0) &&
(flags != NO_REQ)) {
rd->flags = flags;
}
rd->flags &= (channelFlag & CHANNEL_2GHZ) ?
REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK;
return true;
}
}
static bool ath9k_regd_is_bit_set(int bit, u64 *bitmask)
{
int byteOffset, bitnum;
u64 val;
byteOffset = bit / 64;
bitnum = bit - byteOffset * 64;
val = ((u64) 1) << bitnum;
if (bitmask[byteOffset] & val)
return true;
else
return false;
}
static void
ath9k_regd_add_reg_classid(u8 *regclassids, u32 maxregids,
u32 *nregids, u8 regclassid)
{
int i;
if (regclassid == 0)
return;
for (i = 0; i < maxregids; i++) {
if (regclassids[i] == regclassid)
return;
if (regclassids[i] == 0)
break;
}
if (i == maxregids)
return;
else {
regclassids[i] = regclassid;
*nregids += 1;
}
return;
}
static bool
ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah,
enum reg_ext_bitmap bit)
{
return (ah->ah_currentRDExt & (1 << bit)) ? true : false;
}
#ifdef ATH_NF_PER_CHAN
static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans,
int nchans)
{
int i, j, next;
for (next = 0; next < nchans; next++) {
for (i = 0; i < NUM_NF_READINGS; i++) {
ichans[next].nfCalHist[i].currIndex = 0;
ichans[next].nfCalHist[i].privNF =
AR_PHY_CCA_MAX_GOOD_VALUE;
ichans[next].nfCalHist[i].invalidNFcount =
AR_PHY_CCA_FILTERWINDOW_LENGTH;
for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
ichans[next].nfCalHist[i].nfCalBuffer[j] =
AR_PHY_CCA_MAX_GOOD_VALUE;
}
}
}
}
#endif
static int ath9k_regd_is_chan_present(struct ath_hal *ah,
u16 c)
{
int i;
for (i = 0; i < 150; i++) {
if (!ah->ah_channels[i].channel)
return -1;
else if (ah->ah_channels[i].channel == c)
return i;
}
return -1;
}
static bool
ath9k_regd_add_channel(struct ath_hal *ah,
u16 c,
u16 c_lo,
u16 c_hi,
u16 maxChan,
u8 ctl,
int pos,
struct regDomain rd5GHz,
struct RegDmnFreqBand *fband,
struct regDomain *rd,
const struct cmode *cm,
struct ath9k_channel *ichans,
bool enableExtendedChannels)
{
struct ath9k_channel *chan;
int ret;
u32 channelFlags = 0;
u8 privFlags = 0;
if (!(c_lo <= c && c <= c_hi)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"c %u out of range [%u..%u]\n",
c, c_lo, c_hi);
return false;
}
if ((fband->channelBW == CHANNEL_HALF_BW) &&
!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping %u half rate channel\n", c);
return false;
}
if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
!(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping %u quarter rate channel\n", c);
return false;
}
if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"c %u > maxChan %u\n", c, maxChan);
return false;
}
if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping ecm channel\n");
return false;
}
if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping HOSTAP channel\n");
return false;
}
if (IS_HT40_MODE(cm->mode) &&
!(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) &&
(fband->useDfs) &&
(rd->conformanceTestLimit != MKK)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n");
return false;
}
if (IS_HT40_MODE(cm->mode) &&
!(ath9k_regd_get_eeprom_reg_ext_bits(ah,
REG_EXT_JAPAN_NONDFS_HT40)) &&
!(fband->useDfs) && (rd->conformanceTestLimit == MKK)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping HT40 channel (en_jap_ht40 = 0)\n");
return false;
}
if (IS_HT40_MODE(cm->mode) &&
!(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) &&
(fband->useDfs) &&
(rd->conformanceTestLimit == MKK)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n");
return false;
}
/* Calculate channel flags */
channelFlags = cm->flags;
switch (fband->channelBW) {
case CHANNEL_HALF_BW:
channelFlags |= CHANNEL_HALF;
break;
case CHANNEL_QUARTER_BW:
channelFlags |= CHANNEL_QUARTER;
break;
}
if (fband->usePassScan & rd->pscan)
channelFlags |= CHANNEL_PASSIVE;
else
channelFlags &= ~CHANNEL_PASSIVE;
if (fband->useDfs & rd->dfsMask)
privFlags = CHANNEL_DFS;
else
privFlags = 0;
if (rd->flags & LIMIT_FRAME_4MS)
privFlags |= CHANNEL_4MS_LIMIT;
if (privFlags & CHANNEL_DFS)
privFlags |= CHANNEL_DISALLOW_ADHOC;
if (rd->flags & ADHOC_PER_11D)
privFlags |= CHANNEL_PER_11D_ADHOC;
if (channelFlags & CHANNEL_PASSIVE) {
if ((c < 2412) || (c > 2462)) {
if (rd5GHz.regDmnEnum == MKK1 ||
rd5GHz.regDmnEnum == MKK2) {
u32 regcap = ah->ah_caps.reg_cap;
if (!(regcap &
(AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
AR_EEPROM_EEREGCAP_EN_KK_U2 |
AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) &&
isUNII1OddChan(c)) {
channelFlags &= ~CHANNEL_PASSIVE;
} else {
privFlags |= CHANNEL_DISALLOW_ADHOC;
}
} else {
privFlags |= CHANNEL_DISALLOW_ADHOC;
}
}
}
if ((cm->mode == ATH9K_MODE_11A) ||
(cm->mode == ATH9K_MODE_11NA_HT20) ||
(cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
(cm->mode == ATH9K_MODE_11NA_HT40MINUS)) {
if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
privFlags |= CHANNEL_DISALLOW_ADHOC;
}
/* Fill in channel details */
ret = ath9k_regd_is_chan_present(ah, c);
if (ret == -1) {
chan = &ah->ah_channels[pos];
chan->channel = c;
chan->maxRegTxPower = fband->powerDfs;
chan->antennaMax = fband->antennaMax;
chan->regDmnFlags = rd->flags;
chan->maxTxPower = AR5416_MAX_RATE_POWER;
chan->minTxPower = AR5416_MAX_RATE_POWER;
chan->channelFlags = channelFlags;
chan->privFlags = privFlags;
} else {
chan = &ah->ah_channels[ret];
chan->channelFlags |= channelFlags;
chan->privFlags |= privFlags;
}
/* Set CTLs */
if ((cm->flags & CHANNEL_ALL) == CHANNEL_A)
chan->conformanceTestLimit[0] = ctl;
else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B)
chan->conformanceTestLimit[1] = ctl;
else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G)
chan->conformanceTestLimit[2] = ctl;
return (ret == -1) ? true : false;
}
static bool ath9k_regd_japan_check(struct ath_hal *ah,
int b,
struct regDomain *rd5GHz)
{
bool skipband = false;
int i;
u32 regcap;
for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) {
if (j_bandcheck[i].freqbandbit == b) {
regcap = ah->ah_caps.reg_cap;
if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) {
skipband = true;
} else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) ||
(regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) {
rd5GHz->dfsMask |= DFS_MKK4;
rd5GHz->pscan |= PSCAN_MKK3;
}
break;
}
}
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Skipping %d freq band\n", j_bandcheck[i].freqbandbit);
return skipband;
} }
bool int ath9k_regd_init(struct ath_hal *ah)
ath9k_regd_init_channels(struct ath_hal *ah,
u32 maxchans,
u32 *nchans, u8 *regclassids,
u32 maxregids, u32 *nregids, u16 cc,
bool enableOutdoor,
bool enableExtendedChannels)
{ {
u16 maxChan = 7000;
struct country_code_to_enum_rd *country = NULL; struct country_code_to_enum_rd *country = NULL;
struct regDomain rd5GHz, rd2GHz;
const struct cmode *cm;
struct ath9k_channel *ichans = &ah->ah_channels[0];
int next = 0, b;
u8 ctl;
int regdmn; int regdmn;
u16 chanSep;
unsigned long *modes_avail;
DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX);
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc,
enableOutdoor ? "Enable outdoor" : "",
enableExtendedChannels ? "Enable ecm" : "");
if (!ath9k_regd_is_ccode_valid(ah, cc)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Invalid country code %d\n", cc);
return false;
}
if (!ath9k_regd_is_eeprom_valid(ah)) { if (!ath9k_regd_is_eeprom_valid(ah)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Invalid EEPROM contents\n"); "Invalid EEPROM contents\n");
return false; return -EINVAL;
} }
ah->ah_countryCode = ath9k_regd_get_default_country(ah); ah->ah_countryCode = ath9k_regd_get_default_country(ah);
if (ah->ah_countryCode == CTRY_DEFAULT) { if (ah->ah_countryCode == CTRY_DEFAULT &&
ah->ah_countryCode = cc & COUNTRY_CODE_MASK; ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)
if ((ah->ah_countryCode == CTRY_DEFAULT) && ah->ah_countryCode = CTRY_UNITED_STATES;
(ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) {
ah->ah_countryCode = CTRY_UNITED_STATES;
}
}
#ifdef AH_SUPPORT_11D
if (ah->ah_countryCode == CTRY_DEFAULT) { if (ah->ah_countryCode == CTRY_DEFAULT) {
regdmn = ath9k_regd_get_eepromRD(ah); regdmn = ath9k_regd_get_eepromRD(ah);
country = NULL; country = NULL;
} else { } else {
#endif
country = ath9k_regd_find_country(ah->ah_countryCode); country = ath9k_regd_find_country(ah->ah_countryCode);
if (country == NULL) { if (country == NULL) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Country is NULL!!!!, cc= %d\n", "Country is NULL!!!!, cc= %d\n",
ah->ah_countryCode); ah->ah_countryCode);
return false; return -EINVAL;
} else { } else
regdmn = country->regDmnEnum; regdmn = country->regDmnEnum;
#ifdef AH_SUPPORT_11D
if (((ath9k_regd_get_eepromRD(ah) &
WORLD_SKU_MASK) == WORLD_SKU_PREFIX) &&
(cc == CTRY_UNITED_STATES)) {
if (!isWwrSKU_NoMidband(ah)
&& ath9k_regd_is_fcc_midband_supported(ah))
regdmn = FCC3_FCCA;
else
regdmn = FCC1_FCCA;
}
#endif
}
#ifdef AH_SUPPORT_11D
}
#endif
if (!ath9k_regd_get_wmode_regdomain(ah,
regdmn,
~CHANNEL_2GHZ,
&rd5GHz)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Couldn't find unitary "
"5GHz reg domain for country %u\n",
ah->ah_countryCode);
return false;
}
if (!ath9k_regd_get_wmode_regdomain(ah,
regdmn,
CHANNEL_2GHZ,
&rd2GHz)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Couldn't find unitary 2GHz "
"reg domain for country %u\n",
ah->ah_countryCode);
return false;
} }
if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) || ah->ah_currentRDInUse = regdmn;
(rd5GHz.regDmnEnum == FCC2))) { ah->regpair = ath9k_get_regpair(regdmn);
if (ath9k_regd_is_fcc_midband_supported(ah)) {
if (!ath9k_regd_get_wmode_regdomain(ah,
FCC3_FCCA,
~CHANNEL_2GHZ,
&rd5GHz)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Couldn't find unitary 5GHz "
"reg domain for country %u\n",
ah->ah_countryCode);
return false;
}
}
}
if (country == NULL) {
modes_avail = ah->ah_caps.wireless_modes;
} else {
ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed);
modes_avail = modes_allowed;
if (!enableOutdoor)
maxChan = country->outdoorChanStart;
}
next = 0;
if (maxchans > ARRAY_SIZE(ah->ah_channels))
maxchans = ARRAY_SIZE(ah->ah_channels);
for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) {
u16 c, c_hi, c_lo;
u64 *channelBM = NULL;
struct regDomain *rd = NULL;
struct RegDmnFreqBand *fband = NULL, *freqs;
int8_t low_adj = 0, hi_adj = 0;
if (!test_bit(cm->mode, modes_avail)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"!avail mode %d flags 0x%x\n",
cm->mode, cm->flags);
continue;
}
if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"channels 0x%x not supported "
"by hardware\n", cm->flags);
continue;
}
switch (cm->mode) {
case ATH9K_MODE_11A:
case ATH9K_MODE_11NA_HT20:
case ATH9K_MODE_11NA_HT40PLUS:
case ATH9K_MODE_11NA_HT40MINUS:
rd = &rd5GHz;
channelBM = rd->chan11a;
freqs = &regDmn5GhzFreq[0];
ctl = rd->conformanceTestLimit;
break;
case ATH9K_MODE_11B:
rd = &rd2GHz;
channelBM = rd->chan11b;
freqs = &regDmn2GhzFreq[0];
ctl = rd->conformanceTestLimit | CTL_11B;
break;
case ATH9K_MODE_11G:
case ATH9K_MODE_11NG_HT20:
case ATH9K_MODE_11NG_HT40PLUS:
case ATH9K_MODE_11NG_HT40MINUS:
rd = &rd2GHz;
channelBM = rd->chan11g;
freqs = &regDmn2Ghz11gFreq[0];
ctl = rd->conformanceTestLimit | CTL_11G;
break;
default:
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"Unknown HAL mode 0x%x\n", cm->mode);
continue;
}
if (ath9k_regd_is_chan_bm_zero(channelBM))
continue;
if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) ||
(cm->mode == ATH9K_MODE_11NG_HT40PLUS)) {
hi_adj = -20;
}
if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) ||
(cm->mode == ATH9K_MODE_11NG_HT40MINUS)) {
low_adj = 20;
}
/* XXX: Add a helper here instead */
for (b = 0; b < 64 * BMLEN; b++) {
if (ath9k_regd_is_bit_set(b, channelBM)) {
fband = &freqs[b];
if (rd5GHz.regDmnEnum == MKK1
|| rd5GHz.regDmnEnum == MKK2) {
if (ath9k_regd_japan_check(ah,
b,
&rd5GHz))
continue;
}
ath9k_regd_add_reg_classid(regclassids,
maxregids,
nregids,
fband->
regClassId);
if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) {
chanSep = 40;
if (fband->lowChannel == 5280)
low_adj += 20;
if (fband->lowChannel == 5170)
continue;
} else
chanSep = fband->channelSep;
for (c = fband->lowChannel + low_adj;
((c <= (fband->highChannel + hi_adj)) &&
(c >= (fband->lowChannel + low_adj)));
c += chanSep) {
if (next >= maxchans) {
DPRINTF(ah->ah_sc,
ATH_DBG_REGULATORY,
"too many channels "
"for channel table\n");
goto done;
}
if (ath9k_regd_add_channel(ah,
c, c_lo, c_hi,
maxChan, ctl,
next,
rd5GHz,
fband, rd, cm,
ichans,
enableExtendedChannels))
next++;
}
if (IS_HT40_MODE(cm->mode) &&
(fband->lowChannel == 5280)) {
low_adj -= 20;
}
}
}
}
done:
if (next != 0) {
int i;
if (next > ARRAY_SIZE(ah->ah_channels)) { if (!ah->regpair) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
"too many channels %u; truncating to %u\n", "No regulatory domain pair found, cannot continue\n");
next, (int) ARRAY_SIZE(ah->ah_channels)); return -EINVAL;
next = ARRAY_SIZE(ah->ah_channels);
}
#ifdef ATH_NF_PER_CHAN
ath9k_regd_init_rf_buffer(ichans, next);
#endif
ath9k_regd_sort(ichans, next,
sizeof(struct ath9k_channel),
ath9k_regd_chansort);
ah->ah_nchan = next;
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n");
for (i = 0; i < next; i++) {
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"chan: %d flags: 0x%x\n",
ah->ah_channels[i].channel,
ah->ah_channels[i].channelFlags);
}
} }
*nchans = next;
ah->ah_countryCode = ah->ah_countryCode; if (!country)
country = ath9k_regd_find_country_by_rd(regdmn);
ah->ah_currentRDInUse = regdmn; if (country) {
ah->ah_currentRD5G = rd5GHz.regDmnEnum; ah->alpha2[0] = country->isoName[0];
ah->ah_currentRD2G = rd2GHz.regDmnEnum; ah->alpha2[1] = country->isoName[1];
if (country == NULL) {
ah->ah_iso[0] = 0;
ah->ah_iso[1] = 0;
} else { } else {
ah->ah_iso[0] = country->isoName[0]; ah->alpha2[0] = '0';
ah->ah_iso[1] = country->isoName[1]; ah->alpha2[1] = '0';
} }
return next != 0;
}
struct ath9k_channel*
ath9k_regd_check_channel(struct ath_hal *ah,
const struct ath9k_channel *c)
{
struct ath9k_channel *base, *cc;
int flags = c->channelFlags & CHAN_FLAGS;
int n, lim;
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"channel %u/0x%x (0x%x) requested\n", "Country alpha2 being used: %c%c\n",
c->channel, c->channelFlags, flags); "Regpair detected: 0x%0x\n",
ah->alpha2[0], ah->alpha2[1],
cc = ah->ah_curchan; ah->regpair->regDmnEnum);
if (cc != NULL && cc->channel == c->channel &&
(cc->channelFlags & CHAN_FLAGS) == flags) {
if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
(cc->privFlags & CHANNEL_DFS))
return NULL;
else
return cc;
}
base = ah->ah_channels; return 0;
n = ah->ah_nchan;
for (lim = n; lim != 0; lim >>= 1) {
int d;
cc = &base[lim >> 1];
d = c->channel - cc->channel;
if (d == 0) {
if ((cc->channelFlags & CHAN_FLAGS) == flags) {
if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
(cc->privFlags & CHANNEL_DFS))
return NULL;
else
return cc;
}
d = flags - (cc->channelFlags & CHAN_FLAGS);
}
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
"channel %u/0x%x d %d\n",
cc->channel, cc->channelFlags, d);
if (d > 0) {
base = cc + 1;
lim--;
}
}
DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n",
c->channel, c->channelFlags);
return NULL;
}
u32
ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
struct ath9k_channel *chan)
{
struct ath9k_channel *ichan = NULL;
ichan = ath9k_regd_check_channel(ah, chan);
if (!ichan)
return 0;
return ichan->antennaMax;
} }
u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan)
{ {
u32 ctl = NO_CTL; u32 ctl = NO_CTL;
struct ath9k_channel *ichan;
if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) { if (!ah->regpair ||
(ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah))) {
if (IS_CHAN_B(chan)) if (IS_CHAN_B(chan))
ctl = SD_NO_CTL | CTL_11B; ctl = SD_NO_CTL | CTL_11B;
else if (IS_CHAN_G(chan)) else if (IS_CHAN_G(chan))
ctl = SD_NO_CTL | CTL_11G; ctl = SD_NO_CTL | CTL_11G;
else else
ctl = SD_NO_CTL | CTL_11A; ctl = SD_NO_CTL | CTL_11A;
} else { return ctl;
ichan = ath9k_regd_check_channel(ah, chan);
if (ichan != NULL) {
/* FIXME */
if (IS_CHAN_A(ichan))
ctl = ichan->conformanceTestLimit[0];
else if (IS_CHAN_B(ichan))
ctl = ichan->conformanceTestLimit[1];
else if (IS_CHAN_G(ichan))
ctl = ichan->conformanceTestLimit[2];
if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B)
ctl = (ctl & ~0xf) | CTL_11G;
}
} }
return ctl;
}
void ath9k_regd_get_current_country(struct ath_hal *ah, if (IS_CHAN_B(chan))
struct ath9k_country_entry *ctry) ctl = ah->regpair->reg_2ghz_ctl | CTL_11B;
{ else if (IS_CHAN_G(chan))
u16 rd = ath9k_regd_get_eepromRD(ah); ctl = ah->regpair->reg_5ghz_ctl | CTL_11G;
else
ctl = ah->regpair->reg_5ghz_ctl | CTL_11A;
ctry->isMultidomain = false; return ctl;
if (rd == CTRY_DEFAULT)
ctry->isMultidomain = true;
else if (!(rd & COUNTRY_ERD_FLAG))
ctry->isMultidomain = isWwrSKU(ah);
ctry->countryCode = ah->ah_countryCode;
ctry->regDmnEnum = ah->ah_currentRD;
ctry->regDmn5G = ah->ah_currentRD5G;
ctry->regDmn2G = ah->ah_currentRD2G;
ctry->iso[0] = ah->ah_iso[0];
ctry->iso[1] = ah->ah_iso[1];
ctry->iso[2] = ah->ah_iso[2];
} }
...@@ -19,126 +19,14 @@ ...@@ -19,126 +19,14 @@
#include "ath9k.h" #include "ath9k.h"
#define BMLEN 2
#define BMZERO {(u64) 0, (u64) 0}
#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
{((((_fa >= 0) && (_fa < 64)) ? \
(((u64) 1) << _fa) : (u64) 0) | \
(((_fb >= 0) && (_fb < 64)) ? \
(((u64) 1) << _fb) : (u64) 0) | \
(((_fc >= 0) && (_fc < 64)) ? \
(((u64) 1) << _fc) : (u64) 0) | \
(((_fd >= 0) && (_fd < 64)) ? \
(((u64) 1) << _fd) : (u64) 0) | \
(((_fe >= 0) && (_fe < 64)) ? \
(((u64) 1) << _fe) : (u64) 0) | \
(((_ff >= 0) && (_ff < 64)) ? \
(((u64) 1) << _ff) : (u64) 0) | \
(((_fg >= 0) && (_fg < 64)) ? \
(((u64) 1) << _fg) : (u64) 0) | \
(((_fh >= 0) && (_fh < 64)) ? \
(((u64) 1) << _fh) : (u64) 0) | \
(((_fi >= 0) && (_fi < 64)) ? \
(((u64) 1) << _fi) : (u64) 0) | \
(((_fj >= 0) && (_fj < 64)) ? \
(((u64) 1) << _fj) : (u64) 0) | \
(((_fk >= 0) && (_fk < 64)) ? \
(((u64) 1) << _fk) : (u64) 0) | \
(((_fl >= 0) && (_fl < 64)) ? \
(((u64) 1) << _fl) : (u64) 0) | \
((((_fa > 63) && (_fa < 128)) ? \
(((u64) 1) << (_fa - 64)) : (u64) 0) | \
(((_fb > 63) && (_fb < 128)) ? \
(((u64) 1) << (_fb - 64)) : (u64) 0) | \
(((_fc > 63) && (_fc < 128)) ? \
(((u64) 1) << (_fc - 64)) : (u64) 0) | \
(((_fd > 63) && (_fd < 128)) ? \
(((u64) 1) << (_fd - 64)) : (u64) 0) | \
(((_fe > 63) && (_fe < 128)) ? \
(((u64) 1) << (_fe - 64)) : (u64) 0) | \
(((_ff > 63) && (_ff < 128)) ? \
(((u64) 1) << (_ff - 64)) : (u64) 0) | \
(((_fg > 63) && (_fg < 128)) ? \
(((u64) 1) << (_fg - 64)) : (u64) 0) | \
(((_fh > 63) && (_fh < 128)) ? \
(((u64) 1) << (_fh - 64)) : (u64) 0) | \
(((_fi > 63) && (_fi < 128)) ? \
(((u64) 1) << (_fi - 64)) : (u64) 0) | \
(((_fj > 63) && (_fj < 128)) ? \
(((u64) 1) << (_fj - 64)) : (u64) 0) | \
(((_fk > 63) && (_fk < 128)) ? \
(((u64) 1) << (_fk - 64)) : (u64) 0) | \
(((_fl > 63) && (_fl < 128)) ? \
(((u64) 1) << (_fl - 64)) : (u64) 0)))}
#define DEF_REGDMN FCC1_FCCA
#define DEF_DMN_5 FCC1
#define DEF_DMN_2 FCCA
#define COUNTRY_ERD_FLAG 0x8000 #define COUNTRY_ERD_FLAG 0x8000
#define WORLDWIDE_ROAMING_FLAG 0x4000 #define WORLDWIDE_ROAMING_FLAG 0x4000
#define SUPER_DOMAIN_MASK 0x0fff
#define COUNTRY_CODE_MASK 0x3fff
#define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT)
#define CHANNEL_14 (2484)
#define IS_11G_CH14(_ch,_cf) \
(((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G))
#define NO_PSCAN 0x0ULL
#define PSCAN_FCC 0x0000000000000001ULL
#define PSCAN_FCC_T 0x0000000000000002ULL
#define PSCAN_ETSI 0x0000000000000004ULL
#define PSCAN_MKK1 0x0000000000000008ULL
#define PSCAN_MKK2 0x0000000000000010ULL
#define PSCAN_MKKA 0x0000000000000020ULL
#define PSCAN_MKKA_G 0x0000000000000040ULL
#define PSCAN_ETSIA 0x0000000000000080ULL
#define PSCAN_ETSIB 0x0000000000000100ULL
#define PSCAN_ETSIC 0x0000000000000200ULL
#define PSCAN_WWR 0x0000000000000400ULL
#define PSCAN_MKKA1 0x0000000000000800ULL
#define PSCAN_MKKA1_G 0x0000000000001000ULL
#define PSCAN_MKKA2 0x0000000000002000ULL
#define PSCAN_MKKA2_G 0x0000000000004000ULL
#define PSCAN_MKK3 0x0000000000008000ULL
#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
#define IS_ECM_CHAN 0x8000000000000000ULL
#define isWwrSKU(_ah) \ #define isWwrSKU(_ah) \
(((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \ (((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \
WORLD_SKU_PREFIX) || \ WORLD_SKU_PREFIX) || \
(ath9k_regd_get_eepromRD(_ah) == WORLD)) (ath9k_regd_get_eepromRD(_ah) == WORLD))
#define isWwrSKU_NoMidband(_ah) \
((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \
(ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \
(ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC))
#define isUNII1OddChan(ch) \
((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
#define IS_HT40_MODE(_mode) \
(((_mode == ATH9K_MODE_11NA_HT40PLUS || \
_mode == ATH9K_MODE_11NG_HT40PLUS || \
_mode == ATH9K_MODE_11NA_HT40MINUS || \
_mode == ATH9K_MODE_11NG_HT40MINUS) ? true : false))
#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
#define swap_array(_a, _b, _size) { \
u8 *s = _b; \
int i = _size; \
do { \
u8 tmp = *_a; \
*_a++ = *s; \
*s++ = tmp; \
} while (--i); \
_a -= _size; \
}
#define HALF_MAXCHANBW 10
#define MULTI_DOMAIN_MASK 0xFF00 #define MULTI_DOMAIN_MASK 0xFF00
#define WORLD_SKU_MASK 0x00F0 #define WORLD_SKU_MASK 0x00F0
...@@ -147,81 +35,16 @@ ...@@ -147,81 +35,16 @@
#define CHANNEL_HALF_BW 10 #define CHANNEL_HALF_BW 10
#define CHANNEL_QUARTER_BW 5 #define CHANNEL_QUARTER_BW 5
typedef int ath_hal_cmp_t(const void *, const void *);
struct reg_dmn_pair_mapping { struct reg_dmn_pair_mapping {
u16 regDmnEnum; u16 regDmnEnum;
u16 regDmn5GHz; u16 reg_5ghz_ctl;
u16 regDmn2GHz; u16 reg_2ghz_ctl;
u32 flags5GHz;
u32 flags2GHz;
u64 pscanMask;
u16 singleCC;
};
struct ccmap {
char isoName[3];
u16 countryCode;
}; };
struct country_code_to_enum_rd { struct country_code_to_enum_rd {
u16 countryCode; u16 countryCode;
u16 regDmnEnum; u16 regDmnEnum;
const char *isoName; const char *isoName;
const char *name;
bool allow11g;
bool allow11aTurbo;
bool allow11gTurbo;
bool allow11ng20;
bool allow11ng40;
bool allow11na20;
bool allow11na40;
u16 outdoorChanStart;
};
struct RegDmnFreqBand {
u16 lowChannel;
u16 highChannel;
u8 powerDfs;
u8 antennaMax;
u8 channelBW;
u8 channelSep;
u64 useDfs;
u64 usePassScan;
u8 regClassId;
};
struct regDomain {
u16 regDmnEnum;
u8 conformanceTestLimit;
u64 dfsMask;
u64 pscan;
u32 flags;
u64 chan11a[BMLEN];
u64 chan11a_turbo[BMLEN];
u64 chan11a_dyn_turbo[BMLEN];
u64 chan11b[BMLEN];
u64 chan11g[BMLEN];
u64 chan11g_turbo[BMLEN];
};
struct cmode {
u32 mode;
u32 flags;
};
#define YES true
#define NO false
struct japan_bandcheck {
u16 freqbandbit;
u32 eepromflagtocheck;
};
struct common_mode_power {
u16 lchan;
u16 hchan;
u8 pwrlvl;
}; };
enum CountryCode { enum CountryCode {
......
...@@ -150,1766 +150,324 @@ enum EnumRd { ...@@ -150,1766 +150,324 @@ enum EnumRd {
MKK9_MKKC = 0xFE, MKK9_MKKC = 0xFE,
MKK9_MKKA2 = 0xFF, MKK9_MKKA2 = 0xFF,
APL1 = 0x0150,
APL2 = 0x0250,
APL3 = 0x0350,
APL4 = 0x0450,
APL5 = 0x0550,
APL6 = 0x0650,
APL7 = 0x0750,
APL8 = 0x0850,
APL9 = 0x0950,
APL10 = 0x1050,
ETSI1 = 0x0130,
ETSI2 = 0x0230,
ETSI3 = 0x0330,
ETSI4 = 0x0430,
ETSI5 = 0x0530,
ETSI6 = 0x0630,
ETSIA = 0x0A30,
ETSIB = 0x0B30,
ETSIC = 0x0C30,
FCC1 = 0x0110,
FCC2 = 0x0120,
FCC3 = 0x0160,
FCC4 = 0x0165,
FCC5 = 0x0510,
FCC6 = 0x0610,
FCCA = 0x0A10,
APLD = 0x0D50,
MKK1 = 0x0140,
MKK2 = 0x0240,
MKK3 = 0x0340,
MKK4 = 0x0440,
MKK5 = 0x0540,
MKK6 = 0x0640,
MKK7 = 0x0740,
MKK8 = 0x0840,
MKK9 = 0x0940,
MKK10 = 0x0B40,
MKK11 = 0x1140,
MKK12 = 0x1240,
MKK13 = 0x0C40,
MKK14 = 0x1440,
MKK15 = 0x1540,
MKKA = 0x0A40,
MKKC = 0x0A50,
NULL1 = 0x0198,
WORLD = 0x0199, WORLD = 0x0199,
DEBUG_REG_DMN = 0x01ff, DEBUG_REG_DMN = 0x01ff,
}; };
enum { enum ctl_group {
FCC = 0x10, CTL_FCC = 0x10,
MKK = 0x40, CTL_MKK = 0x40,
ETSI = 0x30, CTL_ETSI = 0x30,
};
enum {
NO_REQ = 0x00000000,
DISALLOW_ADHOC_11A = 0x00000001,
DISALLOW_ADHOC_11A_TURB = 0x00000002,
NEED_NFC = 0x00000004,
ADHOC_PER_11D = 0x00000008,
ADHOC_NO_11A = 0x00000010,
PUBLIC_SAFETY_DOMAIN = 0x00000020,
LIMIT_FRAME_4MS = 0x00000040,
NO_HOSTAP = 0x00000080,
REQ_MASK = 0x000000FF,
}; };
#define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \ /* Regpair to CTL band mapping */
(~(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
#define REG_DOMAIN_5GHZ_MASK REQ_MASK
static struct reg_dmn_pair_mapping regDomainPairs[] = { static struct reg_dmn_pair_mapping regDomainPairs[] = {
{NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ, /* regpair, 5 GHz CTL, 2 GHz CTL */
PSCAN_DEFER, 0}, {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN},
{NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {NULL1_WORLD, NO_CTL, CTL_ETSI},
{NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {NULL1_ETSIB, NO_CTL, CTL_ETSI},
{NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {NULL1_ETSIC, NO_CTL, CTL_ETSI},
{FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {FCC2_FCCA, CTL_FCC, CTL_FCC},
{FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {FCC2_WORLD, CTL_FCC, CTL_ETSI},
{FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {FCC2_ETSIC, CTL_FCC, CTL_ETSI},
{FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {FCC3_FCCA, CTL_FCC, CTL_FCC},
{FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {FCC3_WORLD, CTL_FCC, CTL_ETSI},
{FCC4_FCCA, FCC4, FCCA, {FCC4_FCCA, CTL_FCC, CTL_FCC},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, {FCC5_FCCA, CTL_FCC, CTL_FCC},
0}, {FCC6_FCCA, CTL_FCC, CTL_FCC},
{FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {FCC6_WORLD, CTL_FCC, CTL_ETSI},
{FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
{FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {ETSI1_WORLD, CTL_ETSI, CTL_ETSI},
{ETSI2_WORLD, CTL_ETSI, CTL_ETSI},
{ETSI1_WORLD, ETSI1, WORLD, {ETSI3_WORLD, CTL_ETSI, CTL_ETSI},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, {ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
0}, {ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
{ETSI2_WORLD, ETSI2, WORLD, {ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
0}, /* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
{ETSI3_WORLD, ETSI3, WORLD, {ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, {FRANCE_RES, CTL_ETSI, CTL_ETSI},
0},
{ETSI4_WORLD, ETSI4, WORLD, {FCC1_WORLD, CTL_FCC, CTL_ETSI},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, {FCC1_FCCA, CTL_FCC, CTL_FCC},
0}, {APL1_WORLD, CTL_FCC, CTL_ETSI},
{ETSI5_WORLD, ETSI5, WORLD, {APL2_WORLD, CTL_FCC, CTL_ETSI},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, {APL3_WORLD, CTL_FCC, CTL_ETSI},
0}, {APL4_WORLD, CTL_FCC, CTL_ETSI},
{ETSI6_WORLD, ETSI6, WORLD, {APL5_WORLD, CTL_FCC, CTL_ETSI},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, {APL6_WORLD, CTL_ETSI, CTL_ETSI},
0}, {APL8_WORLD, CTL_ETSI, CTL_ETSI},
{APL9_WORLD, CTL_ETSI, CTL_ETSI},
{ETSI3_ETSIA, ETSI3, WORLD,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER, {APL3_FCCA, CTL_FCC, CTL_FCC},
0}, {APL1_ETSIC, CTL_FCC, CTL_ETSI},
{FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {APL2_ETSIC, CTL_FCC, CTL_ETSI},
{APL2_APLD, CTL_FCC, NO_CTL},
{FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
{FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK1_MKKA, CTL_MKK, CTL_MKK},
{APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK1_MKKB, CTL_MKK, CTL_MKK},
{APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK1_FCCA, CTL_MKK, CTL_FCC},
{APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK1_MKKA1, CTL_MKK, CTL_MKK},
{APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK1_MKKA2, CTL_MKK, CTL_MKK},
{APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK1_MKKC, CTL_MKK, CTL_MKK},
{APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
{APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK2_MKKA, CTL_MKK, CTL_MKK},
{APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK3_MKKA, CTL_MKK, CTL_MKK},
{MKK3_MKKB, CTL_MKK, CTL_MKK},
{APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK3_MKKA1, CTL_MKK, CTL_MKK},
{APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK3_MKKA2, CTL_MKK, CTL_MKK},
{APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0}, {MKK3_MKKC, CTL_MKK, CTL_MKK},
{APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER,}, {MKK3_FCCA, CTL_MKK, CTL_FCC},
{MKK1_MKKA, MKK1, MKKA, {MKK4_MKKA, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK4_MKKB, CTL_MKK, CTL_MKK},
PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN}, {MKK4_MKKA1, CTL_MKK, CTL_MKK},
{MKK1_MKKB, MKK1, MKKA, {MKK4_MKKA2, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | {MKK4_MKKC, CTL_MKK, CTL_MKK},
LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, {MKK4_FCCA, CTL_MKK, CTL_FCC},
CTRY_JAPAN1},
{MKK1_FCCA, MKK1, FCCA, {MKK5_MKKB, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK5_MKKA2, CTL_MKK, CTL_MKK},
PSCAN_MKK1, CTRY_JAPAN2}, {MKK5_MKKC, CTL_MKK, CTL_MKK},
{MKK1_MKKA1, MKK1, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK6_MKKB, CTL_MKK, CTL_MKK},
PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4}, {MKK6_MKKA1, CTL_MKK, CTL_MKK},
{MKK1_MKKA2, MKK1, MKKA, {MKK6_MKKA2, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK6_MKKC, CTL_MKK, CTL_MKK},
PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5}, {MKK6_FCCA, CTL_MKK, CTL_FCC},
{MKK1_MKKC, MKK1, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK7_MKKB, CTL_MKK, CTL_MKK},
PSCAN_MKK1, CTRY_JAPAN6}, {MKK7_MKKA1, CTL_MKK, CTL_MKK},
{MKK7_MKKA2, CTL_MKK, CTL_MKK},
{MKK2_MKKA, MKK2, MKKA, {MKK7_MKKC, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | {MKK7_FCCA, CTL_MKK, CTL_FCC},
LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G,
CTRY_JAPAN3}, {MKK8_MKKB, CTL_MKK, CTL_MKK},
{MKK8_MKKA2, CTL_MKK, CTL_MKK},
{MKK3_MKKA, MKK3, MKKA, {MKK8_MKKC, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKKA, CTRY_JAPAN25}, {MKK9_MKKA, CTL_MKK, CTL_MKK},
{MKK3_MKKB, MKK3, MKKA, {MKK9_FCCA, CTL_MKK, CTL_FCC},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | {MKK9_MKKA1, CTL_MKK, CTL_MKK},
LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G, {MKK9_MKKA2, CTL_MKK, CTL_MKK},
CTRY_JAPAN7}, {MKK9_MKKC, CTL_MKK, CTL_MKK},
{MKK3_MKKA1, MKK3, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK10_MKKA, CTL_MKK, CTL_MKK},
PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26}, {MKK10_FCCA, CTL_MKK, CTL_FCC},
{MKK3_MKKA2, MKK3, MKKA, {MKK10_MKKA1, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK10_MKKA2, CTL_MKK, CTL_MKK},
PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8}, {MKK10_MKKC, CTL_MKK, CTL_MKK},
{MKK3_MKKC, MKK3, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK11_MKKA, CTL_MKK, CTL_MKK},
NO_PSCAN, CTRY_JAPAN9}, {MKK11_FCCA, CTL_MKK, CTL_FCC},
{MKK3_FCCA, MKK3, FCCA, {MKK11_MKKA1, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK11_MKKA2, CTL_MKK, CTL_MKK},
NO_PSCAN, CTRY_JAPAN27}, {MKK11_MKKC, CTL_MKK, CTL_MKK},
{MKK4_MKKA, MKK4, MKKA, {MKK12_MKKA, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK12_FCCA, CTL_MKK, CTL_FCC},
PSCAN_MKK3, CTRY_JAPAN36}, {MKK12_MKKA1, CTL_MKK, CTL_MKK},
{MKK4_MKKB, MKK4, MKKA, {MKK12_MKKA2, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | {MKK12_MKKC, CTL_MKK, CTL_MKK},
LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
CTRY_JAPAN10}, {MKK13_MKKB, CTL_MKK, CTL_MKK},
{MKK4_MKKA1, MKK4, MKKA, {MKK14_MKKA1, CTL_MKK, CTL_MKK},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {MKK15_MKKA1, CTL_MKK, CTL_MKK},
PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28},
{MKK4_MKKA2, MKK4, MKKA, {WOR0_WORLD, NO_CTL, NO_CTL},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {WOR1_WORLD, NO_CTL, NO_CTL},
PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11}, {WOR2_WORLD, NO_CTL, NO_CTL},
{MKK4_MKKC, MKK4, MKKC, {WOR3_WORLD, NO_CTL, NO_CTL},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {WOR4_WORLD, NO_CTL, NO_CTL},
PSCAN_MKK3, CTRY_JAPAN12}, {WOR5_ETSIC, NO_CTL, NO_CTL},
{MKK4_FCCA, MKK4, FCCA, {WOR01_WORLD, NO_CTL, NO_CTL},
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC, {WOR02_WORLD, NO_CTL, NO_CTL},
PSCAN_MKK3, CTRY_JAPAN29}, {EU1_WORLD, NO_CTL, NO_CTL},
{WOR9_WORLD, NO_CTL, NO_CTL},
{MKK5_MKKB, MKK5, MKKA, {WORA_WORLD, NO_CTL, NO_CTL},
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC | {WORB_WORLD, NO_CTL, NO_CTL},
LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
CTRY_JAPAN13},
{MKK5_MKKA2, MKK5, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14},
{MKK5_MKKC, MKK5, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK3, CTRY_JAPAN15},
{MKK6_MKKB, MKK6, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16},
{MKK6_MKKA1, MKK6, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30},
{MKK6_MKKA2, MKK6, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17},
{MKK6_MKKC, MKK6, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1, CTRY_JAPAN18},
{MKK6_FCCA, MKK6, FCCA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
NO_PSCAN, CTRY_JAPAN31},
{MKK7_MKKB, MKK7, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
CTRY_JAPAN19},
{MKK7_MKKA1, MKK7, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32},
{MKK7_MKKA2, MKK7, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
CTRY_JAPAN20},
{MKK7_MKKC, MKK7, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21},
{MKK7_FCCA, MKK7, FCCA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33},
{MKK8_MKKB, MKK8, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
CTRY_JAPAN22},
{MKK8_MKKA2, MKK8, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
CTRY_JAPAN23},
{MKK8_MKKC, MKK8, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN24},
{MKK9_MKKA, MKK9, MKKA,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK2 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
CTRY_JAPAN34},
{MKK9_FCCA, MKK9, FCCA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
NO_PSCAN, CTRY_JAPAN37},
{MKK9_MKKA1, MKK9, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38},
{MKK9_MKKA2, MKK9, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40},
{MKK9_MKKC, MKK9, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
NO_PSCAN, CTRY_JAPAN39},
{MKK10_MKKA, MKK10, MKKA,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKK3, CTRY_JAPAN35},
{MKK10_FCCA, MKK10, FCCA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
NO_PSCAN, CTRY_JAPAN41},
{MKK10_MKKA1, MKK10, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42},
{MKK10_MKKA2, MKK10, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44},
{MKK10_MKKC, MKK10, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
NO_PSCAN, CTRY_JAPAN43},
{MKK11_MKKA, MKK11, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK3, CTRY_JAPAN45},
{MKK11_FCCA, MKK11, FCCA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK3, CTRY_JAPAN46},
{MKK11_MKKA1, MKK11, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47},
{MKK11_MKKA2, MKK11, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49},
{MKK11_MKKC, MKK11, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK3, CTRY_JAPAN48},
{MKK12_MKKA, MKK12, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50},
{MKK12_FCCA, MKK12, FCCA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51},
{MKK12_MKKA1, MKK12, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G,
CTRY_JAPAN52},
{MKK12_MKKA2, MKK12, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
CTRY_JAPAN54},
{MKK12_MKKC, MKK12, MKKC,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53},
{MKK13_MKKB, MKK13, MKKA,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
CTRY_JAPAN57},
{MKK14_MKKA1, MKK14, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58},
{MKK15_MKKA1, MKK15, MKKA,
DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59},
{WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
0},
{WOR1_WORLD, WOR1_WORLD, WOR1_WORLD,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
0},
{WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB,
NO_REQ, PSCAN_DEFER, 0},
{WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
0},
{WOR4_WORLD, WOR4_WORLD, WOR4_WORLD,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
0},
{WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
0},
{WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ,
PSCAN_DEFER, 0},
{WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ,
PSCAN_DEFER, 0},
{EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
{WOR9_WORLD, WOR9_WORLD, WOR9_WORLD,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
0},
{WORA_WORLD, WORA_WORLD, WORA_WORLD,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
0},
{WORB_WORLD, WORB_WORLD, WORB_WORLD,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
0},
}; };
#define NO_INTERSECT_REQ 0xFFFFFFFF
#define NO_UNION_REQ 0
static struct country_code_to_enum_rd allCountries[] = { static struct country_code_to_enum_rd allCountries[] = {
{CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES, {CTRY_DEBUG, NO_ENUMRD, "DB"},
YES, YES, 7000}, {CTRY_DEFAULT, FCC1_FCCA, "CO"},
{CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES, {CTRY_ALBANIA, NULL1_WORLD, "AL"},
YES, YES, YES, YES, 7000}, {CTRY_ALGERIA, NULL1_WORLD, "DZ"},
{CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, NO, {CTRY_ARGENTINA, APL3_WORLD, "AR"},
NO, NO, 7000}, {CTRY_ARMENIA, ETSI4_WORLD, "AM"},
{CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, NO, {CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
NO, NO, 7000}, {CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
{CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES, {CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
NO, YES, NO, 7000}, {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
{CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES, {CTRY_BAHRAIN, APL6_WORLD, "BH"},
YES, NO, NO, 7000}, {CTRY_BELARUS, ETSI1_WORLD, "BY"},
{CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES, {CTRY_BELGIUM, ETSI1_WORLD, "BE"},
YES, YES, YES, 7000}, {CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
{CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES, {CTRY_BELIZE, APL1_ETSIC, "BZ"},
YES, YES, YES, YES, 7000}, {CTRY_BOLIVIA, APL1_ETSIC, "BO"},
{CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES, {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
YES, YES, YES, 7000}, {CTRY_BRAZIL, FCC3_WORLD, "BR"},
{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES, {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
YES, YES, YES, YES, 7000}, {CTRY_BULGARIA, ETSI6_WORLD, "BG"},
{CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES, {CTRY_CANADA, FCC2_FCCA, "CA"},
YES, NO, 7000}, {CTRY_CANADA2, FCC6_FCCA, "CA"},
{CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES, {CTRY_CHILE, APL6_WORLD, "CL"},
YES, YES, YES, 7000}, {CTRY_CHINA, APL1_WORLD, "CN"},
{CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES, {CTRY_COLOMBIA, FCC1_FCCA, "CO"},
YES, YES, YES, 7000}, {CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
{CTRY_BELGIUM2, ETSI4_WORLD, "BL", "BELGIUM", YES, NO, YES, YES, {CTRY_CROATIA, ETSI3_WORLD, "HR"},
YES, YES, YES, 7000}, {CTRY_CYPRUS, ETSI1_WORLD, "CY"},
{CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES, {CTRY_CZECH, ETSI3_WORLD, "CZ"},
YES, YES, 7000}, {CTRY_DENMARK, ETSI1_WORLD, "DK"},
{CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES, {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
YES, YES, 7000}, {CTRY_ECUADOR, FCC1_WORLD, "EC"},
{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA_HERZGOWINA", YES, NO, {CTRY_EGYPT, ETSI3_WORLD, "EG"},
YES, YES, YES, YES, NO, 7000}, {CTRY_EL_SALVADOR, FCC1_WORLD, "SV"},
{CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, NO, {CTRY_ESTONIA, ETSI1_WORLD, "EE"},
YES, NO, 7000}, {CTRY_FINLAND, ETSI1_WORLD, "FI"},
{CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM", {CTRY_FRANCE, ETSI1_WORLD, "FR"},
YES, YES, YES, YES, YES, YES, YES, 7000}, {CTRY_GEORGIA, ETSI4_WORLD, "GE"},
{CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES, {CTRY_GERMANY, ETSI1_WORLD, "DE"},
YES, YES, YES, 7000}, {CTRY_GREECE, ETSI1_WORLD, "GR"},
{CTRY_CANADA, FCC2_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES, {CTRY_GUATEMALA, FCC1_FCCA, "GT"},
YES, YES, 7000}, {CTRY_HONDURAS, NULL1_WORLD, "HN"},
{CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES, {CTRY_HONG_KONG, FCC2_WORLD, "HK"},
YES, YES, 7000}, {CTRY_HUNGARY, ETSI1_WORLD, "HU"},
{CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES, {CTRY_ICELAND, ETSI1_WORLD, "IS"},
YES, YES, 7000}, {CTRY_INDIA, APL6_WORLD, "IN"},
{CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES, {CTRY_INDONESIA, APL1_WORLD, "ID"},
YES, YES, 7000}, {CTRY_IRAN, APL1_WORLD, "IR"},
{CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES, {CTRY_IRELAND, ETSI1_WORLD, "IE"},
YES, YES, NO, 7000}, {CTRY_ISRAEL, NULL1_WORLD, "IL"},
{CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES, {CTRY_ITALY, ETSI1_WORLD, "IT"},
YES, YES, YES, NO, 7000}, {CTRY_JAMAICA, ETSI1_WORLD, "JM"},
{CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, YES,
YES, YES, NO, 7000}, {CTRY_JAPAN, MKK1_MKKA, "JP"},
{CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES, {CTRY_JAPAN1, MKK1_MKKB, "JP"},
YES, YES, 7000}, {CTRY_JAPAN2, MKK1_FCCA, "JP"},
{CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES, {CTRY_JAPAN3, MKK2_MKKA, "JP"},
YES, YES, YES, YES, 7000}, {CTRY_JAPAN4, MKK1_MKKA1, "JP"},
{CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES, {CTRY_JAPAN5, MKK1_MKKA2, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN6, MKK1_MKKC, "JP"},
{CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC", {CTRY_JAPAN7, MKK3_MKKB, "JP"},
YES, YES, YES, YES, YES, YES, YES, 7000}, {CTRY_JAPAN8, MKK3_MKKA2, "JP"},
{CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES, {CTRY_JAPAN9, MKK3_MKKC, "JP"},
YES, NO, 7000}, {CTRY_JAPAN10, MKK4_MKKB, "JP"},
{CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES, {CTRY_JAPAN11, MKK4_MKKA2, "JP"},
YES, NO, 7000}, {CTRY_JAPAN12, MKK4_MKKC, "JP"},
{CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES, {CTRY_JAPAN13, MKK5_MKKB, "JP"},
YES, YES, YES, NO, 7000}, {CTRY_JAPAN14, MKK5_MKKA2, "JP"},
{CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES, {CTRY_JAPAN15, MKK5_MKKC, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN16, MKK6_MKKB, "JP"},
{CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES, {CTRY_JAPAN17, MKK6_MKKA2, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN18, MKK6_MKKC, "JP"},
{CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES, {CTRY_JAPAN19, MKK7_MKKB, "JP"},
YES, YES, 7000}, {CTRY_JAPAN20, MKK7_MKKA2, "JP"},
{CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES, {CTRY_JAPAN21, MKK7_MKKC, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN22, MKK8_MKKB, "JP"},
{CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES, {CTRY_JAPAN23, MKK8_MKKA2, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN24, MKK8_MKKC, "JP"},
{CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES, {CTRY_JAPAN25, MKK3_MKKA, "JP"},
YES, YES, 7000}, {CTRY_JAPAN26, MKK3_MKKA1, "JP"},
{CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES, {CTRY_JAPAN27, MKK3_FCCA, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN28, MKK4_MKKA1, "JP"},
{CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, YES, {CTRY_JAPAN29, MKK4_FCCA, "JP"},
YES, NO, NO, 7000}, {CTRY_JAPAN30, MKK6_MKKA1, "JP"},
{CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES, {CTRY_JAPAN31, MKK6_FCCA, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN32, MKK7_MKKA1, "JP"},
{CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES, {CTRY_JAPAN33, MKK7_FCCA, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN34, MKK9_MKKA, "JP"},
{CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES, {CTRY_JAPAN35, MKK10_MKKA, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN36, MKK4_MKKA, "JP"},
{CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES, {CTRY_JAPAN37, MKK9_FCCA, "JP"},
YES, NO, 7000}, {CTRY_JAPAN38, MKK9_MKKA1, "JP"},
{CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, YES, {CTRY_JAPAN39, MKK9_MKKC, "JP"},
YES, YES, NO, 7000}, {CTRY_JAPAN40, MKK9_MKKA2, "JP"},
{CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES, {CTRY_JAPAN41, MKK10_FCCA, "JP"},
YES, 7000}, {CTRY_JAPAN42, MKK10_MKKA1, "JP"},
{CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES, {CTRY_JAPAN43, MKK10_MKKC, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN44, MKK10_MKKA2, "JP"},
{CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES, {CTRY_JAPAN45, MKK11_MKKA, "JP"},
NO, NO, 7000}, {CTRY_JAPAN46, MKK11_FCCA, "JP"},
{CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES, {CTRY_JAPAN47, MKK11_MKKA1, "JP"},
YES, YES, 7000}, {CTRY_JAPAN48, MKK11_MKKC, "JP"},
{CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES, {CTRY_JAPAN49, MKK11_MKKA2, "JP"},
YES, YES, YES, 7000}, {CTRY_JAPAN50, MKK12_MKKA, "JP"},
{CTRY_JAPAN51, MKK12_FCCA, "JP"},
{CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES, {CTRY_JAPAN52, MKK12_MKKA1, "JP"},
YES, 7000}, {CTRY_JAPAN53, MKK12_MKKC, "JP"},
{CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES, {CTRY_JAPAN54, MKK12_MKKA2, "JP"},
YES, YES, 7000}, {CTRY_JAPAN57, MKK13_MKKB, "JP"},
{CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES, {CTRY_JAPAN58, MKK14_MKKA1, "JP"},
YES, YES, 7000}, {CTRY_JAPAN59, MKK15_MKKA1, "JP"},
{CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES,
YES, YES, 7000}, {CTRY_JORDAN, ETSI2_WORLD, "JO"},
{CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES, {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
YES, YES, 7000}, {CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
{CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES, {CTRY_KOREA_ROC, APL9_WORLD, "KR"},
YES, YES, 7000}, {CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
{CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES, {CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
YES, YES, 7000}, {CTRY_KUWAIT, NULL1_WORLD, "KW"},
{CTRY_LATVIA, ETSI1_WORLD, "LV"},
{CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES, {CTRY_LEBANON, NULL1_WORLD, "LB"},
YES, YES, 7000}, {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
{CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES, {CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
YES, YES, 7000}, {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
{CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES, {CTRY_MACAU, FCC2_WORLD, "MO"},
YES, YES, 7000}, {CTRY_MACEDONIA, NULL1_WORLD, "MK"},
{CTRY_MALAYSIA, APL8_WORLD, "MY"},
{CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES, {CTRY_MALTA, ETSI1_WORLD, "MT"},
YES, YES, 7000}, {CTRY_MEXICO, FCC1_FCCA, "MX"},
{CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES, {CTRY_MONACO, ETSI4_WORLD, "MC"},
YES, YES, 7000}, {CTRY_MOROCCO, NULL1_WORLD, "MA"},
{CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES, {CTRY_NEPAL, APL1_WORLD, "NP"},
YES, YES, 7000}, {CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
{CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
{CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES, {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
YES, YES, 7000}, {CTRY_NORWAY, ETSI1_WORLD, "NO"},
{CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES, {CTRY_OMAN, APL6_WORLD, "OM"},
YES, YES, 7000}, {CTRY_PAKISTAN, NULL1_WORLD, "PK"},
{CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES, {CTRY_PANAMA, FCC1_FCCA, "PA"},
YES, YES, 7000}, {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
{CTRY_PERU, APL1_WORLD, "PE"},
{CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES, {CTRY_PHILIPPINES, APL1_WORLD, "PH"},
YES, YES, 7000}, {CTRY_POLAND, ETSI1_WORLD, "PL"},
{CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES, {CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
YES, YES, 7000}, {CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
{CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES, {CTRY_QATAR, NULL1_WORLD, "QA"},
YES, YES, 7000}, {CTRY_ROMANIA, NULL1_WORLD, "RO"},
{CTRY_RUSSIA, NULL1_WORLD, "RU"},
{CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES, {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
YES, YES, 7000}, {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
{CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES, {CTRY_SINGAPORE, APL6_WORLD, "SG"},
YES, YES, 7000}, {CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
{CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES, {CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
YES, YES, 7000}, {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
{CTRY_SPAIN, ETSI1_WORLD, "ES"},
{CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES, {CTRY_SRI_LANKA, FCC3_WORLD, "LK"},
YES, YES, 7000}, {CTRY_SWEDEN, ETSI1_WORLD, "SE"},
{CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES, {CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
YES, YES, 7000}, {CTRY_SYRIA, NULL1_WORLD, "SY"},
{CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES, {CTRY_TAIWAN, APL3_FCCA, "TW"},
YES, YES, 7000}, {CTRY_THAILAND, NULL1_WORLD, "TH"},
{CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT"},
{CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES, {CTRY_TUNISIA, ETSI3_WORLD, "TN"},
YES, YES, 7000}, {CTRY_TURKEY, ETSI3_WORLD, "TR"},
{CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES, {CTRY_UKRAINE, NULL1_WORLD, "UA"},
YES, YES, 7000}, {CTRY_UAE, NULL1_WORLD, "AE"},
{CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES, {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
YES, YES, 7000}, {CTRY_UNITED_STATES, FCC3_FCCA, "US"},
{CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES, /* This "PS" is for US public safety actually... to support this we
YES, YES, 7000}, * would need to assign new special alpha2 to CRDA db as with the world
{CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES, * regdomain and use another alpha2 */
YES, YES, 7000}, {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"},
{CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES, {CTRY_URUGUAY, APL2_WORLD, "UY"},
YES, YES, 7000}, {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"},
{CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES, {CTRY_VENEZUELA, APL2_ETSIC, "VE"},
YES, YES, 7000}, {CTRY_VIET_NAM, NULL1_WORLD, "VN"},
{CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES, {CTRY_YEMEN, NULL1_WORLD, "YE"},
YES, YES, 7000}, {CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
{CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES,
YES, YES, 7000},
{CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES,
YES, NO, 7000},
{CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES,
YES, YES, NO, NO, 7000},
{CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO,
YES, YES, YES, YES, 7000},
{CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO,
YES, NO, YES, NO, 7000},
{CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2", YES, NO, NO,
YES, NO, YES, NO, 7000},
{CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO,
YES, NO, YES, NO, 7000},
{CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES,
NO, NO, 7000},
{CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES,
YES, YES, 7000},
{CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES,
YES, NO, NO, 7000},
{CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO,
YES, YES, YES, YES, YES, 7000},
{CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES,
YES, YES, YES, 7000},
{CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES,
YES, YES, YES, YES, 7000},
{CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES,
YES, YES, 7000},
{CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, YES,
YES, NO, NO, 7000},
{CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, NO,
YES, NO, 7000},
{CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES,
YES, YES, 7000},
{CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES,
YES, YES, 7000},
{CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES,
YES, YES, 7000},
{CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, YES,
YES, NO, NO, 7000},
{CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES,
YES, YES, 7000},
{CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES,
YES, YES, YES, YES, 7000},
{CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN",
"NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, YES, YES, 7000},
{CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES,
YES, YES, YES, NO, 7000},
{CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES,
YES, YES, 7000},
{CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES,
NO, 7000},
{CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES,
YES, NO, NO, 7000},
{CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES,
YES, YES, 7000},
{CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES,
YES, YES, YES, YES, YES, YES, 7000},
{CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES,
NO, 7000},
{CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES,
YES, YES, YES, YES, 7000},
{CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES,
YES, YES, 7000},
{CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES,
YES, YES, YES, 7000},
{CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES,
YES, YES, YES, YES, 7000},
{CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES,
NO, NO, 7000},
{CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES,
YES, NO, NO, 7000},
{CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, YES, YES,
NO, NO, 7000},
{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO,
YES, YES, YES, NO, NO, 7000},
{CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO",
YES, NO, YES, YES, YES, YES, YES, 7000},
{CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES,
YES, YES, YES, 7000},
{CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES,
YES, YES, YES, YES, 7000},
{CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES,
YES, YES, YES, 7000},
{CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES,
YES, YES, YES, NO, 7000},
{CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES,
YES, YES, 7000},
{CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES,
YES, YES, NO, 7000},
{CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES,
YES, YES, 7000},
{CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES,
YES, YES, YES, YES, 7000},
{CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, YES, YES,
NO, NO, 7000},
{CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES,
YES, YES, 7000},
{CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, YES,
YES, NO, NO, 7000},
{CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO",
YES, NO, YES, YES, YES, YES, NO, 7000},
{CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES,
YES, YES, NO, 7000},
{CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES,
YES, NO, 7000},
{CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, YES,
YES, NO, NO, 7000},
{CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES,
YES, YES, NO, NO, 7000},
{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO,
YES, YES, YES, YES, YES, 7000},
{CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES,
YES, YES, YES, YES, YES, 5825},
{CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS",
"UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES,
YES, 7000},
{CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES,
YES, NO, 7000},
{CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES,
YES, YES, YES, YES, 7000},
{CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, YES,
YES, YES, NO, 7000},
{CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, YES,
YES, NO, NO, 7000},
{CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES,
NO, NO, 7000},
{CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES,
YES, NO, NO, 7000}
};
enum {
NO_DFS = 0x0000000000000000ULL,
DFS_FCC3 = 0x0000000000000001ULL,
DFS_ETSI = 0x0000000000000002ULL,
DFS_MKK4 = 0x0000000000000004ULL,
};
enum {
F1_4915_4925,
F1_4935_4945,
F1_4920_4980,
F1_4942_4987,
F1_4945_4985,
F1_4950_4980,
F1_5035_5040,
F1_5040_5080,
F1_5055_5055,
F1_5120_5240,
F1_5170_5230,
F2_5170_5230,
F1_5180_5240,
F2_5180_5240,
F3_5180_5240,
F4_5180_5240,
F5_5180_5240,
F6_5180_5240,
F7_5180_5240,
F8_5180_5240,
F1_5180_5320,
F1_5240_5280,
F1_5260_5280,
F1_5260_5320,
F2_5260_5320,
F3_5260_5320,
F4_5260_5320,
F5_5260_5320,
F6_5260_5320,
F1_5260_5700,
F1_5280_5320,
F1_5500_5580,
F1_5500_5620,
F1_5500_5700,
F2_5500_5700,
F3_5500_5700,
F4_5500_5700,
F5_5500_5700,
F1_5660_5700,
F1_5745_5805,
F2_5745_5805,
F3_5745_5805,
F1_5745_5825,
F2_5745_5825,
F3_5745_5825,
F4_5745_5825,
F5_5745_5825,
F6_5745_5825,
W1_4920_4980,
W1_5040_5080,
W1_5170_5230,
W1_5180_5240,
W1_5260_5320,
W1_5745_5825,
W1_5500_5700,
A_DEMO_ALL_CHANNELS
};
static struct RegDmnFreqBand regDmn5GhzFreq[] = {
{4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
{4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
{4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7},
{4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0},
{4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0},
{4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0},
{5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
{5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2},
{5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
{5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
{5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
{5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
{5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
{5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1},
{5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
{5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
{5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
{5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0},
{5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0},
{5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
{5180, 5320, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
{5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0},
{5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
PSCAN_FCC | PSCAN_ETSI, 0},
{5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
PSCAN_FCC | PSCAN_ETSI, 0},
{5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3, 0},
{5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI,
PSCAN_FCC | PSCAN_ETSI, 2},
{5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2},
{5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
{5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
{5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0},
{5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
{5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
{5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
{5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4},
{5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
PSCAN_FCC | PSCAN_ETSI, 0},
{5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
PSCAN_FCC | PSCAN_ETSI, 0},
{5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
PSCAN_MKK3 | PSCAN_FCC, 0},
{5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
{5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
{5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
{5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
{5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
{5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
{5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
{5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
{5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
{5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3},
{5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
{4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
{5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
{5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
{5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
{5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
{5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
{5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
{4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
};
enum {
T1_5130_5650,
T1_5150_5670,
T1_5200_5200,
T2_5200_5200,
T3_5200_5200,
T4_5200_5200,
T5_5200_5200,
T6_5200_5200,
T7_5200_5200,
T8_5200_5200,
T1_5200_5280,
T2_5200_5280,
T3_5200_5280,
T4_5200_5280,
T5_5200_5280,
T6_5200_5280,
T1_5200_5240,
T1_5210_5210,
T2_5210_5210,
T3_5210_5210,
T4_5210_5210,
T5_5210_5210,
T6_5210_5210,
T7_5210_5210,
T8_5210_5210,
T9_5210_5210,
T10_5210_5210,
T1_5240_5240,
T1_5210_5250,
T1_5210_5290,
T2_5210_5290,
T3_5210_5290,
T1_5280_5280,
T2_5280_5280,
T1_5290_5290,
T2_5290_5290,
T3_5290_5290,
T1_5250_5290,
T2_5250_5290,
T3_5250_5290,
T4_5250_5290,
T1_5540_5660,
T2_5540_5660,
T3_5540_5660,
T1_5760_5800,
T2_5760_5800,
T3_5760_5800,
T4_5760_5800,
T5_5760_5800,
T6_5760_5800,
T7_5760_5800,
T1_5765_5805,
T2_5765_5805,
T3_5765_5805,
T4_5765_5805,
T5_5765_5805,
T6_5765_5805,
T7_5765_5805,
T8_5765_5805,
T9_5765_5805,
WT1_5210_5250,
WT1_5290_5290,
WT1_5540_5660,
WT1_5760_5800,
};
enum {
F1_2312_2372,
F2_2312_2372,
F1_2412_2472,
F2_2412_2472,
F3_2412_2472,
F1_2412_2462,
F2_2412_2462,
F1_2432_2442,
F1_2457_2472,
F1_2467_2472,
F1_2484_2484,
F2_2484_2484,
F1_2512_2732,
W1_2312_2372,
W1_2412_2412,
W1_2417_2432,
W1_2437_2442,
W1_2447_2457,
W1_2462_2462,
W1_2467_2467,
W2_2467_2467,
W1_2472_2472,
W2_2472_2472,
W1_2484_2484,
W2_2484_2484,
};
static struct RegDmnFreqBand regDmn2GhzFreq[] = {
{2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
{2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
{2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
{2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2484, 2484, 20, 0, 20, 5, NO_DFS,
PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
{2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
{2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
{2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
{2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
{2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
{2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
};
enum {
G1_2312_2372,
G2_2312_2372,
G1_2412_2472,
G2_2412_2472,
G3_2412_2472,
G1_2412_2462,
G2_2412_2462,
G1_2432_2442,
G1_2457_2472,
G1_2512_2732,
G1_2467_2472,
WG1_2312_2372,
WG1_2412_2462,
WG1_2467_2472,
WG2_2467_2472,
G_DEMO_ALL_CHANNELS
};
static struct RegDmnFreqBand regDmn2Ghz11gFreq[] = {
{2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
{2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
{2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
{2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
{2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
{2467, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
{2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
};
enum {
T1_2312_2372,
T1_2437_2437,
T2_2437_2437,
T3_2437_2437,
T1_2512_2732
}; };
static struct regDomain regDomains[] = {
{DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ,
BM(A_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5130_5650, T1_5150_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1,
-1, -1, -1, -1, -1, -1),
BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1,
-1, -1, -1, -1, -1, -1),
BM(G_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1,
-1, -1, -1, -1)},
{APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC, NO_REQ,
BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{APL7, ETSI, DFS_ETSI, PSCAN_ETSI, NO_REQ,
BM(F1_5280_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{APL8, ETSI, NO_DFS, NO_PSCAN,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{APL9, ETSI, DFS_ETSI, PSCAN_ETSI,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{APL10, ETSI, DFS_ETSI, PSCAN_ETSI,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F1_5180_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F4_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
-1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1,
-1, -1, -1, -1, -1, -1),
BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ,
BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700,
F6_5745_5825, -1, -1, -1, -1, -1, -1, -1),
BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
-1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
-1, -1, -1, -1, -1, -1),
BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB,
BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
F2_5260_5320, F4_5500_5700, -1, -1),
BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
DISALLOW_ADHOC_11A_TURB,
BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
DISALLOW_ADHOC_11A_TURB,
BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
-1, -1, -1, -1, -1, -1),
BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO,
BMZERO,
BMZERO},
{MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3,
DISALLOW_ADHOC_11A_TURB,
BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1),
BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3,
DISALLOW_ADHOC_11A_TURB,
BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1,
-1, -1),
BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320,
F4_5500_5700, -1, -1, -1),
BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
DISALLOW_ADHOC_11A_TURB,
BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
F2_5260_5320, F4_5500_5700, -1, -1),
BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO},
{MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BM(F1_5170_5230, F7_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
-1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO,
BMZERO,
BMZERO},
{MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, -1, -1,
-1, -1),
BMZERO,
BMZERO,
BMZERO,
BMZERO,
BMZERO},
{MKK15, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240,
F2_5260_5320, -1, -1, -1),
BMZERO,
BMZERO,
BMZERO,
BMZERO,
BMZERO},
{APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
BMZERO,
BMZERO,
BMZERO,
BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BMZERO},
{ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BMZERO,
BMZERO,
BMZERO,
BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{ETSIB, ETSI, NO_DFS, PSCAN_ETSIB,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BMZERO,
BMZERO,
BMZERO,
BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{ETSIC, ETSI, NO_DFS, PSCAN_ETSIC,
DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
BMZERO,
BMZERO,
BMZERO,
BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ,
BMZERO,
BMZERO,
BMZERO,
BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{MKKA, MKK, NO_DFS,
PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G |
PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB,
BMZERO,
BMZERO,
BMZERO,
BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1),
BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ,
BMZERO,
BMZERO,
BMZERO,
BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ,
BMZERO,
BMZERO,
BMZERO,
BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-1, -1, -1, -1, -1),
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
-1, -1),
BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
ADHOC_PER_11D,
BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-1, -1, -1, -1, -1),
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
ADHOC_PER_11D,
BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-1, -1, -1, -1, -1),
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-1, -1, -1, -1, -1),
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472,
W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
-1, -1),
BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-1, -1, -1, -1, -1),
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
-1, -1),
BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1,
-1, -1, -1, -1, -1, -1),
BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-1, -1, -1, -1, -1),
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-1, -1, -1, -1, -1),
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BMZERO,
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
-1, -1, -1, -1, -1, -1),
BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
-1, -1, -1, -1, -1),
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
-1, -1, -1, -1, -1, -1),
BMZERO,
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, -1, -1, -1, -1, -1,
-1, -1, -1, -1),
BMZERO,
BMZERO,
BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1),
BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
{NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
BMZERO,
BMZERO,
BMZERO,
BMZERO,
BMZERO,
BMZERO}
};
static const struct cmode modes[] = {
{ATH9K_MODE_11A, CHANNEL_A},
{ATH9K_MODE_11B, CHANNEL_B},
{ATH9K_MODE_11G, CHANNEL_G},
{ATH9K_MODE_11NG_HT20, CHANNEL_G_HT20},
{ATH9K_MODE_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
{ATH9K_MODE_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
{ATH9K_MODE_11NA_HT20, CHANNEL_A_HT20},
{ATH9K_MODE_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
{ATH9K_MODE_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
};
static struct japan_bandcheck j_bandcheck[] = {
{F1_5170_5230, AR_EEPROM_EEREGCAP_EN_KK_U1_ODD},
{F4_5180_5240, AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN},
{F2_5260_5320, AR_EEPROM_EEREGCAP_EN_KK_U2},
{F4_5500_5700, AR_EEPROM_EEREGCAP_EN_KK_MIDBAND}
};
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册