/*
 * Copyright (c) 2008 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 <linux/kernel.h>
#include <linux/slab.h>
#include "ath9k.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 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 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;
}

bool ath9k_is_world_regd(struct ath_hw *ah)
{
	return is_wwr_sku(ath9k_regd_get_eepromRD(ah));
}

const struct ieee80211_regdomain *ath9k_default_world_regdomain(void)
{
	/* this is the most restrictive */
	return &ath9k_world_regdom_64;
}

const struct ieee80211_regdomain *ath9k_world_regdomain(struct ath_hw *ah)
{
	switch (ah->regulatory.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();
	}
}

/* Frequency is one where radar detection is required */
static bool ath9k_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 ath9k_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 (ath9k_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, &reg_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 ath9k_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, &reg_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, &reg_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 ath9k_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 (!ath9k_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;
	}
}

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;
	struct ath_softc *sc = aphy->sc;
	struct ath_hw *ah = sc->sc_ah;

	switch (ah->regulatory.regpair->regDmnEnum) {
	case 0x60:
	case 0x63:
	case 0x66:
	case 0x67:
		ath9k_reg_apply_beaconing_flags(wiphy, initiator);
		break;
	case 0x68:
		ath9k_reg_apply_beaconing_flags(wiphy, initiator);
		ath9k_reg_apply_active_scan_flags(wiphy, initiator);
		break;
	}
	return;
}

int ath9k_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
{
	struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
	struct ath_wiphy *aphy = hw->priv;
	struct ath_softc *sc = aphy->sc;

	/* We always apply this */
	ath9k_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 (ath9k_is_world_regd(sc->sc_ah))
			ath9k_reg_apply_world_flags(wiphy, request->initiator);
		break;
	}

	return 0;
}

bool ath9k_regd_is_eeprom_valid(struct ath_hw *ah)
{
	u16 rd = ath9k_regd_get_eepromRD(ah);
	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;
	}
	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)
{
	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*
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(u16 rd)
{
	if (rd & COUNTRY_ERD_FLAG) {
		struct country_code_to_enum_rd *country = NULL;
		u16 cc = rd & ~COUNTRY_ERD_FLAG;

		country = ath9k_regd_find_country(cc);
		if (country != NULL)
			return cc;
	}

	return CTRY_DEFAULT;
}

static struct reg_dmn_pair_mapping*
ath9k_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 &regDomainPairs[i];
	}
	return NULL;
}

int ath9k_regd_init(struct ath_hw *ah)
{
	struct country_code_to_enum_rd *country = NULL;
	u16 regdmn;

	if (!ath9k_regd_is_eeprom_valid(ah)) {
		DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
			"Invalid EEPROM contents\n");
		return -EINVAL;
	}

	regdmn = ath9k_regd_get_eepromRD(ah);
	ah->regulatory.country_code = ath9k_regd_get_default_country(regdmn);

	if (ah->regulatory.country_code == CTRY_DEFAULT &&
	    regdmn == CTRY_DEFAULT)
		ah->regulatory.country_code = CTRY_UNITED_STATES;

	if (ah->regulatory.country_code == CTRY_DEFAULT) {
		country = NULL;
	} else {
		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->regulatory.country_code);
			return -EINVAL;
		} else
			regdmn = country->regDmnEnum;
	}

	ah->regulatory.regpair = ath9k_get_regpair(regdmn);

	if (!ah->regulatory.regpair) {
		DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
			"No regulatory domain pair found, cannot continue\n");
		return -EINVAL;
	}

	if (!country)
		country = ath9k_regd_find_country_by_rd(regdmn);

	if (country) {
		ah->regulatory.alpha2[0] = country->isoName[0];
		ah->regulatory.alpha2[1] = country->isoName[1];
	} else {
		ah->regulatory.alpha2[0] = '0';
		ah->regulatory.alpha2[1] = '0';
	}

	DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
		"Country alpha2 being used: %c%c\n"
		"Regulatory.Regpair detected: 0x%0x\n",
		ah->regulatory.alpha2[0], ah->regulatory.alpha2[1],
		ah->regulatory.regpair->regDmnEnum);

	return 0;
}

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 &&
	     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))
			ctl = SD_NO_CTL | CTL_11G;
		else
			ctl = SD_NO_CTL | CTL_11A;
		return ctl;
	}

	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_2ghz_ctl | CTL_11G;
	else
		ctl = ah->regulatory.regpair->reg_5ghz_ctl | CTL_11A;

	return ctl;
}
