From 3a702e49c03ba959e3f5bb2b74ec9921a81c8c98 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 30 Mar 2009 22:30:29 -0400 Subject: atheros: introduce ath module containing common ath5k/ath9k/ar9170 code This change creates a new module, ath.ko, which includes code that can be shared between ath5k, ath9k and ar9170. For now, extract most of the ath9k regulatory code so it can also be used in ath5k. Signed-off-by: Bob Copeland Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 519 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 519 insertions(+) create mode 100644 drivers/net/wireless/ath/regd.c (limited to 'drivers/net/wireless/ath/regd.c') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c new file mode 100644 index 000000000000..4d3935b6fbdd --- /dev/null +++ b/drivers/net/wireless/ath/regd.c @@ -0,0 +1,519 @@ +/* + * Copyright (c) 2008-2009 Atheros Communications Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "regd.h" +#include "regd_common.h" + +/* + * 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. + */ + +/* 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 ath_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 ath_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 ath_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 ath_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 ath_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 inline bool is_wwr_sku(u16 regd) +{ + return ((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) || + (regd == WORLD); +} + +static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg) +{ + return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG; +} + +bool ath_is_world_regd(struct ath_regulatory *reg) +{ + return is_wwr_sku(ath_regd_get_eepromRD(reg)); +} +EXPORT_SYMBOL(ath_is_world_regd); + +const struct ieee80211_regdomain *ath_default_world_regdomain(void) +{ + /* this is the most restrictive */ + return &ath_world_regdom_64; +} +EXPORT_SYMBOL(ath_default_world_regdomain); + +const struct +ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) +{ + switch (reg->regpair->regDmnEnum) { + case 0x60: + case 0x61: + case 0x62: + return &ath_world_regdom_60_61_62; + case 0x63: + case 0x65: + return &ath_world_regdom_63_65; + case 0x64: + return &ath_world_regdom_64; + case 0x66: + case 0x69: + return &ath_world_regdom_66_69; + case 0x67: + case 0x68: + case 0x6A: + return &ath_world_regdom_67_68_6A; + default: + WARN_ON(1); + return ath_default_world_regdomain(); + } +} +EXPORT_SYMBOL(ath_world_regdomain); + +/* Frequency is one where radar detection is required */ +static bool ath_is_radar_freq(u16 center_freq) +{ + return (center_freq >= 5260 && center_freq <= 5700); +} + +/* + * 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 ath_reg_apply_beaconing_flags( + struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + enum ieee80211_band band; + struct ieee80211_supported_band *sband; + const struct ieee80211_reg_rule *reg_rule; + struct ieee80211_channel *ch; + unsigned int i; + u32 bandwidth = 0; + int r; + + for (band = 0; band < IEEE80211_NUM_BANDS; band++) { + + if (!wiphy->bands[band]) + continue; + + sband = wiphy->bands[band]; + + for (i = 0; i < sband->n_channels; i++) { + + ch = &sband->channels[i]; + + if (ath_is_radar_freq(ch->center_freq) || + (ch->flags & IEEE80211_CHAN_RADAR)) + continue; + + if (initiator == NL80211_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 */ +static void ath_reg_apply_active_scan_flags( + struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + const struct ieee80211_reg_rule *reg_rule; + u32 bandwidth = 0; + int r; + + sband = wiphy->bands[IEEE80211_BAND_2GHZ]; + + /* + * If no country IE has been received always enable active scan + * on these channels. This is only done for specific regulatory SKUs + */ + 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; + ch = &sband->channels[12]; /* CH 13 */ + if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN) + ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN; + return; + } + + /* + * 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 processing of our + * custom regulatory domain. + */ + + 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; + } + + 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; + } +} + +/* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ +void ath_reg_apply_radar_flags(struct wiphy *wiphy) +{ + struct ieee80211_supported_band *sband; + struct ieee80211_channel *ch; + unsigned int i; + + if (!wiphy->bands[IEEE80211_BAND_5GHZ]) + return; + + sband = wiphy->bands[IEEE80211_BAND_5GHZ]; + + for (i = 0; i < sband->n_channels; i++) { + ch = &sband->channels[i]; + if (!ath_is_radar_freq(ch->center_freq)) + 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; + } +} +EXPORT_SYMBOL(ath_reg_apply_radar_flags); + +void ath_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct ath_regulatory *reg) +{ + switch (reg->regpair->regDmnEnum) { + case 0x60: + case 0x63: + case 0x66: + case 0x67: + ath_reg_apply_beaconing_flags(wiphy, initiator); + break; + case 0x68: + ath_reg_apply_beaconing_flags(wiphy, initiator); + ath_reg_apply_active_scan_flags(wiphy, initiator); + break; + } + return; +} +EXPORT_SYMBOL(ath_reg_apply_world_flags); + +int ath_reg_notifier_apply(struct wiphy *wiphy, + struct regulatory_request *request, struct ath_regulatory *reg) +{ + /* We always apply this */ + ath_reg_apply_radar_flags(wiphy); + + switch (request->initiator) { + case NL80211_REGDOM_SET_BY_DRIVER: + case NL80211_REGDOM_SET_BY_CORE: + case NL80211_REGDOM_SET_BY_USER: + break; + case NL80211_REGDOM_SET_BY_COUNTRY_IE: + if (ath_is_world_regd(reg)) + ath_reg_apply_world_flags(wiphy, request->initiator, + reg); + break; + } + + return 0; +} +EXPORT_SYMBOL(ath_reg_notifier_apply); + +bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) +{ + u16 rd = ath_regd_get_eepromRD(reg); + int i; + + 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; + } + printk(KERN_DEBUG + "ath: invalid regulatory domain/country code 0x%x\n", rd); + return false; +} +EXPORT_SYMBOL(ath_regd_is_eeprom_valid); + +/* EEPROM country code to regpair mapping */ +static struct country_code_to_enum_rd* +ath_regd_find_country(u16 countryCode) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(allCountries); i++) { + if (allCountries[i].countryCode == countryCode) + return &allCountries[i]; + } + return NULL; +} + +/* EEPROM rd code to regpair mapping */ +static struct country_code_to_enum_rd* +ath_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 ath_regd_get_default_country(u16 rd) +{ + if (rd & COUNTRY_ERD_FLAG) { + struct country_code_to_enum_rd *country = NULL; + u16 cc = rd & ~COUNTRY_ERD_FLAG; + + country = ath_regd_find_country(cc); + if (country != NULL) + return cc; + } + + return CTRY_DEFAULT; +} + +static struct reg_dmn_pair_mapping* +ath_get_regpair(int regdmn) +{ + int i; + + if (regdmn == NO_ENUMRD) + return NULL; + for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) { + if (regDomainPairs[i].regDmnEnum == regdmn) + return ®DomainPairs[i]; + } + return NULL; +} + +int ath_regd_init(struct ath_regulatory *reg) +{ + struct country_code_to_enum_rd *country = NULL; + u16 regdmn; + + if (!ath_regd_is_eeprom_valid(reg)) { + printk(KERN_DEBUG "ath: Invalid EEPROM contents\n"); + return -EINVAL; + } + + regdmn = ath_regd_get_eepromRD(reg); + reg->country_code = ath_regd_get_default_country(regdmn); + + if (reg->country_code == CTRY_DEFAULT && + regdmn == CTRY_DEFAULT) + reg->country_code = CTRY_UNITED_STATES; + + if (reg->country_code == CTRY_DEFAULT) { + country = NULL; + } else { + country = ath_regd_find_country(reg->country_code); + if (country == NULL) { + printk(KERN_DEBUG + "ath: Country is NULL!!!!, cc= %d\n", + reg->country_code); + return -EINVAL; + } else + regdmn = country->regDmnEnum; + } + + reg->regpair = ath_get_regpair(regdmn); + + if (!reg->regpair) { + printk(KERN_DEBUG "ath: " + "No regulatory domain pair found, cannot continue\n"); + return -EINVAL; + } + + if (!country) + country = ath_regd_find_country_by_rd(regdmn); + + if (country) { + reg->alpha2[0] = country->isoName[0]; + reg->alpha2[1] = country->isoName[1]; + } else { + reg->alpha2[0] = '0'; + reg->alpha2[1] = '0'; + } + + printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", + reg->alpha2[0], reg->alpha2[1]); + printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n", + reg->regpair->regDmnEnum); + + return 0; +} +EXPORT_SYMBOL(ath_regd_init); + +u32 ath_regd_get_band_ctl(struct ath_regulatory *reg, + enum ieee80211_band band) +{ + if (!reg->regpair || + (reg->country_code == CTRY_DEFAULT && + is_wwr_sku(ath_regd_get_eepromRD(reg)))) { + return SD_NO_CTL; + } + + switch (band) { + case IEEE80211_BAND_2GHZ: + return reg->regpair->reg_2ghz_ctl; + case IEEE80211_BAND_5GHZ: + return reg->regpair->reg_5ghz_ctl; + default: + return NO_CTL; + } + + return NO_CTL; +} +EXPORT_SYMBOL(ath_regd_get_band_ctl); -- cgit v1.2.3 From e3bb249be89dd387e78ca382d08fad31745edac9 Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Mon, 30 Mar 2009 22:30:30 -0400 Subject: ath: move more setup code into ath_regd_init Setup the wiphy regulatory parameters when first initializing the Atheros regulatory module. We can remove five exported symbols this way and simplify the driver code for both ath5k and ath9k. Signed-off-by: Bob Copeland Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 55 +++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 13 deletions(-) (limited to 'drivers/net/wireless/ath/regd.c') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 4d3935b6fbdd..3ccf21cceb5a 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -126,14 +126,13 @@ bool ath_is_world_regd(struct ath_regulatory *reg) } EXPORT_SYMBOL(ath_is_world_regd); -const struct ieee80211_regdomain *ath_default_world_regdomain(void) +static const struct ieee80211_regdomain *ath_default_world_regdomain(void) { /* this is the most restrictive */ return &ath_world_regdom_64; } -EXPORT_SYMBOL(ath_default_world_regdomain); -const struct +static const struct ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) { switch (reg->regpair->regDmnEnum) { @@ -158,7 +157,6 @@ ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg) return ath_default_world_regdomain(); } } -EXPORT_SYMBOL(ath_world_regdomain); /* Frequency is one where radar detection is required */ static bool ath_is_radar_freq(u16 center_freq) @@ -285,7 +283,7 @@ static void ath_reg_apply_active_scan_flags( } /* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */ -void ath_reg_apply_radar_flags(struct wiphy *wiphy) +static void ath_reg_apply_radar_flags(struct wiphy *wiphy) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -316,11 +314,10 @@ void ath_reg_apply_radar_flags(struct wiphy *wiphy) IEEE80211_CHAN_PASSIVE_SCAN; } } -EXPORT_SYMBOL(ath_reg_apply_radar_flags); -void ath_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator, - struct ath_regulatory *reg) +static void ath_reg_apply_world_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator, + struct ath_regulatory *reg) { switch (reg->regpair->regDmnEnum) { case 0x60: @@ -336,7 +333,6 @@ void ath_reg_apply_world_flags(struct wiphy *wiphy, } return; } -EXPORT_SYMBOL(ath_reg_apply_world_flags); int ath_reg_notifier_apply(struct wiphy *wiphy, struct regulatory_request *request, struct ath_regulatory *reg) @@ -360,7 +356,7 @@ int ath_reg_notifier_apply(struct wiphy *wiphy, } EXPORT_SYMBOL(ath_reg_notifier_apply); -bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) +static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) { u16 rd = ath_regd_get_eepromRD(reg); int i; @@ -381,7 +377,6 @@ bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) "ath: invalid regulatory domain/country code 0x%x\n", rd); return false; } -EXPORT_SYMBOL(ath_regd_is_eeprom_valid); /* EEPROM country code to regpair mapping */ static struct country_code_to_enum_rd* @@ -438,7 +433,40 @@ ath_get_regpair(int regdmn) return NULL; } -int ath_regd_init(struct ath_regulatory *reg) +static int ath_regd_init_wiphy(struct ath_regulatory *reg, struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) +{ + const struct ieee80211_regdomain *regd; + + wiphy->reg_notifier = reg_notifier; + wiphy->strict_regulatory = true; + + if (ath_is_world_regd(reg)) { + /* + * Anything applied here (prior to wiphy registration) gets + * saved on the wiphy orig_* parameters + */ + regd = ath_world_regdomain(reg); + wiphy->custom_regulatory = true; + wiphy->strict_regulatory = false; + } else { + /* + * This gets applied in the case of the absense of CRDA, + * it's our own custom world regulatory domain, similar to + * cfg80211's but we enable passive scanning. + */ + regd = ath_default_world_regdomain(); + } + wiphy_apply_custom_regulatory(wiphy, regd); + ath_reg_apply_radar_flags(wiphy); + ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg); + return 0; +} + +int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) { struct country_code_to_enum_rd *country = NULL; u16 regdmn; @@ -492,6 +520,7 @@ int ath_regd_init(struct ath_regulatory *reg) printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n", reg->regpair->regDmnEnum); + ath_regd_init_wiphy(reg, wiphy, reg_notifier); return 0; } EXPORT_SYMBOL(ath_regd_init); -- cgit v1.2.3 From 6b2b2ffbef7750e51bfa74e92229ecee10b59307 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 30 Mar 2009 22:30:34 -0400 Subject: ath: space cleanup Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'drivers/net/wireless/ath/regd.c') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 3ccf21cceb5a..4b5c851b81ff 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -173,9 +173,9 @@ static bool ath_is_radar_freq(u16 center_freq) * received a beacon on a channel we can enable active scan and * adhoc (or beaconing). */ -static void ath_reg_apply_beaconing_flags( - struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) +static void +ath_reg_apply_beaconing_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { enum ieee80211_band band; struct ieee80211_supported_band *sband; @@ -232,9 +232,9 @@ static void ath_reg_apply_beaconing_flags( } /* Allows active scan scan on Ch 12 and 13 */ -static void ath_reg_apply_active_scan_flags( - struct wiphy *wiphy, - enum nl80211_reg_initiator initiator) +static void +ath_reg_apply_active_scan_flags(struct wiphy *wiphy, + enum nl80211_reg_initiator initiator) { struct ieee80211_supported_band *sband; struct ieee80211_channel *ch; @@ -316,8 +316,8 @@ static void ath_reg_apply_radar_flags(struct wiphy *wiphy) } static void ath_reg_apply_world_flags(struct wiphy *wiphy, - enum nl80211_reg_initiator initiator, - struct ath_regulatory *reg) + enum nl80211_reg_initiator initiator, + struct ath_regulatory *reg) { switch (reg->regpair->regDmnEnum) { case 0x60: @@ -335,7 +335,8 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy, } int ath_reg_notifier_apply(struct wiphy *wiphy, - struct regulatory_request *request, struct ath_regulatory *reg) + struct regulatory_request *request, + struct ath_regulatory *reg) { /* We always apply this */ ath_reg_apply_radar_flags(wiphy); @@ -433,8 +434,10 @@ ath_get_regpair(int regdmn) return NULL; } -static int ath_regd_init_wiphy(struct ath_regulatory *reg, struct wiphy *wiphy, - int (*reg_notifier)(struct wiphy *wiphy, +static int +ath_regd_init_wiphy(struct ath_regulatory *reg, + struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)) { const struct ieee80211_regdomain *regd; @@ -464,9 +467,11 @@ static int ath_regd_init_wiphy(struct ath_regulatory *reg, struct wiphy *wiphy, return 0; } -int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy, - int (*reg_notifier)(struct wiphy *wiphy, - struct regulatory_request *request)) +int +ath_regd_init(struct ath_regulatory *reg, + struct wiphy *wiphy, + int (*reg_notifier)(struct wiphy *wiphy, + struct regulatory_request *request)) { struct country_code_to_enum_rd *country = NULL; u16 regdmn; -- cgit v1.2.3 From 85efc86eb7c6cbb1c8ce8d99b10b948be033fbb9 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Mon, 13 Apr 2009 21:41:46 -0400 Subject: atheros: fix propagation of bad EEPROM on regulatory init When the EEPROM is not in good condition we cannot continue so we currently bail out but only ath5k is bailing out properly. Both ath9k and ar9170 were proceeding and if a user were to run into this they'd see an obscure panic. Lets propagate the error as intended and make sure we inform the user by lifting the error message from debug to a kernel error. Stable note: You can find a port of this page here: http://bombadil.infradead.org/~mcgrof/patches/ath9k/ath9k-fix-eeprom.patch.txt Cc: stable@kernel.org Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net/wireless/ath/regd.c') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 4b5c851b81ff..526c7f1308db 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -477,7 +477,7 @@ ath_regd_init(struct ath_regulatory *reg, u16 regdmn; if (!ath_regd_is_eeprom_valid(reg)) { - printk(KERN_DEBUG "ath: Invalid EEPROM contents\n"); + printk(KERN_ERR "ath: Invalid EEPROM contents\n"); return -EINVAL; } -- cgit v1.2.3 From d323655372590c533c275b1d798f9d1221efb5c6 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 20 Apr 2009 14:31:42 +0200 Subject: cfg80211: clean up includes Trying to separate header files into net/wireless.h and net/cfg80211.h has been a source of confusion. Remove net/wireless.h (because there also is the linux/wireless.h) and subsume everything into net/cfg80211.h -- except the definitions for regulatory structures which get moved to a new header net/regulatory.h. The "new" net/cfg80211.h is now divided into sections. There are no real changes in this patch but code shuffling and some very minor documentation fixes. I have also, to make things reflect reality, put in a copyright line for Luis to net/regulatory.h since that is probably exclusively written by him but was formerly in a file that only had my copyright line. Signed-off-by: Johannes Berg Cc: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net/wireless/ath/regd.c') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 526c7f1308db..fdf07c822081 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "regd.h" #include "regd_common.h" -- cgit v1.2.3 From 038659e7c6b385065cb223872771ac437ef70b62 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Sat, 2 May 2009 00:37:17 -0400 Subject: cfg80211: Process regulatory max bandwidth checks for HT40 We are not correctly listening to the regulatory max bandwidth settings. To actually make use of it we need to redesign things a bit. This patch does the work for that. We do this to so we can obey to regulatory rules accordingly for use of HT40. We end up dealing with HT40 by having two passes for each channel. The first check will see if a 20 MHz channel fits into the channel's center freq on a given frequency range. We check for a 20 MHz banwidth channel as that is the maximum an individual channel will use, at least for now. The first pass will go ahead and check if the regulatory rule for that given center of frequency allows 40 MHz bandwidths and we use this to determine whether or not the channel supports HT40 or not. So to support HT40 you'll need at a regulatory rule that allows you to use 40 MHz channels but you're channel must also be enabled and support 20 MHz by itself. The second pass is done after we do the regulatory checks over an device's supported channel list. On each channel we'll check if the control channel and the extension both: o exist o are enabled o regulatory allows 40 MHz bandwidth on its frequency range This work allows allows us to idependently check for HT40- and HT40+. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/ath/regd.c') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index fdf07c822081..7a89f9fac7d4 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -200,8 +200,10 @@ ath_reg_apply_beaconing_flags(struct wiphy *wiphy, continue; if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) { - r = freq_reg_info(wiphy, ch->center_freq, - &bandwidth, ®_rule); + r = freq_reg_info(wiphy, + ch->center_freq, + bandwidth, + ®_rule); if (r) continue; /* @@ -265,7 +267,7 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy, */ ch = &sband->channels[11]; /* CH 12 */ - r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, ®_rule); + 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) @@ -273,7 +275,7 @@ ath_reg_apply_active_scan_flags(struct wiphy *wiphy, } ch = &sband->channels[12]; /* CH 13 */ - r = freq_reg_info(wiphy, ch->center_freq, &bandwidth, ®_rule); + 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) -- cgit v1.2.3 From e03e5ffd8d3327d23d76be5d63cfbbb537b1af59 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Tue, 2 Jun 2009 16:30:56 -0400 Subject: ath: make regulatory parsing more verbose on debug This should help when reviewing issues regarding regulatory domain on ath5k/ath9k/ar9170. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath/regd.c | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) (limited to 'drivers/net/wireless/ath/regd.c') diff --git a/drivers/net/wireless/ath/regd.c b/drivers/net/wireless/ath/regd.c index 7a89f9fac7d4..eef370bd1211 100644 --- a/drivers/net/wireless/ath/regd.c +++ b/drivers/net/wireless/ath/regd.c @@ -366,11 +366,17 @@ static bool ath_regd_is_eeprom_valid(struct ath_regulatory *reg) if (rd & COUNTRY_ERD_FLAG) { /* EEPROM value is a country code */ u16 cc = rd & ~COUNTRY_ERD_FLAG; + printk(KERN_DEBUG + "ath: EEPROM indicates we should expect " + "a country code\n"); for (i = 0; i < ARRAY_SIZE(allCountries); i++) if (allCountries[i].countryCode == cc) return true; } else { /* EEPROM value is a regpair value */ + if (rd != CTRY_DEFAULT) + printk(KERN_DEBUG "ath: EEPROM indicates we " + "should expect a direct regpair map\n"); for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) if (regDomainPairs[i].regDmnEnum == rd) return true; @@ -477,6 +483,11 @@ ath_regd_init(struct ath_regulatory *reg, struct country_code_to_enum_rd *country = NULL; u16 regdmn; + if (!reg) + return -EINVAL; + + printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd); + if (!ath_regd_is_eeprom_valid(reg)) { printk(KERN_ERR "ath: Invalid EEPROM contents\n"); return -EINVAL; @@ -486,20 +497,30 @@ ath_regd_init(struct ath_regulatory *reg, reg->country_code = ath_regd_get_default_country(regdmn); if (reg->country_code == CTRY_DEFAULT && - regdmn == CTRY_DEFAULT) + regdmn == CTRY_DEFAULT) { + printk(KERN_DEBUG "ath: EEPROM indicates default " + "country code should be used\n"); reg->country_code = CTRY_UNITED_STATES; + } if (reg->country_code == CTRY_DEFAULT) { country = NULL; } else { + printk(KERN_DEBUG "ath: doing EEPROM country->regdmn " + "map search\n"); country = ath_regd_find_country(reg->country_code); if (country == NULL) { printk(KERN_DEBUG - "ath: Country is NULL!!!!, cc= %d\n", + "ath: no valid country maps found for " + "country code: 0x%0x\n", reg->country_code); return -EINVAL; - } else + } else { regdmn = country->regDmnEnum; + printk(KERN_DEBUG "ath: country maps to " + "regdmn code: 0x%0x\n", + regdmn); + } } reg->regpair = ath_get_regpair(regdmn); @@ -523,7 +544,7 @@ ath_regd_init(struct ath_regulatory *reg, printk(KERN_DEBUG "ath: Country alpha2 being used: %c%c\n", reg->alpha2[0], reg->alpha2[1]); - printk(KERN_DEBUG "ath: Regpair detected: 0x%0x\n", + printk(KERN_DEBUG "ath: Regpair used: 0x%0x\n", reg->regpair->regDmnEnum); ath_regd_init_wiphy(reg, wiphy, reg_notifier); -- cgit v1.2.3