From aaba5f80589206abbc823b4fa7cb0440b4a1c907 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Thu, 8 Dec 2011 23:59:24 +0530 Subject: [PATCH] --- yaml --- r: 278891 b: refs/heads/master c: de1c732b1891a25f3f2f52ef7211a3d567bbd588 h: refs/heads/master i: 278889: b1dea9fe8a00aa0849c1c0fc8d61e09a71ba7ee8 278887: ed7b7de915f9efaa625eb5f523e086f0d26eaf9f v: v3 --- [refs] | 2 +- trunk/drivers/net/wireless/ath/ath.h | 1 + trunk/drivers/net/wireless/ath/regd.c | 55 +++++++++++++++++++++++++-- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index c3f5a10bdb49..06c2b19097d9 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 43fcb430a4cfb7bd7c82600edeb3ca65f202a5f3 +refs/heads/master: de1c732b1891a25f3f2f52ef7211a3d567bbd588 diff --git a/trunk/drivers/net/wireless/ath/ath.h b/trunk/drivers/net/wireless/ath/ath.h index 4596c33a7a69..3e4dd2d483b8 100644 --- a/trunk/drivers/net/wireless/ath/ath.h +++ b/trunk/drivers/net/wireless/ath/ath.h @@ -152,6 +152,7 @@ struct ath_common { struct ath_cycle_counters cc_survey; struct ath_regulatory regulatory; + struct ath_regulatory reg_world_copy; const struct ath_ops *ops; const struct ath_bus_ops *bus_ops; diff --git a/trunk/drivers/net/wireless/ath/regd.c b/trunk/drivers/net/wireless/ath/regd.c index ed4966fdb8d3..10dea37431b3 100644 --- a/trunk/drivers/net/wireless/ath/regd.c +++ b/trunk/drivers/net/wireless/ath/regd.c @@ -21,6 +21,8 @@ #include "regd.h" #include "regd_common.h" +static int __ath_regd_init(struct ath_regulatory *reg); + /* * This is a set of common rules used by our world regulatory domains. * We have 12 world regulatory domains. To save space we consolidate @@ -347,10 +349,26 @@ static void ath_reg_apply_world_flags(struct wiphy *wiphy, } } +static u16 ath_regd_find_country_by_name(char *alpha2) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE(allCountries); i++) { + if (!memcmp(allCountries[i].isoName, alpha2, 2)) + return allCountries[i].countryCode; + } + + return -1; +} + int ath_reg_notifier_apply(struct wiphy *wiphy, struct regulatory_request *request, struct ath_regulatory *reg) { + struct ath_common *common = container_of(reg, struct ath_common, + regulatory); + u16 country_code; + /* We always apply this */ ath_reg_apply_radar_flags(wiphy); @@ -363,14 +381,37 @@ int ath_reg_notifier_apply(struct wiphy *wiphy, return 0; switch (request->initiator) { - case NL80211_REGDOM_SET_BY_DRIVER: case NL80211_REGDOM_SET_BY_CORE: + /* + * If common->reg_world_copy is world roaming it means we *were* + * world roaming... so we now have to restore that data. + */ + if (!ath_is_world_regd(&common->reg_world_copy)) + break; + + memcpy(reg, &common->reg_world_copy, + sizeof(struct ath_regulatory)); + break; + case NL80211_REGDOM_SET_BY_DRIVER: 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); + if (!ath_is_world_regd(reg)) + break; + + country_code = ath_regd_find_country_by_name(request->alpha2); + if (country_code == (u16) -1) + break; + + reg->current_rd = COUNTRY_ERD_FLAG; + reg->current_rd |= country_code; + + printk(KERN_DEBUG "ath: regdomain 0x%0x updated by CountryIE\n", + reg->current_rd); + __ath_regd_init(reg); + + ath_reg_apply_world_flags(wiphy, request->initiator, reg); + break; } @@ -588,12 +629,18 @@ ath_regd_init(struct ath_regulatory *reg, int (*reg_notifier)(struct wiphy *wiphy, struct regulatory_request *request)) { + struct ath_common *common = container_of(reg, struct ath_common, + regulatory); int r; r = __ath_regd_init(reg); if (r) return r; + if (ath_is_world_regd(reg)) + memcpy(&common->reg_world_copy, reg, + sizeof(struct ath_regulatory)); + ath_regd_init_wiphy(reg, wiphy, reg_notifier); return 0;