2012-03-16 14:55:40

by Vivek Natarajan

[permalink] [raw]
Subject: [RFC] cfg80211: Indicate the automatic channel selection capability

Let the driver automatically select the channel based on the
channel conditions when it is not explicitly set.
The drivers which have this capability in the firmware can set
the WIPHY_FLAG_SUPPORTS_ACS flag to indicate that to the
userspace.

Signed-off-by: Vivek Natarajan <[email protected]>
---
include/linux/nl80211.h | 5 +++++
include/net/cfg80211.h | 2 ++
net/wireless/nl80211.c | 3 +++
3 files changed, 10 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index be35a68..8d15101 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1197,6 +1197,9 @@ enum nl80211_commands {
* @NL80211_ATTR_NOACK_MAP: This u16 bitmap contains the No Ack Policy of
* up to 16 TIDs.
*
+ * @NL80211_ATTR_ACS: Indicates whether the firmware is capable of doing
+ * automatic channel selection if the channel is not explicitly set.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1442,6 +1445,8 @@ enum nl80211_attrs {

NL80211_ATTR_NOACK_MAP,

+ NL80211_ATTR_ACS,
+
/* add attributes here, update the policy in nl80211.c */

__NL80211_ATTR_AFTER_LAST,
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0178c74..aa93a2c 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1760,6 +1760,7 @@ struct cfg80211_ops {
* responds to probe-requests in hardware.
* @WIPHY_FLAG_OFFCHAN_TX: Device supports direct off-channel TX.
* @WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL: Device supports remain-on-channel call.
+ * @WIPHY_FLAG_SUPPORTS_ACS: Device supports automatic channel selection.
*/
enum wiphy_flags {
WIPHY_FLAG_CUSTOM_REGULATORY = BIT(0),
@@ -1783,6 +1784,7 @@ enum wiphy_flags {
WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD = BIT(19),
WIPHY_FLAG_OFFCHAN_TX = BIT(20),
WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL = BIT(21),
+ WIPHY_FLAG_SUPPORTS_ACS = BIT(22),
};

/**
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 1998c36..3a876326 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -204,6 +204,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
.len = NL80211_HT_CAPABILITY_LEN
},
[NL80211_ATTR_NOACK_MAP] = { .type = NLA_U16 },
+ [NL80211_ATTR_ACS] = { .type = NLA_FLAG },
};

/* policy for the key attributes */
@@ -749,6 +750,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_SUPPORT);
if (dev->wiphy.flags & WIPHY_FLAG_TDLS_EXTERNAL_SETUP)
NLA_PUT_FLAG(msg, NL80211_ATTR_TDLS_EXTERNAL_SETUP);
+ if (dev->wiphy.flags & WIPHY_FLAG_SUPPORTS_ACS)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_ACS);

NLA_PUT(msg, NL80211_ATTR_CIPHER_SUITES,
sizeof(u32) * dev->wiphy.n_cipher_suites,
--
1.7.9



2012-03-16 15:21:45

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC] cfg80211: Indicate the automatic channel selection capability

On Fri, 2012-03-16 at 20:25 +0530, Vivek Natarajan wrote:
> Let the driver automatically select the channel based on the
> channel conditions when it is not explicitly set.
> The drivers which have this capability in the firmware can set
> the WIPHY_FLAG_SUPPORTS_ACS flag to indicate that to the
> userspace.

> + * @NL80211_ATTR_ACS: Indicates whether the firmware is capable of doing
> + * automatic channel selection if the channel is not explicitly set.

Ok so ... this is lacking a lot of information. The state "channel is
not explicitly set" doesn't even really exist either for AP mode. I'm
assuming you're talking about AP mode since you never actually said
so ......

Since there's no "channel unset" state, you'd want to have some sort of
"please select a good channel and tell me" when you do START_AP in
nl80211, or something like that, right?

Please think about this a bit more.

johannes


2012-03-16 14:55:47

by Vivek Natarajan

[permalink] [raw]
Subject: [RFC] wpa_supplicant: Add support for ACS.

If the frequency is set as 0 in the conf file, pass it to the driver
for using automatic channel selection instead of hardcoding the channel
as 11. Since some drivers have the capability to choose the channel
based on the channel conditions, this patch enables that flexibility.

Signed-hostap-by: Vivek Natarajan <[email protected]>
---
src/ap/hw_features.c | 3 ++-
src/drivers/driver.h | 2 ++
src/drivers/driver_nl80211.c | 8 +++++++-
wpa_supplicant/ap.c | 8 +++++---
4 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 8c6fef2..997d205 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -677,7 +677,8 @@ int hostapd_select_hw_mode(struct hostapd_iface *iface)
* the channel automatically */
wpa_printf(MSG_ERROR, "Channel not configured "
"(hw_mode/channel in hostapd.conf)");
- return -3;
+ if (!(iface->drv_flags & WPA_DRIVER_FLAGS_ACS))
+ return -3;
}
if (ok == 0 && iface->conf->channel != 0) {
hostapd_logger(iface->bss[0], NULL,
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 04aedcf..92e078b 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -790,6 +790,8 @@ struct wpa_driver_capa {
#define WPA_DRIVER_FLAGS_PROBE_RESP_OFFLOAD 0x00200000
/* Driver supports U-APSD in AP mode */
#define WPA_DRIVER_FLAGS_AP_UAPSD 0x00400000
+#define WPA_DRIVER_FLAGS_ACS 0x00800000
+
unsigned int flags;

int max_scan_ssids;
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index 184b26f..1f0e6ee 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -2466,6 +2466,11 @@ broken_combination:
capa->flags |= WPA_DRIVER_FLAGS_BSS_SELECTION;
}

+ if (tb[NL80211_ATTR_ACS]) {
+ wpa_printf(MSG_DEBUG, "nl80211: Using driver-based ACS");
+ capa->flags |= WPA_DRIVER_FLAGS_ACS;
+ }
+
/* default to 5000 since early versions of mac80211 don't set it */
capa->max_remain_on_chan = 5000;

@@ -6365,7 +6370,8 @@ static int wpa_driver_nl80211_ap(struct wpa_driver_nl80211_data *drv,
nlmode = NL80211_IFTYPE_AP;

if (wpa_driver_nl80211_set_mode(&drv->first_bss, nlmode) ||
- wpa_driver_nl80211_set_freq(&drv->first_bss, params->freq, 0, 0)) {
+ ((params->freq) &&
+ wpa_driver_nl80211_set_freq(&drv->first_bss, params->freq, 0, 0))) {
nl80211_remove_monitor_interface(drv);
return -1;
}
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index 48a6169..6a9187c 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -53,9 +53,11 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
os_strlcpy(bss->iface, wpa_s->ifname, sizeof(bss->iface));

if (ssid->frequency == 0) {
- /* default channel 11 */
- conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
- conf->channel = 11;
+ if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_ACS)) {
+ /* default channel 11 */
+ conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
+ conf->channel = 11;
+ }
} else if (ssid->frequency >= 2412 && ssid->frequency <= 2472) {
conf->hw_mode = HOSTAPD_MODE_IEEE80211G;
conf->channel = (ssid->frequency - 2407) / 5;
--
1.7.0.4