Jesse Keating 7a32965
From linville@tuxdriver.com Thu Jul 15 15:40:22 2010
Jesse Keating 7a32965
From: "John W. Linville" <linville@tuxdriver.com>
Jesse Keating 7a32965
Subject: [RFC] wireless: only use alpha2 regulatory information from country IE
Jesse Keating 7a32965
Date: Thu, 15 Jul 2010 15:06:47 -0400
Jesse Keating 7a32965
Jesse Keating 7a32965
The meaning and/or usage of the country IE is somewhat poorly defined.
Jesse Keating 7a32965
In practice, this means that regulatory rulesets in a country IE are
Jesse Keating 7a32965
often incomplete and might be untrustworthy.  This removes the code
Jesse Keating 7a32965
associated with interpreting those rulesets while preserving respect
Jesse Keating 7a32965
for country "alpha2" codes also contained in the country IE.
Jesse Keating 7a32965
Jesse Keating 7a32965
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Jesse Keating 7a32965
---
Jesse Keating 7a32965
This patch is compile-tested only!  Please feel free to suggest that
Jesse Keating 7a32965
I have left something out or missed some nuance of our regulatory
Jesse Keating 7a32965
enforcement code...
Jesse Keating 7a32965
Jesse Keating 7a32965
 include/net/regulatory.h |    1 -
Jesse Keating 7a32965
 net/wireless/reg.c       |  625 +---------------------------------------------
Jesse Keating 7a32965
 2 files changed, 12 insertions(+), 614 deletions(-)
Jesse Keating 7a32965
Jesse Keating 7a32965
diff --git a/include/net/regulatory.h b/include/net/regulatory.h
Jesse Keating 7a32965
index f873ee3..9e103a4 100644
Jesse Keating 7a32965
--- a/include/net/regulatory.h
Jesse Keating 7a32965
+++ b/include/net/regulatory.h
Jesse Keating 7a32965
@@ -54,7 +54,6 @@ struct regulatory_request {
Jesse Keating 7a32965
 	enum nl80211_reg_initiator initiator;
Jesse Keating 7a32965
 	char alpha2[2];
Jesse Keating 7a32965
 	bool intersect;
Jesse Keating 7a32965
-	u32 country_ie_checksum;
Jesse Keating 7a32965
 	enum environment_cap country_ie_env;
Jesse Keating 7a32965
 	struct list_head list;
Jesse Keating 7a32965
 };
Jesse Keating 7a32965
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
Jesse Keating 7a32965
index 1ac2bdd..678d0bd 100644
Jesse Keating 7a32965
--- a/net/wireless/reg.c
Jesse Keating 7a32965
+++ b/net/wireless/reg.c
Jesse Keating 7a32965
@@ -67,17 +67,9 @@ static struct platform_device *reg_pdev;
Jesse Keating 7a32965
 const struct ieee80211_regdomain *cfg80211_regdomain;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /*
Jesse Keating 7a32965
- * We use this as a place for the rd structure built from the
Jesse Keating 7a32965
- * last parsed country IE to rest until CRDA gets back to us with
Jesse Keating 7a32965
- * what it thinks should apply for the same country
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static const struct ieee80211_regdomain *country_ie_regdomain;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/*
Jesse Keating 7a32965
  * Protects static reg.c components:
Jesse Keating 7a32965
  *     - cfg80211_world_regdom
Jesse Keating 7a32965
  *     - cfg80211_regdom
Jesse Keating 7a32965
- *     - country_ie_regdomain
Jesse Keating 7a32965
  *     - last_request
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
 static DEFINE_MUTEX(reg_mutex);
Jesse Keating 7a32965
@@ -275,25 +267,6 @@ static bool is_user_regdom_saved(void)
Jesse Keating 7a32965
 	return true;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-/**
Jesse Keating 7a32965
- * country_ie_integrity_changes - tells us if the country IE has changed
Jesse Keating 7a32965
- * @checksum: checksum of country IE of fields we are interested in
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * If the country IE has not changed you can ignore it safely. This is
Jesse Keating 7a32965
- * useful to determine if two devices are seeing two different country IEs
Jesse Keating 7a32965
- * even on the same alpha2. Note that this will return false if no IE has
Jesse Keating 7a32965
- * been set on the wireless core yet.
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static bool country_ie_integrity_changes(u32 checksum)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	/* If no IE has been set then the checksum doesn't change */
Jesse Keating 7a32965
-	if (unlikely(!last_request->country_ie_checksum))
Jesse Keating 7a32965
-		return false;
Jesse Keating 7a32965
-	if (unlikely(last_request->country_ie_checksum != checksum))
Jesse Keating 7a32965
-		return true;
Jesse Keating 7a32965
-	return false;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 static int reg_copy_regd(const struct ieee80211_regdomain **dst_regd,
Jesse Keating 7a32965
 			 const struct ieee80211_regdomain *src_regd)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
@@ -506,471 +479,6 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /*
Jesse Keating 7a32965
- * This is a work around for sanity checking ieee80211_channel_to_frequency()'s
Jesse Keating 7a32965
- * work. ieee80211_channel_to_frequency() can for example currently provide a
Jesse Keating 7a32965
- * 2 GHz channel when in fact a 5 GHz channel was desired. An example would be
Jesse Keating 7a32965
- * an AP providing channel 8 on a country IE triplet when it sent this on the
Jesse Keating 7a32965
- * 5 GHz band, that channel is designed to be channel 8 on 5 GHz, not a 2 GHz
Jesse Keating 7a32965
- * channel.
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * This can be removed once ieee80211_channel_to_frequency() takes in a band.
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static bool chan_in_band(int chan, enum ieee80211_band band)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	int center_freq = ieee80211_channel_to_frequency(chan);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	switch (band) {
Jesse Keating 7a32965
-	case IEEE80211_BAND_2GHZ:
Jesse Keating 7a32965
-		if (center_freq <= 2484)
Jesse Keating 7a32965
-			return true;
Jesse Keating 7a32965
-		return false;
Jesse Keating 7a32965
-	case IEEE80211_BAND_5GHZ:
Jesse Keating 7a32965
-		if (center_freq >= 5005)
Jesse Keating 7a32965
-			return true;
Jesse Keating 7a32965
-		return false;
Jesse Keating 7a32965
-	default:
Jesse Keating 7a32965
-		return false;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/*
Jesse Keating 7a32965
- * Some APs may send a country IE triplet for each channel they
Jesse Keating 7a32965
- * support and while this is completely overkill and silly we still
Jesse Keating 7a32965
- * need to support it. We avoid making a single rule for each channel
Jesse Keating 7a32965
- * though and to help us with this we use this helper to find the
Jesse Keating 7a32965
- * actual subband end channel. These type of country IE triplet
Jesse Keating 7a32965
- * scenerios are handled then, all yielding two regulaotry rules from
Jesse Keating 7a32965
- * parsing a country IE:
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * [1]
Jesse Keating 7a32965
- * [2]
Jesse Keating 7a32965
- * [36]
Jesse Keating 7a32965
- * [40]
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * [1]
Jesse Keating 7a32965
- * [2-4]
Jesse Keating 7a32965
- * [5-12]
Jesse Keating 7a32965
- * [36]
Jesse Keating 7a32965
- * [40-44]
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * [1-4]
Jesse Keating 7a32965
- * [5-7]
Jesse Keating 7a32965
- * [36-44]
Jesse Keating 7a32965
- * [48-64]
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * [36-36]
Jesse Keating 7a32965
- * [40-40]
Jesse Keating 7a32965
- * [44-44]
Jesse Keating 7a32965
- * [48-48]
Jesse Keating 7a32965
- * [52-52]
Jesse Keating 7a32965
- * [56-56]
Jesse Keating 7a32965
- * [60-60]
Jesse Keating 7a32965
- * [64-64]
Jesse Keating 7a32965
- * [100-100]
Jesse Keating 7a32965
- * [104-104]
Jesse Keating 7a32965
- * [108-108]
Jesse Keating 7a32965
- * [112-112]
Jesse Keating 7a32965
- * [116-116]
Jesse Keating 7a32965
- * [120-120]
Jesse Keating 7a32965
- * [124-124]
Jesse Keating 7a32965
- * [128-128]
Jesse Keating 7a32965
- * [132-132]
Jesse Keating 7a32965
- * [136-136]
Jesse Keating 7a32965
- * [140-140]
Jesse Keating 7a32965
- *
Jesse Keating 7a32965
- * Returns 0 if the IE has been found to be invalid in the middle
Jesse Keating 7a32965
- * somewhere.
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static int max_subband_chan(enum ieee80211_band band,
Jesse Keating 7a32965
-			    int orig_cur_chan,
Jesse Keating 7a32965
-			    int orig_end_channel,
Jesse Keating 7a32965
-			    s8 orig_max_power,
Jesse Keating 7a32965
-			    u8 **country_ie,
Jesse Keating 7a32965
-			    u8 *country_ie_len)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	u8 *triplets_start = *country_ie;
Jesse Keating 7a32965
-	u8 len_at_triplet = *country_ie_len;
Jesse Keating 7a32965
-	int end_subband_chan = orig_end_channel;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * We'll deal with padding for the caller unless
Jesse Keating 7a32965
-	 * its not immediate and we don't process any channels
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	if (*country_ie_len == 1) {
Jesse Keating 7a32965
-		*country_ie += 1;
Jesse Keating 7a32965
-		*country_ie_len -= 1;
Jesse Keating 7a32965
-		return orig_end_channel;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* Move to the next triplet and then start search */
Jesse Keating 7a32965
-	*country_ie += 3;
Jesse Keating 7a32965
-	*country_ie_len -= 3;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (!chan_in_band(orig_cur_chan, band))
Jesse Keating 7a32965
-		return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	while (*country_ie_len >= 3) {
Jesse Keating 7a32965
-		int end_channel = 0;
Jesse Keating 7a32965
-		struct ieee80211_country_ie_triplet *triplet =
Jesse Keating 7a32965
-			(struct ieee80211_country_ie_triplet *) *country_ie;
Jesse Keating 7a32965
-		int cur_channel = 0, next_expected_chan;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* means last triplet is completely unrelated to this one */
Jesse Keating 7a32965
-		if (triplet->ext.reg_extension_id >=
Jesse Keating 7a32965
-				IEEE80211_COUNTRY_EXTENSION_ID) {
Jesse Keating 7a32965
-			*country_ie -= 3;
Jesse Keating 7a32965
-			*country_ie_len += 3;
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (triplet->chans.first_channel == 0) {
Jesse Keating 7a32965
-			*country_ie += 1;
Jesse Keating 7a32965
-			*country_ie_len -= 1;
Jesse Keating 7a32965
-			if (*country_ie_len != 0)
Jesse Keating 7a32965
-				return 0;
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (triplet->chans.num_channels == 0)
Jesse Keating 7a32965
-			return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* Monitonically increasing channel order */
Jesse Keating 7a32965
-		if (triplet->chans.first_channel <= end_subband_chan)
Jesse Keating 7a32965
-			return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (!chan_in_band(triplet->chans.first_channel, band))
Jesse Keating 7a32965
-			return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* 2 GHz */
Jesse Keating 7a32965
-		if (triplet->chans.first_channel <= 14) {
Jesse Keating 7a32965
-			end_channel = triplet->chans.first_channel +
Jesse Keating 7a32965
-				triplet->chans.num_channels - 1;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-		else {
Jesse Keating 7a32965
-			end_channel =  triplet->chans.first_channel +
Jesse Keating 7a32965
-				(4 * (triplet->chans.num_channels - 1));
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (!chan_in_band(end_channel, band))
Jesse Keating 7a32965
-			return 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (orig_max_power != triplet->chans.max_power) {
Jesse Keating 7a32965
-			*country_ie -= 3;
Jesse Keating 7a32965
-			*country_ie_len += 3;
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		cur_channel = triplet->chans.first_channel;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* The key is finding the right next expected channel */
Jesse Keating 7a32965
-		if (band == IEEE80211_BAND_2GHZ)
Jesse Keating 7a32965
-			next_expected_chan = end_subband_chan + 1;
Jesse Keating 7a32965
-		 else
Jesse Keating 7a32965
-			next_expected_chan = end_subband_chan + 4;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (cur_channel != next_expected_chan) {
Jesse Keating 7a32965
-			*country_ie -= 3;
Jesse Keating 7a32965
-			*country_ie_len += 3;
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		end_subband_chan = end_channel;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* Move to the next one */
Jesse Keating 7a32965
-		*country_ie += 3;
Jesse Keating 7a32965
-		*country_ie_len -= 3;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * Padding needs to be dealt with if we processed
Jesse Keating 7a32965
-		 * some channels.
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		if (*country_ie_len == 1) {
Jesse Keating 7a32965
-			*country_ie += 1;
Jesse Keating 7a32965
-			*country_ie_len -= 1;
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* If seen, the IE is invalid */
Jesse Keating 7a32965
-		if (*country_ie_len == 2)
Jesse Keating 7a32965
-			return 0;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	if (end_subband_chan == orig_end_channel) {
Jesse Keating 7a32965
-		*country_ie = triplets_start;
Jesse Keating 7a32965
-		*country_ie_len = len_at_triplet;
Jesse Keating 7a32965
-		return orig_end_channel;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return end_subband_chan;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/*
Jesse Keating 7a32965
- * Converts a country IE to a regulatory domain. A regulatory domain
Jesse Keating 7a32965
- * structure has a lot of information which the IE doesn't yet have,
Jesse Keating 7a32965
- * so for the other values we use upper max values as we will intersect
Jesse Keating 7a32965
- * with our userspace regulatory agent to get lower bounds.
Jesse Keating 7a32965
- */
Jesse Keating 7a32965
-static struct ieee80211_regdomain *country_ie_2_rd(
Jesse Keating 7a32965
-				enum ieee80211_band band,
Jesse Keating 7a32965
-				u8 *country_ie,
Jesse Keating 7a32965
-				u8 country_ie_len,
Jesse Keating 7a32965
-				u32 *checksum)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	struct ieee80211_regdomain *rd = NULL;
Jesse Keating 7a32965
-	unsigned int i = 0;
Jesse Keating 7a32965
-	char alpha2[2];
Jesse Keating 7a32965
-	u32 flags = 0;
Jesse Keating 7a32965
-	u32 num_rules = 0, size_of_regd = 0;
Jesse Keating 7a32965
-	u8 *triplets_start = NULL;
Jesse Keating 7a32965
-	u8 len_at_triplet = 0;
Jesse Keating 7a32965
-	/* the last channel we have registered in a subband (triplet) */
Jesse Keating 7a32965
-	int last_sub_max_channel = 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	*checksum = 0xDEADBEEF;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* Country IE requirements */
Jesse Keating 7a32965
-	BUG_ON(country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN ||
Jesse Keating 7a32965
-		country_ie_len & 0x01);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	alpha2[0] = country_ie[0];
Jesse Keating 7a32965
-	alpha2[1] = country_ie[1];
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * Third octet can be:
Jesse Keating 7a32965
-	 *    'I' - Indoor
Jesse Keating 7a32965
-	 *    'O' - Outdoor
Jesse Keating 7a32965
-	 *
Jesse Keating 7a32965
-	 *  anything else we assume is no restrictions
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	if (country_ie[2] == 'I')
Jesse Keating 7a32965
-		flags = NL80211_RRF_NO_OUTDOOR;
Jesse Keating 7a32965
-	else if (country_ie[2] == 'O')
Jesse Keating 7a32965
-		flags = NL80211_RRF_NO_INDOOR;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	country_ie += 3;
Jesse Keating 7a32965
-	country_ie_len -= 3;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	triplets_start = country_ie;
Jesse Keating 7a32965
-	len_at_triplet = country_ie_len;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	*checksum ^= ((flags ^ alpha2[0] ^ alpha2[1]) << 8);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * We need to build a reg rule for each triplet, but first we must
Jesse Keating 7a32965
-	 * calculate the number of reg rules we will need. We will need one
Jesse Keating 7a32965
-	 * for each channel subband
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	while (country_ie_len >= 3) {
Jesse Keating 7a32965
-		int end_channel = 0;
Jesse Keating 7a32965
-		struct ieee80211_country_ie_triplet *triplet =
Jesse Keating 7a32965
-			(struct ieee80211_country_ie_triplet *) country_ie;
Jesse Keating 7a32965
-		int cur_sub_max_channel = 0, cur_channel = 0;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (triplet->ext.reg_extension_id >=
Jesse Keating 7a32965
-				IEEE80211_COUNTRY_EXTENSION_ID) {
Jesse Keating 7a32965
-			country_ie += 3;
Jesse Keating 7a32965
-			country_ie_len -= 3;
Jesse Keating 7a32965
-			continue;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * APs can add padding to make length divisible
Jesse Keating 7a32965
-		 * by two, required by the spec.
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		if (triplet->chans.first_channel == 0) {
Jesse Keating 7a32965
-			country_ie++;
Jesse Keating 7a32965
-			country_ie_len--;
Jesse Keating 7a32965
-			/* This is expected to be at the very end only */
Jesse Keating 7a32965
-			if (country_ie_len != 0)
Jesse Keating 7a32965
-				return NULL;
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (triplet->chans.num_channels == 0)
Jesse Keating 7a32965
-			return NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (!chan_in_band(triplet->chans.first_channel, band))
Jesse Keating 7a32965
-			return NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* 2 GHz */
Jesse Keating 7a32965
-		if (band == IEEE80211_BAND_2GHZ)
Jesse Keating 7a32965
-			end_channel = triplet->chans.first_channel +
Jesse Keating 7a32965
-				triplet->chans.num_channels - 1;
Jesse Keating 7a32965
-		else
Jesse Keating 7a32965
-			/*
Jesse Keating 7a32965
-			 * 5 GHz -- For example in country IEs if the first
Jesse Keating 7a32965
-			 * channel given is 36 and the number of channels is 4
Jesse Keating 7a32965
-			 * then the individual channel numbers defined for the
Jesse Keating 7a32965
-			 * 5 GHz PHY by these parameters are: 36, 40, 44, and 48
Jesse Keating 7a32965
-			 * and not 36, 37, 38, 39.
Jesse Keating 7a32965
-			 *
Jesse Keating 7a32965
-			 * See: http://tinyurl.com/11d-clarification
Jesse Keating 7a32965
-			 */
Jesse Keating 7a32965
-			end_channel =  triplet->chans.first_channel +
Jesse Keating 7a32965
-				(4 * (triplet->chans.num_channels - 1));
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		cur_channel = triplet->chans.first_channel;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * Enhancement for APs that send a triplet for every channel
Jesse Keating 7a32965
-		 * or for whatever reason sends triplets with multiple channels
Jesse Keating 7a32965
-		 * separated when in fact they should be together.
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		end_channel = max_subband_chan(band,
Jesse Keating 7a32965
-					       cur_channel,
Jesse Keating 7a32965
-					       end_channel,
Jesse Keating 7a32965
-					       triplet->chans.max_power,
Jesse Keating 7a32965
-					       &country_ie,
Jesse Keating 7a32965
-					       &country_ie_len);
Jesse Keating 7a32965
-		if (!end_channel)
Jesse Keating 7a32965
-			return NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (!chan_in_band(end_channel, band))
Jesse Keating 7a32965
-			return NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		cur_sub_max_channel = end_channel;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* Basic sanity check */
Jesse Keating 7a32965
-		if (cur_sub_max_channel < cur_channel)
Jesse Keating 7a32965
-			return NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * Do not allow overlapping channels. Also channels
Jesse Keating 7a32965
-		 * passed in each subband must be monotonically
Jesse Keating 7a32965
-		 * increasing
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		if (last_sub_max_channel) {
Jesse Keating 7a32965
-			if (cur_channel <= last_sub_max_channel)
Jesse Keating 7a32965
-				return NULL;
Jesse Keating 7a32965
-			if (cur_sub_max_channel <= last_sub_max_channel)
Jesse Keating 7a32965
-				return NULL;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * When dot11RegulatoryClassesRequired is supported
Jesse Keating 7a32965
-		 * we can throw ext triplets as part of this soup,
Jesse Keating 7a32965
-		 * for now we don't care when those change as we
Jesse Keating 7a32965
-		 * don't support them
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		*checksum ^= ((cur_channel ^ cur_sub_max_channel) << 8) |
Jesse Keating 7a32965
-		  ((cur_sub_max_channel ^ cur_sub_max_channel) << 16) |
Jesse Keating 7a32965
-		  ((triplet->chans.max_power ^ cur_sub_max_channel) << 24);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		last_sub_max_channel = cur_sub_max_channel;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		num_rules++;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (country_ie_len >= 3) {
Jesse Keating 7a32965
-			country_ie += 3;
Jesse Keating 7a32965
-			country_ie_len -= 3;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * Note: this is not a IEEE requirement but
Jesse Keating 7a32965
-		 * simply a memory requirement
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		if (num_rules > NL80211_MAX_SUPP_REG_RULES)
Jesse Keating 7a32965
-			return NULL;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	country_ie = triplets_start;
Jesse Keating 7a32965
-	country_ie_len = len_at_triplet;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	size_of_regd = sizeof(struct ieee80211_regdomain) +
Jesse Keating 7a32965
-		(num_rules * sizeof(struct ieee80211_reg_rule));
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rd = kzalloc(size_of_regd, GFP_KERNEL);
Jesse Keating 7a32965
-	if (!rd)
Jesse Keating 7a32965
-		return NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	rd->n_reg_rules = num_rules;
Jesse Keating 7a32965
-	rd->alpha2[0] = alpha2[0];
Jesse Keating 7a32965
-	rd->alpha2[1] = alpha2[1];
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/* This time around we fill in the rd */
Jesse Keating 7a32965
-	while (country_ie_len >= 3) {
Jesse Keating 7a32965
-		int end_channel = 0;
Jesse Keating 7a32965
-		struct ieee80211_country_ie_triplet *triplet =
Jesse Keating 7a32965
-			(struct ieee80211_country_ie_triplet *) country_ie;
Jesse Keating 7a32965
-		struct ieee80211_reg_rule *reg_rule = NULL;
Jesse Keating 7a32965
-		struct ieee80211_freq_range *freq_range = NULL;
Jesse Keating 7a32965
-		struct ieee80211_power_rule *power_rule = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * Must parse if dot11RegulatoryClassesRequired is true,
Jesse Keating 7a32965
-		 * we don't support this yet
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		if (triplet->ext.reg_extension_id >=
Jesse Keating 7a32965
-				IEEE80211_COUNTRY_EXTENSION_ID) {
Jesse Keating 7a32965
-			country_ie += 3;
Jesse Keating 7a32965
-			country_ie_len -= 3;
Jesse Keating 7a32965
-			continue;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (triplet->chans.first_channel == 0) {
Jesse Keating 7a32965
-			country_ie++;
Jesse Keating 7a32965
-			country_ie_len--;
Jesse Keating 7a32965
-			break;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		reg_rule = &rd->reg_rules[i];
Jesse Keating 7a32965
-		freq_range = &reg_rule->freq_range;
Jesse Keating 7a32965
-		power_rule = &reg_rule->power_rule;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		reg_rule->flags = flags;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/* 2 GHz */
Jesse Keating 7a32965
-		if (band == IEEE80211_BAND_2GHZ)
Jesse Keating 7a32965
-			end_channel = triplet->chans.first_channel +
Jesse Keating 7a32965
-				triplet->chans.num_channels -1;
Jesse Keating 7a32965
-		else
Jesse Keating 7a32965
-			end_channel =  triplet->chans.first_channel +
Jesse Keating 7a32965
-				(4 * (triplet->chans.num_channels - 1));
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		end_channel = max_subband_chan(band,
Jesse Keating 7a32965
-					       triplet->chans.first_channel,
Jesse Keating 7a32965
-					       end_channel,
Jesse Keating 7a32965
-					       triplet->chans.max_power,
Jesse Keating 7a32965
-					       &country_ie,
Jesse Keating 7a32965
-					       &country_ie_len);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * The +10 is since the regulatory domain expects
Jesse Keating 7a32965
-		 * the actual band edge, not the center of freq for
Jesse Keating 7a32965
-		 * its start and end freqs, assuming 20 MHz bandwidth on
Jesse Keating 7a32965
-		 * the channels passed
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		freq_range->start_freq_khz =
Jesse Keating 7a32965
-			MHZ_TO_KHZ(ieee80211_channel_to_frequency(
Jesse Keating 7a32965
-				triplet->chans.first_channel) - 10);
Jesse Keating 7a32965
-		freq_range->end_freq_khz =
Jesse Keating 7a32965
-			MHZ_TO_KHZ(ieee80211_channel_to_frequency(
Jesse Keating 7a32965
-				end_channel) + 10);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * These are large arbitrary values we use to intersect later.
Jesse Keating 7a32965
-		 * Increment this if we ever support >= 40 MHz channels
Jesse Keating 7a32965
-		 * in IEEE 802.11
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40);
Jesse Keating 7a32965
-		power_rule->max_antenna_gain = DBI_TO_MBI(100);
Jesse Keating 7a32965
-		power_rule->max_eirp = DBM_TO_MBM(triplet->chans.max_power);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		i++;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		if (country_ie_len >= 3) {
Jesse Keating 7a32965
-			country_ie += 3;
Jesse Keating 7a32965
-			country_ie_len -= 3;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-		BUG_ON(i > NL80211_MAX_SUPP_REG_RULES);
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	return rd;
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-/*
Jesse Keating 7a32965
  * Helper for regdom_intersect(), this does the real
Jesse Keating 7a32965
  * mathematical intersection fun
Jesse Keating 7a32965
  */
Jesse Keating 7a32965
@@ -1191,7 +699,6 @@ static int freq_reg_info_regd(struct wiphy *wiphy,
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	return -EINVAL;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
-EXPORT_SYMBOL(freq_reg_info);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 int freq_reg_info(struct wiphy *wiphy,
Jesse Keating 7a32965
 		  u32 center_freq,
Jesse Keating 7a32965
@@ -1205,6 +712,7 @@ int freq_reg_info(struct wiphy *wiphy,
Jesse Keating 7a32965
 				  reg_rule,
Jesse Keating 7a32965
 				  NULL);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
+EXPORT_SYMBOL(freq_reg_info);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /*
Jesse Keating 7a32965
  * Note that right now we assume the desired channel bandwidth
Jesse Keating 7a32965
@@ -1243,41 +751,8 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
Jesse Keating 7a32965
 			  desired_bw_khz,
Jesse Keating 7a32965
 			  &reg_rule);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	if (r) {
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * This means no regulatory rule was found in the country IE
Jesse Keating 7a32965
-		 * with a frequency range on the center_freq's band, since
Jesse Keating 7a32965
-		 * IEEE-802.11 allows for a country IE to have a subset of the
Jesse Keating 7a32965
-		 * regulatory information provided in a country we ignore
Jesse Keating 7a32965
-		 * disabling the channel unless at least one reg rule was
Jesse Keating 7a32965
-		 * found on the center_freq's band. For details see this
Jesse Keating 7a32965
-		 * clarification:
Jesse Keating 7a32965
-		 *
Jesse Keating 7a32965
-		 * http://tinyurl.com/11d-clarification
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-		if (r == -ERANGE &&
Jesse Keating 7a32965
-		    last_request->initiator ==
Jesse Keating 7a32965
-		    NL80211_REGDOM_SET_BY_COUNTRY_IE) {
Jesse Keating 7a32965
-			REG_DBG_PRINT("cfg80211: Leaving channel %d MHz "
Jesse Keating 7a32965
-				"intact on %s - no rule found in band on "
Jesse Keating 7a32965
-				"Country IE\n",
Jesse Keating 7a32965
-			chan->center_freq, wiphy_name(wiphy));
Jesse Keating 7a32965
-		} else {
Jesse Keating 7a32965
-		/*
Jesse Keating 7a32965
-		 * In this case we know the country IE has at least one reg rule
Jesse Keating 7a32965
-		 * for the band so we respect its band definitions
Jesse Keating 7a32965
-		 */
Jesse Keating 7a32965
-			if (last_request->initiator ==
Jesse Keating 7a32965
-			    NL80211_REGDOM_SET_BY_COUNTRY_IE)
Jesse Keating 7a32965
-				REG_DBG_PRINT("cfg80211: Disabling "
Jesse Keating 7a32965
-					"channel %d MHz on %s due to "
Jesse Keating 7a32965
-					"Country IE\n",
Jesse Keating 7a32965
-					chan->center_freq, wiphy_name(wiphy));
Jesse Keating 7a32965
-			flags |= IEEE80211_CHAN_DISABLED;
Jesse Keating 7a32965
-			chan->flags = flags;
Jesse Keating 7a32965
-		}
Jesse Keating 7a32965
+	if (r)
Jesse Keating 7a32965
 		return;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	power_rule = &reg_rule->power_rule;
Jesse Keating 7a32965
 	freq_range = &reg_rule->freq_range;
Jesse Keating 7a32965
@@ -2010,7 +1485,7 @@ EXPORT_SYMBOL(regulatory_hint);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 /* Caller must hold reg_mutex */
Jesse Keating 7a32965
 static bool reg_same_country_ie_hint(struct wiphy *wiphy,
Jesse Keating 7a32965
-			u32 country_ie_checksum)
Jesse Keating 7a32965
+			char *alpha2, enum environment_cap env)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct wiphy *request_wiphy;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -2026,13 +1501,17 @@ static bool reg_same_country_ie_hint(struct wiphy *wiphy,
Jesse Keating 7a32965
 		return false;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	if (likely(request_wiphy != wiphy))
Jesse Keating 7a32965
-		return !country_ie_integrity_changes(country_ie_checksum);
Jesse Keating 7a32965
+		return (last_request->alpha2[0] == alpha2[0] &&
Jesse Keating 7a32965
+			last_request->alpha2[1] == alpha2[1] &&
Jesse Keating 7a32965
+			last_request->country_ie_env == env);
Jesse Keating 7a32965
 	/*
Jesse Keating 7a32965
 	 * We should not have let these through at this point, they
Jesse Keating 7a32965
 	 * should have been picked up earlier by the first alpha2 check
Jesse Keating 7a32965
 	 * on the device
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
-	if (WARN_ON(!country_ie_integrity_changes(country_ie_checksum)))
Jesse Keating 7a32965
+	if (WARN_ON((last_request->alpha2[0] == alpha2[0] &&
Jesse Keating 7a32965
+			last_request->alpha2[1] == alpha2[1] &&
Jesse Keating 7a32965
+			last_request->country_ie_env == env )))
Jesse Keating 7a32965
 		return true;
Jesse Keating 7a32965
 	return false;
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
@@ -2048,7 +1527,6 @@ void regulatory_hint_11d(struct wiphy *wiphy,
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
 	struct ieee80211_regdomain *rd = NULL;
Jesse Keating 7a32965
 	char alpha2[2];
Jesse Keating 7a32965
-	u32 checksum = 0;
Jesse Keating 7a32965
 	enum environment_cap env = ENVIRON_ANY;
Jesse Keating 7a32965
 	struct regulatory_request *request;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -2064,14 +1542,6 @@ void regulatory_hint_11d(struct wiphy *wiphy,
Jesse Keating 7a32965
 	if (country_ie_len < IEEE80211_COUNTRY_IE_MIN_LEN)
Jesse Keating 7a32965
 		goto out;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * Pending country IE processing, this can happen after we
Jesse Keating 7a32965
-	 * call CRDA and wait for a response if a beacon was received before
Jesse Keating 7a32965
-	 * we were able to process the last regulatory_hint_11d() call
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	if (country_ie_regdomain)
Jesse Keating 7a32965
-		goto out;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	alpha2[0] = country_ie[0];
Jesse Keating 7a32965
 	alpha2[1] = country_ie[1];
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -2090,12 +1560,6 @@ void regulatory_hint_11d(struct wiphy *wiphy,
Jesse Keating 7a32965
 	    wiphy_idx_valid(last_request->wiphy_idx)))
Jesse Keating 7a32965
 		goto out;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	rd = country_ie_2_rd(band, country_ie, country_ie_len, &checksum);
Jesse Keating 7a32965
-	if (!rd) {
Jesse Keating 7a32965
-		REG_DBG_PRINT("cfg80211: Ignoring bogus country IE\n");
Jesse Keating 7a32965
-		goto out;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	/*
Jesse Keating 7a32965
 	 * This will not happen right now but we leave it here for the
Jesse Keating 7a32965
 	 * the future when we want to add suspend/resume support and having
Jesse Keating 7a32965
@@ -2105,24 +1569,17 @@ void regulatory_hint_11d(struct wiphy *wiphy,
Jesse Keating 7a32965
 	 * If we hit this before we add this support we want to be informed of
Jesse Keating 7a32965
 	 * it as it would indicate a mistake in the current design
Jesse Keating 7a32965
 	 */
Jesse Keating 7a32965
-	if (WARN_ON(reg_same_country_ie_hint(wiphy, checksum)))
Jesse Keating 7a32965
+	if (WARN_ON(reg_same_country_ie_hint(wiphy, alpha2, env)))
Jesse Keating 7a32965
 		goto free_rd_out;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	request = kzalloc(sizeof(struct regulatory_request), GFP_KERNEL);
Jesse Keating 7a32965
 	if (!request)
Jesse Keating 7a32965
 		goto free_rd_out;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * We keep this around for when CRDA comes back with a response so
Jesse Keating 7a32965
-	 * we can intersect with that
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	country_ie_regdomain = rd;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	request->wiphy_idx = get_wiphy_idx(wiphy);
Jesse Keating 7a32965
-	request->alpha2[0] = rd->alpha2[0];
Jesse Keating 7a32965
-	request->alpha2[1] = rd->alpha2[1];
Jesse Keating 7a32965
+	request->alpha2[0] = alpha2[0];
Jesse Keating 7a32965
+	request->alpha2[1] = alpha2[1];
Jesse Keating 7a32965
 	request->initiator = NL80211_REGDOM_SET_BY_COUNTRY_IE;
Jesse Keating 7a32965
-	request->country_ie_checksum = checksum;
Jesse Keating 7a32965
 	request->country_ie_env = env;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	mutex_unlock(&reg_mutex);
Jesse Keating 7a32965
@@ -2383,33 +1840,6 @@ static void print_regdomain_info(const struct ieee80211_regdomain *rd)
Jesse Keating 7a32965
 	print_rd_rules(rd);
Jesse Keating 7a32965
 }
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-#ifdef CONFIG_CFG80211_REG_DEBUG
Jesse Keating 7a32965
-static void reg_country_ie_process_debug(
Jesse Keating 7a32965
-	const struct ieee80211_regdomain *rd,
Jesse Keating 7a32965
-	const struct ieee80211_regdomain *country_ie_regdomain,
Jesse Keating 7a32965
-	const struct ieee80211_regdomain *intersected_rd)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-	printk(KERN_DEBUG "cfg80211: Received country IE:\n");
Jesse Keating 7a32965
-	print_regdomain_info(country_ie_regdomain);
Jesse Keating 7a32965
-	printk(KERN_DEBUG "cfg80211: CRDA thinks this should applied:\n");
Jesse Keating 7a32965
-	print_regdomain_info(rd);
Jesse Keating 7a32965
-	if (intersected_rd) {
Jesse Keating 7a32965
-		printk(KERN_DEBUG "cfg80211: We intersect both of these "
Jesse Keating 7a32965
-			"and get:\n");
Jesse Keating 7a32965
-		print_regdomain_info(intersected_rd);
Jesse Keating 7a32965
-		return;
Jesse Keating 7a32965
-	}
Jesse Keating 7a32965
-	printk(KERN_DEBUG "cfg80211: Intersection between both failed\n");
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-#else
Jesse Keating 7a32965
-static inline void reg_country_ie_process_debug(
Jesse Keating 7a32965
-	const struct ieee80211_regdomain *rd,
Jesse Keating 7a32965
-	const struct ieee80211_regdomain *country_ie_regdomain,
Jesse Keating 7a32965
-	const struct ieee80211_regdomain *intersected_rd)
Jesse Keating 7a32965
-{
Jesse Keating 7a32965
-}
Jesse Keating 7a32965
-#endif
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 /* Takes ownership of rd only if it doesn't fail */
Jesse Keating 7a32965
 static int __set_regdom(const struct ieee80211_regdomain *rd)
Jesse Keating 7a32965
 {
Jesse Keating 7a32965
@@ -2521,34 +1951,6 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
Jesse Keating 7a32965
 		return 0;
Jesse Keating 7a32965
 	}
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * Country IE requests are handled a bit differently, we intersect
Jesse Keating 7a32965
-	 * the country IE rd with what CRDA believes that country should have
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * Userspace could have sent two replies with only
Jesse Keating 7a32965
-	 * one kernel request. By the second reply we would have
Jesse Keating 7a32965
-	 * already processed and consumed the country_ie_regdomain.
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-	if (!country_ie_regdomain)
Jesse Keating 7a32965
-		return -EALREADY;
Jesse Keating 7a32965
-	BUG_ON(rd == country_ie_regdomain);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	/*
Jesse Keating 7a32965
-	 * Intersect what CRDA returned and our what we
Jesse Keating 7a32965
-	 * had built from the Country IE received
Jesse Keating 7a32965
-	 */
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	intersected_rd = regdom_intersect(rd, country_ie_regdomain);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	reg_country_ie_process_debug(rd,
Jesse Keating 7a32965
-				     country_ie_regdomain,
Jesse Keating 7a32965
-				     intersected_rd);
Jesse Keating 7a32965
-
Jesse Keating 7a32965
-	kfree(country_ie_regdomain);
Jesse Keating 7a32965
-	country_ie_regdomain = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	if (!intersected_rd)
Jesse Keating 7a32965
 		return -EINVAL;
Jesse Keating 7a32965
 
Jesse Keating 7a32965
@@ -2688,9 +2090,6 @@ void /* __init_or_exit */ regulatory_exit(void)
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	reset_regdomains();
Jesse Keating 7a32965
 
Jesse Keating 7a32965
-	kfree(country_ie_regdomain);
Jesse Keating 7a32965
-	country_ie_regdomain = NULL;
Jesse Keating 7a32965
-
Jesse Keating 7a32965
 	kfree(last_request);
Jesse Keating 7a32965
 
Jesse Keating 7a32965
 	platform_device_unregister(reg_pdev);
Jesse Keating 7a32965
-- 
Jesse Keating 7a32965
1.7.1.1
Jesse Keating 7a32965
Jesse Keating 7a32965