diff options
Diffstat (limited to 'drivers/net/wireless/brcm80211/brcmsmac/channel.c')
-rw-r--r-- | drivers/net/wireless/brcm80211/brcmsmac/channel.c | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/channel.c b/drivers/net/wireless/brcm80211/brcmsmac/channel.c index 55e9f45fce22..eb77ac3cfb6b 100644 --- a/drivers/net/wireless/brcm80211/brcmsmac/channel.c +++ b/drivers/net/wireless/brcm80211/brcmsmac/channel.c @@ -628,6 +628,40 @@ brcms_c_country_aggregate_map(struct brcms_cm_info *wlc_cm, const char *ccode, return false; } +/* + * Indicates whether the country provided is valid to pass + * to cfg80211 or not. + * + * returns true if valid; false if not. + */ +static bool brcms_c_country_valid(const char *ccode) +{ + /* + * only allow ascii alpha uppercase for the first 2 + * chars. + */ + if (!((0x80 & ccode[0]) == 0 && ccode[0] >= 0x41 && ccode[0] <= 0x5A && + (0x80 & ccode[1]) == 0 && ccode[1] >= 0x41 && ccode[1] <= 0x5A && + ccode[2] == '\0')) + return false; + + /* + * do not match ISO 3166-1 user assigned country codes + * that may be in the driver table + */ + if (!strcmp("AA", ccode) || /* AA */ + !strcmp("ZZ", ccode) || /* ZZ */ + ccode[0] == 'X' || /* XA - XZ */ + (ccode[0] == 'Q' && /* QM - QZ */ + (ccode[1] >= 'M' && ccode[1] <= 'Z'))) + return false; + + if (!strcmp("NA", ccode)) + return false; + + return true; +} + /* Lookup a country info structure from a null terminated country * abbreviation and regrev directly with no translation. */ @@ -1076,7 +1110,7 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) char country_abbrev[BRCM_CNTRY_BUF_SZ]; const struct country_info *country; struct brcms_pub *pub = wlc->pub; - char *ccode; + struct ssb_sprom *sprom = &wlc->hw->d11core->bus->sprom; BCMMSG(wlc->wiphy, "wl%d\n", wlc->pub->unit); @@ -1088,9 +1122,8 @@ struct brcms_cm_info *brcms_c_channel_mgr_attach(struct brcms_c_info *wlc) wlc->cmi = wlc_cm; /* store the country code for passing up as a regulatory hint */ - ccode = getvar(wlc->hw->sih, BRCMS_SROM_CCODE); - if (ccode) - strncpy(wlc->pub->srom_ccode, ccode, BRCM_CNTRY_BUF_SZ - 1); + if (sprom->alpha2 && brcms_c_country_valid(sprom->alpha2)) + strncpy(wlc->pub->srom_ccode, sprom->alpha2, sizeof(sprom->alpha2)); /* * internal country information which must match |