1*dd1de374Slin wang - Sun Microsystems - Beijing China /* 2*dd1de374Slin wang - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 3*dd1de374Slin wang - Sun Microsystems - Beijing China * Use is subject to license terms. 4*dd1de374Slin wang - Sun Microsystems - Beijing China */ 5*dd1de374Slin wang - Sun Microsystems - Beijing China 6*dd1de374Slin wang - Sun Microsystems - Beijing China /* 7*dd1de374Slin wang - Sun Microsystems - Beijing China * Copyright (c) 2008 Atheros Communications Inc. 8*dd1de374Slin wang - Sun Microsystems - Beijing China * 9*dd1de374Slin wang - Sun Microsystems - Beijing China * Permission to use, copy, modify, and/or distribute this software for any 10*dd1de374Slin wang - Sun Microsystems - Beijing China * purpose with or without fee is hereby granted, provided that the above 11*dd1de374Slin wang - Sun Microsystems - Beijing China * copyright notice and this permission notice appear in all copies. 12*dd1de374Slin wang - Sun Microsystems - Beijing China * 13*dd1de374Slin wang - Sun Microsystems - Beijing China * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 14*dd1de374Slin wang - Sun Microsystems - Beijing China * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 15*dd1de374Slin wang - Sun Microsystems - Beijing China * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 16*dd1de374Slin wang - Sun Microsystems - Beijing China * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 17*dd1de374Slin wang - Sun Microsystems - Beijing China * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 18*dd1de374Slin wang - Sun Microsystems - Beijing China * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 19*dd1de374Slin wang - Sun Microsystems - Beijing China * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 20*dd1de374Slin wang - Sun Microsystems - Beijing China */ 21*dd1de374Slin wang - Sun Microsystems - Beijing China 22*dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_core.h" 23*dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_hw.h" 24*dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_regd.h" 25*dd1de374Slin wang - Sun Microsystems - Beijing China #include "arn_regd_common.h" 26*dd1de374Slin wang - Sun Microsystems - Beijing China 27*dd1de374Slin wang - Sun Microsystems - Beijing China static int 28*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_chansort(const void *a, const void *b) 29*dd1de374Slin wang - Sun Microsystems - Beijing China { 30*dd1de374Slin wang - Sun Microsystems - Beijing China const struct ath9k_channel *ca = a; 31*dd1de374Slin wang - Sun Microsystems - Beijing China const struct ath9k_channel *cb = b; 32*dd1de374Slin wang - Sun Microsystems - Beijing China 33*dd1de374Slin wang - Sun Microsystems - Beijing China return (ca->channel == cb->channel) ? 34*dd1de374Slin wang - Sun Microsystems - Beijing China (ca->channelFlags & CHAN_FLAGS) - 35*dd1de374Slin wang - Sun Microsystems - Beijing China (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel; 36*dd1de374Slin wang - Sun Microsystems - Beijing China } 37*dd1de374Slin wang - Sun Microsystems - Beijing China 38*dd1de374Slin wang - Sun Microsystems - Beijing China static void 39*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_sort(void *a, uint32_t n, uint32_t size, ath_hal_cmp_t *cmp) 40*dd1de374Slin wang - Sun Microsystems - Beijing China { 41*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t *aa = a; 42*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t *ai, *t; 43*dd1de374Slin wang - Sun Microsystems - Beijing China 44*dd1de374Slin wang - Sun Microsystems - Beijing China for (ai = aa + size; --n >= 1; ai += size) 45*dd1de374Slin wang - Sun Microsystems - Beijing China for (t = ai; t > aa; t -= size) { 46*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t *u = t - size; 47*dd1de374Slin wang - Sun Microsystems - Beijing China if (cmp(u, t) <= 0) 48*dd1de374Slin wang - Sun Microsystems - Beijing China break; 49*dd1de374Slin wang - Sun Microsystems - Beijing China swap(u, t, size); 50*dd1de374Slin wang - Sun Microsystems - Beijing China } 51*dd1de374Slin wang - Sun Microsystems - Beijing China } 52*dd1de374Slin wang - Sun Microsystems - Beijing China 53*dd1de374Slin wang - Sun Microsystems - Beijing China static uint16_t 54*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_eepromRD(struct ath_hal *ah) 55*dd1de374Slin wang - Sun Microsystems - Beijing China { 56*dd1de374Slin wang - Sun Microsystems - Beijing China return (ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG); 57*dd1de374Slin wang - Sun Microsystems - Beijing China } 58*dd1de374Slin wang - Sun Microsystems - Beijing China 59*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 60*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_chan_bm_zero(uint64_t *bitmask) 61*dd1de374Slin wang - Sun Microsystems - Beijing China { 62*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 63*dd1de374Slin wang - Sun Microsystems - Beijing China 64*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < BMLEN; i++) { 65*dd1de374Slin wang - Sun Microsystems - Beijing China if (bitmask[i] != 0) 66*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 67*dd1de374Slin wang - Sun Microsystems - Beijing China } 68*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 69*dd1de374Slin wang - Sun Microsystems - Beijing China } 70*dd1de374Slin wang - Sun Microsystems - Beijing China 71*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 72*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_eeprom_valid(struct ath_hal *ah) 73*dd1de374Slin wang - Sun Microsystems - Beijing China { 74*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t rd = ath9k_regd_get_eepromRD(ah); 75*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 76*dd1de374Slin wang - Sun Microsystems - Beijing China 77*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd & COUNTRY_ERD_FLAG) { 78*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t cc = rd & ~COUNTRY_ERD_FLAG; 79*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(allCountries); i++) 80*dd1de374Slin wang - Sun Microsystems - Beijing China if (allCountries[i].countryCode == cc) 81*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 82*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 83*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) 84*dd1de374Slin wang - Sun Microsystems - Beijing China if (regDomainPairs[i].regDmnEnum == rd) 85*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 86*dd1de374Slin wang - Sun Microsystems - Beijing China } 87*dd1de374Slin wang - Sun Microsystems - Beijing China 88*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 89*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: invalid regulatory domain/country code 0x%x\n", 90*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, rd)); 91*dd1de374Slin wang - Sun Microsystems - Beijing China 92*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 93*dd1de374Slin wang - Sun Microsystems - Beijing China } 94*dd1de374Slin wang - Sun Microsystems - Beijing China 95*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 96*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah) 97*dd1de374Slin wang - Sun Microsystems - Beijing China { 98*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t regcap; 99*dd1de374Slin wang - Sun Microsystems - Beijing China 100*dd1de374Slin wang - Sun Microsystems - Beijing China regcap = ah->ah_caps.reg_cap; 101*dd1de374Slin wang - Sun Microsystems - Beijing China 102*dd1de374Slin wang - Sun Microsystems - Beijing China if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND) 103*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 104*dd1de374Slin wang - Sun Microsystems - Beijing China else 105*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 106*dd1de374Slin wang - Sun Microsystems - Beijing China } 107*dd1de374Slin wang - Sun Microsystems - Beijing China 108*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 109*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_ccode_valid(struct ath_hal *ah, uint16_t cc) 110*dd1de374Slin wang - Sun Microsystems - Beijing China { 111*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t rd; 112*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 113*dd1de374Slin wang - Sun Microsystems - Beijing China 114*dd1de374Slin wang - Sun Microsystems - Beijing China if (cc == CTRY_DEFAULT) 115*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 116*dd1de374Slin wang - Sun Microsystems - Beijing China if (cc == CTRY_DEBUG) 117*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 118*dd1de374Slin wang - Sun Microsystems - Beijing China 119*dd1de374Slin wang - Sun Microsystems - Beijing China rd = ath9k_regd_get_eepromRD(ah); 120*dd1de374Slin wang - Sun Microsystems - Beijing China 121*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n", 122*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, rd)); 123*dd1de374Slin wang - Sun Microsystems - Beijing China 124*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd & COUNTRY_ERD_FLAG) { 125*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 126*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: EEPROM setting is country code %u\n", 127*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, rd & ~COUNTRY_ERD_FLAG)); 128*dd1de374Slin wang - Sun Microsystems - Beijing China return (cc == (rd & ~COUNTRY_ERD_FLAG)); 129*dd1de374Slin wang - Sun Microsystems - Beijing China } 130*dd1de374Slin wang - Sun Microsystems - Beijing China 131*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 132*dd1de374Slin wang - Sun Microsystems - Beijing China if (cc == allCountries[i].countryCode) { 133*dd1de374Slin wang - Sun Microsystems - Beijing China #ifdef ARN_SUPPORT_11D 134*dd1de374Slin wang - Sun Microsystems - Beijing China if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) 135*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 136*dd1de374Slin wang - Sun Microsystems - Beijing China #endif 137*dd1de374Slin wang - Sun Microsystems - Beijing China if (allCountries[i].regDmnEnum == rd || 138*dd1de374Slin wang - Sun Microsystems - Beijing China rd == DEBUG_REG_DMN || rd == NO_ENUMRD) 139*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 140*dd1de374Slin wang - Sun Microsystems - Beijing China } 141*dd1de374Slin wang - Sun Microsystems - Beijing China } 142*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 143*dd1de374Slin wang - Sun Microsystems - Beijing China } 144*dd1de374Slin wang - Sun Microsystems - Beijing China 145*dd1de374Slin wang - Sun Microsystems - Beijing China static void 146*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, 147*dd1de374Slin wang - Sun Microsystems - Beijing China struct country_code_to_enum_rd *country, 148*dd1de374Slin wang - Sun Microsystems - Beijing China struct regDomain *rd5GHz, 149*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t *modes_allowed) 150*dd1de374Slin wang - Sun Microsystems - Beijing China 151*dd1de374Slin wang - Sun Microsystems - Beijing China { 152*dd1de374Slin wang - Sun Microsystems - Beijing China bcopy(ah->ah_caps.wireless_modes, modes_allowed, 153*dd1de374Slin wang - Sun Microsystems - Beijing China sizeof (ah->ah_caps.wireless_modes)); 154*dd1de374Slin wang - Sun Microsystems - Beijing China 155*dd1de374Slin wang - Sun Microsystems - Beijing China if (is_set(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) && 156*dd1de374Slin wang - Sun Microsystems - Beijing China (!country->allow11g)) 157*dd1de374Slin wang - Sun Microsystems - Beijing China clr_bit(ATH9K_MODE_11G, modes_allowed); 158*dd1de374Slin wang - Sun Microsystems - Beijing China 159*dd1de374Slin wang - Sun Microsystems - Beijing China if (is_set(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) && 160*dd1de374Slin wang - Sun Microsystems - Beijing China (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a))) 161*dd1de374Slin wang - Sun Microsystems - Beijing China clr_bit(ATH9K_MODE_11A, modes_allowed); 162*dd1de374Slin wang - Sun Microsystems - Beijing China 163*dd1de374Slin wang - Sun Microsystems - Beijing China if (is_set(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes) && 164*dd1de374Slin wang - Sun Microsystems - Beijing China (!country->allow11ng20)) 165*dd1de374Slin wang - Sun Microsystems - Beijing China clr_bit(ATH9K_MODE_11NG_HT20, modes_allowed); 166*dd1de374Slin wang - Sun Microsystems - Beijing China 167*dd1de374Slin wang - Sun Microsystems - Beijing China if (is_set(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes) && 168*dd1de374Slin wang - Sun Microsystems - Beijing China (!country->allow11na20)) 169*dd1de374Slin wang - Sun Microsystems - Beijing China clr_bit(ATH9K_MODE_11NA_HT20, modes_allowed); 170*dd1de374Slin wang - Sun Microsystems - Beijing China 171*dd1de374Slin wang - Sun Microsystems - Beijing China if (is_set(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) && 172*dd1de374Slin wang - Sun Microsystems - Beijing China (!country->allow11ng40)) 173*dd1de374Slin wang - Sun Microsystems - Beijing China clr_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed); 174*dd1de374Slin wang - Sun Microsystems - Beijing China 175*dd1de374Slin wang - Sun Microsystems - Beijing China if (is_set(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) && 176*dd1de374Slin wang - Sun Microsystems - Beijing China (!country->allow11ng40)) 177*dd1de374Slin wang - Sun Microsystems - Beijing China clr_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed); 178*dd1de374Slin wang - Sun Microsystems - Beijing China 179*dd1de374Slin wang - Sun Microsystems - Beijing China if (is_set(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) && 180*dd1de374Slin wang - Sun Microsystems - Beijing China (!country->allow11na40)) 181*dd1de374Slin wang - Sun Microsystems - Beijing China clr_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed); 182*dd1de374Slin wang - Sun Microsystems - Beijing China 183*dd1de374Slin wang - Sun Microsystems - Beijing China if (is_set(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) && 184*dd1de374Slin wang - Sun Microsystems - Beijing China (!country->allow11na40)) 185*dd1de374Slin wang - Sun Microsystems - Beijing China clr_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed); 186*dd1de374Slin wang - Sun Microsystems - Beijing China } 187*dd1de374Slin wang - Sun Microsystems - Beijing China 188*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t 189*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_public_safety_sku(struct ath_hal *ah) 190*dd1de374Slin wang - Sun Microsystems - Beijing China { 191*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t rd; 192*dd1de374Slin wang - Sun Microsystems - Beijing China 193*dd1de374Slin wang - Sun Microsystems - Beijing China rd = ath9k_regd_get_eepromRD(ah); 194*dd1de374Slin wang - Sun Microsystems - Beijing China 195*dd1de374Slin wang - Sun Microsystems - Beijing China switch (rd) { 196*dd1de374Slin wang - Sun Microsystems - Beijing China case FCC4_FCCA: 197*dd1de374Slin wang - Sun Microsystems - Beijing China case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG): 198*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 199*dd1de374Slin wang - Sun Microsystems - Beijing China case DEBUG_REG_DMN: 200*dd1de374Slin wang - Sun Microsystems - Beijing China case NO_ENUMRD: 201*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49) 202*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 203*dd1de374Slin wang - Sun Microsystems - Beijing China break; 204*dd1de374Slin wang - Sun Microsystems - Beijing China } 205*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 206*dd1de374Slin wang - Sun Microsystems - Beijing China } 207*dd1de374Slin wang - Sun Microsystems - Beijing China 208*dd1de374Slin wang - Sun Microsystems - Beijing China static struct country_code_to_enum_rd * 209*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_find_country(uint16_t countryCode) 210*dd1de374Slin wang - Sun Microsystems - Beijing China { 211*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 212*dd1de374Slin wang - Sun Microsystems - Beijing China 213*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(allCountries); i++) { 214*dd1de374Slin wang - Sun Microsystems - Beijing China if (allCountries[i].countryCode == countryCode) 215*dd1de374Slin wang - Sun Microsystems - Beijing China return (&allCountries[i]); 216*dd1de374Slin wang - Sun Microsystems - Beijing China } 217*dd1de374Slin wang - Sun Microsystems - Beijing China return (NULL); 218*dd1de374Slin wang - Sun Microsystems - Beijing China } 219*dd1de374Slin wang - Sun Microsystems - Beijing China 220*dd1de374Slin wang - Sun Microsystems - Beijing China static uint16_t 221*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_default_country(struct ath_hal *ah) 222*dd1de374Slin wang - Sun Microsystems - Beijing China { 223*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t rd; 224*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 225*dd1de374Slin wang - Sun Microsystems - Beijing China 226*dd1de374Slin wang - Sun Microsystems - Beijing China rd = ath9k_regd_get_eepromRD(ah); 227*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd & COUNTRY_ERD_FLAG) { 228*dd1de374Slin wang - Sun Microsystems - Beijing China struct country_code_to_enum_rd *country = NULL; 229*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t cc = rd & ~COUNTRY_ERD_FLAG; 230*dd1de374Slin wang - Sun Microsystems - Beijing China 231*dd1de374Slin wang - Sun Microsystems - Beijing China country = ath9k_regd_find_country(cc); 232*dd1de374Slin wang - Sun Microsystems - Beijing China if (country != NULL) 233*dd1de374Slin wang - Sun Microsystems - Beijing China return (cc); 234*dd1de374Slin wang - Sun Microsystems - Beijing China } 235*dd1de374Slin wang - Sun Microsystems - Beijing China 236*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) 237*dd1de374Slin wang - Sun Microsystems - Beijing China if (regDomainPairs[i].regDmnEnum == rd) { 238*dd1de374Slin wang - Sun Microsystems - Beijing China if (regDomainPairs[i].singleCC != 0) 239*dd1de374Slin wang - Sun Microsystems - Beijing China return (regDomainPairs[i].singleCC); 240*dd1de374Slin wang - Sun Microsystems - Beijing China else 241*dd1de374Slin wang - Sun Microsystems - Beijing China i = ARRAY_SIZE(regDomainPairs); 242*dd1de374Slin wang - Sun Microsystems - Beijing China } 243*dd1de374Slin wang - Sun Microsystems - Beijing China return (CTRY_DEFAULT); 244*dd1de374Slin wang - Sun Microsystems - Beijing China } 245*dd1de374Slin wang - Sun Microsystems - Beijing China 246*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 247*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_valid_reg_domain(int regDmn, struct regDomain *rd) 248*dd1de374Slin wang - Sun Microsystems - Beijing China { 249*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 250*dd1de374Slin wang - Sun Microsystems - Beijing China 251*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(regDomains); i++) { 252*dd1de374Slin wang - Sun Microsystems - Beijing China if (regDomains[i].regDmnEnum == regDmn) { 253*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd != NULL) { 254*dd1de374Slin wang - Sun Microsystems - Beijing China (void) memcpy(rd, ®Domains[i], 255*dd1de374Slin wang - Sun Microsystems - Beijing China sizeof (struct regDomain)); 256*dd1de374Slin wang - Sun Microsystems - Beijing China } 257*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 258*dd1de374Slin wang - Sun Microsystems - Beijing China } 259*dd1de374Slin wang - Sun Microsystems - Beijing China } 260*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 261*dd1de374Slin wang - Sun Microsystems - Beijing China } 262*dd1de374Slin wang - Sun Microsystems - Beijing China 263*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 264*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_valid_reg_domainPair(int regDmnPair) 265*dd1de374Slin wang - Sun Microsystems - Beijing China { 266*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 267*dd1de374Slin wang - Sun Microsystems - Beijing China 268*dd1de374Slin wang - Sun Microsystems - Beijing China if (regDmnPair == NO_ENUMRD) 269*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 270*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { 271*dd1de374Slin wang - Sun Microsystems - Beijing China if (regDomainPairs[i].regDmnEnum == regDmnPair) 272*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 273*dd1de374Slin wang - Sun Microsystems - Beijing China } 274*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 275*dd1de374Slin wang - Sun Microsystems - Beijing China } 276*dd1de374Slin wang - Sun Microsystems - Beijing China 277*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 278*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, 279*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t channelFlag, struct regDomain *rd) 280*dd1de374Slin wang - Sun Microsystems - Beijing China { 281*dd1de374Slin wang - Sun Microsystems - Beijing China int i, found; 282*dd1de374Slin wang - Sun Microsystems - Beijing China uint64_t flags = NO_REQ; 283*dd1de374Slin wang - Sun Microsystems - Beijing China struct reg_dmn_pair_mapping *regPair = NULL; 284*dd1de374Slin wang - Sun Microsystems - Beijing China int regOrg; 285*dd1de374Slin wang - Sun Microsystems - Beijing China 286*dd1de374Slin wang - Sun Microsystems - Beijing China regOrg = regDmn; 287*dd1de374Slin wang - Sun Microsystems - Beijing China if (regDmn == CTRY_DEFAULT) { 288*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t rdnum; 289*dd1de374Slin wang - Sun Microsystems - Beijing China rdnum = ath9k_regd_get_eepromRD(ah); 290*dd1de374Slin wang - Sun Microsystems - Beijing China 291*dd1de374Slin wang - Sun Microsystems - Beijing China if (!(rdnum & COUNTRY_ERD_FLAG)) { 292*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) || 293*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_valid_reg_domainPair(rdnum)) { 294*dd1de374Slin wang - Sun Microsystems - Beijing China regDmn = rdnum; 295*dd1de374Slin wang - Sun Microsystems - Beijing China } 296*dd1de374Slin wang - Sun Microsystems - Beijing China } 297*dd1de374Slin wang - Sun Microsystems - Beijing China } 298*dd1de374Slin wang - Sun Microsystems - Beijing China 299*dd1de374Slin wang - Sun Microsystems - Beijing China if ((regDmn & MULTI_DOMAIN_MASK) == 0) { 300*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0, found = 0; 301*dd1de374Slin wang - Sun Microsystems - Beijing China (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) { 302*dd1de374Slin wang - Sun Microsystems - Beijing China if (regDomainPairs[i].regDmnEnum == regDmn) { 303*dd1de374Slin wang - Sun Microsystems - Beijing China regPair = ®DomainPairs[i]; 304*dd1de374Slin wang - Sun Microsystems - Beijing China found = 1; 305*dd1de374Slin wang - Sun Microsystems - Beijing China } 306*dd1de374Slin wang - Sun Microsystems - Beijing China } 307*dd1de374Slin wang - Sun Microsystems - Beijing China if (!found) { 308*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 309*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: Failed to find reg domain pair %u\n", 310*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, regDmn)); 311*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 312*dd1de374Slin wang - Sun Microsystems - Beijing China } 313*dd1de374Slin wang - Sun Microsystems - Beijing China if (!(channelFlag & CHANNEL_2GHZ)) { 314*dd1de374Slin wang - Sun Microsystems - Beijing China regDmn = regPair->regDmn5GHz; 315*dd1de374Slin wang - Sun Microsystems - Beijing China flags = regPair->flags5GHz; 316*dd1de374Slin wang - Sun Microsystems - Beijing China } 317*dd1de374Slin wang - Sun Microsystems - Beijing China if (channelFlag & CHANNEL_2GHZ) { 318*dd1de374Slin wang - Sun Microsystems - Beijing China regDmn = regPair->regDmn2GHz; 319*dd1de374Slin wang - Sun Microsystems - Beijing China flags = regPair->flags2GHz; 320*dd1de374Slin wang - Sun Microsystems - Beijing China } 321*dd1de374Slin wang - Sun Microsystems - Beijing China } 322*dd1de374Slin wang - Sun Microsystems - Beijing China 323*dd1de374Slin wang - Sun Microsystems - Beijing China found = ath9k_regd_is_valid_reg_domain(regDmn, rd); 324*dd1de374Slin wang - Sun Microsystems - Beijing China if (!found) { 325*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 326*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: Failed to find unitary reg domain %u\n", 327*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, regDmn)); 328*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 329*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 330*dd1de374Slin wang - Sun Microsystems - Beijing China rd->pscan &= regPair->pscanMask; 331*dd1de374Slin wang - Sun Microsystems - Beijing China if (((regOrg & MULTI_DOMAIN_MASK) == 0) && 332*dd1de374Slin wang - Sun Microsystems - Beijing China (flags != NO_REQ)) { 333*dd1de374Slin wang - Sun Microsystems - Beijing China rd->flags = (uint32_t)flags; /* LINT */ 334*dd1de374Slin wang - Sun Microsystems - Beijing China } 335*dd1de374Slin wang - Sun Microsystems - Beijing China 336*dd1de374Slin wang - Sun Microsystems - Beijing China rd->flags &= (channelFlag & CHANNEL_2GHZ) ? 337*dd1de374Slin wang - Sun Microsystems - Beijing China REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK; 338*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 339*dd1de374Slin wang - Sun Microsystems - Beijing China } 340*dd1de374Slin wang - Sun Microsystems - Beijing China } 341*dd1de374Slin wang - Sun Microsystems - Beijing China 342*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 343*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_bit_set(int bit, uint64_t *bitmask) 344*dd1de374Slin wang - Sun Microsystems - Beijing China { 345*dd1de374Slin wang - Sun Microsystems - Beijing China int byteOffset, bitnum; 346*dd1de374Slin wang - Sun Microsystems - Beijing China uint64_t val; 347*dd1de374Slin wang - Sun Microsystems - Beijing China 348*dd1de374Slin wang - Sun Microsystems - Beijing China byteOffset = bit / 64; 349*dd1de374Slin wang - Sun Microsystems - Beijing China bitnum = bit - byteOffset * 64; 350*dd1de374Slin wang - Sun Microsystems - Beijing China val = ((uint64_t)1) << bitnum; 351*dd1de374Slin wang - Sun Microsystems - Beijing China if (bitmask[byteOffset] & val) 352*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_TRUE); 353*dd1de374Slin wang - Sun Microsystems - Beijing China else 354*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 355*dd1de374Slin wang - Sun Microsystems - Beijing China } 356*dd1de374Slin wang - Sun Microsystems - Beijing China 357*dd1de374Slin wang - Sun Microsystems - Beijing China static void 358*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_add_reg_classid(uint8_t *regclassids, uint32_t maxregids, 359*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t *nregids, uint8_t regclassid) 360*dd1de374Slin wang - Sun Microsystems - Beijing China { 361*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 362*dd1de374Slin wang - Sun Microsystems - Beijing China 363*dd1de374Slin wang - Sun Microsystems - Beijing China if (regclassid == 0) 364*dd1de374Slin wang - Sun Microsystems - Beijing China return; 365*dd1de374Slin wang - Sun Microsystems - Beijing China 366*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < maxregids; i++) { 367*dd1de374Slin wang - Sun Microsystems - Beijing China if (regclassids[i] == regclassid) 368*dd1de374Slin wang - Sun Microsystems - Beijing China return; 369*dd1de374Slin wang - Sun Microsystems - Beijing China if (regclassids[i] == 0) 370*dd1de374Slin wang - Sun Microsystems - Beijing China break; 371*dd1de374Slin wang - Sun Microsystems - Beijing China } 372*dd1de374Slin wang - Sun Microsystems - Beijing China 373*dd1de374Slin wang - Sun Microsystems - Beijing China if (i == maxregids) 374*dd1de374Slin wang - Sun Microsystems - Beijing China return; 375*dd1de374Slin wang - Sun Microsystems - Beijing China else { 376*dd1de374Slin wang - Sun Microsystems - Beijing China regclassids[i] = regclassid; 377*dd1de374Slin wang - Sun Microsystems - Beijing China *nregids += 1; 378*dd1de374Slin wang - Sun Microsystems - Beijing China } 379*dd1de374Slin wang - Sun Microsystems - Beijing China } 380*dd1de374Slin wang - Sun Microsystems - Beijing China 381*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 382*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah, 383*dd1de374Slin wang - Sun Microsystems - Beijing China enum reg_ext_bitmap bit) 384*dd1de374Slin wang - Sun Microsystems - Beijing China { 385*dd1de374Slin wang - Sun Microsystems - Beijing China return ((ah->ah_currentRDExt & (1 << bit)) ? B_TRUE : B_FALSE); 386*dd1de374Slin wang - Sun Microsystems - Beijing China } 387*dd1de374Slin wang - Sun Microsystems - Beijing China 388*dd1de374Slin wang - Sun Microsystems - Beijing China #ifdef ARN_NF_PER_CHAN 389*dd1de374Slin wang - Sun Microsystems - Beijing China 390*dd1de374Slin wang - Sun Microsystems - Beijing China static void 391*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans, int nchans) 392*dd1de374Slin wang - Sun Microsystems - Beijing China { 393*dd1de374Slin wang - Sun Microsystems - Beijing China int i, j, next; 394*dd1de374Slin wang - Sun Microsystems - Beijing China 395*dd1de374Slin wang - Sun Microsystems - Beijing China for (next = 0; next < nchans; next++) { 396*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < NUM_NF_READINGS; i++) { 397*dd1de374Slin wang - Sun Microsystems - Beijing China ichans[next].nfCalHist[i].currIndex = 0; 398*dd1de374Slin wang - Sun Microsystems - Beijing China ichans[next].nfCalHist[i].privNF = 399*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CCA_MAX_GOOD_VALUE; 400*dd1de374Slin wang - Sun Microsystems - Beijing China ichans[next].nfCalHist[i].invalidNFcount = 401*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CCA_FILTERWINDOW_LENGTH; 402*dd1de374Slin wang - Sun Microsystems - Beijing China for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { 403*dd1de374Slin wang - Sun Microsystems - Beijing China ichans[next].nfCalHist[i].nfCalBuffer[j] = 404*dd1de374Slin wang - Sun Microsystems - Beijing China AR_PHY_CCA_MAX_GOOD_VALUE; 405*dd1de374Slin wang - Sun Microsystems - Beijing China } 406*dd1de374Slin wang - Sun Microsystems - Beijing China } 407*dd1de374Slin wang - Sun Microsystems - Beijing China } 408*dd1de374Slin wang - Sun Microsystems - Beijing China } 409*dd1de374Slin wang - Sun Microsystems - Beijing China #endif 410*dd1de374Slin wang - Sun Microsystems - Beijing China 411*dd1de374Slin wang - Sun Microsystems - Beijing China static int 412*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_chan_present(struct ath_hal *ah, uint16_t c) 413*dd1de374Slin wang - Sun Microsystems - Beijing China { 414*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 415*dd1de374Slin wang - Sun Microsystems - Beijing China 416*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < 150; i++) { 417*dd1de374Slin wang - Sun Microsystems - Beijing China if (!ah->ah_channels[i].channel) 418*dd1de374Slin wang - Sun Microsystems - Beijing China return (-1); 419*dd1de374Slin wang - Sun Microsystems - Beijing China else if (ah->ah_channels[i].channel == c) 420*dd1de374Slin wang - Sun Microsystems - Beijing China return (i); 421*dd1de374Slin wang - Sun Microsystems - Beijing China } 422*dd1de374Slin wang - Sun Microsystems - Beijing China 423*dd1de374Slin wang - Sun Microsystems - Beijing China return (-1); 424*dd1de374Slin wang - Sun Microsystems - Beijing China } 425*dd1de374Slin wang - Sun Microsystems - Beijing China 426*dd1de374Slin wang - Sun Microsystems - Beijing China /* ARGSUSED */ 427*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 428*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_add_channel( 429*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal *ah, 430*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t c, 431*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t c_lo, 432*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t c_hi, 433*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t maxChan, 434*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t ctl, 435*dd1de374Slin wang - Sun Microsystems - Beijing China int pos, 436*dd1de374Slin wang - Sun Microsystems - Beijing China struct regDomain rd5GHz, 437*dd1de374Slin wang - Sun Microsystems - Beijing China struct RegDmnFreqBand *fband, 438*dd1de374Slin wang - Sun Microsystems - Beijing China struct regDomain *rd, 439*dd1de374Slin wang - Sun Microsystems - Beijing China const struct cmode *cm, 440*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichans, 441*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t enableExtendedChannels) 442*dd1de374Slin wang - Sun Microsystems - Beijing China { 443*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *chan; 444*dd1de374Slin wang - Sun Microsystems - Beijing China int ret; 445*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t channelFlags = 0; 446*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t privFlags = 0; 447*dd1de374Slin wang - Sun Microsystems - Beijing China 448*dd1de374Slin wang - Sun Microsystems - Beijing China if (!(c_lo <= c && c <= c_hi)) { 449*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 450*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: c %u out of range [%u..%u]\n", 451*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, c, c_lo, c_hi)); 452*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 453*dd1de374Slin wang - Sun Microsystems - Beijing China } 454*dd1de374Slin wang - Sun Microsystems - Beijing China if ((fband->channelBW == CHANNEL_HALF_BW) && 455*dd1de374Slin wang - Sun Microsystems - Beijing China !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) { 456*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 457*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: Skipping %u half rate channel\n", 458*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, c)); 459*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 460*dd1de374Slin wang - Sun Microsystems - Beijing China } 461*dd1de374Slin wang - Sun Microsystems - Beijing China 462*dd1de374Slin wang - Sun Microsystems - Beijing China if ((fband->channelBW == CHANNEL_QUARTER_BW) && 463*dd1de374Slin wang - Sun Microsystems - Beijing China !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) { 464*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 465*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: Skipping %u quarter rate channel\n", 466*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, c)); 467*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 468*dd1de374Slin wang - Sun Microsystems - Beijing China } 469*dd1de374Slin wang - Sun Microsystems - Beijing China 470*dd1de374Slin wang - Sun Microsystems - Beijing China if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) { 471*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 472*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: c %u > maxChan %u\n", 473*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, c, maxChan)); 474*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 475*dd1de374Slin wang - Sun Microsystems - Beijing China } 476*dd1de374Slin wang - Sun Microsystems - Beijing China 477*dd1de374Slin wang - Sun Microsystems - Beijing China if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) { 478*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 479*dd1de374Slin wang - Sun Microsystems - Beijing China "Skipping ecm channel\n")); 480*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 481*dd1de374Slin wang - Sun Microsystems - Beijing China } 482*dd1de374Slin wang - Sun Microsystems - Beijing China 483*dd1de374Slin wang - Sun Microsystems - Beijing China if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == ATH9K_M_HOSTAP)) { 484*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 485*dd1de374Slin wang - Sun Microsystems - Beijing China "Skipping HOSTAP channel\n")); 486*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 487*dd1de374Slin wang - Sun Microsystems - Beijing China } 488*dd1de374Slin wang - Sun Microsystems - Beijing China 489*dd1de374Slin wang - Sun Microsystems - Beijing China if (IS_HT40_MODE(cm->mode) && 490*dd1de374Slin wang - Sun Microsystems - Beijing China !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) && 491*dd1de374Slin wang - Sun Microsystems - Beijing China (fband->useDfs) && 492*dd1de374Slin wang - Sun Microsystems - Beijing China (rd->conformanceTestLimit != MKK)) { 493*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 494*dd1de374Slin wang - Sun Microsystems - Beijing China "Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n")); 495*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 496*dd1de374Slin wang - Sun Microsystems - Beijing China } 497*dd1de374Slin wang - Sun Microsystems - Beijing China 498*dd1de374Slin wang - Sun Microsystems - Beijing China if (IS_HT40_MODE(cm->mode) && 499*dd1de374Slin wang - Sun Microsystems - Beijing China !(ath9k_regd_get_eeprom_reg_ext_bits(ah, 500*dd1de374Slin wang - Sun Microsystems - Beijing China REG_EXT_JAPAN_NONDFS_HT40)) && 501*dd1de374Slin wang - Sun Microsystems - Beijing China !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) { 502*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 503*dd1de374Slin wang - Sun Microsystems - Beijing China "Skipping HT40 channel (en_jap_ht40 = 0)\n")); 504*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 505*dd1de374Slin wang - Sun Microsystems - Beijing China } 506*dd1de374Slin wang - Sun Microsystems - Beijing China 507*dd1de374Slin wang - Sun Microsystems - Beijing China if (IS_HT40_MODE(cm->mode) && 508*dd1de374Slin wang - Sun Microsystems - Beijing China !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) && 509*dd1de374Slin wang - Sun Microsystems - Beijing China (fband->useDfs) && 510*dd1de374Slin wang - Sun Microsystems - Beijing China (rd->conformanceTestLimit == MKK)) { 511*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 512*dd1de374Slin wang - Sun Microsystems - Beijing China "Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n")); 513*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 514*dd1de374Slin wang - Sun Microsystems - Beijing China } 515*dd1de374Slin wang - Sun Microsystems - Beijing China 516*dd1de374Slin wang - Sun Microsystems - Beijing China /* Calculate channel flags */ 517*dd1de374Slin wang - Sun Microsystems - Beijing China 518*dd1de374Slin wang - Sun Microsystems - Beijing China channelFlags = cm->flags; 519*dd1de374Slin wang - Sun Microsystems - Beijing China 520*dd1de374Slin wang - Sun Microsystems - Beijing China switch (fband->channelBW) { 521*dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_HALF_BW: 522*dd1de374Slin wang - Sun Microsystems - Beijing China channelFlags |= CHANNEL_HALF; 523*dd1de374Slin wang - Sun Microsystems - Beijing China break; 524*dd1de374Slin wang - Sun Microsystems - Beijing China case CHANNEL_QUARTER_BW: 525*dd1de374Slin wang - Sun Microsystems - Beijing China channelFlags |= CHANNEL_QUARTER; 526*dd1de374Slin wang - Sun Microsystems - Beijing China break; 527*dd1de374Slin wang - Sun Microsystems - Beijing China } 528*dd1de374Slin wang - Sun Microsystems - Beijing China 529*dd1de374Slin wang - Sun Microsystems - Beijing China if (fband->usePassScan & rd->pscan) 530*dd1de374Slin wang - Sun Microsystems - Beijing China channelFlags |= CHANNEL_PASSIVE; 531*dd1de374Slin wang - Sun Microsystems - Beijing China else 532*dd1de374Slin wang - Sun Microsystems - Beijing China channelFlags &= ~CHANNEL_PASSIVE; 533*dd1de374Slin wang - Sun Microsystems - Beijing China if (fband->useDfs & rd->dfsMask) 534*dd1de374Slin wang - Sun Microsystems - Beijing China privFlags = CHANNEL_DFS; 535*dd1de374Slin wang - Sun Microsystems - Beijing China else 536*dd1de374Slin wang - Sun Microsystems - Beijing China privFlags = 0; 537*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd->flags & LIMIT_FRAME_4MS) 538*dd1de374Slin wang - Sun Microsystems - Beijing China privFlags |= CHANNEL_4MS_LIMIT; 539*dd1de374Slin wang - Sun Microsystems - Beijing China if (privFlags & CHANNEL_DFS) 540*dd1de374Slin wang - Sun Microsystems - Beijing China privFlags |= CHANNEL_DISALLOW_ADHOC; 541*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd->flags & ADHOC_PER_11D) 542*dd1de374Slin wang - Sun Microsystems - Beijing China privFlags |= CHANNEL_PER_11D_ADHOC; 543*dd1de374Slin wang - Sun Microsystems - Beijing China 544*dd1de374Slin wang - Sun Microsystems - Beijing China if (channelFlags & CHANNEL_PASSIVE) { 545*dd1de374Slin wang - Sun Microsystems - Beijing China if ((c < 2412) || (c > 2462)) { 546*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd5GHz.regDmnEnum == MKK1 || 547*dd1de374Slin wang - Sun Microsystems - Beijing China rd5GHz.regDmnEnum == MKK2) { 548*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t regcap = ah->ah_caps.reg_cap; 549*dd1de374Slin wang - Sun Microsystems - Beijing China if (!(regcap & 550*dd1de374Slin wang - Sun Microsystems - Beijing China (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | 551*dd1de374Slin wang - Sun Microsystems - Beijing China AR_EEPROM_EEREGCAP_EN_KK_U2 | 552*dd1de374Slin wang - Sun Microsystems - Beijing China AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) && 553*dd1de374Slin wang - Sun Microsystems - Beijing China isUNII1OddChan(c)) { 554*dd1de374Slin wang - Sun Microsystems - Beijing China channelFlags &= ~CHANNEL_PASSIVE; 555*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 556*dd1de374Slin wang - Sun Microsystems - Beijing China privFlags |= CHANNEL_DISALLOW_ADHOC; 557*dd1de374Slin wang - Sun Microsystems - Beijing China } 558*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 559*dd1de374Slin wang - Sun Microsystems - Beijing China privFlags |= CHANNEL_DISALLOW_ADHOC; 560*dd1de374Slin wang - Sun Microsystems - Beijing China } 561*dd1de374Slin wang - Sun Microsystems - Beijing China } 562*dd1de374Slin wang - Sun Microsystems - Beijing China } 563*dd1de374Slin wang - Sun Microsystems - Beijing China 564*dd1de374Slin wang - Sun Microsystems - Beijing China if ((cm->mode == ATH9K_MODE_11A) || 565*dd1de374Slin wang - Sun Microsystems - Beijing China (cm->mode == ATH9K_MODE_11NA_HT20) || 566*dd1de374Slin wang - Sun Microsystems - Beijing China (cm->mode == ATH9K_MODE_11NA_HT40PLUS) || 567*dd1de374Slin wang - Sun Microsystems - Beijing China (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) { 568*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A)) 569*dd1de374Slin wang - Sun Microsystems - Beijing China privFlags |= CHANNEL_DISALLOW_ADHOC; 570*dd1de374Slin wang - Sun Microsystems - Beijing China } 571*dd1de374Slin wang - Sun Microsystems - Beijing China 572*dd1de374Slin wang - Sun Microsystems - Beijing China /* Fill in channel details */ 573*dd1de374Slin wang - Sun Microsystems - Beijing China 574*dd1de374Slin wang - Sun Microsystems - Beijing China ret = ath9k_regd_is_chan_present(ah, c); 575*dd1de374Slin wang - Sun Microsystems - Beijing China if (ret == -1) { 576*dd1de374Slin wang - Sun Microsystems - Beijing China chan = &ah->ah_channels[pos]; 577*dd1de374Slin wang - Sun Microsystems - Beijing China chan->channel = c; 578*dd1de374Slin wang - Sun Microsystems - Beijing China chan->maxRegTxPower = fband->powerDfs; 579*dd1de374Slin wang - Sun Microsystems - Beijing China chan->antennaMax = fband->antennaMax; 580*dd1de374Slin wang - Sun Microsystems - Beijing China chan->regDmnFlags = rd->flags; 581*dd1de374Slin wang - Sun Microsystems - Beijing China chan->maxTxPower = AR5416_MAX_RATE_POWER; 582*dd1de374Slin wang - Sun Microsystems - Beijing China chan->minTxPower = AR5416_MAX_RATE_POWER; 583*dd1de374Slin wang - Sun Microsystems - Beijing China chan->channelFlags = channelFlags; 584*dd1de374Slin wang - Sun Microsystems - Beijing China chan->privFlags = privFlags; 585*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 586*dd1de374Slin wang - Sun Microsystems - Beijing China chan = &ah->ah_channels[ret]; 587*dd1de374Slin wang - Sun Microsystems - Beijing China chan->channelFlags |= channelFlags; 588*dd1de374Slin wang - Sun Microsystems - Beijing China chan->privFlags |= privFlags; 589*dd1de374Slin wang - Sun Microsystems - Beijing China } 590*dd1de374Slin wang - Sun Microsystems - Beijing China 591*dd1de374Slin wang - Sun Microsystems - Beijing China /* Set CTLs */ 592*dd1de374Slin wang - Sun Microsystems - Beijing China 593*dd1de374Slin wang - Sun Microsystems - Beijing China if ((cm->flags & CHANNEL_ALL) == CHANNEL_A) 594*dd1de374Slin wang - Sun Microsystems - Beijing China chan->conformanceTestLimit[0] = ctl; 595*dd1de374Slin wang - Sun Microsystems - Beijing China else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B) 596*dd1de374Slin wang - Sun Microsystems - Beijing China chan->conformanceTestLimit[1] = ctl; 597*dd1de374Slin wang - Sun Microsystems - Beijing China else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G) 598*dd1de374Slin wang - Sun Microsystems - Beijing China chan->conformanceTestLimit[2] = ctl; 599*dd1de374Slin wang - Sun Microsystems - Beijing China 600*dd1de374Slin wang - Sun Microsystems - Beijing China return ((ret == -1) ? B_TRUE : B_FALSE); 601*dd1de374Slin wang - Sun Microsystems - Beijing China } 602*dd1de374Slin wang - Sun Microsystems - Beijing China 603*dd1de374Slin wang - Sun Microsystems - Beijing China static boolean_t 604*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_japan_check(struct ath_hal *ah, int b, struct regDomain *rd5GHz) 605*dd1de374Slin wang - Sun Microsystems - Beijing China { 606*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t skipband = B_FALSE; 607*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 608*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t regcap; 609*dd1de374Slin wang - Sun Microsystems - Beijing China 610*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) { 611*dd1de374Slin wang - Sun Microsystems - Beijing China if (j_bandcheck[i].freqbandbit == b) { 612*dd1de374Slin wang - Sun Microsystems - Beijing China regcap = ah->ah_caps.reg_cap; 613*dd1de374Slin wang - Sun Microsystems - Beijing China if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) { 614*dd1de374Slin wang - Sun Microsystems - Beijing China skipband = B_TRUE; 615*dd1de374Slin wang - Sun Microsystems - Beijing China } else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) || 616*dd1de374Slin wang - Sun Microsystems - Beijing China (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) { 617*dd1de374Slin wang - Sun Microsystems - Beijing China rd5GHz->dfsMask |= DFS_MKK4; 618*dd1de374Slin wang - Sun Microsystems - Beijing China rd5GHz->pscan |= PSCAN_MKK3; 619*dd1de374Slin wang - Sun Microsystems - Beijing China } 620*dd1de374Slin wang - Sun Microsystems - Beijing China break; 621*dd1de374Slin wang - Sun Microsystems - Beijing China } 622*dd1de374Slin wang - Sun Microsystems - Beijing China } 623*dd1de374Slin wang - Sun Microsystems - Beijing China 624*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 625*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: Skipping %d freq band\n", 626*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, j_bandcheck[i].freqbandbit)); 627*dd1de374Slin wang - Sun Microsystems - Beijing China 628*dd1de374Slin wang - Sun Microsystems - Beijing China return (skipband); 629*dd1de374Slin wang - Sun Microsystems - Beijing China } 630*dd1de374Slin wang - Sun Microsystems - Beijing China 631*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t 632*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_init_channels( 633*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath_hal *ah, 634*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t maxchans, 635*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t *nchans, 636*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t *regclassids, 637*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t maxregids, 638*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t *nregids, 639*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t cc, 640*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t enableOutdoor, 641*dd1de374Slin wang - Sun Microsystems - Beijing China boolean_t enableExtendedChannels) 642*dd1de374Slin wang - Sun Microsystems - Beijing China { 643*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t maxChan = 7000; 644*dd1de374Slin wang - Sun Microsystems - Beijing China struct country_code_to_enum_rd *country = NULL; 645*dd1de374Slin wang - Sun Microsystems - Beijing China struct regDomain rd5GHz, rd2GHz; 646*dd1de374Slin wang - Sun Microsystems - Beijing China const struct cmode *cm; 647*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichans = &ah->ah_channels[0]; 648*dd1de374Slin wang - Sun Microsystems - Beijing China int next = 0, b; 649*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t ctl; 650*dd1de374Slin wang - Sun Microsystems - Beijing China int regdmn; 651*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t chanSep; 652*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t *modes_avail; 653*dd1de374Slin wang - Sun Microsystems - Beijing China uint8_t modes_allowed[4]; 654*dd1de374Slin wang - Sun Microsystems - Beijing China 655*dd1de374Slin wang - Sun Microsystems - Beijing China (void) memset(modes_allowed, 0, sizeof (modes_allowed)); 656*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "arn: ath9k_regd_init_channels(): " 657*dd1de374Slin wang - Sun Microsystems - Beijing China "cc %u %s %s\n", 658*dd1de374Slin wang - Sun Microsystems - Beijing China cc, 659*dd1de374Slin wang - Sun Microsystems - Beijing China enableOutdoor ? "Enable outdoor" : "", 660*dd1de374Slin wang - Sun Microsystems - Beijing China enableExtendedChannels ? "Enable ecm" : "")); 661*dd1de374Slin wang - Sun Microsystems - Beijing China 662*dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_regd_is_ccode_valid(ah, cc)) { 663*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_XMIT, "arn: ath9k_regd_init_channels(): " 664*dd1de374Slin wang - Sun Microsystems - Beijing China "invalid country code %d\n", cc)); 665*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 666*dd1de374Slin wang - Sun Microsystems - Beijing China } 667*dd1de374Slin wang - Sun Microsystems - Beijing China 668*dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_regd_is_eeprom_valid(ah)) { 669*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_ANY, "arn: ath9k_regd_init_channels(): " 670*dd1de374Slin wang - Sun Microsystems - Beijing China "invalid EEPROM contents\n")); 671*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 672*dd1de374Slin wang - Sun Microsystems - Beijing China } 673*dd1de374Slin wang - Sun Microsystems - Beijing China 674*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_countryCode = ath9k_regd_get_default_country(ah); 675*dd1de374Slin wang - Sun Microsystems - Beijing China 676*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_countryCode == CTRY_DEFAULT) { 677*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_countryCode = cc & COUNTRY_CODE_MASK; 678*dd1de374Slin wang - Sun Microsystems - Beijing China if ((ah->ah_countryCode == CTRY_DEFAULT) && 679*dd1de374Slin wang - Sun Microsystems - Beijing China (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) { 680*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_countryCode = CTRY_UNITED_STATES; 681*dd1de374Slin wang - Sun Microsystems - Beijing China } 682*dd1de374Slin wang - Sun Microsystems - Beijing China } 683*dd1de374Slin wang - Sun Microsystems - Beijing China 684*dd1de374Slin wang - Sun Microsystems - Beijing China #ifdef ARN_SUPPORT_11D 685*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_countryCode == CTRY_DEFAULT) { 686*dd1de374Slin wang - Sun Microsystems - Beijing China regdmn = ath9k_regd_get_eepromRD(ah); 687*dd1de374Slin wang - Sun Microsystems - Beijing China country = NULL; 688*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 689*dd1de374Slin wang - Sun Microsystems - Beijing China #endif 690*dd1de374Slin wang - Sun Microsystems - Beijing China country = ath9k_regd_find_country(ah->ah_countryCode); 691*dd1de374Slin wang - Sun Microsystems - Beijing China if (country == NULL) { 692*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 693*dd1de374Slin wang - Sun Microsystems - Beijing China "arn: ath9k_regd_init_channels(): " 694*dd1de374Slin wang - Sun Microsystems - Beijing China "Country is NULL!!!!, cc= %d\n", 695*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_countryCode)); 696*dd1de374Slin wang - Sun Microsystems - Beijing China 697*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 698*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 699*dd1de374Slin wang - Sun Microsystems - Beijing China regdmn = country->regDmnEnum; 700*dd1de374Slin wang - Sun Microsystems - Beijing China #ifdef ARN_SUPPORT_11D 701*dd1de374Slin wang - Sun Microsystems - Beijing China if (((ath9k_regd_get_eepromRD(ah) & 702*dd1de374Slin wang - Sun Microsystems - Beijing China WORLD_SKU_MASK) == WORLD_SKU_PREFIX) && 703*dd1de374Slin wang - Sun Microsystems - Beijing China (cc == CTRY_UNITED_STATES)) { 704*dd1de374Slin wang - Sun Microsystems - Beijing China if (!isWwrSKU_NoMidband(ah) && 705*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_is_fcc_midband_supported(ah)) 706*dd1de374Slin wang - Sun Microsystems - Beijing China regdmn = FCC3_FCCA; 707*dd1de374Slin wang - Sun Microsystems - Beijing China else 708*dd1de374Slin wang - Sun Microsystems - Beijing China regdmn = FCC1_FCCA; 709*dd1de374Slin wang - Sun Microsystems - Beijing China } 710*dd1de374Slin wang - Sun Microsystems - Beijing China #endif 711*dd1de374Slin wang - Sun Microsystems - Beijing China } 712*dd1de374Slin wang - Sun Microsystems - Beijing China #ifdef ARN_SUPPORT_11D 713*dd1de374Slin wang - Sun Microsystems - Beijing China } 714*dd1de374Slin wang - Sun Microsystems - Beijing China #endif 715*dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_regd_get_wmode_regdomain(ah, regdmn, 716*dd1de374Slin wang - Sun Microsystems - Beijing China ~CHANNEL_2GHZ, &rd5GHz)) { 717*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "arn: ath9k_regd_init_channels(): " 718*dd1de374Slin wang - Sun Microsystems - Beijing China "couldn't find unitary " 719*dd1de374Slin wang - Sun Microsystems - Beijing China "5GHz reg domain for country %u\n", 720*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_countryCode)); 721*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 722*dd1de374Slin wang - Sun Microsystems - Beijing China } 723*dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_regd_get_wmode_regdomain(ah, regdmn, 724*dd1de374Slin wang - Sun Microsystems - Beijing China CHANNEL_2GHZ, &rd2GHz)) { 725*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "arn: ath9k_regd_init_channels(): " 726*dd1de374Slin wang - Sun Microsystems - Beijing China "couldn't find unitary 2GHz " 727*dd1de374Slin wang - Sun Microsystems - Beijing China "reg domain for country %u\n", 728*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_countryCode)); 729*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 730*dd1de374Slin wang - Sun Microsystems - Beijing China } 731*dd1de374Slin wang - Sun Microsystems - Beijing China 732*dd1de374Slin wang - Sun Microsystems - Beijing China if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) || 733*dd1de374Slin wang - Sun Microsystems - Beijing China (rd5GHz.regDmnEnum == FCC2))) { 734*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_regd_is_fcc_midband_supported(ah)) { 735*dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_regd_get_wmode_regdomain(ah, 736*dd1de374Slin wang - Sun Microsystems - Beijing China FCC3_FCCA, ~CHANNEL_2GHZ, &rd5GHz)) { 737*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 738*dd1de374Slin wang - Sun Microsystems - Beijing China "arn: ath9k_regd_init_channels(): " 739*dd1de374Slin wang - Sun Microsystems - Beijing China "couldn't find unitary 5GHz " 740*dd1de374Slin wang - Sun Microsystems - Beijing China "reg domain for country %u\n", 741*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_countryCode)); 742*dd1de374Slin wang - Sun Microsystems - Beijing China return (B_FALSE); 743*dd1de374Slin wang - Sun Microsystems - Beijing China } 744*dd1de374Slin wang - Sun Microsystems - Beijing China } 745*dd1de374Slin wang - Sun Microsystems - Beijing China } 746*dd1de374Slin wang - Sun Microsystems - Beijing China 747*dd1de374Slin wang - Sun Microsystems - Beijing China if (country == NULL) { 748*dd1de374Slin wang - Sun Microsystems - Beijing China modes_avail = ah->ah_caps.wireless_modes; 749*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 750*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed); 751*dd1de374Slin wang - Sun Microsystems - Beijing China modes_avail = modes_allowed; 752*dd1de374Slin wang - Sun Microsystems - Beijing China 753*dd1de374Slin wang - Sun Microsystems - Beijing China if (!enableOutdoor) 754*dd1de374Slin wang - Sun Microsystems - Beijing China maxChan = country->outdoorChanStart; 755*dd1de374Slin wang - Sun Microsystems - Beijing China } 756*dd1de374Slin wang - Sun Microsystems - Beijing China 757*dd1de374Slin wang - Sun Microsystems - Beijing China next = 0; 758*dd1de374Slin wang - Sun Microsystems - Beijing China 759*dd1de374Slin wang - Sun Microsystems - Beijing China if (maxchans > ARRAY_SIZE(ah->ah_channels)) 760*dd1de374Slin wang - Sun Microsystems - Beijing China maxchans = ARRAY_SIZE(ah->ah_channels); 761*dd1de374Slin wang - Sun Microsystems - Beijing China 762*dd1de374Slin wang - Sun Microsystems - Beijing China for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) { 763*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t c, c_hi, c_lo; 764*dd1de374Slin wang - Sun Microsystems - Beijing China uint64_t *channelBM = NULL; 765*dd1de374Slin wang - Sun Microsystems - Beijing China struct regDomain *rd = NULL; 766*dd1de374Slin wang - Sun Microsystems - Beijing China struct RegDmnFreqBand *fband = NULL, *freqs; 767*dd1de374Slin wang - Sun Microsystems - Beijing China int8_t low_adj = 0, hi_adj = 0; 768*dd1de374Slin wang - Sun Microsystems - Beijing China 769*dd1de374Slin wang - Sun Microsystems - Beijing China if (!is_set(cm->mode, modes_avail)) { 770*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 771*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: !avail mode %d flags 0x%x\n", 772*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, cm->mode, cm->flags)); 773*dd1de374Slin wang - Sun Microsystems - Beijing China continue; 774*dd1de374Slin wang - Sun Microsystems - Beijing China } 775*dd1de374Slin wang - Sun Microsystems - Beijing China if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { 776*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 777*dd1de374Slin wang - Sun Microsystems - Beijing China "arn: ath9k_regd_init_channels(): " 778*dd1de374Slin wang - Sun Microsystems - Beijing China "channels 0x%x not supported " 779*dd1de374Slin wang - Sun Microsystems - Beijing China "by hardware\n", cm->flags)); 780*dd1de374Slin wang - Sun Microsystems - Beijing China continue; 781*dd1de374Slin wang - Sun Microsystems - Beijing China } 782*dd1de374Slin wang - Sun Microsystems - Beijing China 783*dd1de374Slin wang - Sun Microsystems - Beijing China switch (cm->mode) { 784*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11A: 785*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NA_HT20: 786*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NA_HT40PLUS: 787*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NA_HT40MINUS: 788*dd1de374Slin wang - Sun Microsystems - Beijing China rd = &rd5GHz; 789*dd1de374Slin wang - Sun Microsystems - Beijing China channelBM = rd->chan11a; 790*dd1de374Slin wang - Sun Microsystems - Beijing China freqs = ®Dmn5GhzFreq[0]; 791*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = rd->conformanceTestLimit; 792*dd1de374Slin wang - Sun Microsystems - Beijing China break; 793*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11B: 794*dd1de374Slin wang - Sun Microsystems - Beijing China rd = &rd2GHz; 795*dd1de374Slin wang - Sun Microsystems - Beijing China channelBM = rd->chan11b; 796*dd1de374Slin wang - Sun Microsystems - Beijing China freqs = ®Dmn2GhzFreq[0]; 797*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = rd->conformanceTestLimit | CTL_11B; 798*dd1de374Slin wang - Sun Microsystems - Beijing China break; 799*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11G: 800*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NG_HT20: 801*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NG_HT40PLUS: 802*dd1de374Slin wang - Sun Microsystems - Beijing China case ATH9K_MODE_11NG_HT40MINUS: 803*dd1de374Slin wang - Sun Microsystems - Beijing China rd = &rd2GHz; 804*dd1de374Slin wang - Sun Microsystems - Beijing China channelBM = rd->chan11g; 805*dd1de374Slin wang - Sun Microsystems - Beijing China freqs = ®Dmn2Ghz11gFreq[0]; 806*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = rd->conformanceTestLimit | CTL_11G; 807*dd1de374Slin wang - Sun Microsystems - Beijing China break; 808*dd1de374Slin wang - Sun Microsystems - Beijing China default: 809*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 810*dd1de374Slin wang - Sun Microsystems - Beijing China "arn: ath9k_regd_init_channels(): " 811*dd1de374Slin wang - Sun Microsystems - Beijing China "Unknown HAL mode 0x%x\n", cm->mode)); 812*dd1de374Slin wang - Sun Microsystems - Beijing China continue; 813*dd1de374Slin wang - Sun Microsystems - Beijing China } 814*dd1de374Slin wang - Sun Microsystems - Beijing China 815*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_regd_is_chan_bm_zero(channelBM)) 816*dd1de374Slin wang - Sun Microsystems - Beijing China continue; 817*dd1de374Slin wang - Sun Microsystems - Beijing China 818*dd1de374Slin wang - Sun Microsystems - Beijing China if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) || 819*dd1de374Slin wang - Sun Microsystems - Beijing China (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) { 820*dd1de374Slin wang - Sun Microsystems - Beijing China hi_adj = -20; 821*dd1de374Slin wang - Sun Microsystems - Beijing China } 822*dd1de374Slin wang - Sun Microsystems - Beijing China 823*dd1de374Slin wang - Sun Microsystems - Beijing China if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) || 824*dd1de374Slin wang - Sun Microsystems - Beijing China (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) { 825*dd1de374Slin wang - Sun Microsystems - Beijing China low_adj = 20; 826*dd1de374Slin wang - Sun Microsystems - Beijing China } 827*dd1de374Slin wang - Sun Microsystems - Beijing China 828*dd1de374Slin wang - Sun Microsystems - Beijing China /* XXX: Add a helper here instead */ 829*dd1de374Slin wang - Sun Microsystems - Beijing China for (b = 0; b < 64 * BMLEN; b++) { 830*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_regd_is_bit_set(b, channelBM)) { 831*dd1de374Slin wang - Sun Microsystems - Beijing China fband = &freqs[b]; 832*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd5GHz.regDmnEnum == MKK1 || 833*dd1de374Slin wang - Sun Microsystems - Beijing China rd5GHz.regDmnEnum == MKK2) { 834*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_regd_japan_check(ah, 835*dd1de374Slin wang - Sun Microsystems - Beijing China b, &rd5GHz)) 836*dd1de374Slin wang - Sun Microsystems - Beijing China continue; 837*dd1de374Slin wang - Sun Microsystems - Beijing China } 838*dd1de374Slin wang - Sun Microsystems - Beijing China 839*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_add_reg_classid(regclassids, 840*dd1de374Slin wang - Sun Microsystems - Beijing China maxregids, 841*dd1de374Slin wang - Sun Microsystems - Beijing China nregids, 842*dd1de374Slin wang - Sun Microsystems - Beijing China fband->regClassId); 843*dd1de374Slin wang - Sun Microsystems - Beijing China 844*dd1de374Slin wang - Sun Microsystems - Beijing China if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) { 845*dd1de374Slin wang - Sun Microsystems - Beijing China chanSep = 40; 846*dd1de374Slin wang - Sun Microsystems - Beijing China if (fband->lowChannel == 5280) 847*dd1de374Slin wang - Sun Microsystems - Beijing China low_adj += 20; 848*dd1de374Slin wang - Sun Microsystems - Beijing China 849*dd1de374Slin wang - Sun Microsystems - Beijing China if (fband->lowChannel == 5170) 850*dd1de374Slin wang - Sun Microsystems - Beijing China continue; 851*dd1de374Slin wang - Sun Microsystems - Beijing China } else 852*dd1de374Slin wang - Sun Microsystems - Beijing China chanSep = fband->channelSep; 853*dd1de374Slin wang - Sun Microsystems - Beijing China 854*dd1de374Slin wang - Sun Microsystems - Beijing China for (c = fband->lowChannel + low_adj; 855*dd1de374Slin wang - Sun Microsystems - Beijing China ((c <= (fband->highChannel + hi_adj)) && 856*dd1de374Slin wang - Sun Microsystems - Beijing China (c >= (fband->lowChannel + low_adj))); 857*dd1de374Slin wang - Sun Microsystems - Beijing China c += chanSep) { 858*dd1de374Slin wang - Sun Microsystems - Beijing China if (next >= maxchans) { 859*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 860*dd1de374Slin wang - Sun Microsystems - Beijing China "too many channels " 861*dd1de374Slin wang - Sun Microsystems - Beijing China "for channel table\n")); 862*dd1de374Slin wang - Sun Microsystems - Beijing China goto done; 863*dd1de374Slin wang - Sun Microsystems - Beijing China } 864*dd1de374Slin wang - Sun Microsystems - Beijing China if (ath9k_regd_add_channel(ah, 865*dd1de374Slin wang - Sun Microsystems - Beijing China c, c_lo, c_hi, 866*dd1de374Slin wang - Sun Microsystems - Beijing China maxChan, ctl, 867*dd1de374Slin wang - Sun Microsystems - Beijing China next, 868*dd1de374Slin wang - Sun Microsystems - Beijing China rd5GHz, 869*dd1de374Slin wang - Sun Microsystems - Beijing China fband, rd, cm, 870*dd1de374Slin wang - Sun Microsystems - Beijing China ichans, 871*dd1de374Slin wang - Sun Microsystems - Beijing China enableExtendedChannels)) 872*dd1de374Slin wang - Sun Microsystems - Beijing China next++; 873*dd1de374Slin wang - Sun Microsystems - Beijing China } 874*dd1de374Slin wang - Sun Microsystems - Beijing China if (IS_HT40_MODE(cm->mode) && 875*dd1de374Slin wang - Sun Microsystems - Beijing China (fband->lowChannel == 5280)) { 876*dd1de374Slin wang - Sun Microsystems - Beijing China low_adj -= 20; 877*dd1de374Slin wang - Sun Microsystems - Beijing China } 878*dd1de374Slin wang - Sun Microsystems - Beijing China } 879*dd1de374Slin wang - Sun Microsystems - Beijing China } 880*dd1de374Slin wang - Sun Microsystems - Beijing China } 881*dd1de374Slin wang - Sun Microsystems - Beijing China done: 882*dd1de374Slin wang - Sun Microsystems - Beijing China if (next != 0) { 883*dd1de374Slin wang - Sun Microsystems - Beijing China int i; 884*dd1de374Slin wang - Sun Microsystems - Beijing China 885*dd1de374Slin wang - Sun Microsystems - Beijing China if (next > ARRAY_SIZE(ah->ah_channels)) { 886*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, 887*dd1de374Slin wang - Sun Microsystems - Beijing China "arn: ath9k_regd_init_channels(): " 888*dd1de374Slin wang - Sun Microsystems - Beijing China "too many channels %u; truncating to %u\n", 889*dd1de374Slin wang - Sun Microsystems - Beijing China next, (int)ARRAY_SIZE(ah->ah_channels))); 890*dd1de374Slin wang - Sun Microsystems - Beijing China next = ARRAY_SIZE(ah->ah_channels); 891*dd1de374Slin wang - Sun Microsystems - Beijing China } 892*dd1de374Slin wang - Sun Microsystems - Beijing China #ifdef ARN_NF_PER_CHAN 893*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_init_rf_buffer(ichans, next); 894*dd1de374Slin wang - Sun Microsystems - Beijing China #endif 895*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_sort(ichans, next, sizeof (struct ath9k_channel), 896*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_chansort); 897*dd1de374Slin wang - Sun Microsystems - Beijing China 898*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_nchan = next; 899*dd1de374Slin wang - Sun Microsystems - Beijing China 900*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "arn: ath9k_regd_init_channels(): " 901*dd1de374Slin wang - Sun Microsystems - Beijing China "Channel list:\n")); 902*dd1de374Slin wang - Sun Microsystems - Beijing China for (i = 0; i < next; i++) { 903*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "arn: " 904*dd1de374Slin wang - Sun Microsystems - Beijing China "chan: %d flags: 0x%x\n", 905*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_channels[i].channel, 906*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_channels[i].channelFlags)); 907*dd1de374Slin wang - Sun Microsystems - Beijing China } 908*dd1de374Slin wang - Sun Microsystems - Beijing China } 909*dd1de374Slin wang - Sun Microsystems - Beijing China *nchans = next; 910*dd1de374Slin wang - Sun Microsystems - Beijing China 911*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_countryCode = ah->ah_countryCode; 912*dd1de374Slin wang - Sun Microsystems - Beijing China 913*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_currentRDInUse = (uint16_t)regdmn; /* LINT */ 914*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_currentRD5G = rd5GHz.regDmnEnum; 915*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_currentRD2G = rd2GHz.regDmnEnum; 916*dd1de374Slin wang - Sun Microsystems - Beijing China if (country == NULL) { 917*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_iso[0] = 0; 918*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_iso[1] = 0; 919*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 920*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_iso[0] = country->isoName[0]; 921*dd1de374Slin wang - Sun Microsystems - Beijing China ah->ah_iso[1] = country->isoName[1]; 922*dd1de374Slin wang - Sun Microsystems - Beijing China } 923*dd1de374Slin wang - Sun Microsystems - Beijing China 924*dd1de374Slin wang - Sun Microsystems - Beijing China return (next != 0); 925*dd1de374Slin wang - Sun Microsystems - Beijing China } 926*dd1de374Slin wang - Sun Microsystems - Beijing China 927*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel * 928*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_check_channel(struct ath_hal *ah, const struct ath9k_channel *c) 929*dd1de374Slin wang - Sun Microsystems - Beijing China { 930*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *base, *cc; 931*dd1de374Slin wang - Sun Microsystems - Beijing China 932*dd1de374Slin wang - Sun Microsystems - Beijing China int flags = c->channelFlags & CHAN_FLAGS; 933*dd1de374Slin wang - Sun Microsystems - Beijing China int n, lim; 934*dd1de374Slin wang - Sun Microsystems - Beijing China 935*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "arn: " 936*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: channel %u/0x%x (0x%x) requested\n", __func__, 937*dd1de374Slin wang - Sun Microsystems - Beijing China c->channel, c->channelFlags, flags)); 938*dd1de374Slin wang - Sun Microsystems - Beijing China 939*dd1de374Slin wang - Sun Microsystems - Beijing China cc = ah->ah_curchan; 940*dd1de374Slin wang - Sun Microsystems - Beijing China if (cc != NULL && cc->channel == c->channel && 941*dd1de374Slin wang - Sun Microsystems - Beijing China (cc->channelFlags & CHAN_FLAGS) == flags) { 942*dd1de374Slin wang - Sun Microsystems - Beijing China if ((cc->privFlags & CHANNEL_INTERFERENCE) && 943*dd1de374Slin wang - Sun Microsystems - Beijing China (cc->privFlags & CHANNEL_DFS)) 944*dd1de374Slin wang - Sun Microsystems - Beijing China return (NULL); 945*dd1de374Slin wang - Sun Microsystems - Beijing China else 946*dd1de374Slin wang - Sun Microsystems - Beijing China return (cc); 947*dd1de374Slin wang - Sun Microsystems - Beijing China } 948*dd1de374Slin wang - Sun Microsystems - Beijing China 949*dd1de374Slin wang - Sun Microsystems - Beijing China base = ah->ah_channels; 950*dd1de374Slin wang - Sun Microsystems - Beijing China n = ah->ah_nchan; 951*dd1de374Slin wang - Sun Microsystems - Beijing China 952*dd1de374Slin wang - Sun Microsystems - Beijing China for (lim = n; lim != 0; lim >>= 1) { 953*dd1de374Slin wang - Sun Microsystems - Beijing China int d; 954*dd1de374Slin wang - Sun Microsystems - Beijing China cc = &base[lim >> 1]; 955*dd1de374Slin wang - Sun Microsystems - Beijing China d = c->channel - cc->channel; 956*dd1de374Slin wang - Sun Microsystems - Beijing China if (d == 0) { 957*dd1de374Slin wang - Sun Microsystems - Beijing China if ((cc->channelFlags & CHAN_FLAGS) == flags) { 958*dd1de374Slin wang - Sun Microsystems - Beijing China if ((cc->privFlags & CHANNEL_INTERFERENCE) && 959*dd1de374Slin wang - Sun Microsystems - Beijing China (cc->privFlags & CHANNEL_DFS)) 960*dd1de374Slin wang - Sun Microsystems - Beijing China return (NULL); 961*dd1de374Slin wang - Sun Microsystems - Beijing China else 962*dd1de374Slin wang - Sun Microsystems - Beijing China return (cc); 963*dd1de374Slin wang - Sun Microsystems - Beijing China } 964*dd1de374Slin wang - Sun Microsystems - Beijing China d = flags - (cc->channelFlags & CHAN_FLAGS); 965*dd1de374Slin wang - Sun Microsystems - Beijing China } 966*dd1de374Slin wang - Sun Microsystems - Beijing China 967*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "arn: " 968*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: channel %u/0x%x d %d\n", __func__, 969*dd1de374Slin wang - Sun Microsystems - Beijing China cc->channel, cc->channelFlags, d)); 970*dd1de374Slin wang - Sun Microsystems - Beijing China 971*dd1de374Slin wang - Sun Microsystems - Beijing China if (d > 0) { 972*dd1de374Slin wang - Sun Microsystems - Beijing China base = cc + 1; 973*dd1de374Slin wang - Sun Microsystems - Beijing China lim--; 974*dd1de374Slin wang - Sun Microsystems - Beijing China } 975*dd1de374Slin wang - Sun Microsystems - Beijing China } 976*dd1de374Slin wang - Sun Microsystems - Beijing China 977*dd1de374Slin wang - Sun Microsystems - Beijing China ARN_DBG((ARN_DBG_REGULATORY, "arn: " 978*dd1de374Slin wang - Sun Microsystems - Beijing China "%s: no match for %u/0x%x\n", 979*dd1de374Slin wang - Sun Microsystems - Beijing China __func__, c->channel, c->channelFlags)); 980*dd1de374Slin wang - Sun Microsystems - Beijing China 981*dd1de374Slin wang - Sun Microsystems - Beijing China return (NULL); 982*dd1de374Slin wang - Sun Microsystems - Beijing China } 983*dd1de374Slin wang - Sun Microsystems - Beijing China 984*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t 985*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_antenna_allowed(struct ath_hal *ah, struct ath9k_channel *chan) 986*dd1de374Slin wang - Sun Microsystems - Beijing China { 987*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichan = NULL; 988*dd1de374Slin wang - Sun Microsystems - Beijing China 989*dd1de374Slin wang - Sun Microsystems - Beijing China ichan = ath9k_regd_check_channel(ah, chan); 990*dd1de374Slin wang - Sun Microsystems - Beijing China if (!ichan) 991*dd1de374Slin wang - Sun Microsystems - Beijing China return (0); 992*dd1de374Slin wang - Sun Microsystems - Beijing China 993*dd1de374Slin wang - Sun Microsystems - Beijing China return (ichan->antennaMax); 994*dd1de374Slin wang - Sun Microsystems - Beijing China } 995*dd1de374Slin wang - Sun Microsystems - Beijing China 996*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t 997*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) 998*dd1de374Slin wang - Sun Microsystems - Beijing China { 999*dd1de374Slin wang - Sun Microsystems - Beijing China uint32_t ctl = NO_CTL; 1000*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_channel *ichan; 1001*dd1de374Slin wang - Sun Microsystems - Beijing China 1002*dd1de374Slin wang - Sun Microsystems - Beijing China if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) { 1003*dd1de374Slin wang - Sun Microsystems - Beijing China if (IS_CHAN_B(chan)) 1004*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = SD_NO_CTL | CTL_11B; 1005*dd1de374Slin wang - Sun Microsystems - Beijing China else if (IS_CHAN_G(chan)) 1006*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = SD_NO_CTL | CTL_11G; 1007*dd1de374Slin wang - Sun Microsystems - Beijing China else 1008*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = SD_NO_CTL | CTL_11A; 1009*dd1de374Slin wang - Sun Microsystems - Beijing China } else { 1010*dd1de374Slin wang - Sun Microsystems - Beijing China ichan = ath9k_regd_check_channel(ah, chan); 1011*dd1de374Slin wang - Sun Microsystems - Beijing China if (ichan != NULL) { 1012*dd1de374Slin wang - Sun Microsystems - Beijing China /* FIXME */ 1013*dd1de374Slin wang - Sun Microsystems - Beijing China if (IS_CHAN_A(ichan)) 1014*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = ichan->conformanceTestLimit[0]; 1015*dd1de374Slin wang - Sun Microsystems - Beijing China else if (IS_CHAN_B(ichan)) 1016*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = ichan->conformanceTestLimit[1]; 1017*dd1de374Slin wang - Sun Microsystems - Beijing China else if (IS_CHAN_G(ichan)) 1018*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = ichan->conformanceTestLimit[2]; 1019*dd1de374Slin wang - Sun Microsystems - Beijing China 1020*dd1de374Slin wang - Sun Microsystems - Beijing China if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B) 1021*dd1de374Slin wang - Sun Microsystems - Beijing China ctl = (ctl & ~0xf) | CTL_11G; 1022*dd1de374Slin wang - Sun Microsystems - Beijing China } 1023*dd1de374Slin wang - Sun Microsystems - Beijing China } 1024*dd1de374Slin wang - Sun Microsystems - Beijing China return (ctl); 1025*dd1de374Slin wang - Sun Microsystems - Beijing China } 1026*dd1de374Slin wang - Sun Microsystems - Beijing China 1027*dd1de374Slin wang - Sun Microsystems - Beijing China void 1028*dd1de374Slin wang - Sun Microsystems - Beijing China ath9k_regd_get_current_country(struct ath_hal *ah, 1029*dd1de374Slin wang - Sun Microsystems - Beijing China struct ath9k_country_entry *ctry) 1030*dd1de374Slin wang - Sun Microsystems - Beijing China { 1031*dd1de374Slin wang - Sun Microsystems - Beijing China uint16_t rd = ath9k_regd_get_eepromRD(ah); 1032*dd1de374Slin wang - Sun Microsystems - Beijing China 1033*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->isMultidomain = B_FALSE; 1034*dd1de374Slin wang - Sun Microsystems - Beijing China if (rd == CTRY_DEFAULT) 1035*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->isMultidomain = B_TRUE; 1036*dd1de374Slin wang - Sun Microsystems - Beijing China else if (!(rd & COUNTRY_ERD_FLAG)) 1037*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->isMultidomain = isWwrSKU(ah); 1038*dd1de374Slin wang - Sun Microsystems - Beijing China 1039*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->countryCode = ah->ah_countryCode; 1040*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->regDmnEnum = ah->ah_currentRD; 1041*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->regDmn5G = ah->ah_currentRD5G; 1042*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->regDmn2G = ah->ah_currentRD2G; 1043*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->iso[0] = ah->ah_iso[0]; 1044*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->iso[1] = ah->ah_iso[1]; 1045*dd1de374Slin wang - Sun Microsystems - Beijing China ctry->iso[2] = ah->ah_iso[2]; 1046*dd1de374Slin wang - Sun Microsystems - Beijing China } 1047