Index: chromeos/compat-wireless/net/wireless/reg.c |
diff --git a/chromeos/compat-wireless/net/wireless/reg.c b/chromeos/compat-wireless/net/wireless/reg.c |
index f180db0de66cbc2163ce3dab641b46cb647226d2..fbe45484c7db2ad780725648574e4da8d02f397c 100644 |
--- a/chromeos/compat-wireless/net/wireless/reg.c |
+++ b/chromeos/compat-wireless/net/wireless/reg.c |
@@ -723,7 +723,9 @@ EXPORT_SYMBOL(freq_reg_info); |
* on the wiphy with the target_bw specified. Then we can simply use |
* that below for the desired_bw_khz below. |
*/ |
-static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, |
+static void handle_channel(struct wiphy *wiphy, |
+ enum nl80211_reg_initiator initiator, |
+ enum ieee80211_band band, |
unsigned int chan_idx) |
{ |
int r; |
@@ -751,8 +753,26 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, |
desired_bw_khz, |
®_rule); |
- if (r) |
+ if (r) { |
+ /* |
+ * We will disable all channels that do not match our |
+ * recieved regulatory rule unless the hint is coming |
+ * from a Country IE and the Country IE had no information |
+ * about a band. The IEEE 802.11 spec allows for an AP |
+ * to send only a subset of the regulatory rules allowed, |
+ * so an AP in the US that only supports 2.4 GHz may only send |
+ * a country IE with information for the 2.4 GHz band |
+ * while 5 GHz is still supported. |
+ */ |
+ if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE && |
+ r == -ERANGE) |
+ return; |
+ |
+ REG_DBG_PRINT("cfg80211: Disabling freq %d MHz\n", |
+ chan->center_freq); |
+ chan->flags = IEEE80211_CHAN_DISABLED; |
return; |
+ } |
power_rule = ®_rule->power_rule; |
freq_range = ®_rule->freq_range; |
@@ -787,7 +807,9 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band, |
chan->max_power = (int) MBM_TO_DBM(power_rule->max_eirp); |
} |
-static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) |
+static void handle_band(struct wiphy *wiphy, |
+ enum ieee80211_band band, |
+ enum nl80211_reg_initiator initiator) |
{ |
unsigned int i; |
struct ieee80211_supported_band *sband; |
@@ -796,7 +818,7 @@ static void handle_band(struct wiphy *wiphy, enum ieee80211_band band) |
sband = wiphy->bands[band]; |
for (i = 0; i < sband->n_channels; i++) |
- handle_channel(wiphy, band, i); |
+ handle_channel(wiphy, initiator, band, i); |
} |
static bool ignore_reg_update(struct wiphy *wiphy, |
@@ -812,6 +834,7 @@ static bool ignore_reg_update(struct wiphy *wiphy, |
* desired regulatory domain set |
*/ |
if (wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY && !wiphy->regd && |
+ initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE && |
!is_world_regdom(last_request->alpha2)) |
return true; |
return false; |
@@ -1033,7 +1056,7 @@ void wiphy_update_regulatory(struct wiphy *wiphy, |
goto out; |
for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
if (wiphy->bands[band]) |
- handle_band(wiphy, band); |
+ handle_band(wiphy, band, initiator); |
} |
out: |
reg_process_beacons(wiphy); |
@@ -1170,7 +1193,7 @@ static int ignore_request(struct wiphy *wiphy, |
return 0; |
return -EALREADY; |
} |
- return REG_INTERSECT; |
+ return 0; |
case NL80211_REGDOM_SET_BY_DRIVER: |
if (last_request->initiator == NL80211_REGDOM_SET_BY_CORE) { |
if (regdom_changes(pending_request->alpha2)) |