Skip to contentSkip to conversation

Regulatory and ath9k support for ITS-G5 band (5.9 GHz)

PATCH New Michal Sojka 3 participants 23 messages Nov 23, 2015 – Nov 30, 2015

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

v2 cover Regulatory and ath9k support for ITS-G5 band (5.9 GHz)

This patch series is another attempt to mainline support for ITS-G5 band (5.9 GHz) designated for Intelligent Transportation Systems.

Based on the discussion with Jouni [1], this version adds the following restrictions for using the band:

1. Custom reg db must be provided by the user.
2. CONFIG_CFG80211_REG_ITSG5_BAND must be enabled.
3. The band is restricted to OCB mode. I.e. beaconing and scanning is disabled.

Patches 1-3 do some refactoring and cleanup. They are independent of the rest of the series. Patches 4-7 add regulatory support (mainly the points mentioned above) and finally patch 8 adds support for ITS-G5 to the ath9k driver.

[1]: http://www.mail-archive.com/[email protected]/msg13795.html

Michal Sojka (8):
cfg80211: reg: Remove unused function parameter
cfg80211: Remove unused cfg80211_can_use_iftype_chan()
cfg80211: reg: Refactor calculation of bandwidth flags
cfg80211: reg: Properly handle rules for 5 and 10 MHz channels
cfg80211: Add support for OCB-only channels
cfg80211: reg: Add NL80211_RRF_USER_REGD_NEEDED flag
cfg80211: Add Kconfig option for ITS-G5 band (5.9 GHz)
ath9k: Add support for ITS-G5 band (5.9 GHz)

 drivers/net/wireless/ath/ath9k/common-init.c |  19 +++++
 drivers/net/wireless/ath/ath9k/hw.h          |   2 +-
 drivers/net/wireless/ath/regd.c              |  23 +++--
 include/net/cfg80211.h                       |   5 ++
 include/uapi/linux/nl80211.h                 |   6 ++
 net/wireless/Kconfig                         |  27 ++++++
 net/wireless/chan.c                          |   6 +-
 net/wireless/core.h                          |   7 --
 net/wireless/ibss.c                          |  12 ++-
 net/wireless/mesh.c                          |   3 +-
 net/wireless/nl80211.c                       |  12 +--
 net/wireless/reg.c                           | 123 +++++++++++++--------------
 net/wireless/scan.c                          |   4 +-
 net/wireless/sme.c                           |   3 +-
 net/wireless/util.c                          | 114 -------------------------
 net/wireless/wext-sme.c                      |   3 +-
 16 files changed, 161 insertions(+), 208 deletions(-)
Signature · 1 line
2.5.3
#1 lore raw

PATCH v2 1/8 cfg80211: reg: Remove unused function parameter

---
 net/wireless/reg.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)
net/wireless/reg.c +3 -4
index 2e8d6f3..43b3e57 100644
@@ -1052,7 +1052,7 @@ static u32 map_regdom_flags(u32 rd_flags)
 }
 
 static const struct ieee80211_reg_rule *
-freq_reg_info_regd(struct wiphy *wiphy, u32 center_freq,
+freq_reg_info_regd(u32 center_freq,
 		   const struct ieee80211_regdomain *regd, u32 bw)
 {
 	int i;
@@ -1097,7 +1097,7 @@ __freq_reg_info(struct wiphy *wiphy, u32 center_freq, u32 min_bw)
 	u32 bw;
 
 	for (bw = MHZ_TO_KHZ(20); bw >= min_bw; bw = bw / 2) {
-		reg_rule = freq_reg_info_regd(wiphy, center_freq, regd, bw);
+		reg_rule = freq_reg_info_regd(center_freq, regd, bw);
 		if (!IS_ERR(reg_rule))
 			return reg_rule;
 	}
@@ -1765,8 +1765,7 @@ static void handle_channel_custom(struct wiphy *wiphy,
 	u32 bw;
 
 	for (bw = MHZ_TO_KHZ(20); bw >= MHZ_TO_KHZ(5); bw = bw / 2) {
-		reg_rule = freq_reg_info_regd(wiphy,
-					      MHZ_TO_KHZ(chan->center_freq),
+		reg_rule = freq_reg_info_regd(MHZ_TO_KHZ(chan->center_freq),
 					      regd, bw);
 		if (!IS_ERR(reg_rule))
 			break;
Signature · 1 line
2.5.3
#2 lore raw

PATCH v2 2/8 cfg80211: Remove unused cfg80211_can_use_iftype_chan()

In reply to Michal Sojka

Last caller of this function was removed in 3.17 in commit 97dc94f1d933c9df2c0b327066ea130c0e92083f.

---
 net/wireless/core.h |   7 ----
 net/wireless/util.c | 114 ----------------------------------------------------
 2 files changed, 121 deletions(-)
net/wireless/core.h +0 -7
index a618b4b..022ccad 100644
@@ -416,13 +416,6 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev);
 void cfg80211_process_wdev_events(struct wireless_dev *wdev);
 
-int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev,
-				 struct wireless_dev *wdev,
-				 enum nl80211_iftype iftype,
-				 struct ieee80211_channel *chan,
-				 enum cfg80211_chan_mode chanmode,
-				 u8 radar_detect);
-
 /**
  * cfg80211_chandef_dfs_usable - checks if chandef is DFS usable
  * @wiphy: the wiphy to validate against
net/wireless/util.c +0 -114

120 lines not on this page · raw message

Signature · 1 line
2.5.3
maintainer
#3 lore raw

PATCH v2 2/8 cfg80211: Remove unused cfg80211_can_use_iftype_chan()

Quoted 3 lines · Michal Sojka

Last caller of this function was removed in 3.17 in commit 97dc94f1d933c9df2c0b327066ea130c0e92083f.

Heh.

I've applied the first two patches for now - will review the others in more detail later.

johannes

#4 lore raw

PATCH v2 3/8 cfg80211: reg: Refactor calculation of bandwidth flags

In reply to Michal Sojka

The same piece of code appears at two places. Make a function from it.

---
 net/wireless/reg.c | 91 ++++++++++++++++++++++--------------------------------
 1 file changed, 37 insertions(+), 54 deletions(-)
net/wireless/reg.c +37 -54
index 43b3e57..0a4f548 100644
@@ -1166,6 +1166,41 @@ static void chan_reg_rule_print_dbg(const struct ieee80211_regdomain *regd,
 #endif
 }
 
+static uint32_t reg_rule_to_chan_bw_flags(const struct ieee80211_regdomain *regd,
+					  const struct ieee80211_reg_rule *reg_rule,
+					  const struct ieee80211_channel *chan)
+{
+	const struct ieee80211_freq_range *freq_range = NULL;
+	u32 max_bandwidth_khz, bw_flags = 0;
+
+	freq_range = &reg_rule->freq_range;
+
+	max_bandwidth_khz = freq_range->max_bandwidth_khz;
+	/* Check if auto calculation requested */
+	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
+		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
+
+	/* If we get a reg_rule we can assume that at least 5Mhz fit */
+	if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq),
+			     MHZ_TO_KHZ(10)))
+		bw_flags |= IEEE80211_CHAN_NO_10MHZ;
+	if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq),
+			     MHZ_TO_KHZ(20)))
+		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
+
+	if (max_bandwidth_khz < MHZ_TO_KHZ(10))
+		bw_flags |= IEEE80211_CHAN_NO_10MHZ;
+	if (max_bandwidth_khz < MHZ_TO_KHZ(20))
+		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
+	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
+		bw_flags |= IEEE80211_CHAN_NO_HT40;
+	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
+		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
+	if (max_bandwidth_khz < MHZ_TO_KHZ(160))
+		bw_flags |= IEEE80211_CHAN_NO_160MHZ;
+	return bw_flags;
+}
+
 /*
  * Note that right now we assume the desired channel bandwidth
  * is always 20 MHz for each individual channel (HT40 uses 20 MHz
@@ -1178,11 +1213,9 @@ static void handle_channel(struct wiphy *wiphy,
 	u32 flags, bw_flags = 0;
 	const struct ieee80211_reg_rule *reg_rule = NULL;
 	const struct ieee80211_power_rule *power_rule = NULL;
-	const struct ieee80211_freq_range *freq_range = NULL;
 	struct wiphy *request_wiphy = NULL;
 	struct regulatory_request *lr = get_last_request();
 	const struct ieee80211_regdomain *regd;
-	u32 max_bandwidth_khz;
 
 	request_wiphy = wiphy_idx_to_wiphy(lr->wiphy_idx);
 
@@ -1223,31 +1256,7 @@ static void handle_channel(struct wiphy *wiphy,
 	chan_reg_rule_print_dbg(regd, chan, reg_rule);
 
 	power_rule = &reg_rule->power_rule;
-	freq_range = &reg_rule->freq_range;
-
-	max_bandwidth_khz = freq_range->max_bandwidth_khz;
-	/* Check if auto calculation requested */
-	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
-		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
-
-	/* If we get a reg_rule we can assume that at least 5Mhz fit */
-	if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq),
-			     MHZ_TO_KHZ(10)))
-		bw_flags |= IEEE80211_CHAN_NO_10MHZ;
-	if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq),
-			     MHZ_TO_KHZ(20)))
-		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
-
-	if (max_bandwidth_khz < MHZ_TO_KHZ(10))
-		bw_flags |= IEEE80211_CHAN_NO_10MHZ;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(20))
-		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
-		bw_flags |= IEEE80211_CHAN_NO_HT40;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
-		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(160))
-		bw_flags |= IEEE80211_CHAN_NO_160MHZ;
+	bw_flags = reg_rule_to_chan_bw_flags(regd, reg_rule, chan);
 
 	if (lr->initiator == NL80211_REGDOM_SET_BY_DRIVER &&
 	    request_wiphy && request_wiphy == wiphy &&
@@ -1760,8 +1769,6 @@ static void handle_channel_custom(struct wiphy *wiphy,
 	u32 bw_flags = 0;
 	const struct ieee80211_reg_rule *reg_rule = NULL;
 	const struct ieee80211_power_rule *power_rule = NULL;
-	const struct ieee80211_freq_range *freq_range = NULL;
-	u32 max_bandwidth_khz;
 	u32 bw;
 
 	for (bw = MHZ_TO_KHZ(20); bw >= MHZ_TO_KHZ(5); bw = bw / 2) {
@@ -1786,31 +1793,7 @@ static void handle_channel_custom(struct wiphy *wiphy,
 	chan_reg_rule_print_dbg(regd, chan, reg_rule);
 
 	power_rule = &reg_rule->power_rule;
-	freq_range = &reg_rule->freq_range;
-
-	max_bandwidth_khz = freq_range->max_bandwidth_khz;
-	/* Check if auto calculation requested */
-	if (reg_rule->flags & NL80211_RRF_AUTO_BW)
-		max_bandwidth_khz = reg_get_max_bandwidth(regd, reg_rule);
-
-	/* If we get a reg_rule we can assume that at least 5Mhz fit */
-	if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq),
-			     MHZ_TO_KHZ(10)))
-		bw_flags |= IEEE80211_CHAN_NO_10MHZ;
-	if (!reg_does_bw_fit(freq_range, MHZ_TO_KHZ(chan->center_freq),
-			     MHZ_TO_KHZ(20)))
-		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
-
-	if (max_bandwidth_khz < MHZ_TO_KHZ(10))
-		bw_flags |= IEEE80211_CHAN_NO_10MHZ;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(20))
-		bw_flags |= IEEE80211_CHAN_NO_20MHZ;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(40))
-		bw_flags |= IEEE80211_CHAN_NO_HT40;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(80))
-		bw_flags |= IEEE80211_CHAN_NO_80MHZ;
-	if (max_bandwidth_khz < MHZ_TO_KHZ(160))
-		bw_flags |= IEEE80211_CHAN_NO_160MHZ;
+	bw_flags = reg_rule_to_chan_bw_flags(regd, reg_rule, chan);
 
 	chan->dfs_state_entered = jiffies;
 	chan->dfs_state = NL80211_DFS_USABLE;
Signature · 1 line
2.5.3
maintainer
#5 lore raw

PATCH v2 3/8 cfg80211: reg: Refactor calculation of bandwidth flags

Quoted 3 lines · Michal Sojka

The same piece of code appears at two places. Make a function from it.

Also applied.

johannes

#6 lore raw

PATCH v2 4/8 cfg80211: reg: Properly handle rules for 5 and 10 MHz channels

In reply to Michal Sojka

Regulatory rules are applied to channels as if the channel is at least 20 MHz wide. This is a problem when dealing with 5 and 10 MHz channels because side channels of a regulatory rule get disabled even when they fall into rule's frequency range.

This problem was already fixed in commit 4edd56981c8fbb349b1529a2feaf772636eb1c83, but only for custom regulatory domains provided by drivers. Here we fix it also for all other (e.g. user-supplied) regulatory domains.

Before that, similar commit was
reverted (e33e2241e272eddc38339692500bd1c7d8753a77) due to it allowing running AP on channel 12 in the US regulatory domain. I have checked that this is not possible with this change:

  # iw reg set US
  # iw dev wlan0 interface add wlan0_ap  type __ap
  # iw dev wlan0_ap set channel 12
  command failed: Invalid argument (-22)
---
 net/wireless/reg.c | 8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
net/wireless/reg.c +2 -6
index 0a4f548..35eaeeb 100644
@@ -1201,11 +1201,6 @@ static uint32_t reg_rule_to_chan_bw_flags(const struct ieee80211_regdomain *regd
 	return bw_flags;
 }
 
-/*
- * Note that right now we assume the desired channel bandwidth
- * is always 20 MHz for each individual channel (HT40 uses 20 MHz
- * per channel, the primary and the extension channel).
- */
 static void handle_channel(struct wiphy *wiphy,
 			   enum nl80211_reg_initiator initiator,
 			   struct ieee80211_channel *chan)
@@ -1221,7 +1216,8 @@ static void handle_channel(struct wiphy *wiphy,
 
 	flags = chan->orig_flags;
 
-	reg_rule = freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq));
+	reg_rule = __freq_reg_info(wiphy, MHZ_TO_KHZ(chan->center_freq),
+				   MHZ_TO_KHZ(5));
 	if (IS_ERR(reg_rule)) {
 		/*
 		 * We will disable all channels that do not match our
Signature · 1 line
2.5.3
maintainer Applied
#7 lore raw

PATCH v2 4/8 cfg80211: reg: Properly handle rules for 5 and 10 MHz channels

Quoted 20 lines · Michal Sojka

Regulatory rules are applied to channels as if the channel is at least
20 MHz wide. This is a problem when dealing with 5 and 10 MHz channels
because side channels of a regulatory rule get disabled even when they
fall into rule's frequency range.

This problem was already fixed in commit 4edd56981c8fbb349b1529a2feaf772636eb1c83, but only for custom regulatory
domains provided by drivers. Here we fix it also for all other (e.g. user-supplied) regulatory domains.

Before that, similar commit was
reverted (e33e2241e272eddc38339692500bd1c7d8753a77) due to it allowing
running AP on channel 12 in the US regulatory domain. I have checked that this is not possible with this change:

Quoted 5 lines

? # iw reg set US
? # iw dev wlan0 interface add wlan0_ap??type __ap ? # iw dev wlan0_ap set channel 12
? command failed: Invalid argument (-22)

Applied, with some fixups to the commit message :)

johannes

#8 lore raw

PATCH v2 4/8 cfg80211: reg: Properly handle rules for 5 and 10 MHz channels

In reply to Michal Sojka
Quoted 5 lines · Michal Sojka

Regulatory rules are applied to channels as if the channel is at least 20 MHz wide. This is a problem when dealing with 5 and 10 MHz channels because side channels of a regulatory rule get disabled even when they fall into rule's frequency range.

Quoted 8 lines

This problem was already fixed in commit 4edd56981c8fbb349b1529a2feaf772636eb1c83, but only for custom regulatory domains provided by drivers. Here we fix it also for all other (e.g. user-supplied) regulatory domains.

Before that, similar commit was
reverted (e33e2241e272eddc38339692500bd1c7d8753a77) due to it allowing running AP on channel 12 in the US regulatory domain.

I'm afraid this new patch needs to be reverted as well since it allows active scanning on channel 12 in the US regulatory domain. I.e., every full scan with this commit included results in a Probe Request frame being sent on channel 12..

This 5 and 10 MHz channel case needs to be handled in a way that does not enable 20 MHz channels that go beyond the regdb rule. Channel 12 is 2457-2477 MHz and the regdb rule for US covers 2402-2472 MHz. This used to disable channel 12 correctly, but with this new change, that 5 MHz range going beyond the rule is not noticed and channel 12 gets included even with 20 MHz bandwidth.

Quoted 6 lines

I have checked that this is not possible with this change:

  # iw reg set US
  # iw dev wlan0 interface add wlan0_ap  type __ap
  # iw dev wlan0_ap set channel 12
  command failed: Invalid argument (-22)

That's not sufficient. Please take a look at a sniffer capture on what goes out when running
iw reg set US
iw dev wlan0 scan

Signature · 1 line
Jouni Malinen                                            PGP id EFC895FA
maintainer
#9 lore raw

PATCH v2 4/8 cfg80211: reg: Properly handle rules for 5 and 10 MHz channels

Quoted 21 lines · Jouni Malinen
Quoted 15 lines · Michal Sojka

Regulatory rules are applied to channels as if the channel is at least
20 MHz wide. This is a problem when dealing with 5 and 10 MHz channels
because side channels of a regulatory rule get disabled even when they
fall into rule's frequency range.

This problem was already fixed in commit 4edd56981c8fbb349b1529a2feaf772636eb1c83, but only for custom regulatory
domains provided by drivers. Here we fix it also for all other (e.g.
user-supplied) regulatory domains.

Quoted 4 lines

Before that, similar commit was
reverted (e33e2241e272eddc38339692500bd1c7d8753a77) due to it allowing
running AP on channel 12 in the US regulatory domain.

Quoted 5 lines

I'm afraid this new patch needs to be reverted as well since it allows active scanning on channel 12 in the US regulatory domain. I.e., every full scan with this commit included results in a Probe Request frame being sent on channel 12..

I've dropped it from my tree.

johannes

#10 lore raw

PATCH v2 5/8 cfg80211: Add support for OCB-only channels

In reply to Michal Sojka

We don't want channels designated for Intelligent Transportation Systems to be used in other modes than OCB. We therefore introduce regulatory and channel flags that prevent scanning (for performance reasons) and beaconing on these channels.

Although regulatory documents do not talk about which modes to use, we limit the mode to OCB in order to prevent accidental use of the band by other applications.

---
 include/net/cfg80211.h       |  2 ++
 include/uapi/linux/nl80211.h |  2 ++
 net/wireless/chan.c          |  6 ++++--
 net/wireless/ibss.c          | 12 ++++++++----
 net/wireless/mesh.c          |  3 ++-
 net/wireless/nl80211.c       | 12 ++++++------
 net/wireless/reg.c           |  2 ++
 net/wireless/scan.c          |  4 ++--
 net/wireless/sme.c           |  3 ++-
 net/wireless/wext-sme.c      |  3 ++-
 10 files changed, 32 insertions(+), 17 deletions(-)
include/net/cfg80211.h +2 -0
index 2c7bdb8..b47ac3e 100644
@@ -117,6 +117,7 @@ enum ieee80211_band {
  *	on this channel.
  * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted
  *	on this channel.
+ * @IEEE80211_CHAN_OCB_ONLY: only OCB mode is allowed on this channel.
  *
  */
 enum ieee80211_channel_flags {
@@ -133,6 +134,7 @@ enum ieee80211_channel_flags {
 	IEEE80211_CHAN_IR_CONCURRENT	= 1<<10,
 	IEEE80211_CHAN_NO_20MHZ		= 1<<11,
 	IEEE80211_CHAN_NO_10MHZ		= 1<<12,
+	IEEE80211_CHAN_OCB_ONLY		= 1<<13,
 };
 
 #define IEEE80211_CHAN_NO_HT40 \
include/uapi/linux/nl80211.h +2 -0
index 1f0b4cf..07e6105 100644
@@ -2865,6 +2865,7 @@ enum nl80211_sched_scan_match_attr {
  * @NL80211_RRF_NO_HT40PLUS: channels can't be used in HT40+ operation
  * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
  * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
+ * @NL80211_RRF_OCB_ONLY: only OCB mode can be used here
  */
 enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_OFDM		= 1<<0,
@@ -2882,6 +2883,7 @@ enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_HT40PLUS		= 1<<14,
 	NL80211_RRF_NO_80MHZ		= 1<<15,
 	NL80211_RRF_NO_160MHZ		= 1<<16,
+	NL80211_RRF_OCB_ONLY		= 1<<17,
 };
 
 #define NL80211_RRF_PASSIVE_SCAN	NL80211_RRF_NO_IR
net/wireless/chan.c +4 -2
index 59cabc9..b1ab77a 100644
@@ -804,7 +804,8 @@ static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy,
 {
 	bool res;
 	u32 prohibited_flags = IEEE80211_CHAN_DISABLED |
-			       IEEE80211_CHAN_RADAR;
+			       IEEE80211_CHAN_RADAR |
+			       IEEE80211_CHAN_OCB_ONLY;
 
 	trace_cfg80211_reg_can_beacon(wiphy, chandef, iftype, check_no_ir);
 
@@ -814,7 +815,8 @@ static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy,
 	if (cfg80211_chandef_dfs_required(wiphy, chandef, iftype) > 0 &&
 	    cfg80211_chandef_dfs_available(wiphy, chandef)) {
 		/* We can skip IEEE80211_CHAN_NO_IR if chandef dfs available */
-		prohibited_flags = IEEE80211_CHAN_DISABLED;
+		prohibited_flags = IEEE80211_CHAN_DISABLED |
+				   IEEE80211_CHAN_OCB_ONLY;
 	}
 
 	res = cfg80211_chandef_usable(wiphy, chandef, prohibited_flags);
net/wireless/ibss.c +8 -4
index 4c55fab..d9df7f0 100644
@@ -258,9 +258,9 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 
 			for (i = 0; i < sband->n_channels; i++) {
 				chan = &sband->channels[i];
-				if (chan->flags & IEEE80211_CHAN_NO_IR)
-					continue;
-				if (chan->flags & IEEE80211_CHAN_DISABLED)
+				if (chan->flags & IEEE80211_CHAN_NO_IR ||
+				    chan->flags & IEEE80211_CHAN_DISABLED ||
+				    chan->flags & IEEE80211_CHAN_OCB_ONLY)
 					continue;
 				new_chan = chan;
 				break;
@@ -277,6 +277,9 @@ int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
 					NL80211_CHAN_NO_HT);
 	}
 
+	if (wdev->wext.ibss.chandef.chan->flags & IEEE80211_CHAN_OCB_ONLY)
+		return -EINVAL;
+
 	/* don't join -- SSID is not there */
 	if (!wdev->wext.ibss.ssid_len)
 		return 0;
@@ -331,7 +334,8 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
 		if (!chan)
 			return -EINVAL;
 		if (chan->flags & IEEE80211_CHAN_NO_IR ||
-		    chan->flags & IEEE80211_CHAN_DISABLED)
+		    chan->flags & IEEE80211_CHAN_DISABLED ||
+		    chan->flags & IEEE80211_CHAN_OCB_ONLY)
 			return -EINVAL;
 	}
 
net/wireless/mesh.c +2 -1
index 092300b..99866ff 100644
@@ -143,7 +143,8 @@ int __cfg80211_join_mesh(struct cfg80211_registered_device *rdev,
 				chan = &sband->channels[i];
 				if (chan->flags & (IEEE80211_CHAN_NO_IR |
 						   IEEE80211_CHAN_DISABLED |
-						   IEEE80211_CHAN_RADAR))
+						   IEEE80211_CHAN_RADAR |
+						   IEEE80211_CHAN_OCB_ONLY))
 					continue;
 				setup->chandef.chan = chan;
 				break;
net/wireless/nl80211.c +6 -6
index c71e274..85b1df6 100644
@@ -5860,8 +5860,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 				goto out_free;
 			}
 
-			/* ignore disabled channels */
-			if (chan->flags & IEEE80211_CHAN_DISABLED)
+			/* ignore disabled and OCB-only channels */
+			if (chan->flags & (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_OCB_ONLY))
 				continue;
 
 			request->channels[i] = chan;
@@ -5880,7 +5880,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
 
 				chan = &wiphy->bands[band]->channels[j];
 
-				if (chan->flags & IEEE80211_CHAN_DISABLED)
+				if (chan->flags & (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_OCB_ONLY))
 					continue;
 
 				request->channels[i] = chan;
@@ -6247,8 +6247,8 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
 				goto out_free;
 			}
 
-			/* ignore disabled channels */
-			if (chan->flags & IEEE80211_CHAN_DISABLED)
+			/* ignore disabled and OCB-only channels */
+			if (chan->flags & (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_OCB_ONLY))
 				continue;
 
 			request->channels[i] = chan;
@@ -6265,7 +6265,7 @@ nl80211_parse_sched_scan(struct wiphy *wiphy, struct wireless_dev *wdev,
 
 				chan = &wiphy->bands[band]->channels[j];
 
-				if (chan->flags & IEEE80211_CHAN_DISABLED)
+				if (chan->flags & (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_OCB_ONLY))
 					continue;
 
 				request->channels[i] = chan;
net/wireless/reg.c +2 -0
index 35eaeeb..8b7110d 100644
@@ -1048,6 +1048,8 @@ static u32 map_regdom_flags(u32 rd_flags)
 		channel_flags |= IEEE80211_CHAN_NO_80MHZ;
 	if (rd_flags & NL80211_RRF_NO_160MHZ)
 		channel_flags |= IEEE80211_CHAN_NO_160MHZ;
+	if (rd_flags & NL80211_RRF_OCB_ONLY)
+		channel_flags |= IEEE80211_CHAN_OCB_ONLY;
 	return channel_flags;
 }
 
net/wireless/scan.c +2 -2
index 14d5369..67e4515 100644
@@ -1236,9 +1236,9 @@ int cfg80211_wext_siwscan(struct net_device *dev,
 			continue;
 
 		for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
-			/* ignore disabled channels */
+			/* ignore disabled and OCB-only channels */
 			if (wiphy->bands[band]->channels[j].flags &
-						IEEE80211_CHAN_DISABLED)
+			    (IEEE80211_CHAN_DISABLED | IEEE80211_CHAN_OCB_ONLY))
 				continue;
 
 			/* If we have a wireless request structure and the
net/wireless/sme.c +2 -1
index 8020b5b..817c879 100644
@@ -103,7 +103,8 @@ static int cfg80211_conn_scan(struct wireless_dev *wdev)
 				continue;
 			for (j = 0; j < bands->n_channels; j++) {
 				channel = &bands->channels[j];
-				if (channel->flags & IEEE80211_CHAN_DISABLED)
+				if (channel->flags & IEEE80211_CHAN_DISABLED ||
+				    channel->flags & IEEE80211_CHAN_OCB_ONLY)
 					continue;
 				request->channels[i++] = channel;
 			}
net/wireless/wext-sme.c +2 -1
index a4e8af3..34a50c1 100644
@@ -83,7 +83,8 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
 		chan = ieee80211_get_channel(wdev->wiphy, freq);
 		if (!chan)
 			return -EINVAL;
-		if (chan->flags & IEEE80211_CHAN_DISABLED)
+		if (chan->flags & IEEE80211_CHAN_DISABLED ||
+		    chan->flags & IEEE80211_CHAN_OCB_ONLY)
 			return -EINVAL;
 	}
 
Signature · 1 line
2.5.3
maintainer
#11 lore raw

PATCH v2 5/8 cfg80211: Add support for OCB-only channels

net/wireless/chan.c

Quoted 13 lines · Michal Sojka

?#define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR

net/wireless/chan.c +0 -0
index 59cabc9..b1ab77a 100644
@@ -804,7 +804,8 @@ static bool _cfg80211_reg_can_beacon(struct wiphy
 *wiphy,
 ?{
 ?	bool res;

? u32 prohibited_flags = IEEE80211_CHAN_DISABLED |

net/wireless/chan.c +2 -1
-			???????IEEE80211_CHAN_RADAR;
+			???????IEEE80211_CHAN_RADAR |
+			???????IEEE80211_CHAN_OCB_ONLY;

So ... for the kernel, I don't *like* this approach, because it requires touching every single driver, and every single person who writes code in the future must be aware of the special handling for this flag.

For userspace, however, this approach is simply impossible. Consider an older version of wpa_supplicant, that queries the channel list and isn't aware of the OCB_ONLY flag. This version would take the channel list and build a scan request with it, only to get the scan rejected since some channels it picked were only usable for OCB, as far as I can tell.

I think the solution to this would be to redefine the CHAN_DISABLED flag to mean "channel disabled for non-ocb mode" and add a CHAN_OCB_ENABLED flag.

Then code that knows about OCB would simply not test CHAN_DISABLED, but would instead test CHAN_OCB_ENABLED instead - and if that's clear OCB would not be permitted.

However, this would have the side effect of enabling OCB *only* on OCB channels, which might not be a good idea, for testing purposes one might want to use the regular 2.4 or 5 GHz channels? If so, OCB could still be made to do something like

	ocb_usable = (flags & OCB_ENABLED) || !(flags & DISABLED);

or we could even make the channel list internally maintain a CHAN_OCB_USABLE flag that essentially encodes the logic above.

In any case, this would collapse the patch down to modifying only OCB code and nothing else, which is nice, and would keep existing userspace working since it would just see disabled channels while ignoring the OCB flag.

johannes

#12 lore raw

PATCH v2 5/8 cfg80211: Add support for OCB-only channels

Quoted 43 lines · Johannes Berg

net/wireless/chan.c static bool _cfg80211_reg_can_beacon(struct wiphy *wiphy, · line 808

Quoted 13 lines · Michal Sojka

 #define NL80211_RRF_PASSIVE_SCAN NL80211_RRF_NO_IR

net/wireless/chan.c +0 -0
index 59cabc9..b1ab77a 100644
@@ -804,7 +804,8 @@ static bool _cfg80211_reg_can_beacon(struct wiphy
 *wiphy,
  {
  	bool res;

  u32 prohibited_flags = IEEE80211_CHAN_DISABLED |

net/wireless/chan.c +2 -1
-			       IEEE80211_CHAN_RADAR;
+			       IEEE80211_CHAN_RADAR |
+			       IEEE80211_CHAN_OCB_ONLY;

So ... for the kernel, I don't *like* this approach, because it requires touching every single driver, and every single person who writes code in the future must be aware of the special handling for this flag.

For userspace, however, this approach is simply impossible. Consider an older version of wpa_supplicant, that queries the channel list and isn't aware of the OCB_ONLY flag. This version would take the channel list and build a scan request with it, only to get the scan rejected since some channels it picked were only usable for OCB, as far as I can tell.

I think the solution to this would be to redefine the CHAN_DISABLED flag to mean "channel disabled for non-ocb mode" and add a CHAN_OCB_ENABLED flag.

Then code that knows about OCB would simply not test CHAN_DISABLED, but would instead test CHAN_OCB_ENABLED instead - and if that's clear OCB would not be permitted.

However, this would have the side effect of enabling OCB *only* on OCB channels, which might not be a good idea, for testing purposes one might want to use the regular 2.4 or 5 GHz channels? If so, OCB could still be made to do something like

	ocb_usable = (flags & OCB_ENABLED) || !(flags & DISABLED);
Quoted 7 lines

or we could even make the channel list internally maintain a CHAN_OCB_USABLE flag that essentially encodes the logic above.

In any case, this would collapse the patch down to modifying only OCB code and nothing else, which is nice, and would keep existing userspace working since it would just see disabled channels while ignoring the OCB flag.

Yes, this makes perfect sense. I'll rework the patch.

-Michal

#13 lore raw

PATCH v2 6/8 cfg80211: reg: Add NL80211_RRF_USER_REGD_NEEDED flag

In reply to Michal Sojka

In order to prevent accidental use of Intelligent Transportation System band (5.9 GHz), we require system integrators to provide custom userspace regulatory database enabling the use of the band. However, drivers that provide their own regulatory database (such as ath9k) would not enable that band in this case, because they do not allow using other bands than those specified in their database.

The NL80211_RRF_USER_REGD_NEEDED flag introduced in this commit allows drivers to specify that certain band is enabled only if it is additionally enabled in user-supplied regulatory database. If the band is not present there, the channels are simply disabled.

---
 include/net/cfg80211.h       |  3 +++
 include/uapi/linux/nl80211.h |  4 ++++
 net/wireless/reg.c           | 15 +++++++++++++++
 3 files changed, 22 insertions(+)
include/net/cfg80211.h +3 -0
index b47ac3e..75026d3 100644
@@ -118,6 +118,8 @@ enum ieee80211_band {
  * @IEEE80211_CHAN_NO_10MHZ: 10 MHz bandwidth is not permitted
  *	on this channel.
  * @IEEE80211_CHAN_OCB_ONLY: only OCB mode is allowed on this channel.
+ * @IEEE80211_CHAN_USER_REGD_NEEDED: can only be used if allowed by
+ *	user-supplied regulatory domain.
  *
  */
 enum ieee80211_channel_flags {
@@ -135,6 +137,7 @@ enum ieee80211_channel_flags {
 	IEEE80211_CHAN_NO_20MHZ		= 1<<11,
 	IEEE80211_CHAN_NO_10MHZ		= 1<<12,
 	IEEE80211_CHAN_OCB_ONLY		= 1<<13,
+	IEEE80211_CHAN_USER_REGD_NEEDED	= 1<<14,
 };
 
 #define IEEE80211_CHAN_NO_HT40 \
include/uapi/linux/nl80211.h +4 -0
index 07e6105..ae17589 100644
@@ -2866,6 +2866,9 @@ enum nl80211_sched_scan_match_attr {
  * @NL80211_RRF_NO_80MHZ: 80MHz operation not allowed
  * @NL80211_RRF_NO_160MHZ: 160MHz operation not allowed
  * @NL80211_RRF_OCB_ONLY: only OCB mode can be used here
+ * @NL80211_RRF_USER_REGD_NEEDED: when specified in driver's
+ *	CUSTOM_REG regulatory domain, the band can only be used if it
+ *	is also allowed in user-supplied regulatory domain.
  */
 enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_OFDM		= 1<<0,
@@ -2884,6 +2887,7 @@ enum nl80211_reg_rule_flags {
 	NL80211_RRF_NO_80MHZ		= 1<<15,
 	NL80211_RRF_NO_160MHZ		= 1<<16,
 	NL80211_RRF_OCB_ONLY		= 1<<17,
+	NL80211_RRF_USER_REGD_NEEDED	= 1<<18,
 };
 
 #define NL80211_RRF_PASSIVE_SCAN	NL80211_RRF_NO_IR
net/wireless/reg.c +15 -0
index 8b7110d..9d9d826 100644
@@ -1050,6 +1050,8 @@ static u32 map_regdom_flags(u32 rd_flags)
 		channel_flags |= IEEE80211_CHAN_NO_160MHZ;
 	if (rd_flags & NL80211_RRF_OCB_ONLY)
 		channel_flags |= IEEE80211_CHAN_OCB_ONLY;
+	if (rd_flags & NL80211_RRF_USER_REGD_NEEDED)
+		channel_flags |= IEEE80211_CHAN_USER_REGD_NEEDED;
 	return channel_flags;
 }
 
@@ -1280,6 +1282,16 @@ static void handle_channel(struct wiphy *wiphy,
 		return;
 	}
 
+	if (lr->initiator == NL80211_REGDOM_SET_BY_USER &&
+	    flags & IEEE80211_CHAN_USER_REGD_NEEDED) {
+		/* The driver allows using this frequency only if it
+		 * is allowed in user-supplied regulatory domain,
+		 * which is the case here. This is the only place
+		 * where a disabled channel can be enabled again.
+		 */
+		flags &= ~IEEE80211_CHAN_DISABLED;
+	}
+
 	chan->dfs_state = NL80211_DFS_USABLE;
 	chan->dfs_state_entered = jiffies;
 
@@ -1798,6 +1810,9 @@ static void handle_channel_custom(struct wiphy *wiphy,
 
 	chan->beacon_found = false;
 
+	if (reg_rule->flags & NL80211_RRF_USER_REGD_NEEDED)
+		chan->flags |= IEEE80211_CHAN_DISABLED;
+
 	if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED)
 		chan->flags = chan->orig_flags | bw_flags |
 			      map_regdom_flags(reg_rule->flags);
Signature · 1 line
2.5.3
maintainer
#14 lore raw

PATCH v2 6/8 cfg80211: reg: Add NL80211_RRF_USER_REGD_NEEDED flag

Quoted 7 lines · Michal Sojka

?
The NL80211_RRF_USER_REGD_NEEDED flag introduced in this commit allows
drivers to specify that certain band is enabled only if it is additionally enabled in user-supplied regulatory database. If the band
is not present there, the channels are simply disabled.

I can see why you'd want this flag internally (although it'll require rework given the comments on the previous patch) - but is there a reason to export it in nl80211? Then again, perhaps it *would* be good to show this information in userspace?

johannes

#15 lore raw

PATCH v2 6/8 cfg80211: reg: Add NL80211_RRF_USER_REGD_NEEDED flag

Quoted 9 lines · Johannes Berg
Quoted 7 lines · Michal Sojka


The NL80211_RRF_USER_REGD_NEEDED flag introduced in this commit allows
drivers to specify that certain band is enabled only if it is additionally enabled in user-supplied regulatory database. If the band
is not present there, the channels are simply disabled.

Quoted 3 lines

I can see why you'd want this flag internally (although it'll require rework given the comments on the previous patch) - but is there a reason to export it in nl80211?

I don't see any reason either. Only all regulatory rule flags (nl80211_reg_rule_flags) happen to be "exported". Shall I add new field (e.g. internal_flags) to struct ieee80211_reg_rule and define new enum for it?

Quoted 2 lines

Then again, perhaps it *would* be good to show this information in userspace?

What do you mean by "show"? nl80211_put_regdom() already sends regdom flags to userspace. Or do you mean introducing a new channel attribute and send it in nl80211_msg_put_channel()?

-Michal

maintainer
#16 lore raw

PATCH v2 6/8 cfg80211: reg: Add NL80211_RRF_USER_REGD_NEEDED flag

Quoted 4 lines · Michal Sojka

What do you mean by "show"? nl80211_put_regdom() already sends regdom flags to userspace. Or do you mean introducing a new channel attribute and send it in nl80211_msg_put_channel()?

No, I meant keeping the flag - so that people can know with "iw list" or something that they need a special regdomain to enable the channels?

johannes

#17 lore raw

PATCH v2 7/8 cfg80211: Add Kconfig option for ITS-G5 band (5.9 GHz)

In reply to Michal Sojka

This option is meant for use by drivers and other subsystems to enable support for the Intelligent Transportation System (ITS-G5) band. The option depends on CFG80211_CERTIFICATION_ONUS as the use of this band is restricted. EU allows using it only for certain applications, USA require certification.

---
 net/wireless/Kconfig | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
net/wireless/Kconfig +27 -0
index da72ed3..faa0ab1 100644
@@ -132,6 +132,33 @@ config CFG80211_REG_RELAX_NO_IR
 	 support this feature by declaring the appropriate channel flags and
 	 capabilities in their registration flow.
 
+config CFG80211_REG_ITSG5_BAND
+	bool "cfg80211 support for ITS-G5 band (5.9 GHz)"
+	def_bool n
+	depends on CFG80211_CERTIFICATION_ONUS
+	---help---
+	This option enables support for Inteligent Transportation System (ITS)
+	band i.e. frequencies from 5.850 to 5.925 GHz. In Europe, the band is
+	standardized in the ETSI EN 302 663 standard. The use of this band is
+	restricted by regulatory documents mentioned below. Enable this option
+	only if you comply with them.
+
+	In Europe, the band is split into several sub-bands regulated by
+	separate documents:
+
+	- ITS-G5A (5.875 to 5.905 GHz) band is reserved for ITS road safety
+	  related applications and is regulated by Commission Decision
+	  2008/671/EC.
+
+	- ITS-G5B (5.855 to 5.875 GHz) band is reserved for ITS non-safety
+	  applications and is regulated by ECC Recommendation ECC/REC/(08)01.
+
+	- ITS-G5D (5.905 to 5.925 GHz) band is reserved for future ITS
+	  applications and is regulated by ECC Decision ECC/DEC(02)01.
+
+	In the US, the band is regulated by FCC 03-324 and the devices using it
+	must be certified.
+
 config CFG80211_DEFAULT_PS
 	bool "enable powersave by default"
 	depends on CFG80211
Signature · 1 line
2.5.3
maintainer
#18 lore raw

PATCH v2 7/8 cfg80211: Add Kconfig option for ITS-G5 band (5.9 GHz)

Quoted 7 lines · Michal Sojka

This option is meant for use by drivers and other subsystems to enable
support for the Intelligent Transportation System (ITS-G5) band. The option depends on CFG80211_CERTIFICATION_ONUS as the use of this band is
restricted. EU allows using it only for certain applications, USA require certification.

Hm. Why do we need this now? I see that you're checking it in ath9k, to enable the "ITSG5" channels, but why wouldn't you always do that, now that you have the extra checks with the user regdb being required and all?

johannes

#19 lore raw

PATCH v2 7/8 cfg80211: Add Kconfig option for ITS-G5 band (5.9 GHz)

Quoted 9 lines · Johannes Berg
Quoted 7 lines · Michal Sojka

This option is meant for use by drivers and other subsystems to enable
support for the Intelligent Transportation System (ITS-G5) band. The option depends on CFG80211_CERTIFICATION_ONUS as the use of this band is
restricted. EU allows using it only for certain applications, USA require certification.

Quoted 4 lines

Hm. Why do we need this now? I see that you're checking it in ath9k, to enable the "ITSG5" channels, but why wouldn't you always do that, now that you have the extra checks with the user regdb being required and all?

Because in [1] Jouni said that

"kernel config option + custom regdb would certainly be much closer to what I'd like to see from the regulatory enforcement view point"

I also like the fact that the help text mentions the relevant regulatory documents. I guess the users would appreciate that.

-Michal

[1] http://www.mail-archive.com/[email protected]/msg13795.html

maintainer
#20 lore raw

PATCH v2 7/8 cfg80211: Add Kconfig option for ITS-G5 band (5.9 GHz)

Quoted 10 lines · Michal Sojka

?
Because in [1] Jouni said that

???"kernel config option + custom regdb would certainly be much closer to what I'd like to see from the regulatory enforcement view point"

I also like the fact that the help text mentions the relevant regulatory documents. I guess the users would appreciate that.

Fair enough, but I'm not really convinced that the Kconfig option is needed for what Jouni really required.

In any case, I spoke with him yesterday and we don't think that your patches are going to work as is - we'll need to change the regulatory flags it seems. I'll comment more specifically on the patches.

johannes

#21 lore raw

PATCH v2 7/8 cfg80211: Add Kconfig option for ITS-G5 band (5.9 GHz)

Quoted 12 lines · Johannes Berg
Quoted 10 lines · Michal Sojka


Because in [1] Jouni said that

   "kernel config option + custom regdb would certainly be much closer to what I'd like to see from the regulatory enforcement view point"

I also like the fact that the help text mentions the relevant regulatory documents. I guess the users would appreciate that.

Quoted 6 lines

Fair enough, but I'm not really convinced that the Kconfig option is needed for what Jouni really required.

In any case, I spoke with him yesterday and we don't think that your patches are going to work as is - we'll need to change the regulatory flags it seems. I'll comment more specifically on the patches.

OK. I'll wait for that.

-Michal

#22 lore raw

PATCH v2 8/8 ath9k: Add support for ITS-G5 band (5.9 GHz)

In reply to Michal Sojka

The patch adds support for Intelligent Transportation System (ITS-G5) band to the ath9k driver. The corresponding channels are allowed only if CONFIG_CFG80211_REG_ITSG5_BAND is set and if the user provides custom regulatory database. In addition, the band is limited to OCB mode.

---
 drivers/net/wireless/ath/ath9k/common-init.c | 19 +++++++++++++++++++
 drivers/net/wireless/ath/ath9k/hw.h          |  2 +-
 drivers/net/wireless/ath/regd.c              | 23 ++++++++++++++++++-----
 3 files changed, 38 insertions(+), 6 deletions(-)
drivers/net/wireless/ath/ath9k/common-init.c +19 -0
index a006c14..0b61c63 100644
@@ -86,6 +86,25 @@ static const struct ieee80211_channel ath9k_5ghz_chantable[] = {
 	CHAN5G(5785, 35), /* Channel 157 */
 	CHAN5G(5805, 36), /* Channel 161 */
 	CHAN5G(5825, 37), /* Channel 165 */
+
+	/* ITS-G5B */
+	CHAN5G(5855, 38), /* Channel 171 */
+	CHAN5G(5860, 39), /* Channel 172 */
+	CHAN5G(5865, 40), /* Channel 173 */
+	CHAN5G(5870, 41), /* Channel 174 */
+	/* ITS-G5A */
+	CHAN5G(5875, 42), /* Channel 175 */
+	CHAN5G(5880, 43), /* Channel 176 */
+	CHAN5G(5885, 44), /* Channel 177 */
+	CHAN5G(5890, 45), /* Channel 178 */
+	CHAN5G(5895, 46), /* Channel 179 */
+	CHAN5G(5900, 47), /* Channel 180 */
+	CHAN5G(5905, 48), /* Channel 181 */
+	/* ITS-G5D */
+	CHAN5G(5910, 49), /* Channel 182 */
+	CHAN5G(5915, 50), /* Channel 183 */
+	CHAN5G(5920, 51), /* Channel 184 */
+	CHAN5G(5925, 52), /* Channel 185 */
 };
 
 /* Atheros hardware rate code addition for short premble */
drivers/net/wireless/ath/ath9k/hw.h +1 -1
index 831a544..cb126ff 100644
@@ -73,7 +73,7 @@
 
 #define ATH9K_RSSI_BAD			-128
 
-#define ATH9K_NUM_CHANNELS	38
+#define ATH9K_NUM_CHANNELS	53
 
 /* Register read/write primitives */
 #define REG_WRITE(_ah, _reg, _val) \
drivers/net/wireless/ath/regd.c +18 -5
index 06ea6cc..38706ff 100644
@@ -50,6 +50,14 @@ static int __ath_regd_init(struct ath_regulatory *reg);
 #define ATH9K_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 80, 0, 30,\
 					 NL80211_RRF_NO_IR)
 
+#ifdef CONFIG_CFG80211_REG_ITSG5_BAND
+#define ATH9K_5GHZ_ITSG5	REG_RULE(5850, 5925, 10, 0, 33, \
+					 NL80211_RRF_USER_REGD_NEEDED | \
+					 NL80211_RRF_OCB_ONLY)
+#else
+#define ATH9K_5GHZ_ITSG5	{} /* Empty rule does not match any channel */
+#endif
+
 #define ATH9K_2GHZ_ALL		ATH9K_2GHZ_CH01_11, \
 				ATH9K_2GHZ_CH12_13, \
 				ATH9K_2GHZ_CH14
@@ -64,53 +72,58 @@ static int __ath_regd_init(struct ath_regulatory *reg);
 /* Can be used for:
  * 0x60, 0x61, 0x62 */
 static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
-	.n_reg_rules = 5,
+	.n_reg_rules = 6,
 	.alpha2 =  "99",
 	.reg_rules = {
 		ATH9K_2GHZ_ALL,
 		ATH9K_5GHZ_ALL,
+		ATH9K_5GHZ_ITSG5,
 	}
 };
 
 /* Can be used by 0x63 and 0x65 */
 static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
-	.n_reg_rules = 4,
+	.n_reg_rules = 5,
 	.alpha2 =  "99",
 	.reg_rules = {
 		ATH9K_2GHZ_CH01_11,
 		ATH9K_2GHZ_CH12_13,
 		ATH9K_5GHZ_NO_MIDBAND,
+		ATH9K_5GHZ_ITSG5,
 	}
 };
 
 /* Can be used by 0x64 only */
 static const struct ieee80211_regdomain ath_world_regdom_64 = {
-	.n_reg_rules = 3,
+	.n_reg_rules = 4,
 	.alpha2 =  "99",
 	.reg_rules = {
 		ATH9K_2GHZ_CH01_11,
 		ATH9K_5GHZ_NO_MIDBAND,
+		ATH9K_5GHZ_ITSG5,
 	}
 };
 
 /* Can be used by 0x66 and 0x69 */
 static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
-	.n_reg_rules = 3,
+	.n_reg_rules = 4,
 	.alpha2 =  "99",
 	.reg_rules = {
 		ATH9K_2GHZ_CH01_11,
 		ATH9K_5GHZ_ALL,
+		ATH9K_5GHZ_ITSG5,
 	}
 };
 
 /* 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,
+	.n_reg_rules = 5,
 	.alpha2 =  "99",
 	.reg_rules = {
 		ATH9K_2GHZ_CH01_11,
 		ATH9K_2GHZ_CH12_13,
 		ATH9K_5GHZ_ALL,
+		ATH9K_5GHZ_ITSG5,
 	}
 };
 
Signature · 1 line
2.5.3