2013-11-25 19:56:22

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH v3 1/4] cfg80211: add reg_get_dfs_region()

From: "Luis R. Rodriguez" <[email protected]>

This can be used outside of the regulatory context for any checks
on the DFS region. The central cfg80211 dfs_region is always used
and if it does not match with the wiphy a debug print is issued.

Signed-off-by: Luis R. Rodriguez <[email protected]>
---
net/wireless/reg.c | 27 +++++++++++++++++++++++++++
net/wireless/reg.h | 1 +
2 files changed, 28 insertions(+)

diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index ec54e1a..7d20d84 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -135,6 +135,33 @@ static const char *reg_dfs_region_str(enum nl80211_dfs_regions dfs_region)
return "Unknown";
}

+enum nl80211_dfs_regions reg_get_dfs_region(struct wiphy *wiphy)
+{
+ const struct ieee80211_regdomain *regd = NULL;
+ const struct ieee80211_regdomain *wiphy_regd = NULL;
+
+ regd = get_cfg80211_regdom();
+ if (!wiphy)
+ goto out;
+
+ wiphy_regd = get_wiphy_regdom(wiphy);
+ if (!wiphy_regd)
+ goto out;
+
+ if (wiphy_regd->dfs_region == regd->dfs_region)
+ goto out;
+
+ REG_DBG_PRINT("%s: device specific dfs_region "
+ "(%s) disagrees with cfg80211's "
+ "central dfs_region (%s)\n",
+ dev_name(&wiphy->dev),
+ reg_dfs_region_str(wiphy_regd->dfs_region),
+ reg_dfs_region_str(regd->dfs_region));
+
+out:
+ return regd->dfs_region;
+}
+
static void rcu_free_regdom(const struct ieee80211_regdomain *r)
{
if (!r)
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index cc4c2c0..02bd8f4 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -21,6 +21,7 @@ extern const struct ieee80211_regdomain __rcu *cfg80211_regdomain;
bool reg_is_valid_request(const char *alpha2);
bool is_world_regdom(const char *alpha2);
bool reg_supported_dfs_region(enum nl80211_dfs_regions dfs_region);
+enum nl80211_dfs_regions reg_get_dfs_region(struct wiphy *wiphy);

int regulatory_hint_user(const char *alpha2,
enum nl80211_user_reg_hint_type user_reg_hint_type);
--
1.7.9.5



2013-11-26 20:19:59

by Janusz Dziedzic

[permalink] [raw]
Subject: Re: [PATCH v3 4/4] cfg80211: DFS use 10 minutes CAC when weather channels

2013/11/26 Simon Wunderlich <[email protected]>:
>
>> When nominal bandwidth falls completely or partly
>> within the band 5600MHz to 5650MHz the CAC time shall
>> be 10 minutes.
>> This is ETSI requirement. FCC forbids weather channels usage.
>
> Although it is correct to handle that with longer times and all, I don't think
> we should enable weather channels at all, not even for ETSI. Unlike "normal"
> channels, it requires 99.99% detection rate in CAC, which is (I think)
> practically impossible.
>
> I guess we need ath9k (or other drivers, maybe ath10k too) to disallow CAC on
> these channels, if we know that the drivers can do it? Although I don't think
> it's technically possible ...
>
ath.ko already disable weather channels by default.
But in case driver will pass DFS certification (meet all requirements)
- why not use weather channels?

BR
Janusz

2013-11-26 14:50:18

by Simon Wunderlich

[permalink] [raw]
Subject: Re: [PATCH v3 4/4] cfg80211: DFS use 10 minutes CAC when weather channels


> When nominal bandwidth falls completely or partly
> within the band 5600MHz to 5650MHz the CAC time shall
> be 10 minutes.
> This is ETSI requirement. FCC forbids weather channels usage.

Although it is correct to handle that with longer times and all, I don't think
we should enable weather channels at all, not even for ETSI. Unlike "normal"
channels, it requires 99.99% detection rate in CAC, which is (I think)
practically impossible.

I guess we need ath9k (or other drivers, maybe ath10k too) to disallow CAC on
these channels, if we know that the drivers can do it? Although I don't think
it's technically possible ...

Cheers,
Simon

2013-11-25 19:56:23

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH v3 2/4] cfg80211: DFS check dfs_region before usage

From: "Luis R. Rodriguez" <[email protected]>

Check the DFS region before channel availability check.

Signed-off-by: Luis R. Rodriguez <[email protected]>
Signed-off-by: Janusz Dziedzic <[email protected]>
---
net/wireless/nl80211.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 70290f8..81579ae 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5650,8 +5650,13 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
struct net_device *dev = info->user_ptr[1];
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_chan_def chandef;
+ enum nl80211_dfs_regions dfs_region;
int err;

+ dfs_region = reg_get_dfs_region(wdev->wiphy);
+ if (dfs_region == NL80211_DFS_UNSET)
+ return -EINVAL;
+
err = nl80211_parse_chandef(rdev, info, &chandef);
if (err)
return err;
--
1.7.9.5


2013-11-26 20:39:23

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 4/4] cfg80211: DFS use 10 minutes CAC when weather channels

On Tue, 2013-11-26 at 21:19 +0100, Janusz Dziedzic wrote:

> ath.ko already disable weather channels by default.
> But in case driver will pass DFS certification (meet all requirements)
> - why not use weather channels?

Since I'm a lazy bastard - can you demonstrate such a driver? I'm
guessing not (immediately), so I'll drop your patches for now - maybe
better to go back to the drawing board and get all of this into regdb
etc. Doesn't seem critical to get it into the kernel now, if nobody
really supports it anyway ...

johannes


2013-11-25 19:56:24

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH v3 3/4] cfg80211/mac80211: DFS pass CAC time as a parameter

Send Channel Availability Check time as a parameter
of start_radar_detection() callback.
We could have different CAC time configuration for
Off-channel CAC and for weather channels.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
include/net/cfg80211.h | 3 ++-
net/mac80211/cfg.c | 8 ++++----
net/wireless/nl80211.c | 3 ++-
3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 6c2bc32..ce6bf12 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2434,7 +2434,8 @@ struct cfg80211_ops {

int (*start_radar_detection)(struct wiphy *wiphy,
struct net_device *dev,
- struct cfg80211_chan_def *chandef);
+ struct cfg80211_chan_def *chandef,
+ u32 cac_time_ms);
int (*update_ft_ies)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_update_ft_ies_params *ftie);
int (*crit_proto_start)(struct wiphy *wiphy,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 267d3ac..5d69538 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2893,11 +2893,11 @@ static int ieee80211_cancel_remain_on_channel(struct wiphy *wiphy,

static int ieee80211_start_radar_detection(struct wiphy *wiphy,
struct net_device *dev,
- struct cfg80211_chan_def *chandef)
+ struct cfg80211_chan_def *chandef,
+ u32 cac_time_ms)
{
struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
struct ieee80211_local *local = sdata->local;
- unsigned long timeout;
int err;

if (!list_empty(&local->roc_list) || local->scanning)
@@ -2915,9 +2915,9 @@ static int ieee80211_start_radar_detection(struct wiphy *wiphy,
if (err)
return err;

- timeout = msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
ieee80211_queue_delayed_work(&sdata->local->hw,
- &sdata->dfs_cac_timer_work, timeout);
+ &sdata->dfs_cac_timer_work,
+ msecs_to_jiffies(cac_time_ms));

return 0;
}
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 81579ae..b705640 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5686,7 +5686,8 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
if (err)
return err;

- err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
+ err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef,
+ IEEE80211_DFS_MIN_CAC_TIME_MS);
if (!err) {
wdev->channel = chandef.chan;
wdev->cac_started = true;
--
1.7.9.5


2013-11-25 19:56:26

by Janusz Dziedzic

[permalink] [raw]
Subject: [PATCH v3 4/4] cfg80211: DFS use 10 minutes CAC when weather channels

When nominal bandwidth falls completely or partly
within the band 5600MHz to 5650MHz the CAC time shall
be 10 minutes.
This is ETSI requirement. FCC forbids weather channels usage.

Signed-off-by: Janusz Dziedzic <[email protected]>
---
include/net/cfg80211.h | 7 ++++-
net/wireless/chan.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
net/wireless/core.h | 4 +++
net/wireless/mlme.c | 2 +-
net/wireless/nl80211.c | 7 ++++-
5 files changed, 91 insertions(+), 3 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ce6bf12..027c907 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -125,9 +125,12 @@ enum ieee80211_channel_flags {
#define IEEE80211_CHAN_NO_HT40 \
(IEEE80211_CHAN_NO_HT40PLUS | IEEE80211_CHAN_NO_HT40MINUS)

-#define IEEE80211_DFS_MIN_CAC_TIME_MS 60000
+#define IEEE80211_DFS_MIN_CAC_TIME_MS (60 * 1000)
#define IEEE80211_DFS_MIN_NOP_TIME_MS (30 * 60 * 1000)

+/* ETSI EN 301 893 V1.7.0 - Table D.1 */
+#define IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS (10 * 60 * 1000)
+
/**
* struct ieee80211_channel - channel definition
*
@@ -3061,6 +3064,7 @@ struct cfg80211_cached_keys;
* @p2p_started: true if this is a P2P Device that has been started
* @cac_started: true if DFS channel availability check has been started
* @cac_start_time: timestamp (jiffies) when the dfs state was entered.
+ * @cac_time_ms: CAC time in ms
* @ps: powersave mode is enabled
* @ps_timeout: dynamic powersave timeout
* @ap_unexpected_nlportid: (private) netlink port ID of application
@@ -3118,6 +3122,7 @@ struct wireless_dev {

bool cac_started;
unsigned long cac_start_time;
+ unsigned int cac_time_ms;

#ifdef CONFIG_CFG80211_WEXT
/* wext data */
diff --git a/net/wireless/chan.c b/net/wireless/chan.c
index 78559b5..680f469 100644
--- a/net/wireless/chan.c
+++ b/net/wireless/chan.c
@@ -490,6 +490,80 @@ static bool cfg80211_chandef_dfs_available(struct wiphy *wiphy,
return r;
}

+static int cfg80211_get_chans_dfs_is_weather(struct wiphy *wiphy,
+ u32 center_freq,
+ u32 bandwidth)
+{
+ struct ieee80211_channel *c;
+ u32 start_freq, end_freq, freq;
+
+ start_freq = cfg80211_get_start_freq(center_freq, bandwidth);
+ end_freq = cfg80211_get_end_freq(center_freq, bandwidth);
+
+ /*
+ * ETSI EN 301 893 V1.7.0 Table D.1
+ * 5600 - 5650MHz - weather radar channels
+ */
+ for (freq = start_freq; freq <= end_freq; freq += 20) {
+ c = ieee80211_get_channel(wiphy, freq);
+ if (!c)
+ return -EINVAL;
+ if (c->center_freq >= 5600 && c->center_freq <= 5650)
+ return 1;
+ }
+ return 0;
+}
+
+static int
+cfg80211_chandef_dfs_is_weather(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef)
+{
+ int width;
+ int r;
+
+ if (WARN_ON(!cfg80211_chandef_valid(chandef)))
+ return -EINVAL;
+
+ width = cfg80211_chandef_get_width(chandef);
+ if (width < 0)
+ return -EINVAL;
+
+ r = cfg80211_get_chans_dfs_is_weather(wiphy, chandef->center_freq1,
+ width);
+
+ if (r)
+ return r;
+
+ if (!chandef->center_freq2)
+ return 0;
+
+ return cfg80211_get_chans_dfs_is_weather(wiphy, chandef->center_freq2,
+ width);
+}
+
+unsigned int
+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_dfs_regions dfs_region)
+{
+ unsigned int timeout_ms = IEEE80211_DFS_MIN_CAC_TIME_MS;
+
+ switch (dfs_region) {
+ case NL80211_DFS_ETSI:
+ if (cfg80211_chandef_dfs_is_weather(wiphy, chandef) > 0)
+ timeout_ms = IEEE80211_DFS_WEATHER_MIN_CAC_TIME_MS;
+ break;
+ /* TODO check JP CAC time */
+ case NL80211_DFS_JP:
+ break;
+ /* FCC don't allow weather channels */
+ case NL80211_DFS_FCC:
+ default:
+ break;
+ }
+
+ return timeout_ms;
+}

static bool cfg80211_secondary_chans_ok(struct wiphy *wiphy,
u32 center_freq, u32 bandwidth,
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 0a277c3..88d9d0f 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -400,6 +400,10 @@ void cfg80211_set_dfs_state(struct wiphy *wiphy,

void cfg80211_dfs_channels_update_work(struct work_struct *work);

+unsigned int
+cfg80211_chandef_dfs_cac_time(struct wiphy *wiphy,
+ const struct cfg80211_chan_def *chandef,
+ enum nl80211_dfs_regions dfs_region);

static inline int
cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 52cca05..6601e81 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -778,7 +778,7 @@ void cfg80211_cac_event(struct net_device *netdev,
switch (event) {
case NL80211_RADAR_CAC_FINISHED:
timeout = wdev->cac_start_time +
- msecs_to_jiffies(IEEE80211_DFS_MIN_CAC_TIME_MS);
+ msecs_to_jiffies(wdev->cac_time_ms);
WARN_ON(!time_after_eq(jiffies, timeout));
cfg80211_set_dfs_state(wiphy, chandef, NL80211_DFS_AVAILABLE);
break;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index b705640..94fea18 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5651,6 +5651,7 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
struct wireless_dev *wdev = dev->ieee80211_ptr;
struct cfg80211_chan_def chandef;
enum nl80211_dfs_regions dfs_region;
+ unsigned int cac_time_ms;
int err;

dfs_region = reg_get_dfs_region(wdev->wiphy);
@@ -5686,12 +5687,16 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
if (err)
return err;

+ cac_time_ms = cfg80211_chandef_dfs_cac_time(&rdev->wiphy, &chandef,
+ dfs_region);
+
err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef,
- IEEE80211_DFS_MIN_CAC_TIME_MS);
+ cac_time_ms);
if (!err) {
wdev->channel = chandef.chan;
wdev->cac_started = true;
wdev->cac_start_time = jiffies;
+ wdev->cac_time_ms = cac_time_ms;
}
return err;
}
--
1.7.9.5


2013-11-27 06:16:56

by Janusz Dziedzic

[permalink] [raw]
Subject: Re: [PATCH v3 4/4] cfg80211: DFS use 10 minutes CAC when weather channels

2013/11/26 Johannes Berg <[email protected]>:
> On Tue, 2013-11-26 at 21:19 +0100, Janusz Dziedzic wrote:
>
>> ath.ko already disable weather channels by default.
>> But in case driver will pass DFS certification (meet all requirements)
>> - why not use weather channels?
>
> Since I'm a lazy bastard - can you demonstrate such a driver? I'm
> guessing not (immediately), so I'll drop your patches for now - maybe
> better to go back to the drawing board and get all of this into regdb
> etc. Doesn't seem critical to get it into the kernel now, if nobody
> really supports it anyway ...
>

I could say something more after DFS tests.
What about patch 1 and 2?

BR
Janusz

2013-12-03 12:54:29

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 1/4] cfg80211: add reg_get_dfs_region()

On Mon, 2013-11-25 at 20:56 +0100, Janusz Dziedzic wrote:
> From: "Luis R. Rodriguez" <[email protected]>
>
> This can be used outside of the regulatory context for any checks
> on the DFS region. The central cfg80211 dfs_region is always used
> and if it does not match with the wiphy a debug print is issued.

Ok I've applied patches 1 and 2

johannes


2013-12-02 14:43:42

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3 4/4] cfg80211: DFS use 10 minutes CAC when weather channels

On Wed, 2013-11-27 at 07:16 +0100, Janusz Dziedzic wrote:
> What about patch 1 and 2?

I guess those still make sense as is.

johannes