From 5f8e077c0adc0dc7cfad64cdc05276e1961a1394 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 22 Jan 2009 15:16:48 -0800 Subject: ath9k: simplify regulatory code Now that cfg80211 has its own regulatory infrastructure we can condense ath9k's regulatory code considerably. We only keep data we need to provide our own regulatory_hint(), reg_notifier() and information necessary for calibration. Atheros hardware supports 12 world regulatory domains, since these are custom we apply them through the the new wiphy_apply_custom_regulatory(). Although we have 12 we can consolidate these into 5 structures based on frequency and apply a different set of flags that differentiate them on a case by case basis through the reg_notifier(). If CRDA is not found our own custom world regulatory domain is applied, this is identical to cfg80211's except we enable passive scan on most frequencies. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 1188 ++++++++++--------------------------- 1 file changed, 328 insertions(+), 860 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 64043e99facf..90f0c982430c 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -21,174 +21,323 @@ #include "regd.h" #include "regd_common.h" -static int ath9k_regd_chansort(const void *a, const void *b) -{ - const struct ath9k_channel *ca = a; - const struct ath9k_channel *cb = b; - - return (ca->channel == cb->channel) ? - (ca->channelFlags & CHAN_FLAGS) - - (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel; -} +/* + * This is a set of common rules used by our world regulatory domains. + * We have 12 world regulatory domains. To save space we consolidate + * the regulatory domains in 5 structures by frequency and change + * the flags on our reg_notifier() on a case by case basis. + */ -static void -ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp) -{ - u8 *aa = a; - u8 *ai, *t; - - for (ai = aa + size; --n >= 1; ai += size) - for (t = ai; t > aa; t -= size) { - u8 *u = t - size; - if (cmp(u, t) <= 0) - break; - swap_array(u, t, size); - } -} +/* Only these channels all allow active scan on all world regulatory domains */ +#define ATH9K_2GHZ_CH01_11 REG_RULE(2412-10, 2462+10, 40, 0, 20, 0) + +/* We enable active scan on these a case by case basis by regulatory domain */ +#define ATH9K_2GHZ_CH12_13 REG_RULE(2467-10, 2472+10, 40, 0, 20,\ + NL80211_RRF_PASSIVE_SCAN) +#define ATH9K_2GHZ_CH14 REG_RULE(2484-10, 2484+10, 40, 0, 20,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM) + +/* We allow IBSS on these on a case by case basis by regulatory domain */ +#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 40, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) +#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 40, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) +#define ATH9K_5GHZ_5725_5850 REG_RULE(5725-10, 5850+10, 40, 0, 30,\ + NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS) + +#define ATH9K_2GHZ_ALL ATH9K_2GHZ_CH01_11, \ + ATH9K_2GHZ_CH12_13, \ + ATH9K_2GHZ_CH14 + +#define ATH9K_5GHZ_ALL ATH9K_5GHZ_5150_5350, \ + ATH9K_5GHZ_5470_5850 +/* This one skips what we call "mid band" */ +#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \ + ATH9K_5GHZ_5725_5850 + +/* Can be used for: + * 0x60, 0x61, 0x62 */ +static const struct ieee80211_regdomain ath9k_world_regdom_60_61_62 = { + .n_reg_rules = 5, + .alpha2 = "99", + .reg_rules = { + ATH9K_2GHZ_ALL, + ATH9K_5GHZ_ALL, + } +}; + +/* Can be used by 0x63 and 0x65 */ +static const struct ieee80211_regdomain ath9k_world_regdom_63_65 = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + ATH9K_2GHZ_CH01_11, + ATH9K_2GHZ_CH12_13, + ATH9K_5GHZ_NO_MIDBAND, + } +}; + +/* Can be used by 0x64 only */ +static const struct ieee80211_regdomain ath9k_world_regdom_64 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + ATH9K_2GHZ_CH01_11, + ATH9K_5GHZ_NO_MIDBAND, + } +}; + +/* Can be used by 0x66 and 0x69 */ +static const struct ieee80211_regdomain ath9k_world_regdom_66_69 = { + .n_reg_rules = 3, + .alpha2 = "99", + .reg_rules = { + ATH9K_2GHZ_CH01_11, + ATH9K_5GHZ_ALL, + } +}; + +/* Can be used by 0x67, 0x6A and 0x68 */ +static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = { + .n_reg_rules = 4, + .alpha2 = "99", + .reg_rules = { + ATH9K_2GHZ_CH01_11, + ATH9K_2GHZ_CH12_13, + ATH9K_5GHZ_ALL, + } +}; static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah) { return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG; } -static bool ath9k_regd_is_chan_bm_zero(u64 *bitmask) +u16 ath9k_regd_get_rd(struct ath_hal *ah) { - int i; + return ath9k_regd_get_eepromRD(ah); +} - for (i = 0; i < BMLEN; i++) { - if (bitmask[i] != 0) - return false; - } - return true; +bool ath9k_is_world_regd(struct ath_hal *ah) +{ + return isWwrSKU(ah); } -static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) +const struct ieee80211_regdomain *ath9k_default_world_regdomain(void) { - u16 rd = ath9k_regd_get_eepromRD(ah); - int i; + /* this is the most restrictive */ + return &ath9k_world_regdom_64; +} - if (rd & COUNTRY_ERD_FLAG) { - u16 cc = rd & ~COUNTRY_ERD_FLAG; - for (i = 0; i < ARRAY_SIZE(allCountries); i++) - if (allCountries[i].countryCode == cc) - return true; - } else { - for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) - if (regDomainPairs[i].regDmnEnum == rd) - return true; +const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah) +{ + switch (ah->regpair->regDmnEnum) { + case 0x60: + case 0x61: + case 0x62: + return &ath9k_world_regdom_60_61_62; + case 0x63: + case 0x65: + return &ath9k_world_regdom_63_65; + case 0x64: + return &ath9k_world_regdom_64; + case 0x66: + case 0x69: + return &ath9k_world_regdom_66_69; + case 0x67: + case 0x68: + case 0x6A: + return &ath9k_world_regdom_67_68_6A; + default: + WARN_ON(1); + return ath9k_default_world_regdomain(); } - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "invalid regulatory domain/country code 0x%x\n", rd); - return false; } -static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah) +/* Enable adhoc on 5 GHz if allowed by 11d */ +static void ath9k_reg_apply_5ghz_adhoc_flags(struct wiphy *wiphy, + enum reg_set_by setby) { - u32 regcap; - - regcap = ah->ah_caps.reg_cap; + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath_softc *sc = hw->priv; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + u32 bandwidth = 0; + int r; + + if (setby != REGDOM_SET_BY_COUNTRY_IE) + return; + if (!test_bit(ATH9K_MODE_11A, + sc->sc_ah->ah_caps.wireless_modes)) + return; - if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND) - return true; - else - return false; + sband = wiphy->bands[IEEE80211_BAND_5GHZ]; + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + r = freq_reg_info(wiphy, ch->center_freq, + &bandwidth, ®_rule); + if (r) + continue; + /* If 11d had a rule for this channel ensure we enable adhoc + * if it allows us to use it. Note that we would have disabled + * it by applying our static world regdomain by default during + * probe */ + if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) + ch->flags &= ~NL80211_RRF_NO_IBSS; + } } -static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah, - u16 cc) +/* Allows active scan scan on Ch 12 and 13 */ +static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum reg_set_by setby) { - u16 rd; - int i; - - if (cc == CTRY_DEFAULT) - return true; - if (cc == CTRY_DEBUG) - return true; + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + u32 bandwidth = 0; + int r; + + /* Force passive scan on Channels 12-13 */ + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; + + /* If no country IE has been received always enable active scan + * on these channels */ + if (setby != REGDOM_SET_BY_COUNTRY_IE) { + ch = &sband->channels[11]; /* CH 12 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } - rd = ath9k_regd_get_eepromRD(ah); - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "EEPROM regdomain 0x%x\n", rd); + /* If a country IE has been recieved check its rule for this + * channel first before enabling active scan. The passive scan + * would have been enforced by the initial probe processing on + * our custom regulatory domain. */ - if (rd & COUNTRY_ERD_FLAG) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "EEPROM setting is country code %u\n", - rd & ~COUNTRY_ERD_FLAG); - return cc == (rd & ~COUNTRY_ERD_FLAG); + ch = &sband->channels[11]; /* CH 12 */ + r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, ®_rule); + if (!r) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; } - for (i = 0; i < ARRAY_SIZE(allCountries); i++) { - if (cc == allCountries[i].countryCode) { -#ifdef AH_SUPPORT_11D - if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) - return true; -#endif - if (allCountries[i].regDmnEnum == rd || - rd == DEBUG_REG_DMN || rd == NO_ENUMRD) - return true; - } + ch = &sband->channels[12]; /* CH 13 */ + r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, ®_rule); + if (!r) { + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; } - return false; } -static void -ath9k_regd_get_wmodes_nreg(struct ath_hal *ah, - struct country_code_to_enum_rd *country, - struct regDomain *rd5GHz, - unsigned long *modes_allowed) +/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ +void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) { - bitmap_copy(modes_allowed, ah->ah_caps.wireless_modes, ATH9K_MODE_MAX); + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; - if (test_bit(ATH9K_MODE_11G, ah->ah_caps.wireless_modes) && - (!country->allow11g)) - clear_bit(ATH9K_MODE_11G, modes_allowed); + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) + return; - if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes) && - (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a))) - clear_bit(ATH9K_MODE_11A, modes_allowed); + sband = wiphy->bands[IEEE80211_BAND_5GHZ]; - if (test_bit(ATH9K_MODE_11NG_HT20, ah->ah_caps.wireless_modes) - && (!country->allow11ng20)) - clear_bit(ATH9K_MODE_11NG_HT20, modes_allowed); + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (ch->center_freq < 5260) + continue; + if (ch->center_freq > 5700) + continue; + /* We always enable radar detection/DFS on this + * frequency range. Additionally we also apply on + * this frequency range: + * - If STA mode does not yet have DFS supports disable + * active scanning + * - If adhoc mode does not support DFS yet then + * disable adhoc in the frequency. + * - If AP mode does not yet support radar detection/DFS + * do not allow AP mode + */ + if (!(ch->flags & IEEE80211_CHAN_DISABLED)) + ch->flags |= IEEE80211_CHAN_RADAR | + IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN; + } +} - if (test_bit(ATH9K_MODE_11NA_HT20, ah->ah_caps.wireless_modes) - && (!country->allow11na20)) - clear_bit(ATH9K_MODE_11NA_HT20, modes_allowed); +void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath_softc *sc = hw->priv; + struct ath_hal *ah = sc->sc_ah; + + switch (ah->regpair->regDmnEnum) { + case 0x60: + case 0x63: + case 0x66: + case 0x67: + ath9k_reg_apply_5ghz_adhoc_flags(wiphy, setby); + break; + case 0x68: + ath9k_reg_apply_5ghz_adhoc_flags(wiphy, setby); + ath9k_reg_apply_active_scan_flags(wiphy, setby); + break; + } + return; +} - if (test_bit(ATH9K_MODE_11NG_HT40PLUS, ah->ah_caps.wireless_modes) && - (!country->allow11ng40)) - clear_bit(ATH9K_MODE_11NG_HT40PLUS, modes_allowed); +int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) +{ + struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); + struct ath_softc *sc = hw->priv; - if (test_bit(ATH9K_MODE_11NG_HT40MINUS, ah->ah_caps.wireless_modes) && - (!country->allow11ng40)) - clear_bit(ATH9K_MODE_11NG_HT40MINUS, modes_allowed); + /* We always apply this */ + ath9k_reg_apply_radar_flags(wiphy); - if (test_bit(ATH9K_MODE_11NA_HT40PLUS, ah->ah_caps.wireless_modes) && - (!country->allow11na40)) - clear_bit(ATH9K_MODE_11NA_HT40PLUS, modes_allowed); + switch (request->initiator) { + case REGDOM_SET_BY_DRIVER: + case REGDOM_SET_BY_INIT: + case REGDOM_SET_BY_CORE: + case REGDOM_SET_BY_USER: + break; + case REGDOM_SET_BY_COUNTRY_IE: + if (ath9k_is_world_regd(sc->sc_ah)) + ath9k_reg_apply_world_flags(wiphy, request->initiator); + break; + } - if (test_bit(ATH9K_MODE_11NA_HT40MINUS, ah->ah_caps.wireless_modes) && - (!country->allow11na40)) - clear_bit(ATH9K_MODE_11NA_HT40MINUS, modes_allowed); + return 0; } -bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah) +bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) { - u16 rd; - - rd = ath9k_regd_get_eepromRD(ah); + u16 rd = ath9k_regd_get_eepromRD(ah); + int i; - switch (rd) { - case FCC4_FCCA: - case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG): - return true; - case DEBUG_REG_DMN: - case NO_ENUMRD: - if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49) - return true; - break; + if (rd & COUNTRY_ERD_FLAG) { + /* EEPROM value is a country code */ + u16 cc = rd & ~COUNTRY_ERD_FLAG; + for (i = 0; i < ARRAY_SIZE(allCountries); i++) + if (allCountries[i].countryCode == cc) + return true; + } else { + /* EEPROM value is a regpair value */ + for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) + if (regDomainPairs[i].regDmnEnum == rd) + return true; } + DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, + "invalid regulatory domain/country code 0x%x\n", rd); return false; } +/* EEPROM country code to regpair mapping */ static struct country_code_to_enum_rd* ath9k_regd_find_country(u16 countryCode) { @@ -201,10 +350,23 @@ ath9k_regd_find_country(u16 countryCode) return NULL; } +/* EEPROM rd code to regpair mapping */ +static struct country_code_to_enum_rd* +ath9k_regd_find_country_by_rd(int regdmn) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(allCountries); i++) { + if (allCountries[i].regDmnEnum == regdmn) + return &allCountries[i]; + } + return NULL; +} + +/* Returns the map of the EEPROM set RD to a country code */ static u16 ath9k_regd_get_default_country(struct ath_hal *ah) { u16 rd; - int i; rd = ath9k_regd_get_eepromRD(ah); if (rd & COUNTRY_ERD_FLAG) { @@ -216,798 +378,104 @@ static u16 ath9k_regd_get_default_country(struct ath_hal *ah) return cc; } - for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) - if (regDomainPairs[i].regDmnEnum == rd) { - if (regDomainPairs[i].singleCC != 0) - return regDomainPairs[i].singleCC; - else - i = ARRAY_SIZE(regDomainPairs); - } return CTRY_DEFAULT; } -static bool ath9k_regd_is_valid_reg_domain(int regDmn, - struct regDomain *rd) -{ - int i; - - for (i = 0; i < ARRAY_SIZE(regDomains); i++) { - if (regDomains[i].regDmnEnum == regDmn) { - if (rd != NULL) { - memcpy(rd, ®Domains[i], - sizeof(struct regDomain)); - } - return true; - } - } - return false; -} - -static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair) +static struct reg_dmn_pair_mapping* +ath9k_get_regpair(int regdmn) { int i; - if (regDmnPair == NO_ENUMRD) - return false; + if (regdmn == NO_ENUMRD) + return NULL; for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { - if (regDomainPairs[i].regDmnEnum == regDmnPair) - return true; + if (regDomainPairs[i].regDmnEnum == regdmn) + return ®DomainPairs[i]; } - return false; -} - -static bool -ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn, - u16 channelFlag, struct regDomain *rd) -{ - int i, found; - u64 flags = NO_REQ; - struct reg_dmn_pair_mapping *regPair = NULL; - int regOrg; - - regOrg = regDmn; - if (regDmn == CTRY_DEFAULT) { - u16 rdnum; - rdnum = ath9k_regd_get_eepromRD(ah); - - if (!(rdnum & COUNTRY_ERD_FLAG)) { - if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) || - ath9k_regd_is_valid_reg_domainPair(rdnum)) { - regDmn = rdnum; - } - } - } - - if ((regDmn & MULTI_DOMAIN_MASK) == 0) { - for (i = 0, found = 0; - (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) { - if (regDomainPairs[i].regDmnEnum == regDmn) { - regPair = ®DomainPairs[i]; - found = 1; - } - } - if (!found) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Failed to find reg domain pair %u\n", regDmn); - return false; - } - if (!(channelFlag & CHANNEL_2GHZ)) { - regDmn = regPair->regDmn5GHz; - flags = regPair->flags5GHz; - } - if (channelFlag & CHANNEL_2GHZ) { - regDmn = regPair->regDmn2GHz; - flags = regPair->flags2GHz; - } - } - - found = ath9k_regd_is_valid_reg_domain(regDmn, rd); - if (!found) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Failed to find unitary reg domain %u\n", regDmn); - return false; - } else { - rd->pscan &= regPair->pscanMask; - if (((regOrg & MULTI_DOMAIN_MASK) == 0) && - (flags != NO_REQ)) { - rd->flags = flags; - } - - rd->flags &= (channelFlag & CHANNEL_2GHZ) ? - REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK; - return true; - } -} - -static bool ath9k_regd_is_bit_set(int bit, u64 *bitmask) -{ - int byteOffset, bitnum; - u64 val; - - byteOffset = bit / 64; - bitnum = bit - byteOffset * 64; - val = ((u64) 1) << bitnum; - if (bitmask[byteOffset] & val) - return true; - else - return false; -} - -static void -ath9k_regd_add_reg_classid(u8 *regclassids, u32 maxregids, - u32 *nregids, u8 regclassid) -{ - int i; - - if (regclassid == 0) - return; - - for (i = 0; i < maxregids; i++) { - if (regclassids[i] == regclassid) - return; - if (regclassids[i] == 0) - break; - } - - if (i == maxregids) - return; - else { - regclassids[i] = regclassid; - *nregids += 1; - } - - return; -} - -static bool -ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah, - enum reg_ext_bitmap bit) -{ - return (ah->ah_currentRDExt & (1 << bit)) ? true : false; -} - -#ifdef ATH_NF_PER_CHAN - -static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans, - int nchans) -{ - int i, j, next; - - for (next = 0; next < nchans; next++) { - for (i = 0; i < NUM_NF_READINGS; i++) { - ichans[next].nfCalHist[i].currIndex = 0; - ichans[next].nfCalHist[i].privNF = - AR_PHY_CCA_MAX_GOOD_VALUE; - ichans[next].nfCalHist[i].invalidNFcount = - AR_PHY_CCA_FILTERWINDOW_LENGTH; - for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { - ichans[next].nfCalHist[i].nfCalBuffer[j] = - AR_PHY_CCA_MAX_GOOD_VALUE; - } - } - } -} -#endif - -static int ath9k_regd_is_chan_present(struct ath_hal *ah, - u16 c) -{ - int i; - - for (i = 0; i < 150; i++) { - if (!ah->ah_channels[i].channel) - return -1; - else if (ah->ah_channels[i].channel == c) - return i; - } - - return -1; -} - -static bool -ath9k_regd_add_channel(struct ath_hal *ah, - u16 c, - u16 c_lo, - u16 c_hi, - u16 maxChan, - u8 ctl, - int pos, - struct regDomain rd5GHz, - struct RegDmnFreqBand *fband, - struct regDomain *rd, - const struct cmode *cm, - struct ath9k_channel *ichans, - bool enableExtendedChannels) -{ - struct ath9k_channel *chan; - int ret; - u32 channelFlags = 0; - u8 privFlags = 0; - - if (!(c_lo <= c && c <= c_hi)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "c %u out of range [%u..%u]\n", - c, c_lo, c_hi); - return false; - } - if ((fband->channelBW == CHANNEL_HALF_BW) && - !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_HALFRATE)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Skipping %u half rate channel\n", c); - return false; - } - - if ((fband->channelBW == CHANNEL_QUARTER_BW) && - !(ah->ah_caps.hw_caps & ATH9K_HW_CAP_CHAN_QUARTERRATE)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Skipping %u quarter rate channel\n", c); - return false; - } - - if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "c %u > maxChan %u\n", c, maxChan); - return false; - } - - if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Skipping ecm channel\n"); - return false; - } - - if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == NL80211_IFTYPE_AP)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Skipping HOSTAP channel\n"); - return false; - } - - if (IS_HT40_MODE(cm->mode) && - !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) && - (fband->useDfs) && - (rd->conformanceTestLimit != MKK)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n"); - return false; - } - - if (IS_HT40_MODE(cm->mode) && - !(ath9k_regd_get_eeprom_reg_ext_bits(ah, - REG_EXT_JAPAN_NONDFS_HT40)) && - !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Skipping HT40 channel (en_jap_ht40 = 0)\n"); - return false; - } - - if (IS_HT40_MODE(cm->mode) && - !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) && - (fband->useDfs) && - (rd->conformanceTestLimit == MKK)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n"); - return false; - } - - /* Calculate channel flags */ - - channelFlags = cm->flags; - - switch (fband->channelBW) { - case CHANNEL_HALF_BW: - channelFlags |= CHANNEL_HALF; - break; - case CHANNEL_QUARTER_BW: - channelFlags |= CHANNEL_QUARTER; - break; - } - - if (fband->usePassScan & rd->pscan) - channelFlags |= CHANNEL_PASSIVE; - else - channelFlags &= ~CHANNEL_PASSIVE; - if (fband->useDfs & rd->dfsMask) - privFlags = CHANNEL_DFS; - else - privFlags = 0; - if (rd->flags & LIMIT_FRAME_4MS) - privFlags |= CHANNEL_4MS_LIMIT; - if (privFlags & CHANNEL_DFS) - privFlags |= CHANNEL_DISALLOW_ADHOC; - if (rd->flags & ADHOC_PER_11D) - privFlags |= CHANNEL_PER_11D_ADHOC; - - if (channelFlags & CHANNEL_PASSIVE) { - if ((c < 2412) || (c > 2462)) { - if (rd5GHz.regDmnEnum == MKK1 || - rd5GHz.regDmnEnum == MKK2) { - u32 regcap = ah->ah_caps.reg_cap; - if (!(regcap & - (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN | - AR_EEPROM_EEREGCAP_EN_KK_U2 | - AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) && - isUNII1OddChan(c)) { - channelFlags &= ~CHANNEL_PASSIVE; - } else { - privFlags |= CHANNEL_DISALLOW_ADHOC; - } - } else { - privFlags |= CHANNEL_DISALLOW_ADHOC; - } - } - } - - if ((cm->mode == ATH9K_MODE_11A) || - (cm->mode == ATH9K_MODE_11NA_HT20) || - (cm->mode == ATH9K_MODE_11NA_HT40PLUS) || - (cm->mode == ATH9K_MODE_11NA_HT40MINUS)) { - if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A)) - privFlags |= CHANNEL_DISALLOW_ADHOC; - } - - /* Fill in channel details */ - - ret = ath9k_regd_is_chan_present(ah, c); - if (ret == -1) { - chan = &ah->ah_channels[pos]; - chan->channel = c; - chan->maxRegTxPower = fband->powerDfs; - chan->antennaMax = fband->antennaMax; - chan->regDmnFlags = rd->flags; - chan->maxTxPower = AR5416_MAX_RATE_POWER; - chan->minTxPower = AR5416_MAX_RATE_POWER; - chan->channelFlags = channelFlags; - chan->privFlags = privFlags; - } else { - chan = &ah->ah_channels[ret]; - chan->channelFlags |= channelFlags; - chan->privFlags |= privFlags; - } - - /* Set CTLs */ - - if ((cm->flags & CHANNEL_ALL) == CHANNEL_A) - chan->conformanceTestLimit[0] = ctl; - else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B) - chan->conformanceTestLimit[1] = ctl; - else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G) - chan->conformanceTestLimit[2] = ctl; - - return (ret == -1) ? true : false; -} - -static bool ath9k_regd_japan_check(struct ath_hal *ah, - int b, - struct regDomain *rd5GHz) -{ - bool skipband = false; - int i; - u32 regcap; - - for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) { - if (j_bandcheck[i].freqbandbit == b) { - regcap = ah->ah_caps.reg_cap; - if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) { - skipband = true; - } else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) || - (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) { - rd5GHz->dfsMask |= DFS_MKK4; - rd5GHz->pscan |= PSCAN_MKK3; - } - break; - } - } - - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Skipping %d freq band\n", j_bandcheck[i].freqbandbit); - - return skipband; + return NULL; } -bool -ath9k_regd_init_channels(struct ath_hal *ah, - u32 maxchans, - u32 *nchans, u8 *regclassids, - u32 maxregids, u32 *nregids, u16 cc, - bool enableOutdoor, - bool enableExtendedChannels) +int ath9k_regd_init(struct ath_hal *ah) { - u16 maxChan = 7000; struct country_code_to_enum_rd *country = NULL; - struct regDomain rd5GHz, rd2GHz; - const struct cmode *cm; - struct ath9k_channel *ichans = &ah->ah_channels[0]; - int next = 0, b; - u8 ctl; int regdmn; - u16 chanSep; - unsigned long *modes_avail; - DECLARE_BITMAP(modes_allowed, ATH9K_MODE_MAX); - - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "cc %u %s %s\n", cc, - enableOutdoor ? "Enable outdoor" : "", - enableExtendedChannels ? "Enable ecm" : ""); - - if (!ath9k_regd_is_ccode_valid(ah, cc)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Invalid country code %d\n", cc); - return false; - } if (!ath9k_regd_is_eeprom_valid(ah)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Invalid EEPROM contents\n"); - return false; + return -EINVAL; } 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; - } - } + 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); country = NULL; } else { -#endif country = ath9k_regd_find_country(ah->ah_countryCode); if (country == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Country is NULL!!!!, cc= %d\n", ah->ah_countryCode); - return false; - } else { + return -EINVAL; + } 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 (!isWwrSKU_NoMidband(ah) - && ath9k_regd_is_fcc_midband_supported(ah)) - regdmn = FCC3_FCCA; - else - regdmn = FCC1_FCCA; - } -#endif - } -#ifdef AH_SUPPORT_11D - } -#endif - if (!ath9k_regd_get_wmode_regdomain(ah, - regdmn, - ~CHANNEL_2GHZ, - &rd5GHz)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Couldn't find unitary " - "5GHz reg domain for country %u\n", - ah->ah_countryCode); - return false; - } - if (!ath9k_regd_get_wmode_regdomain(ah, - regdmn, - CHANNEL_2GHZ, - &rd2GHz)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Couldn't find unitary 2GHz " - "reg domain for country %u\n", - ah->ah_countryCode); - return false; } - if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) || - (rd5GHz.regDmnEnum == FCC2))) { - if (ath9k_regd_is_fcc_midband_supported(ah)) { - if (!ath9k_regd_get_wmode_regdomain(ah, - FCC3_FCCA, - ~CHANNEL_2GHZ, - &rd5GHz)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Couldn't find unitary 5GHz " - "reg domain for country %u\n", - ah->ah_countryCode); - return false; - } - } - } - - if (country == NULL) { - modes_avail = ah->ah_caps.wireless_modes; - } else { - ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz, modes_allowed); - modes_avail = modes_allowed; - - if (!enableOutdoor) - maxChan = country->outdoorChanStart; - } - - next = 0; - - if (maxchans > ARRAY_SIZE(ah->ah_channels)) - maxchans = ARRAY_SIZE(ah->ah_channels); - - for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) { - u16 c, c_hi, c_lo; - u64 *channelBM = NULL; - struct regDomain *rd = NULL; - struct RegDmnFreqBand *fband = NULL, *freqs; - int8_t low_adj = 0, hi_adj = 0; - - if (!test_bit(cm->mode, modes_avail)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "!avail mode %d flags 0x%x\n", - cm->mode, cm->flags); - continue; - } - if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "channels 0x%x not supported " - "by hardware\n", cm->flags); - continue; - } - - switch (cm->mode) { - case ATH9K_MODE_11A: - case ATH9K_MODE_11NA_HT20: - case ATH9K_MODE_11NA_HT40PLUS: - case ATH9K_MODE_11NA_HT40MINUS: - rd = &rd5GHz; - channelBM = rd->chan11a; - freqs = ®Dmn5GhzFreq[0]; - ctl = rd->conformanceTestLimit; - break; - case ATH9K_MODE_11B: - rd = &rd2GHz; - channelBM = rd->chan11b; - freqs = ®Dmn2GhzFreq[0]; - ctl = rd->conformanceTestLimit | CTL_11B; - break; - case ATH9K_MODE_11G: - case ATH9K_MODE_11NG_HT20: - case ATH9K_MODE_11NG_HT40PLUS: - case ATH9K_MODE_11NG_HT40MINUS: - rd = &rd2GHz; - channelBM = rd->chan11g; - freqs = ®Dmn2Ghz11gFreq[0]; - ctl = rd->conformanceTestLimit | CTL_11G; - break; - default: - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Unknown HAL mode 0x%x\n", cm->mode); - continue; - } - - if (ath9k_regd_is_chan_bm_zero(channelBM)) - continue; - - if ((cm->mode == ATH9K_MODE_11NA_HT40PLUS) || - (cm->mode == ATH9K_MODE_11NG_HT40PLUS)) { - hi_adj = -20; - } - - if ((cm->mode == ATH9K_MODE_11NA_HT40MINUS) || - (cm->mode == ATH9K_MODE_11NG_HT40MINUS)) { - low_adj = 20; - } - - /* XXX: Add a helper here instead */ - for (b = 0; b < 64 * BMLEN; b++) { - if (ath9k_regd_is_bit_set(b, channelBM)) { - fband = &freqs[b]; - if (rd5GHz.regDmnEnum == MKK1 - || rd5GHz.regDmnEnum == MKK2) { - if (ath9k_regd_japan_check(ah, - b, - &rd5GHz)) - continue; - } - - ath9k_regd_add_reg_classid(regclassids, - maxregids, - nregids, - fband-> - regClassId); - - if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) { - chanSep = 40; - if (fband->lowChannel == 5280) - low_adj += 20; - - if (fband->lowChannel == 5170) - continue; - } else - chanSep = fband->channelSep; - - for (c = fband->lowChannel + low_adj; - ((c <= (fband->highChannel + hi_adj)) && - (c >= (fband->lowChannel + low_adj))); - c += chanSep) { - if (next >= maxchans) { - DPRINTF(ah->ah_sc, - ATH_DBG_REGULATORY, - "too many channels " - "for channel table\n"); - goto done; - } - if (ath9k_regd_add_channel(ah, - c, c_lo, c_hi, - maxChan, ctl, - next, - rd5GHz, - fband, rd, cm, - ichans, - enableExtendedChannels)) - next++; - } - if (IS_HT40_MODE(cm->mode) && - (fband->lowChannel == 5280)) { - low_adj -= 20; - } - } - } - } -done: - if (next != 0) { - int i; + ah->ah_currentRDInUse = regdmn; + ah->regpair = ath9k_get_regpair(regdmn); - if (next > ARRAY_SIZE(ah->ah_channels)) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "too many channels %u; truncating to %u\n", - 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 ath9k_channel), - ath9k_regd_chansort); - - ah->ah_nchan = next; - - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n"); - for (i = 0; i < next; i++) { - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "chan: %d flags: 0x%x\n", - ah->ah_channels[i].channel, - ah->ah_channels[i].channelFlags); - } + if (!ah->regpair) { + DPRINTF(ah->ah_sc, ATH_DBG_FATAL, + "No regulatory domain pair found, cannot continue\n"); + return -EINVAL; } - *nchans = next; - ah->ah_countryCode = ah->ah_countryCode; + if (!country) + country = ath9k_regd_find_country_by_rd(regdmn); - ah->ah_currentRDInUse = regdmn; - ah->ah_currentRD5G = rd5GHz.regDmnEnum; - ah->ah_currentRD2G = rd2GHz.regDmnEnum; - if (country == NULL) { - ah->ah_iso[0] = 0; - ah->ah_iso[1] = 0; + if (country) { + ah->alpha2[0] = country->isoName[0]; + ah->alpha2[1] = country->isoName[1]; } else { - ah->ah_iso[0] = country->isoName[0]; - ah->ah_iso[1] = country->isoName[1]; + ah->alpha2[0] = '0'; + ah->alpha2[1] = '0'; } - return next != 0; -} - -struct ath9k_channel* -ath9k_regd_check_channel(struct ath_hal *ah, - const struct ath9k_channel *c) -{ - struct ath9k_channel *base, *cc; - - int flags = c->channelFlags & CHAN_FLAGS; - int n, lim; - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "channel %u/0x%x (0x%x) requested\n", - c->channel, c->channelFlags, flags); - - cc = ah->ah_curchan; - if (cc != NULL && cc->channel == c->channel && - (cc->channelFlags & CHAN_FLAGS) == flags) { - if ((cc->privFlags & CHANNEL_INTERFERENCE) && - (cc->privFlags & CHANNEL_DFS)) - return NULL; - else - return cc; - } + "Country alpha2 being used: %c%c\n", + "Regpair detected: 0x%0x\n", + ah->alpha2[0], ah->alpha2[1], + ah->regpair->regDmnEnum); - base = ah->ah_channels; - n = ah->ah_nchan; - - for (lim = n; lim != 0; lim >>= 1) { - int d; - cc = &base[lim >> 1]; - d = c->channel - cc->channel; - if (d == 0) { - if ((cc->channelFlags & CHAN_FLAGS) == flags) { - if ((cc->privFlags & CHANNEL_INTERFERENCE) && - (cc->privFlags & CHANNEL_DFS)) - return NULL; - else - return cc; - } - d = flags - (cc->channelFlags & CHAN_FLAGS); - } - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "channel %u/0x%x d %d\n", - cc->channel, cc->channelFlags, d); - if (d > 0) { - base = cc + 1; - lim--; - } - } - DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "no match for %u/0x%x\n", - c->channel, c->channelFlags); - return NULL; -} - -u32 -ath9k_regd_get_antenna_allowed(struct ath_hal *ah, - struct ath9k_channel *chan) -{ - struct ath9k_channel *ichan = NULL; - - ichan = ath9k_regd_check_channel(ah, chan); - if (!ichan) - return 0; - - return ichan->antennaMax; + return 0; } u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) { u32 ctl = NO_CTL; - struct ath9k_channel *ichan; - if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) { + if (!ah->regpair || + (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah))) { if (IS_CHAN_B(chan)) ctl = SD_NO_CTL | CTL_11B; else if (IS_CHAN_G(chan)) ctl = SD_NO_CTL | CTL_11G; else ctl = SD_NO_CTL | CTL_11A; - } else { - ichan = ath9k_regd_check_channel(ah, chan); - if (ichan != NULL) { - /* FIXME */ - if (IS_CHAN_A(ichan)) - ctl = ichan->conformanceTestLimit[0]; - else if (IS_CHAN_B(ichan)) - ctl = ichan->conformanceTestLimit[1]; - else if (IS_CHAN_G(ichan)) - ctl = ichan->conformanceTestLimit[2]; - - if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B) - ctl = (ctl & ~0xf) | CTL_11G; - } + return ctl; } - return ctl; -} -void ath9k_regd_get_current_country(struct ath_hal *ah, - struct ath9k_country_entry *ctry) -{ - u16 rd = ath9k_regd_get_eepromRD(ah); + if (IS_CHAN_B(chan)) + ctl = ah->regpair->reg_2ghz_ctl | CTL_11B; + else if (IS_CHAN_G(chan)) + ctl = ah->regpair->reg_5ghz_ctl | CTL_11G; + else + ctl = ah->regpair->reg_5ghz_ctl | CTL_11A; - ctry->isMultidomain = false; - if (rd == CTRY_DEFAULT) - ctry->isMultidomain = true; - else if (!(rd & COUNTRY_ERD_FLAG)) - ctry->isMultidomain = isWwrSKU(ah); - - ctry->countryCode = ah->ah_countryCode; - ctry->regDmnEnum = ah->ah_currentRD; - ctry->regDmn5G = ah->ah_currentRD5G; - ctry->regDmn2G = ah->ah_currentRD2G; - ctry->iso[0] = ah->ah_iso[0]; - ctry->iso[1] = ah->ah_iso[1]; - ctry->iso[2] = ah->ah_iso[2]; + return ctl; } -- cgit v1.2.3 From 0c6666e4c43a10a224c63e3270c963d97f7e8cc8 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 26 Jan 2009 06:48:10 -0800 Subject: ath9k: fix debug print on regd With debugging enabled and with ATH_DBG_REGULATORY selected we wouldn't get the full print out of one line, reason is we used "," instead of nothing to separate two lines. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 90f0c982430c..ec88f78743e9 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -447,7 +447,7 @@ int ath9k_regd_init(struct ath_hal *ah) } DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, - "Country alpha2 being used: %c%c\n", + "Country alpha2 being used: %c%c\n" "Regpair detected: 0x%0x\n", ah->alpha2[0], ah->alpha2[1], ah->regpair->regDmnEnum); -- cgit v1.2.3 From 8c63c46d58c9dca6d0bfacfb41958c55d9b75ea0 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 28 Jan 2009 12:17:47 -0800 Subject: ath9k: replace usage of internal wireless_modes for conf No need to use our internal wireless mode variable when cfg80211 already has its own. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index ec88f78743e9..b84fbe30109b 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -158,8 +158,6 @@ const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah) static void ath9k_reg_apply_5ghz_adhoc_flags(struct wiphy *wiphy, enum reg_set_by setby) { - struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath_softc *sc = hw->priv; struct ieee80211_supported_band *sband; const struct ieee80211_reg_rule *reg_rule; struct ieee80211_channel *ch; @@ -169,8 +167,7 @@ static void ath9k_reg_apply_5ghz_adhoc_flags(struct wiphy *wiphy, if (setby != REGDOM_SET_BY_COUNTRY_IE) return; - if (!test_bit(ATH9K_MODE_11A, - sc->sc_ah->ah_caps.wireless_modes)) + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) return; sband = wiphy->bands[IEEE80211_BAND_5GHZ]; -- cgit v1.2.3 From 547e4c2e64d0be5e8491abb49ee6b0f0f8272de1 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 28 Jan 2009 12:17:48 -0800 Subject: ath9k: move check for radar freqs into a helper This will be used later. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index b84fbe30109b..cccec40139c2 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -154,6 +154,12 @@ const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah) } } +/* Frequency is one where radar detection is required */ +static bool ath9k_is_radar_freq(u16 center_freq) +{ + return (center_freq >= 5260 && center_freq <= 5700); +} + /* Enable adhoc on 5 GHz if allowed by 11d */ static void ath9k_reg_apply_5ghz_adhoc_flags(struct wiphy *wiphy, enum reg_set_by setby) @@ -247,9 +253,7 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) for (i = 0; i < sband->n_channels; i++) { ch = &sband->channels[i]; - if (ch->center_freq < 5260) - continue; - if (ch->center_freq > 5700) + if (!ath9k_is_radar_freq(ch->center_freq)) continue; /* We always enable radar detection/DFS on this * frequency range. Additionally we also apply on -- cgit v1.2.3 From 7519a8f0778bdb14f07cf685fa5fee6ab07e734c Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 28 Jan 2009 12:17:49 -0800 Subject: ath9k: remove passive scan on 5 GHz if country IE knows better If we have new found information about our location and the current country regulatory domain does not have passive scan flag requirements we should be able to actively scan now on those channels. Since AP functionality is not allowed where passive scan flags are set this means if you have a world regulatory domain and you get a country IE that allows that channel (with active scan) then we lift the passive-scan requirement so you can then use AP mode. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index cccec40139c2..dfcc3b5274cb 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -160,8 +160,12 @@ static bool ath9k_is_radar_freq(u16 center_freq) return (center_freq >= 5260 && center_freq <= 5700); } -/* Enable adhoc on 5 GHz if allowed by 11d */ -static void ath9k_reg_apply_5ghz_adhoc_flags(struct wiphy *wiphy, +/* + * Enable adhoc on 5 GHz if allowed by 11d. + * Remove passive scan if channel is allowed by 11d, + * except when on radar frequencies. + */ +static void ath9k_reg_apply_5ghz_beaconing_flags(struct wiphy *wiphy, enum reg_set_by setby) { struct ieee80211_supported_band *sband; @@ -189,6 +193,10 @@ static void ath9k_reg_apply_5ghz_adhoc_flags(struct wiphy *wiphy, * probe */ if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) ch->flags &= ~NL80211_RRF_NO_IBSS; + if (!ath9k_is_radar_freq(ch->center_freq)) + continue; + if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= ~NL80211_RRF_PASSIVE_SCAN; } } @@ -283,10 +291,10 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) case 0x63: case 0x66: case 0x67: - ath9k_reg_apply_5ghz_adhoc_flags(wiphy, setby); + ath9k_reg_apply_5ghz_beaconing_flags(wiphy, setby); break; case 0x68: - ath9k_reg_apply_5ghz_adhoc_flags(wiphy, setby); + ath9k_reg_apply_5ghz_beaconing_flags(wiphy, setby); ath9k_reg_apply_active_scan_flags(wiphy, setby); break; } -- cgit v1.2.3 From de9f97efb2ea2a32a610932d881e4d3653e0f932 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 2 Feb 2009 20:35:05 -0800 Subject: ath9k: fix reg_notifier() flags used upon a country IE The nl80211 rule flags were being used. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index dfcc3b5274cb..fe08a4fdf770 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -192,11 +192,11 @@ static void ath9k_reg_apply_5ghz_beaconing_flags(struct wiphy *wiphy, * it by applying our static world regdomain by default during * probe */ if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) - ch->flags &= ~NL80211_RRF_NO_IBSS; + ch->flags &= ~IEEE80211_CHAN_NO_IBSS; if (!ath9k_is_radar_freq(ch->center_freq)) continue; if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) - ch->flags &= ~NL80211_RRF_PASSIVE_SCAN; + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; } } -- cgit v1.2.3 From 394cf0a1ca02e7998c8d01975b60a3cdc121e7d8 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 9 Feb 2009 13:26:54 +0530 Subject: ath9k: Header file cleanup Split the core header files into manageable pieces. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index fe08a4fdf770..819feb963821 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -16,9 +16,7 @@ #include #include -#include "core.h" -#include "hw.h" -#include "regd.h" +#include "ath9k.h" #include "regd_common.h" /* -- cgit v1.2.3 From d6bad496c6fbe3adb3323915a8b0430fa2955199 Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 9 Feb 2009 13:27:08 +0530 Subject: ath9k: Move regulatory information to a separate structure Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 48 +++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 819feb963821..32dd0cb34490 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -108,7 +108,7 @@ static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = { static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah) { - return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG; + return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG; } u16 ath9k_regd_get_rd(struct ath_hal *ah) @@ -129,7 +129,7 @@ const struct ieee80211_regdomain *ath9k_default_world_regdomain(void) const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah) { - switch (ah->regpair->regDmnEnum) { + switch (ah->regulatory.regpair->regDmnEnum) { case 0x60: case 0x61: case 0x62: @@ -284,7 +284,7 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) struct ath_softc *sc = hw->priv; struct ath_hal *ah = sc->sc_ah; - switch (ah->regpair->regDmnEnum) { + switch (ah->regulatory.regpair->regDmnEnum) { case 0x60: case 0x63: case 0x66: @@ -413,30 +413,30 @@ int ath9k_regd_init(struct ath_hal *ah) return -EINVAL; } - ah->ah_countryCode = ath9k_regd_get_default_country(ah); + ah->regulatory.country_code = ath9k_regd_get_default_country(ah); - if (ah->ah_countryCode == CTRY_DEFAULT && + if (ah->regulatory.country_code == CTRY_DEFAULT && ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT) - ah->ah_countryCode = CTRY_UNITED_STATES; + ah->regulatory.country_code = CTRY_UNITED_STATES; - if (ah->ah_countryCode == CTRY_DEFAULT) { + if (ah->regulatory.country_code == CTRY_DEFAULT) { regdmn = ath9k_regd_get_eepromRD(ah); country = NULL; } else { - country = ath9k_regd_find_country(ah->ah_countryCode); + country = ath9k_regd_find_country(ah->regulatory.country_code); if (country == NULL) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Country is NULL!!!!, cc= %d\n", - ah->ah_countryCode); + ah->regulatory.country_code); return -EINVAL; } else regdmn = country->regDmnEnum; } - ah->ah_currentRDInUse = regdmn; - ah->regpair = ath9k_get_regpair(regdmn); + ah->regulatory.current_rd_inuse = regdmn; + ah->regulatory.regpair = ath9k_get_regpair(regdmn); - if (!ah->regpair) { + if (!ah->regulatory.regpair) { DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "No regulatory domain pair found, cannot continue\n"); return -EINVAL; @@ -446,18 +446,18 @@ int ath9k_regd_init(struct ath_hal *ah) country = ath9k_regd_find_country_by_rd(regdmn); if (country) { - ah->alpha2[0] = country->isoName[0]; - ah->alpha2[1] = country->isoName[1]; + ah->regulatory.alpha2[0] = country->isoName[0]; + ah->regulatory.alpha2[1] = country->isoName[1]; } else { - ah->alpha2[0] = '0'; - ah->alpha2[1] = '0'; + ah->regulatory.alpha2[0] = '0'; + ah->regulatory.alpha2[1] = '0'; } DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Country alpha2 being used: %c%c\n" - "Regpair detected: 0x%0x\n", - ah->alpha2[0], ah->alpha2[1], - ah->regpair->regDmnEnum); + "Regulatory.Regpair detected: 0x%0x\n", + ah->regulatory.alpha2[0], ah->regulatory.alpha2[1], + ah->regulatory.regpair->regDmnEnum); return 0; } @@ -466,8 +466,8 @@ u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) { u32 ctl = NO_CTL; - if (!ah->regpair || - (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah))) { + if (!ah->regulatory.regpair || + (ah->regulatory.country_code == CTRY_DEFAULT && isWwrSKU(ah))) { if (IS_CHAN_B(chan)) ctl = SD_NO_CTL | CTL_11B; else if (IS_CHAN_G(chan)) @@ -478,11 +478,11 @@ u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) } if (IS_CHAN_B(chan)) - ctl = ah->regpair->reg_2ghz_ctl | CTL_11B; + ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B; else if (IS_CHAN_G(chan)) - ctl = ah->regpair->reg_5ghz_ctl | CTL_11G; + ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11G; else - ctl = ah->regpair->reg_5ghz_ctl | CTL_11A; + ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A; return ctl; } -- cgit v1.2.3 From cbe61d8a41210600bc76b212edcd4dc0f55c014f Mon Sep 17 00:00:00 2001 From: Sujith Date: Mon, 9 Feb 2009 13:27:12 +0530 Subject: ath9k: Merge ath_hal and ath_hal_5416 structures Finally, merge these structures and have a single HW specific data structure. Signed-off-by: Sujith Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 32dd0cb34490..8c2b56ac55ff 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -106,17 +106,17 @@ static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = { } }; -static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah) +static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah) { return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG; } -u16 ath9k_regd_get_rd(struct ath_hal *ah) +u16 ath9k_regd_get_rd(struct ath_hw *ah) { return ath9k_regd_get_eepromRD(ah); } -bool ath9k_is_world_regd(struct ath_hal *ah) +bool ath9k_is_world_regd(struct ath_hw *ah) { return isWwrSKU(ah); } @@ -127,7 +127,7 @@ const struct ieee80211_regdomain *ath9k_default_world_regdomain(void) return &ath9k_world_regdom_64; } -const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hal *ah) +const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah) { switch (ah->regulatory.regpair->regDmnEnum) { case 0x60: @@ -282,7 +282,7 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct ath_softc *sc = hw->priv; - struct ath_hal *ah = sc->sc_ah; + struct ath_hw *ah = sc->sc_ah; switch (ah->regulatory.regpair->regDmnEnum) { case 0x60: @@ -322,7 +322,7 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) return 0; } -bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah) +bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah) { u16 rd = ath9k_regd_get_eepromRD(ah); int i; @@ -371,7 +371,7 @@ ath9k_regd_find_country_by_rd(int regdmn) } /* Returns the map of the EEPROM set RD to a country code */ -static u16 ath9k_regd_get_default_country(struct ath_hal *ah) +static u16 ath9k_regd_get_default_country(struct ath_hw *ah) { u16 rd; @@ -402,7 +402,7 @@ ath9k_get_regpair(int regdmn) return NULL; } -int ath9k_regd_init(struct ath_hal *ah) +int ath9k_regd_init(struct ath_hw *ah) { struct country_code_to_enum_rd *country = NULL; int regdmn; @@ -462,7 +462,7 @@ int ath9k_regd_init(struct ath_hal *ah) return 0; } -u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan) +u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan) { u32 ctl = NO_CTL; -- cgit v1.2.3 From 63a7c8e254651d1080809de22f0db3ac70fbf914 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Thu, 12 Feb 2009 13:38:53 -0500 Subject: ath9k: remove write-only current_rd_inuse The current_rd_inuse regulatory value is assigned but not used anywhere. Signed-off-by: Bob Copeland Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 8c2b56ac55ff..0c632fff8ada 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -433,7 +433,6 @@ int ath9k_regd_init(struct ath_hw *ah) regdmn = country->regDmnEnum; } - ah->regulatory.current_rd_inuse = regdmn; ah->regulatory.regpair = ath9k_get_regpair(regdmn); if (!ah->regulatory.regpair) { -- cgit v1.2.3 From e775aaf07a72eafdb352a984d820612dd76eab8c Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Thu, 12 Feb 2009 13:38:54 -0500 Subject: ath9k: save a few calls to ath9k_regd_get_eepromRD Since we already have a stack variable to track the eeprom regd, we can grab it up front it and save three calls to fetch it again. Signed-off-by: Bob Copeland Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 0c632fff8ada..99994626081d 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -371,11 +371,8 @@ ath9k_regd_find_country_by_rd(int regdmn) } /* Returns the map of the EEPROM set RD to a country code */ -static u16 ath9k_regd_get_default_country(struct ath_hw *ah) +static u16 ath9k_regd_get_default_country(u16 rd) { - u16 rd; - - rd = ath9k_regd_get_eepromRD(ah); if (rd & COUNTRY_ERD_FLAG) { struct country_code_to_enum_rd *country = NULL; u16 cc = rd & ~COUNTRY_ERD_FLAG; @@ -405,7 +402,7 @@ ath9k_get_regpair(int regdmn) int ath9k_regd_init(struct ath_hw *ah) { struct country_code_to_enum_rd *country = NULL; - int regdmn; + u16 regdmn; if (!ath9k_regd_is_eeprom_valid(ah)) { DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, @@ -413,14 +410,14 @@ int ath9k_regd_init(struct ath_hw *ah) return -EINVAL; } - ah->regulatory.country_code = ath9k_regd_get_default_country(ah); + regdmn = ath9k_regd_get_eepromRD(ah); + ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn); if (ah->regulatory.country_code == CTRY_DEFAULT && - ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT) + regdmn == CTRY_DEFAULT) ah->regulatory.country_code = CTRY_UNITED_STATES; if (ah->regulatory.country_code == CTRY_DEFAULT) { - regdmn = ath9k_regd_get_eepromRD(ah); country = NULL; } else { country = ath9k_regd_find_country(ah->regulatory.country_code); -- cgit v1.2.3 From d0f48f9d1fa9ad01effdf280cda944c6eb518f59 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Thu, 12 Feb 2009 13:38:55 -0500 Subject: ath9k: convert isWwrSKU macro into C code Write isWwrSKU as an inline function and nix the camel-case to make the routine slightly clearer. Change its argument to take the regd value directly so it can eventually be used by ath5k as well. Signed-off-by: Bob Copeland Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 99994626081d..979351540e69 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -106,6 +106,12 @@ static const struct ieee80211_regdomain ath9k_world_regdom_67_68_6A = { } }; +static inline bool is_wwr_sku(u16 regd) +{ + return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || + (regd == WORLD); +} + static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah) { return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG; @@ -118,7 +124,7 @@ u16 ath9k_regd_get_rd(struct ath_hw *ah) bool ath9k_is_world_regd(struct ath_hw *ah) { - return isWwrSKU(ah); + return is_wwr_sku(ath9k_regd_get_eepromRD(ah)); } const struct ieee80211_regdomain *ath9k_default_world_regdomain(void) @@ -463,7 +469,8 @@ u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan) u32 ctl = NO_CTL; if (!ah->regulatory.regpair || - (ah->regulatory.country_code == CTRY_DEFAULT && isWwrSKU(ah))) { + (ah->regulatory.country_code == CTRY_DEFAULT && + is_wwr_sku(ath9k_regd_get_eepromRD(ah)))) { if (IS_CHAN_B(chan)) ctl = SD_NO_CTL | CTL_11B; else if (IS_CHAN_G(chan)) -- cgit v1.2.3 From 17580f6ab172089a31412bc895de5fcef9f8c073 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Thu, 12 Feb 2009 13:38:56 -0500 Subject: ath9k: remove ath9k_regd_get_rd() The function ath9k_regd_get_rd() is unused. Signed-off-by: Bob Copeland Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 979351540e69..eb0d1b754d20 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -117,11 +117,6 @@ static u16 ath9k_regd_get_eepromRD(struct ath_hw *ah) return ah->regulatory.current_rd & ~WORLDWIDE_ROAMING_FLAG; } -u16 ath9k_regd_get_rd(struct ath_hw *ah) -{ - return ath9k_regd_get_eepromRD(ah); -} - bool ath9k_is_world_regd(struct ath_hw *ah) { return is_wwr_sku(ath9k_regd_get_eepromRD(ah)); -- cgit v1.2.3 From 84540869678649074ae040bc9b063ef38ec9c83a Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Sat, 21 Feb 2009 00:20:40 -0500 Subject: ath9k: follow beacon hints on reg_notifier when world roaming If we are roaming we allow to follow beacon hints. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 93 +++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 32 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index eb0d1b754d20..f4595e248875 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -160,13 +160,18 @@ static bool ath9k_is_radar_freq(u16 center_freq) } /* - * Enable adhoc on 5 GHz if allowed by 11d. - * Remove passive scan if channel is allowed by 11d, - * except when on radar frequencies. + * N.B: These exception rules do not apply radar freqs. + * + * - We enable adhoc (or beaconing) if allowed by 11d + * - We enable active scan if the channel is allowed by 11d + * - If no country IE has been processed and a we determine we have + * received a beacon on a channel we can enable active scan and + * adhoc (or beaconing). */ -static void ath9k_reg_apply_5ghz_beaconing_flags(struct wiphy *wiphy, +static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy, enum reg_set_by setby) { + enum ieee80211_band band; struct ieee80211_supported_band *sband; const struct ieee80211_reg_rule *reg_rule; struct ieee80211_channel *ch; @@ -174,29 +179,50 @@ static void ath9k_reg_apply_5ghz_beaconing_flags(struct wiphy *wiphy, u32 bandwidth = 0; int r; - if (setby != REGDOM_SET_BY_COUNTRY_IE) - return; - if (!wiphy->bands[IEEE80211_BAND_5GHZ]) - return; + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { - sband = wiphy->bands[IEEE80211_BAND_5GHZ]; - for (i = 0; i < sband->n_channels; i++) { - ch = &sband->channels[i]; - r = freq_reg_info(wiphy, ch->center_freq, - &bandwidth, ®_rule); - if (r) + if (!wiphy->bands[band]) continue; - /* If 11d had a rule for this channel ensure we enable adhoc - * if it allows us to use it. Note that we would have disabled - * it by applying our static world regdomain by default during - * probe */ - if (!(reg_rule->flags & NL80211_RRF_NO_IBSS)) - ch->flags &= ~IEEE80211_CHAN_NO_IBSS; - if (!ath9k_is_radar_freq(ch->center_freq)) - continue; - if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN)) - ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + + ch = &sband->channels[i]; + + if (ath9k_is_radar_freq(ch->center_freq) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + + if (setby == REGDOM_SET_BY_COUNTRY_IE) { + r = freq_reg_info(wiphy, ch->center_freq, + &bandwidth, ®_rule); + if (r) + continue; + /* + * If 11d had a rule for this channel ensure + * we enable adhoc/beaconing if it allows us to + * use it. Note that we would have disabled it + * by applying our static world regdomain by + * default during init, prior to calling our + * regulatory_hint(). + */ + if (!(reg_rule->flags & + NL80211_RRF_NO_IBSS)) + ch->flags &= + ~IEEE80211_CHAN_NO_IBSS; + if (!(reg_rule->flags & + NL80211_RRF_PASSIVE_SCAN)) + ch->flags &= + ~IEEE80211_CHAN_PASSIVE_SCAN; + } else { + if (ch->beacon_found) + ch->flags &= ~(IEEE80211_CHAN_NO_IBSS | + IEEE80211_CHAN_PASSIVE_SCAN); + } + } } + } /* Allows active scan scan on Ch 12 and 13 */ @@ -209,11 +235,12 @@ static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy, u32 bandwidth = 0; int r; - /* Force passive scan on Channels 12-13 */ sband = wiphy->bands[IEEE80211_BAND_2GHZ]; - /* If no country IE has been received always enable active scan - * on these channels */ + /* + * If no country IE has been received always enable active scan + * on these channels. This is only done for specific regulatory SKUs + */ if (setby != REGDOM_SET_BY_COUNTRY_IE) { ch = &sband->channels[11]; /* CH 12 */ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) @@ -224,10 +251,12 @@ static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy, return; } - /* If a country IE has been recieved check its rule for this + /* + * If a country IE has been recieved check its rule for this * channel first before enabling active scan. The passive scan - * would have been enforced by the initial probe processing on - * our custom regulatory domain. */ + * would have been enforced by the initial processing of our + * custom regulatory domain. + */ ch = &sband->channels[11]; /* CH 12 */ r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, ®_rule); @@ -290,10 +319,10 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) case 0x63: case 0x66: case 0x67: - ath9k_reg_apply_5ghz_beaconing_flags(wiphy, setby); + ath9k_reg_apply_beaconing_flags(wiphy, setby); break; case 0x68: - ath9k_reg_apply_5ghz_beaconing_flags(wiphy, setby); + ath9k_reg_apply_beaconing_flags(wiphy, setby); ath9k_reg_apply_active_scan_flags(wiphy, setby); break; } -- cgit v1.2.3 From 204b190cabf901b4bdece2006acc15a8978288db Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Sat, 21 Feb 2009 14:44:18 -0500 Subject: ath9k: fix 802.11g conformance test limit typo 802.11g is in 2 ghz band, not 5 ghz. Signed-off-by: Bob Copeland Acked-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index f4595e248875..f7d7cc24a129 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -507,7 +507,7 @@ u32 ath9k_regd_get_ctl(struct ath_hw *ah, struct ath9k_channel *chan) if (IS_CHAN_B(chan)) ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11B; else if (IS_CHAN_G(chan)) - ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11G; + ctl = ah->regulatory.regpair->reg_2ghz_ctl | CTL_11G; else ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A; -- cgit v1.2.3 From bce048d77dff3dcfd75d54dc38580c81baa95853 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 3 Mar 2009 19:23:28 +0200 Subject: ath9k: Add data structure for supporting virtual radio/wiphy operation This is the initial step in allowing ath9k to register multiple virtual radios (wiphys). The goal of virtual radios is to allow the same radio to be shared for multiple virtual interfaces that may operate on different channels. The mac80211 virtual interface support is designed only for single channel operation and as such, it is not suitable for this type of use. Anyway, it can be used on top of the virtual radio concept, if desired (e.g., use two virtual radios to handle two channels and then add multiple mac80211 virtual interfaces on top of each virtual radio). The new struct ath_wiphy is now registered as the driver data structure for wiphy. This structure has a pointer to the shared (among virtual wiphys of the same physical radio) struct ath_softc data. The primary wiphy maintains the allocated memory for ath_softc. Secondary (virtual) wiphys will only allocate the new ath_wiphy structure. Registration of secondary wiphys is added in a separate patch. Signed-off-by: Jouni Malinen Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index f7d7cc24a129..639da975bf54 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -311,7 +311,8 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath_softc *sc = hw->priv; + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; struct ath_hw *ah = sc->sc_ah; switch (ah->regulatory.regpair->regDmnEnum) { @@ -332,7 +333,8 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); - struct ath_softc *sc = hw->priv; + struct ath_wiphy *aphy = hw->priv; + struct ath_softc *sc = aphy->sc; /* We always apply this */ ath9k_reg_apply_radar_flags(wiphy); -- cgit v1.2.3 From 0fee54cab7d5ebc58fad8c6a0703c4ea016405e3 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 9 Mar 2009 22:07:40 -0400 Subject: cfg80211: remove REGDOM_SET_BY_INIT This is not used as we can always just assume the first regulatory domain set will _always_ be a static regulatory domain. REGDOM_SET_BY_CORE will be the first request from cfg80211 for a regdomain and that then populates the first regulatory request. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index 639da975bf54..ff0afc02f3ce 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -341,7 +341,6 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) switch (request->initiator) { case REGDOM_SET_BY_DRIVER: - case REGDOM_SET_BY_INIT: case REGDOM_SET_BY_CORE: case REGDOM_SET_BY_USER: break; -- cgit v1.2.3 From 7db90f4a25bd4184f3d36dfa4f512f53b0448da7 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 9 Mar 2009 22:07:41 -0400 Subject: cfg80211: move enum reg_set_by to nl80211.h We do this so we can later inform userspace who set the regulatory domain and provide details of the request. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath9k/regd.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/ath9k/regd.c') diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c index ff0afc02f3ce..b8f9b6d6bec4 100644 --- a/drivers/net/wireless/ath9k/regd.c +++ b/drivers/net/wireless/ath9k/regd.c @@ -168,8 +168,9 @@ static bool ath9k_is_radar_freq(u16 center_freq) * received a beacon on a channel we can enable active scan and * adhoc (or beaconing). */ -static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy, - enum reg_set_by setby) +static void ath9k_reg_apply_beaconing_flags( + struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { enum ieee80211_band band; struct ieee80211_supported_band *sband; @@ -194,7 +195,7 @@ static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy, (ch->flags & IEEE80211_CHAN_RADAR)) continue; - if (setby == REGDOM_SET_BY_COUNTRY_IE) { + if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, ®_rule); if (r) @@ -226,8 +227,9 @@ static void ath9k_reg_apply_beaconing_flags(struct wiphy *wiphy, } /* Allows active scan scan on Ch 12 and 13 */ -static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy, - enum reg_set_by setby) +static void ath9k_reg_apply_active_scan_flags( + struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -241,7 +243,7 @@ static void ath9k_reg_apply_active_scan_flags(struct wiphy *wiphy, * If no country IE has been received always enable active scan * on these channels. This is only done for specific regulatory SKUs */ - if (setby != REGDOM_SET_BY_COUNTRY_IE) { + if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) { ch = &sband->channels[11]; /* CH 12 */ if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; @@ -308,7 +310,8 @@ void ath9k_reg_apply_radar_flags(struct wiphy *wiphy) } } -void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) +void ath9k_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); struct ath_wiphy *aphy = hw->priv; @@ -320,11 +323,11 @@ void ath9k_reg_apply_world_flags(struct wiphy *wiphy, enum reg_set_by setby) case 0x63: case 0x66: case 0x67: - ath9k_reg_apply_beaconing_flags(wiphy, setby); + ath9k_reg_apply_beaconing_flags(wiphy, initiator); break; case 0x68: - ath9k_reg_apply_beaconing_flags(wiphy, setby); - ath9k_reg_apply_active_scan_flags(wiphy, setby); + ath9k_reg_apply_beaconing_flags(wiphy, initiator); + ath9k_reg_apply_active_scan_flags(wiphy, initiator); break; } return; @@ -340,11 +343,11 @@ int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request) ath9k_reg_apply_radar_flags(wiphy); switch (request->initiator) { - case REGDOM_SET_BY_DRIVER: - case REGDOM_SET_BY_CORE: - case REGDOM_SET_BY_USER: + case NL80211_REGDOM_SET_BY_DRIVER: + case NL80211_REGDOM_SET_BY_CORE: + case NL80211_REGDOM_SET_BY_USER: break; - case REGDOM_SET_BY_COUNTRY_IE: + case NL80211_REGDOM_SET_BY_COUNTRY_IE: if (ath9k_is_world_regd(sc->sc_ah)) ath9k_reg_apply_world_flags(wiphy, request->initiator); break; -- cgit v1.2.3