diff options
Diffstat (limited to 'package/ath9k/src/drivers/net/wireless/ath9k/regd.c')
-rw-r--r-- | package/ath9k/src/drivers/net/wireless/ath9k/regd.c | 760 |
1 files changed, 338 insertions, 422 deletions
diff --git a/package/ath9k/src/drivers/net/wireless/ath9k/regd.c b/package/ath9k/src/drivers/net/wireless/ath9k/regd.c index 519cae877..8a99365ab 100644 --- a/package/ath9k/src/drivers/net/wireless/ath9k/regd.c +++ b/package/ath9k/src/drivers/net/wireless/ath9k/regd.c @@ -16,7 +16,7 @@ #include <linux/kernel.h> #include <linux/slab.h> -#include "ath9k.h" +#include "core.h" #include "regd.h" #include "regd_common.h" @@ -50,18 +50,18 @@ static u_int16_t ath9k_regd_get_eepromRD(struct ath_hal *ah) return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG; } -static enum hal_bool ath9k_regd_is_chan_bm_zero(u_int64_t *bitmask) +static bool ath9k_regd_is_chan_bm_zero(u_int64_t *bitmask) { int i; for (i = 0; i < BMLEN; i++) { if (bitmask[i] != 0) - return AH_FALSE; + return false; } - return AH_TRUE; + return true; } -static enum hal_bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) +static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) { u_int16_t rd = ath9k_regd_get_eepromRD(ah); int i; @@ -70,52 +70,49 @@ static enum hal_bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) u_int16_t cc = rd & ~COUNTRY_ERD_FLAG; for (i = 0; i < ARRAY_SIZE(allCountries); i++) if (allCountries[i].countryCode == cc) - return AH_TRUE; + return true; } else { for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) if (regDomainPairs[i].regDmnEnum == rd) - return AH_TRUE; + return true; } - HDPRINTF(ah, HAL_DBG_REGULATORY, + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: invalid regulatory domain/country code 0x%x\n", __func__, rd); - return AH_FALSE; + return false; } -static enum hal_bool ath9k_regd_is_fcc_midband_supported(struct ath_hal - *ah) +static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah) { u_int32_t regcap; regcap = ah->ah_caps.halRegCap; if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND) - return AH_TRUE; + return true; else - return AH_FALSE; + return false; } -static enum hal_bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, - u_int16_t cc) +static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, + u_int16_t cc) { u_int16_t rd; int i; if (cc == CTRY_DEFAULT) - return AH_TRUE; -#ifdef AH_DEBUG_COUNTRY + return true; if (cc == CTRY_DEBUG) - return AH_TRUE; -#endif + return true; + rd = ath9k_regd_get_eepromRD(ah); - HDPRINTF(ah, HAL_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n", + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n", __func__, rd); if (rd & COUNTRY_ERD_FLAG) { - - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: EEPROM setting is country code %u\n", - __func__, rd & ~COUNTRY_ERD_FLAG); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: EEPROM setting is country code %u\n", + __func__, rd & ~COUNTRY_ERD_FLAG); return cc == (rd & ~COUNTRY_ERD_FLAG); } @@ -123,14 +120,14 @@ static enum hal_bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, if (cc == allCountries[i].countryCode) { #ifdef AH_SUPPORT_11D if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) - return AH_TRUE; + return true; #endif if (allCountries[i].regDmnEnum == rd || rd == DEBUG_REG_DMN || rd == NO_ENUMRD) - return AH_TRUE; + return true; } } - return AH_FALSE; + return false; } static u_int @@ -175,7 +172,7 @@ ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, return modesAvail; } -enum hal_bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) +bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) { u_int16_t rd; @@ -184,18 +181,18 @@ enum hal_bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) switch (rd) { case FCC4_FCCA: case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG): - return AH_TRUE; + return true; case DEBUG_REG_DMN: case NO_ENUMRD: if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49) - return AH_TRUE; + return true; break; } - return AH_FALSE; + return false; } -static struct country_code_to_enum_rd *ath9k_regd_find_country(u_int16_t - countryCode) +static struct country_code_to_enum_rd* +ath9k_regd_find_country(u_int16_t countryCode) { int i; @@ -231,8 +228,8 @@ static u_int16_t ath9k_regd_get_default_country(struct ath_hal *ah) return CTRY_DEFAULT; } -static enum hal_bool ath9k_regd_is_valid_reg_domain(int regDmn, - struct regDomain *rd) +static bool ath9k_regd_is_valid_reg_domain(int regDmn, + struct regDomain *rd) { int i; @@ -242,26 +239,26 @@ static enum hal_bool ath9k_regd_is_valid_reg_domain(int regDmn, memcpy(rd, ®Domains[i], sizeof(struct regDomain)); } - return AH_TRUE; + return true; } } - return AH_FALSE; + return false; } -static enum hal_bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair) +static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair) { int i; if (regDmnPair == NO_ENUMRD) - return AH_FALSE; + return false; for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { if (regDomainPairs[i].regDmnEnum == regDmnPair) - return AH_TRUE; + return true; } - return AH_FALSE; + return false; } -static enum hal_bool +static bool ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, u_int16_t channelFlag, struct regDomain *rd) { @@ -284,7 +281,6 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, } if ((regDmn & MULTI_DOMAIN_MASK) == 0) { - for (i = 0, found = 0; (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) { if (regDomainPairs[i].regDmnEnum == regDmn) { @@ -293,10 +289,10 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, } } if (!found) { - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: Failed to find reg domain pair %u\n", - __func__, regDmn); - return AH_FALSE; + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: Failed to find reg domain pair %u\n", + __func__, regDmn); + return false; } if (!(channelFlag & CHANNEL_2GHZ)) { regDmn = regPair->regDmn5GHz; @@ -310,10 +306,10 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, found = ath9k_regd_is_valid_reg_domain(regDmn, rd); if (!found) { - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: Failed to find unitary reg domain %u\n", - __func__, regDmn); - return AH_FALSE; + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: Failed to find unitary reg domain %u\n", + __func__, regDmn); + return false; } else { rd->pscan &= regPair->pscanMask; if (((regOrg & MULTI_DOMAIN_MASK) == 0) && @@ -323,11 +319,11 @@ ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, rd->flags &= (channelFlag & CHANNEL_2GHZ) ? REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK; - return AH_TRUE; + return true; } } -static enum hal_bool ath9k_regd_is_bit_set(int bit, u_int64_t *bitmask) +static bool ath9k_regd_is_bit_set(int bit, u_int64_t *bitmask) { int byteOffset, bitnum; u_int64_t val; @@ -336,9 +332,9 @@ static enum hal_bool ath9k_regd_is_bit_set(int bit, u_int64_t *bitmask) bitnum = bit - byteOffset * 64; val = ((u_int64_t) 1) << bitnum; if (bitmask[byteOffset] & val) - return AH_TRUE; + return true; else - return AH_FALSE; + return false; } static void @@ -367,11 +363,11 @@ ath9k_regd_add_reg_classid(u_int8_t *regclassids, u_int maxregids, return; } -static enum hal_bool +static bool ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah, enum reg_ext_bitmap bit) { - return (ah->ah_currentRDExt & (1 << bit)) ? AH_TRUE : AH_FALSE; + return (ah->ah_currentRDExt & (1 << bit)) ? true : false; } #ifdef ATH_NF_PER_CHAN @@ -397,13 +393,193 @@ static void ath9k_regd_init_rf_buffer(struct hal_channel_internal *ichans, } #endif -enum hal_bool +static bool +ath9k_regd_add_channel(struct ath_hal *ah, + u_int16_t c, + u_int16_t c_lo, + u_int16_t c_hi, + u_int16_t maxChan, + u_int8_t ctl, + int pos, + struct regDomain rd5GHz, + struct RegDmnFreqBand *fband, + struct regDomain *rd, + const struct cmode *cm, + struct hal_channel_internal *ichans, + bool enableExtendedChannels) +{ + struct hal_channel_internal icv; + + if (!(c_lo <= c && c <= c_hi)) { + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: c %u out of range [%u..%u]\n", + __func__, c, c_lo, c_hi); + return false; + } + if ((fband->channelBW == CHANNEL_HALF_BW) && + !ah->ah_caps.halChanHalfRate) { + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: Skipping %u half rate channel\n", + __func__, c); + return false; + } + + if ((fband->channelBW == CHANNEL_QUARTER_BW) && + !ah->ah_caps.halChanQuarterRate) { + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: Skipping %u quarter rate channel\n", + __func__, c); + return false; + } + + if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) { + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: c %u > maxChan %u\n", + __func__, 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 == HAL_M_HOSTAP)) { + 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; + } + + memset(&icv, 0, sizeof(icv)); + icv.channel = c; + icv.channelFlags = cm->flags; + + switch (fband->channelBW) { + case CHANNEL_HALF_BW: + icv.channelFlags |= CHANNEL_HALF; + break; + case CHANNEL_QUARTER_BW: + icv.channelFlags |= CHANNEL_QUARTER; + break; + } + + icv.maxRegTxPower = fband->powerDfs; + icv.antennaMax = fband->antennaMax; + icv.regDmnFlags = rd->flags; + icv.conformanceTestLimit = ctl; + if (fband->usePassScan & rd->pscan) + icv.channelFlags |= CHANNEL_PASSIVE; + else + icv.channelFlags &= ~CHANNEL_PASSIVE; + if (fband->useDfs & rd->dfsMask) + icv.privFlags = CHANNEL_DFS; + else + icv.privFlags = 0; + if (rd->flags & LIMIT_FRAME_4MS) + icv.privFlags |= CHANNEL_4MS_LIMIT; + if (icv.privFlags & CHANNEL_DFS) + icv.privFlags |= CHANNEL_DISALLOW_ADHOC; + if (icv.regDmnFlags & ADHOC_PER_11D) + icv.privFlags |= CHANNEL_PER_11D_ADHOC; + + if (icv.channelFlags & CHANNEL_PASSIVE) { + if ((icv.channel < 2412) || (icv.channel > 2462)) { + if (rd5GHz.regDmnEnum == MKK1 || + rd5GHz.regDmnEnum == MKK2) { + u_int32_t regcap = ah->ah_caps.halRegCap; + if (!(regcap & + (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | + AR_EEPROM_EEREGCAP_EN_KK_U2 | + AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) && + isUNII1OddChan(icv.channel)) { + icv.channelFlags &= ~CHANNEL_PASSIVE; + } else { + icv.privFlags |= CHANNEL_DISALLOW_ADHOC; + } + } else { + icv.privFlags |= CHANNEL_DISALLOW_ADHOC; + } + } + } + + if (cm->mode & (ATH9K_MODE_SEL_11A | + ATH9K_MODE_SEL_11NA_HT20 | + ATH9K_MODE_SEL_11NA_HT40PLUS | + ATH9K_MODE_SEL_11NA_HT40MINUS)) { + if (icv.regDmnFlags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A)) + icv.privFlags |= CHANNEL_DISALLOW_ADHOC; + } + + memcpy(&ichans[pos], &icv, + sizeof(struct hal_channel_internal)); + + return true; +} + +static bool ath9k_regd_japan_check(struct ath_hal *ah, + int b, + struct regDomain *rd5GHz) +{ + bool skipband = false; + int i; + u_int32_t regcap; + + for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) { + if (j_bandcheck[i].freqbandbit == b) { + regcap = ah->ah_caps.halRegCap; + 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, + "%s: Skipping %d freq band\n", + __func__, j_bandcheck[i].freqbandbit); + + return skipband; +} + +bool ath9k_regd_init_channels(struct ath_hal *ah, struct hal_channel *chans, u_int maxchans, u_int *nchans, u_int8_t *regclassids, u_int maxregids, u_int *nregids, u_int16_t cc, - u_int32_t modeSelect, enum hal_bool enableOutdoor, - enum hal_bool enableExtendedChannels) + u_int32_t modeSelect, bool enableOutdoor, + bool enableExtendedChannels) { u_int modesAvail; u_int16_t maxChan = 7000; @@ -413,41 +589,36 @@ ath9k_regd_init_channels(struct ath_hal *ah, struct hal_channel_internal *ichans = &ah->ah_channels[0]; int next = 0, b; u_int8_t ctl; - int is_quarterchan_cap, is_halfchan_cap; int regdmn; u_int16_t chanSep; - HDPRINTF(ah, HAL_DBG_REGULATORY, "%s: cc %u mode 0x%x%s%s\n", + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u mode 0x%x%s%s\n", __func__, cc, modeSelect, enableOutdoor ? " Enable outdoor" : " ", enableExtendedChannels ? " Enable ecm" : ""); if (!ath9k_regd_is_ccode_valid(ah, cc)) { - - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: invalid country code %d\n", __func__, cc); - return AH_FALSE; + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: invalid country code %d\n", __func__, cc); + return false; } if (!ath9k_regd_is_eeprom_valid(ah)) { - - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: invalid EEPROM contents\n", __func__); - return AH_FALSE; + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: invalid EEPROM contents\n", __func__); + return false; } ah->ah_countryCode = ath9k_regd_get_default_country(ah); if (ah->ah_countryCode == CTRY_DEFAULT) { - ah->ah_countryCode = cc & COUNTRY_CODE_MASK; - if ((ah->ah_countryCode == CTRY_DEFAULT) && (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) { - ah->ah_countryCode = CTRY_UNITED_STATES; } } + #ifdef AH_SUPPORT_11D if (ah->ah_countryCode == CTRY_DEFAULT) { regdmn = ath9k_regd_get_eepromRD(ah); @@ -455,22 +626,19 @@ ath9k_regd_init_channels(struct ath_hal *ah, } else { #endif country = ath9k_regd_find_country(ah->ah_countryCode); - if (country == NULL) { - HDPRINTF(ah, HAL_DBG_REGULATORY, - "Country is NULL!!!!, cc= %d\n", - ah->ah_countryCode); - return AH_FALSE; + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "Country is NULL!!!!, cc= %d\n", + ah->ah_countryCode); + return false; } else { regdmn = country->regDmnEnum; #ifdef AH_SUPPORT_11D - if (((ath9k_regd_get_eepromRD(ah) & WORLD_SKU_MASK) - == WORLD_SKU_PREFIX) - && (cc == CTRY_UNITED_STATES)) { + 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)) + && ath9k_regd_is_fcc_midband_supported(ah)) regdmn = FCC3_FCCA; else regdmn = FCC1_FCCA; @@ -480,36 +648,39 @@ ath9k_regd_init_channels(struct ath_hal *ah, #ifdef AH_SUPPORT_11D } #endif - - if (!ath9k_regd_get_wmode_regdomain - (ah, regdmn, ~CHANNEL_2GHZ, &rd5GHz)) { - HDPRINTF(ah, HAL_DBG_REGULATORY, + if (!ath9k_regd_get_wmode_regdomain(ah, + regdmn, + ~CHANNEL_2GHZ, + &rd5GHz)) { + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: couldn't find unitary " "5GHz reg domain for country %u\n", - __func__, ah->ah_countryCode); - return AH_FALSE; + __func__, ah->ah_countryCode); + return false; } - if (!ath9k_regd_get_wmode_regdomain - (ah, regdmn, CHANNEL_2GHZ, &rd2GHz)) { - HDPRINTF(ah, HAL_DBG_REGULATORY, + if (!ath9k_regd_get_wmode_regdomain(ah, + regdmn, + CHANNEL_2GHZ, + &rd2GHz)) { + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: couldn't find unitary 2GHz " "reg domain for country %u\n", - __func__, ah->ah_countryCode); - return AH_FALSE; + __func__, ah->ah_countryCode); + return false; } - if (!isWwrSKU(ah) - && ((rd5GHz.regDmnEnum == FCC1) - || (rd5GHz.regDmnEnum == FCC2))) { + if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) || + (rd5GHz.regDmnEnum == FCC2))) { if (ath9k_regd_is_fcc_midband_supported(ah)) { - - if (!ath9k_regd_get_wmode_regdomain - (ah, FCC3_FCCA, ~CHANNEL_2GHZ, &rd5GHz)) { - HDPRINTF(ah, HAL_DBG_REGULATORY, + if (!ath9k_regd_get_wmode_regdomain(ah, + FCC3_FCCA, + ~CHANNEL_2GHZ, + &rd5GHz)) { + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: couldn't find unitary 5GHz " "reg domain for country %u\n", - __func__, ah->ah_countryCode); - return AH_FALSE; + __func__, ah->ah_countryCode); + return false; } } } @@ -517,9 +688,7 @@ ath9k_regd_init_channels(struct ath_hal *ah, if (country == NULL) { modesAvail = ah->ah_caps.halWirelessModes; } else { - modesAvail = - ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz); - + modesAvail = ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz); if (!enableOutdoor) maxChan = country->outdoorChanStart; } @@ -529,8 +698,6 @@ ath9k_regd_init_channels(struct ath_hal *ah, if (maxchans > ARRAY_SIZE(ah->ah_channels)) maxchans = ARRAY_SIZE(ah->ah_channels); - is_halfchan_cap = ah->ah_caps.halChanHalfRate; - is_quarterchan_cap = ah->ah_caps.halChanQuarterRate; for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) { u_int16_t c, c_hi, c_lo; u_int64_t *channelBM = NULL; @@ -539,26 +706,26 @@ ath9k_regd_init_channels(struct ath_hal *ah, int8_t low_adj = 0, hi_adj = 0; if ((cm->mode & modeSelect) == 0) { - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: skip mode 0x%x flags 0x%x\n", - __func__, cm->mode, cm->flags); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: skip mode 0x%x flags 0x%x\n", + __func__, cm->mode, cm->flags); continue; } if ((cm->mode & modesAvail) == 0) { - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: !avail mode 0x%x (0x%x) flags 0x%x\n", - __func__, modesAvail, cm->mode, - cm->flags); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: !avail mode 0x%x (0x%x) flags 0x%x\n", + __func__, modesAvail, cm->mode, + cm->flags); continue; } if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { - - HDPRINTF(ah, HAL_DBG_REGULATORY, + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: channels 0x%x not supported " "by hardware\n", - __func__, cm->flags); + __func__, cm->flags); continue; } + switch (cm->mode) { case ATH9K_MODE_SEL_11A: case ATH9K_MODE_SEL_11NA_HT20: @@ -585,15 +752,15 @@ ath9k_regd_init_channels(struct ath_hal *ah, ctl = rd->conformanceTestLimit | CTL_11G; break; default: - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: Unkonwn HAL mode 0x%x\n", __func__, - cm->mode); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: Unknown HAL mode 0x%x\n", __func__, + cm->mode); continue; } + if (ath9k_regd_is_chan_bm_zero(channelBM)) continue; - if ((cm->mode == ATH9K_MODE_SEL_11NA_HT40PLUS) || (cm->mode == ATH9K_MODE_SEL_11NG_HT40PLUS)) { hi_adj = -20; @@ -608,57 +775,12 @@ ath9k_regd_init_channels(struct ath_hal *ah, 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) { - int i, skipband = 0; - u_int32_t regcap; - - for (i = 0; - i < ARRAY_SIZE(j_bandcheck); - i++) { - if (j_bandcheck[i]. - freqbandbit == b) { - regcap = - ah->ah_caps. - halRegCap; - if ((j_bandcheck - [i]. - eepromflagtocheck - & regcap) == - 0) { - skipband = - 1; - } 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; - } - } - if (skipband) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "%s: Skipping %d " - "freq band.\n", - __func__, - j_bandcheck[i]. - freqbandbit); + if (ath9k_regd_japan_check(ah, + b, + &rd5GHz)) continue; - } } ath9k_regd_add_reg_classid(regclassids, @@ -667,12 +789,8 @@ ath9k_regd_init_channels(struct ath_hal *ah, fband-> regClassId); - if (IS_HT40_MODE(cm->mode) - && (rd == &rd5GHz)) { - + if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) { chanSep = 40; - - if (fband->lowChannel == 5280) low_adj += 20; @@ -682,263 +800,59 @@ ath9k_regd_init_channels(struct ath_hal *ah, chanSep = fband->channelSep; for (c = fband->lowChannel + low_adj; - ((c <= (fband->highChannel + hi_adj)) - && (c >= - (fband->lowChannel + low_adj))); + ((c <= (fband->highChannel + hi_adj)) && + (c >= (fband->lowChannel + low_adj))); c += chanSep) { - struct hal_channel_internal icv; - - if (!(c_lo <= c && c <= c_hi)) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "%s: c %u out of " - "range [%u..%u]\n", - __func__, c, c_lo, - c_hi); - continue; - } - if ((fband->channelBW == - CHANNEL_HALF_BW) && - !is_halfchan_cap) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "%s: Skipping %u half " - "rate channel\n", - __func__, c); - continue; - } - - if ((fband->channelBW == - CHANNEL_QUARTER_BW) && - !is_quarterchan_cap) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "%s: Skipping %u " - "quarter rate " - "channel\n", - __func__, c); - continue; - } - - if (((c + fband->channelSep) / 2) > - (maxChan + HALF_MAXCHANBW)) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "%s: c %u > " - "maxChan %u\n", - __func__, c, - maxChan); - continue; - } if (next >= maxchans) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "%s: too many " - "channels for channel " - "table\n", - __func__); + DPRINTF(ah->ah_sc, + ATH_DBG_REGULATORY, + "%s: too many channels " + "for channel table\n", + __func__); goto done; } - if ((fband-> - usePassScan & IS_ECM_CHAN) - && !enableExtendedChannels) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "Skipping ecm " - "channel\n"); - continue; - } - if ((rd->flags & NO_HOSTAP) && - (ah->ah_opmode == - HAL_M_HOSTAP)) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "Skipping HOSTAP " - "channel\n"); - continue; - } - if (IS_HT40_MODE(cm->mode) && - ! - (ath9k_regd_get_eeprom_reg_ext_bits - (ah, REG_EXT_FCC_DFS_HT40)) - && (fband->useDfs) - && (rd->conformanceTestLimit != - MKK)) { - - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "Skipping HT40 " - "channel " - "(en_fcc_dfs_ht40 = " - "0)\n"); - continue; - } - if (IS_HT40_MODE(cm->mode) && - ! - (ath9k_regd_get_eeprom_reg_ext_bits - (ah, - REG_EXT_JAPAN_NONDFS_HT40)) - && !(fband->useDfs) - && (rd->conformanceTestLimit == - MKK)) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "Skipping HT40 " - "channel (en_jap_ht40 " - "= 0)\n"); - continue; - } - if (IS_HT40_MODE(cm->mode) && - ! - (ath9k_regd_get_eeprom_reg_ext_bits - (ah, REG_EXT_JAPAN_DFS_HT40)) - && (fband->useDfs) - && (rd->conformanceTestLimit == - MKK)) { - HDPRINTF(ah, - HAL_DBG_REGULATORY, - "Skipping HT40 channel" - " (en_jap_dfs_ht40 = " - "0)\n"); - continue; - } - memset(&icv, 0, sizeof(icv)); - icv.channel = c; - icv.channelFlags = cm->flags; - - switch (fband->channelBW) { - case CHANNEL_HALF_BW: - icv.channelFlags |= - CHANNEL_HALF; - break; - case CHANNEL_QUARTER_BW: - icv.channelFlags |= - CHANNEL_QUARTER; - break; - } - - icv.maxRegTxPower = - fband->powerDfs; - icv.antennaMax = fband->antennaMax; - icv.regDmnFlags = rd->flags; - icv.conformanceTestLimit = ctl; - if (fband->usePassScan & rd->pscan) - icv.channelFlags |= - CHANNEL_PASSIVE; - else - icv.channelFlags &= - ~CHANNEL_PASSIVE; - if (fband->useDfs & rd->dfsMask) - icv.privFlags = - CHANNEL_DFS; - else - icv.privFlags = 0; - if (rd->flags & LIMIT_FRAME_4MS) - icv.privFlags |= - CHANNEL_4MS_LIMIT; - - if (icv.privFlags & CHANNEL_DFS) { - icv.privFlags |= - CHANNEL_DISALLOW_ADHOC; - } - if (icv. - regDmnFlags & ADHOC_PER_11D) { - icv.privFlags |= - CHANNEL_PER_11D_ADHOC; - } - if (icv. - channelFlags & CHANNEL_PASSIVE) { - - if ((icv.channel < 2412) - || (icv.channel > - 2462)) { - if (rd5GHz. - regDmnEnum == - MKK1 - || rd5GHz. - regDmnEnum == - MKK2) { - u_int32_t - regcap - = - ah-> - ah_caps. - halRegCap; - if (! - (regcap - & - (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN - | - AR_EEPROM_EEREGCAP_EN_KK_U2 - | - AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) -&& isUNII1OddChan(icv.channel)) { - - icv.channelFlags &= ~CHANNEL_PASSIVE; - } else { - icv.privFlags |= CHANNEL_DISALLOW_ADHOC; - } - } else { - icv.privFlags |= CHANNEL_DISALLOW_ADHOC; - } - } - } - if (cm-> - mode & (ATH9K_MODE_SEL_11A | - ATH9K_MODE_SEL_11NA_HT20 - | - ATH9K_MODE_SEL_11NA_HT40PLUS - | - ATH9K_MODE_SEL_11NA_HT40MINUS)) { - if (icv. - regDmnFlags & - (ADHOC_NO_11A | - DISALLOW_ADHOC_11A)) { - icv.privFlags |= - CHANNEL_DISALLOW_ADHOC; - } - } - - memcpy(&ichans[next++], &icv, - sizeof(struct - hal_channel_internal)); + 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)) { + if (IS_HT40_MODE(cm->mode) && + (fband->lowChannel == 5280)) { low_adj -= 20; } } } } done: - if (next != 0) { + if (next != 0) { int i; - if (next > ARRAY_SIZE(ah->ah_channels)) { - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: too many channels %u; truncating to %u\n", - __func__, next, - (int) ARRAY_SIZE(ah->ah_channels)); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: too many channels %u; truncating to %u\n", + __func__, next, + (int) ARRAY_SIZE(ah->ah_channels)); 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 hal_channel_internal), ath9k_regd_chansort); ah->ah_nchan = next; - HDPRINTF(ah, HAL_DBG_REGULATORY, "Channel list:\n"); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n"); for (i = 0; i < next; i++) { - HDPRINTF(ah, HAL_DBG_REGULATORY, - "chan: %d flags: 0x%x\n", - ichans[i].channel, - ichans[i].channelFlags); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "chan: %d flags: 0x%x\n", + ichans[i].channel, + ichans[i].channelFlags); chans[i].channel = ichans[i].channel; chans[i].channelFlags = ichans[i].channelFlags; chans[i].privFlags = ichans[i].privFlags; @@ -965,20 +879,22 @@ done: ah->ah_iso[0] = country->isoName[0]; ah->ah_iso[1] = country->isoName[1]; } + return next != 0; } -struct hal_channel_internal *ath9k_regd_check_channel(struct ath_hal *ah, - const struct hal_channel *c) +struct hal_channel_internal* +ath9k_regd_check_channel(struct ath_hal *ah, + const struct hal_channel *c) { struct hal_channel_internal *base, *cc; int flags = c->channelFlags & CHAN_FLAGS; int n, lim; - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: channel %u/0x%x (0x%x) requested\n", __func__, - c->channel, c->channelFlags, flags); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: channel %u/0x%x (0x%x) requested\n", __func__, + c->channel, c->channelFlags, flags); cc = ah->ah_curchan; if (cc != NULL && cc->channel == c->channel && @@ -999,24 +915,24 @@ struct hal_channel_internal *ath9k_regd_check_channel(struct ath_hal *ah, d = c->channel - cc->channel; if (d == 0) { if ((cc->channelFlags & CHAN_FLAGS) == flags) { - if ((cc->privFlags & CHANNEL_INTERFERENCE) - && (cc->privFlags & CHANNEL_DFS)) + if ((cc->privFlags & CHANNEL_INTERFERENCE) && + (cc->privFlags & CHANNEL_DFS)) return NULL; else return cc; } d = flags - (cc->channelFlags & CHAN_FLAGS); } - HDPRINTF(ah, HAL_DBG_REGULATORY, - "%s: channel %u/0x%x d %d\n", __func__, - cc->channel, cc->channelFlags, d); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "%s: channel %u/0x%x d %d\n", __func__, + cc->channel, cc->channelFlags, d); if (d > 0) { base = cc + 1; lim--; } } - HDPRINTF(ah, HAL_DBG_REGULATORY, "%s: no match for %u/0x%x\n", - __func__, c->channel, c->channelFlags); + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: no match for %u/0x%x\n", + __func__, c->channel, c->channelFlags); return NULL; } @@ -1062,9 +978,9 @@ void ath9k_regd_get_current_country(struct ath_hal *ah, { u_int16_t rd = ath9k_regd_get_eepromRD(ah); - ctry->isMultidomain = AH_FALSE; + ctry->isMultidomain = false; if (rd == CTRY_DEFAULT) - ctry->isMultidomain = AH_TRUE; + ctry->isMultidomain = true; else if (!(rd & COUNTRY_ERD_FLAG)) ctry->isMultidomain = isWwrSKU(ah); |