/*
 * 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.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/kernel.h>
#include <linux/export.h>
#include <net/cfg80211.h>
#include <net/mac80211.h>
#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
 * 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 ATH_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 ATH_2GHZ_CH12_13	REG_RULE(2467-10, 2472+10, 40, 0, 20,\
					 NL80211_RRF_NO_IR)
#define ATH_2GHZ_CH14		REG_RULE(2484-10, 2484+10, 40, 0, 20,\
					 NL80211_RRF_NO_IR | \
					 NL80211_RRF_NO_OFDM)

/* We allow IBSS on these on a case by case basis by regulatory domain */
#define ATH_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 80, 0, 30,\
					 NL80211_RRF_NO_IR)
#define ATH_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 80, 0, 30,\
					 NL80211_RRF_NO_IR)
#define ATH_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 80, 0, 30,\
					 NL80211_RRF_NO_IR)

#define ATH_2GHZ_ALL		ATH_2GHZ_CH01_11, \
				ATH_2GHZ_CH12_13, \
				ATH_2GHZ_CH14

#define ATH_5GHZ_ALL		ATH_5GHZ_5150_5350, \
				ATH_5GHZ_5470_5850

/* This one skips what we call "mid band" */
#define ATH_5GHZ_NO_MIDBAND	ATH_5GHZ_5150_5350, \
				ATH_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 = {
		ATH_2GHZ_ALL,
		ATH_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 = {
		ATH_2GHZ_CH01_11,
		ATH_2GHZ_CH12_13,
		ATH_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 = {
		ATH_2GHZ_CH01_11,
		ATH_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 = {
		ATH_2GHZ_CH01_11,
		ATH_5GHZ_ALL,
	}
};

/* Can be used by 0x67, 0x68, 0x6A and 0x6C */
static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
	.n_reg_rules = 4,
	.alpha2 =  "99",
	.reg_rules = {
		ATH_2GHZ_CH01_11,
		ATH_2GHZ_CH12_13,
		ATH_5GHZ_ALL,
	}
};

static bool dynamic_country_user_possible(struct ath_regulatory *reg)
{
	if (IS_ENABLED(CONFIG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
		return true;

	switch (reg->country_code) {
	case CTRY_UNITED_STATES:
	case CTRY_JAPAN1:
	case CTRY_JAPAN2:
	case CTRY_JAPAN3:
	case CTRY_JAPAN4:
	case CTRY_JAPAN5:
	case CTRY_JAPAN6:
	case CTRY_JAPAN7:
	case CTRY_JAPAN8:
	case CTRY_JAPAN9:
	case CTRY_JAPAN10:
	case CTRY_JAPAN11:
	case CTRY_JAPAN12:
	case CTRY_JAPAN13:
	case CTRY_JAPAN14:
	case CTRY_JAPAN15:
	case CTRY_JAPAN16:
	case CTRY_JAPAN17:
	case CTRY_JAPAN18:
	case CTRY_JAPAN19:
	case CTRY_JAPAN20:
	case CTRY_JAPAN21:
	case CTRY_JAPAN22:
	case CTRY_JAPAN23:
	case CTRY_JAPAN24:
	case CTRY_JAPAN25:
	case CTRY_JAPAN26:
	case CTRY_JAPAN27:
	case CTRY_JAPAN28:
	case CTRY_JAPAN29:
	case CTRY_JAPAN30:
	case CTRY_JAPAN31:
	case CTRY_JAPAN32:
	case CTRY_JAPAN33:
	case CTRY_JAPAN34:
	case CTRY_JAPAN35:
	case CTRY_JAPAN36:
	case CTRY_JAPAN37:
	case CTRY_JAPAN38:
	case CTRY_JAPAN39:
	case CTRY_JAPAN40:
	case CTRY_JAPAN41:
	case CTRY_JAPAN42:
	case CTRY_JAPAN43:
	case CTRY_JAPAN44:
	case CTRY_JAPAN45:
	case CTRY_JAPAN46:
	case CTRY_JAPAN47:
	case CTRY_JAPAN48:
	case CTRY_JAPAN49:
	case CTRY_JAPAN50:
	case CTRY_JAPAN51:
	case CTRY_JAPAN52:
	case CTRY_JAPAN53:
	case CTRY_JAPAN54:
	case CTRY_JAPAN55:
	case CTRY_JAPAN56:
	case CTRY_JAPAN57:
	case CTRY_JAPAN58:
	case CTRY_JAPAN59:
		return false;
	}

	return true;
}

static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
{
	if (!IS_ENABLED(CONFIG_ATH_REG_DYNAMIC_USER_REG_HINTS))
		return false;
	if (!dynamic_country_user_possible(reg))
		return false;
	return true;
}

static inline bool is_wwr_sku(u16 regd)
{
	return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
		(((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);

static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
{
	/* this is the most restrictive */
	return &ath_world_regdom_64;
}

static const struct
ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
{
	switch (reg->regpair->reg_domain) {
	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:
	case 0x6C:
		return &ath_world_regdom_67_68_6A_6C;
	default:
		WARN_ON(1);
		return ath_default_world_regdomain();
	}
}

bool ath_is_49ghz_allowed(u16 regdomain)
{
	/* possibly more */
	return regdomain == MKK9_MKKC;
}
EXPORT_SYMBOL(ath_is_49ghz_allowed);

/* Frequency is one where radar detection is required */
static bool ath_is_radar_freq(u16 center_freq,
			      struct ath_regulatory *reg)

{
	if (reg->country_code == CTRY_INDIA)
		return (center_freq >= 5500 && center_freq <= 5700);
	return (center_freq >= 5260 && center_freq <= 5700);
}

static void ath_force_clear_no_ir_chan(struct wiphy *wiphy,
				       struct ieee80211_channel *ch)
{
	const struct ieee80211_reg_rule *reg_rule;

	reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(ch->center_freq));
	if (IS_ERR(reg_rule))
		return;

	if (!(reg_rule->flags & NL80211_RRF_NO_IR))
		if (ch->flags & IEEE80211_CHAN_NO_IR)
			ch->flags &= ~IEEE80211_CHAN_NO_IR;
}

static void ath_force_clear_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
{
	struct ieee80211_channel *ch;

	ch = ieee80211_get_channel(wiphy, center_freq);
	if (!ch)
		return;

	ath_force_clear_no_ir_chan(wiphy, ch);
}

static void ath_force_no_ir_chan(struct ieee80211_channel *ch)
{
	ch->flags |= IEEE80211_CHAN_NO_IR;
}

static void ath_force_no_ir_freq(struct wiphy *wiphy, u16 center_freq)
{
	struct ieee80211_channel *ch;

	ch = ieee80211_get_channel(wiphy, center_freq);
	if (!ch)
		return;

	ath_force_no_ir_chan(ch);
}

static void
__ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
				struct ath_regulatory *reg,
				enum nl80211_reg_initiator initiator,
				struct ieee80211_channel *ch)
{
	if (ath_is_radar_freq(ch->center_freq, reg) ||
	    (ch->flags & IEEE80211_CHAN_RADAR))
		return;

	switch (initiator) {
	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
		ath_force_clear_no_ir_chan(wiphy, ch);
		break;
	case NL80211_REGDOM_SET_BY_USER:
		if (ath_reg_dyn_country_user_allow(reg))
			ath_force_clear_no_ir_chan(wiphy, ch);
		break;
	default:
		if (ch->beacon_found)
			ch->flags &= ~IEEE80211_CHAN_NO_IR;
	}
}

/*
 * These exception rules do not apply radar frequencies.
 *
 * - We enable initiating radiation if the country IE says its fine:
 * - If no country IE has been processed and a we determine we have
 *   received a beacon on a channel we can enable initiating radiation.
 */
static void
ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
			      struct ath_regulatory *reg,
			      enum nl80211_reg_initiator initiator)
{
	enum nl80211_band band;
	struct ieee80211_supported_band *sband;
	struct ieee80211_channel *ch;
	unsigned int i;

	for (band = 0; band < NUM_NL80211_BANDS; band++) {
		if (!wiphy->bands[band])
			continue;
		sband = wiphy->bands[band];
		for (i = 0; i < sband->n_channels; i++) {
			ch = &sband->channels[i];
			__ath_reg_apply_beaconing_flags(wiphy, reg,
							initiator, ch);
		}
	}
}

/**
 * ath_reg_apply_ir_flags()
 * @wiphy: the wiphy to use
 * @initiator: the regulatory hint initiator
 *
 * If no country IE has been received always enable passive scan
 * and no-ibss on these channels. This is only done for specific
 * regulatory SKUs.
 *
 * If a country IE has been received 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.
 */
static void
ath_reg_apply_ir_flags(struct wiphy *wiphy,
		       struct ath_regulatory *reg,
		       enum nl80211_reg_initiator initiator)
{
	struct ieee80211_supported_band *sband;

	sband = wiphy->bands[NL80211_BAND_2GHZ];
	if (!sband)
		return;

	switch(initiator) {
	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
		ath_force_clear_no_ir_freq(wiphy, 2467);
		ath_force_clear_no_ir_freq(wiphy, 2472);
		break;
	case NL80211_REGDOM_SET_BY_USER:
		if (!ath_reg_dyn_country_user_allow(reg))
			break;
		ath_force_clear_no_ir_freq(wiphy, 2467);
		ath_force_clear_no_ir_freq(wiphy, 2472);
		break;
	default:
		ath_force_no_ir_freq(wiphy, 2467);
		ath_force_no_ir_freq(wiphy, 2472);
	}
}

/* Always apply Radar/DFS rules on freq range 5500 MHz - 5700 MHz */
static void ath_reg_apply_radar_flags(struct wiphy *wiphy,
				      struct ath_regulatory *reg)
{
	struct ieee80211_supported_band *sband;
	struct ieee80211_channel *ch;
	unsigned int i;

	if (!wiphy->bands[NL80211_BAND_5GHZ])
		return;

	sband = wiphy->bands[NL80211_BAND_5GHZ];

	for (i = 0; i < sband->n_channels; i++) {
		ch = &sband->channels[i];
		if (!ath_is_radar_freq(ch->center_freq, reg))
			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_IR;
	}
}

static void ath_reg_apply_world_flags(struct wiphy *wiphy,
				      enum nl80211_reg_initiator initiator,
				      struct ath_regulatory *reg)
{
	switch (reg->regpair->reg_domain) {
	case 0x60:
	case 0x63:
	case 0x66:
	case 0x67:
	case 0x6C:
		ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
		break;
	case 0x68:
		ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
		ath_reg_apply_ir_flags(wiphy, reg, initiator);
		break;
	default:
		if (ath_reg_dyn_country_user_allow(reg))
			ath_reg_apply_beaconing_flags(wiphy, reg, initiator);
	}
}

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;
}
EXPORT_SYMBOL(ath_regd_find_country_by_name);

static int __ath_reg_dyn_country(struct wiphy *wiphy,
				 struct ath_regulatory *reg,
				 struct regulatory_request *request)
{
	u16 country_code;

	if (request->initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE &&
	    !ath_is_world_regd(reg))
		return -EINVAL;

	country_code = ath_regd_find_country_by_name(request->alpha2);
	if (country_code == (u16) -1)
		return -EINVAL;

	reg->current_rd = COUNTRY_ERD_FLAG;
	reg->current_rd |= country_code;

	__ath_regd_init(reg);

	ath_reg_apply_world_flags(wiphy, request->initiator, reg);

	return 0;
}

static void ath_reg_dyn_country(struct wiphy *wiphy,
				struct ath_regulatory *reg,
				struct regulatory_request *request)
{
	if (__ath_reg_dyn_country(wiphy, reg, request))
		return;

	printk(KERN_DEBUG "ath: regdomain 0x%0x "
			  "dynamically updated by %s\n",
	       reg->current_rd,
	       reg_initiator_name(request->initiator));
}

void 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);
	/* We always apply this */
	ath_reg_apply_radar_flags(wiphy, reg);

	/*
	 * This would happen when we have sent a custom regulatory request
	 * a world regulatory domain and the scheduler hasn't yet processed
	 * any pending requests in the queue.
	 */
	if (!request)
		return;

	reg->region = request->dfs_region;
	switch (request->initiator) {
	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:
		break;
	case NL80211_REGDOM_SET_BY_USER:
		if (ath_reg_dyn_country_user_allow(reg))
			ath_reg_dyn_country(wiphy, reg, request);
		break;
	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
		ath_reg_dyn_country(wiphy, reg, request);
		break;
	}
}
EXPORT_SYMBOL(ath_reg_notifier_apply);

static 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;
		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].reg_domain == rd)
				return true;
	}
	printk(KERN_DEBUG
		 "ath: invalid regulatory domain/country code 0x%x\n", rd);
	return false;
}

/* 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].reg_domain == regdmn)
			return &regDomainPairs[i];
	}
	return NULL;
}

static int
ath_regd_init_wiphy(struct ath_regulatory *reg,
		    struct wiphy *wiphy,
		    void (*reg_notifier)(struct wiphy *wiphy,
					 struct regulatory_request *request))
{
	const struct ieee80211_regdomain *regd;

	wiphy->reg_notifier = reg_notifier;
	wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
				   REGULATORY_CUSTOM_REG;

	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->regulatory_flags |= REGULATORY_COUNTRY_IE_FOLLOW_POWER;
	} else {
		/*
		 * This gets applied in the case of the absence 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, reg);
	ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
	return 0;
}

/*
 * Some users have reported their EEPROM programmed with
 * 0x8000 or 0x0 set, this is not a supported regulatory
 * domain but since we have more than one user with it we
 * need a solution for them. We default to 0x64, which is
 * the default Atheros world regulatory domain.
 */
static void ath_regd_sanitize(struct ath_regulatory *reg)
{
	if (reg->current_rd != COUNTRY_ERD_FLAG && reg->current_rd != 0)
		return;
	printk(KERN_DEBUG "ath: EEPROM regdomain sanitized\n");
	reg->current_rd = 0x64;
}

static int __ath_regd_init(struct ath_regulatory *reg)
{
	struct country_code_to_enum_rd *country = NULL;
	u16 regdmn;

	if (!reg)
		return -EINVAL;

	ath_regd_sanitize(reg);

	printk(KERN_DEBUG "ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);

	if (!ath_regd_is_eeprom_valid(reg)) {
		pr_err("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) {
		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: no valid country maps found for "
				"country code: 0x%0x\n",
				reg->country_code);
			return -EINVAL;
		} else {
			regdmn = country->regDmnEnum;
			printk(KERN_DEBUG "ath: country maps to "
			       "regdmn code: 0x%0x\n",
			       regdmn);
		}
	}

	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 used: 0x%0x\n",
		reg->regpair->reg_domain);

	return 0;
}

int
ath_regd_init(struct ath_regulatory *reg,
	      struct wiphy *wiphy,
	      void (*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;
}
EXPORT_SYMBOL(ath_regd_init);

u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
			  enum nl80211_band band)
{
	if (!reg->regpair ||
	    (reg->country_code == CTRY_DEFAULT &&
	     is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
		return SD_NO_CTL;
	}

	if (ath_regd_get_eepromRD(reg) == CTRY_DEFAULT) {
		switch (reg->region) {
		case NL80211_DFS_FCC:
			return CTL_FCC;
		case NL80211_DFS_ETSI:
			return CTL_ETSI;
		case NL80211_DFS_JP:
			return CTL_MKK;
		default:
			break;
		}
	}

	switch (band) {
	case NL80211_BAND_2GHZ:
		return reg->regpair->reg_2ghz_ctl;
	case NL80211_BAND_5GHZ:
		return reg->regpair->reg_5ghz_ctl;
	default:
		return NO_CTL;
	}
}
EXPORT_SYMBOL(ath_regd_get_band_ctl);
