2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 00/15] Implementation of periodic scan

Hi,

This patcheset implements initial support for hardware offloaded periodic
scan support. When this is used, the hardware is able to perform scans
automatically at certain intervals without waking up the host, which can
potentially save power.

The hardware can also automatically filter results and only report desired
results to the host. Currently, this patchset supports only filtering on
SSIDs. In the future, support for filtering on RSSI and SNR thresholds can
be added. This set doesn't support variable intervals, and the intervals
need to be configure in the hw driver.

This functionality is based on the periodic scan feature supported by the
wl1271 firmware.

This is an initial implementation and I'd like to get some comments before
submitting the final version.

I've split the implementation in many small patches, just to keep it clear
and due to the zillions of times I've had to task switch while implementing
this. I can merge some of them, if that makes things cleaner.

Cheers,
Luca.


Luciano Coelho (15):
nl80211: add periodic scan commands
cfg80211: add periodic scan request structure
nl80211: alloc and free the periodic_req data
cfg80211: add periodic scan start and stop ops
nl80211: call periodic_start and periodic_stop
mac80211: add support for HW periodic scan
cfg80211: add periodic scan results handler
nl80211: report periodic scan results
cfg80211: add channel support to periodic scan
nl80211: add channel support to the periodic scan
mac80211: pass cfg80211 periodic scan request structure down to the
driver
cfg80211: add ssid support to periodic scan
nl80211: add ssid filtering support to the periodic scan
cfg80211: add ie support for periodic scans
mac80211: create and pass the ies for each band in periodic scans

include/linux/nl80211.h | 8 ++
include/net/cfg80211.h | 44 +++++++
include/net/mac80211.h | 15 +++
net/mac80211/cfg.c | 26 ++++
net/mac80211/driver-ops.h | 27 ++++
net/mac80211/driver-trace.h | 63 ++++++++++
net/mac80211/ieee80211_i.h | 8 ++
net/mac80211/rx.c | 4 +-
net/mac80211/scan.c | 82 +++++++++++++
net/wireless/core.c | 1 +
net/wireless/core.h | 3 +
net/wireless/nl80211.c | 278 +++++++++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.h | 4 +
net/wireless/scan.c | 20 +++
14 files changed, 582 insertions(+), 1 deletions(-)



2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 04/15] cfg80211: add periodic scan start and stop ops

Add periodic_start and periodic_stop operations to the wireless configuration
API.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/net/cfg80211.h | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 84518cc..ac7b934 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1158,6 +1158,8 @@ struct cfg80211_pmksa {
* @set_power_mgmt: Configure WLAN power management. A timeout value of -1
* allows the driver to adjust the dynamic ps timeout value.
* @set_cqm_rssi_config: Configure connection quality monitor RSSI threshold.
+ * @periodic_start: Tell the driver to start a periodic scan.
+ * @periodic_stop: Tell the driver to stop an ongoing periodic scan.
*
* @mgmt_frame_register: Notify driver that a management frame type was
* registered. Note that this callback may not sleep, and cannot run
@@ -1316,6 +1318,12 @@ struct cfg80211_ops {
void (*mgmt_frame_register)(struct wiphy *wiphy,
struct net_device *dev,
u16 frame_type, bool reg);
+ int (*periodic_start)(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_periodic_request *request);
+ int (*periodic_stop)(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_periodic_request *request);
};

/*
--
1.7.0.4


2010-11-11 17:48:53

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 06/15] mac80211: add support for HW periodic scan

On Thu, 2010-11-11 at 17:59 +0200, Luciano Coelho wrote:

> > It may be sched_scan
>
> Hmmm... Scheduled scan is a good idea. And sched_scan is a clear and
> short abbreviation. What do you think, Johannes?

Sounds good to me, thanks for the suggestion Gery!

johannes



2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 13/15] nl80211: add ssid filtering support to the periodic scan

Parse and add ssids information to the periodic scan request.

Signed-off-by: Luciano Coelho <[email protected]>
---
net/wireless/nl80211.c | 38 +++++++++++++++++++++++++++++++++-----
1 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index d5b9047..5ae5935 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3004,10 +3004,11 @@ static int nl80211_start_periodic(struct sk_buff *skb,
struct cfg80211_periodic_request *request;
struct cfg80211_registered_device *rdev;
struct net_device *dev;
+ struct cfg80211_ssid *ssid;
struct ieee80211_channel *channel;
struct nlattr *attr;
struct wiphy *wiphy;
- int err, tmp, n_channels, i;
+ int err, tmp, n_ssids = 0, n_channels, i;
enum ieee80211_band band;

printk("nl80211_start_periodic\n");
@@ -3048,7 +3049,17 @@ static int nl80211_start_periodic(struct sk_buff *skb,
n_channels += wiphy->bands[band]->n_channels;
}

+ if (info->attrs[NL80211_ATTR_SCAN_SSIDS])
+ nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp)
+ n_ssids++;
+
+ if (n_ssids > wiphy->max_periodic_ssids) {
+ err = -EINVAL;
+ goto out ;
+ }
+
request = kzalloc(sizeof(*request)
+ + sizeof(*ssid) * n_ssids
+ sizeof(channel) * n_channels,
GFP_KERNEL);
if (!request) {
@@ -3056,10 +3067,9 @@ static int nl80211_start_periodic(struct sk_buff *skb,
goto out;
}

- request->dev = dev;
- request->wiphy = &rdev->wiphy;
-
- rdev->periodic_req = request;
+ if (n_ssids)
+ request->ssids = (void *)&request->channels[n_channels];
+ request->n_ssids = n_ssids;

i = 0;
if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
@@ -3108,6 +3118,24 @@ static int nl80211_start_periodic(struct sk_buff *skb,

request->n_channels = i;

+ i = 0;
+ if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) {
+ nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) {
+ if (request->ssids[i].ssid_len > IEEE80211_MAX_SSID_LEN) {
+ err = -EINVAL;
+ goto out_free;
+ }
+ memcpy(request->ssids[i].ssid, nla_data(attr), nla_len(attr));
+ request->ssids[i].ssid_len = nla_len(attr);
+ i++;
+ }
+ }
+
+ request->dev = dev;
+ request->wiphy = &rdev->wiphy;
+
+ rdev->periodic_req = request;
+
err = rdev->ops->periodic_start(&rdev->wiphy, dev, request);
if (err) {
out_free:
--
1.7.0.4


2010-11-05 19:45:39

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 07/15] cfg80211: add periodic scan results handler

On Thu, 2010-11-04 at 16:47 +0100, ext Johannes Berg wrote:
> On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
>
> > +void cfg80211_periodic_results(struct cfg80211_periodic_request *req)
> > +{
> > + WARN_ON(req != wiphy_to_dev(req->wiphy)->periodic_req);
> > +
> > + queue_work(cfg80211_wq, &wiphy_to_dev(req->wiphy)->periodic_wk);
> > +}
>
> why even pass it in?

Yeah, I'll recheck this. Probably remove this periodic_req in local
entirely.


--
Cheers,
Luca.


2010-11-01 12:26:00

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 06/15] mac80211: add support for HW periodic scan

Implement support for HW periodic scan. The mac80211 code doesn't perform
periodic scans itself, but calls the driver to start and stop periodic scans.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/net/mac80211.h | 4 +++
net/mac80211/cfg.c | 26 ++++++++++++++++++++
net/mac80211/driver-ops.h | 26 ++++++++++++++++++++
net/mac80211/driver-trace.h | 44 +++++++++++++++++++++++++++++++++++
net/mac80211/ieee80211_i.h | 6 ++++
net/mac80211/scan.c | 54 +++++++++++++++++++++++++++++++++++++++++++
6 files changed, 160 insertions(+), 0 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 9fdf982..4ea2149 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1759,6 +1759,10 @@ struct ieee80211_ops {
u32 iv32, u16 *phase1key);
int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct cfg80211_scan_request *req);
+ int (*periodic_start)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
+ int (*periodic_stop)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif);
void (*sw_scan_start)(struct ieee80211_hw *hw);
void (*sw_scan_complete)(struct ieee80211_hw *hw);
int (*get_stats)(struct ieee80211_hw *hw,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 18bd0e5..ff29840 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1223,6 +1223,30 @@ static int ieee80211_scan(struct wiphy *wiphy,
return ieee80211_request_scan(sdata, req);
}

+static int ieee80211_periodic_start(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_periodic_request *req)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ if(!sdata->local->ops->periodic_start)
+ return -EOPNOTSUPP;
+
+ return ieee80211_request_periodic_start(sdata, req);
+}
+
+static int ieee80211_periodic_stop(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_periodic_request *req)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+
+ if(!sdata->local->ops->periodic_stop)
+ return -EOPNOTSUPP;
+
+ return ieee80211_request_periodic_stop(sdata);
+}
+
static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_auth_request *req)
{
@@ -1654,6 +1678,8 @@ struct cfg80211_ops mac80211_config_ops = {
.suspend = ieee80211_suspend,
.resume = ieee80211_resume,
.scan = ieee80211_scan,
+ .periodic_start= ieee80211_periodic_start,
+ .periodic_stop= ieee80211_periodic_stop,
.auth = ieee80211_auth,
.assoc = ieee80211_assoc,
.deauth = ieee80211_deauth,
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 1698382..c425e1c 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -191,6 +191,32 @@ static inline int drv_hw_scan(struct ieee80211_local *local,
return ret;
}

+static inline int drv_periodic_start(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata)
+{
+ int ret;
+
+ might_sleep();
+
+ trace_drv_periodic_start(local, sdata);
+ ret = local->ops->periodic_start(&local->hw, &sdata->vif);
+ trace_drv_return_int(local, ret);
+ return ret;
+}
+
+static inline int drv_periodic_stop(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata)
+{
+ int ret;
+
+ might_sleep();
+
+ trace_drv_periodic_stop(local, sdata);
+ ret = local->ops->periodic_stop(&local->hw, &sdata->vif);
+ trace_drv_return_int(local, ret);
+ return ret;
+}
+
static inline void drv_sw_scan_start(struct ieee80211_local *local)
{
might_sleep();
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 6831fb1..a09c17d 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -439,6 +439,50 @@ TRACE_EVENT(drv_hw_scan,
)
);

+TRACE_EVENT(drv_periodic_start,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata),
+
+ TP_ARGS(local, sdata),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT,
+ LOCAL_PR_ARG,VIF_PR_ARG
+ )
+);
+
+TRACE_EVENT(drv_periodic_stop,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata),
+
+ TP_ARGS(local, sdata),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ VIF_ENTRY
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ VIF_ASSIGN;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT VIF_PR_FMT,
+ LOCAL_PR_ARG,VIF_PR_ARG
+ )
+);
+
TRACE_EVENT(drv_sw_scan_start,
TP_PROTO(struct ieee80211_local *local),

diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index b80c386..305bd57 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -812,6 +812,7 @@ struct ieee80211_local {
struct cfg80211_ssid scan_ssid;
struct cfg80211_scan_request *int_scan_req;
struct cfg80211_scan_request *scan_req, *hw_scan_req;
+ struct cfg80211_periodic_request *periodic_req;
struct ieee80211_channel *scan_channel;
enum ieee80211_band hw_scan_band;
int scan_channel_idx;
@@ -1115,6 +1116,11 @@ ieee80211_rx_bss_get(struct ieee80211_local *local, u8 *bssid, int freq,
void ieee80211_rx_bss_put(struct ieee80211_local *local,
struct ieee80211_bss *bss);

+/* periodic scan handling */
+int ieee80211_request_periodic_start(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_periodic_request *req);
+int ieee80211_request_periodic_stop(struct ieee80211_sub_if_data *sdata);
+
/* off-channel helpers */
void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local);
void ieee80211_offchannel_stop_station(struct ieee80211_local *local);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 592acfb..fa73abe 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -823,3 +823,57 @@ void ieee80211_scan_cancel(struct ieee80211_local *local)
if (finish)
__ieee80211_scan_completed_finish(&local->hw, false);
}
+
+int ieee80211_request_periodic_start(struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_periodic_request *req)
+{
+ struct ieee80211_local *local = sdata->local;
+ int ret;
+
+ mutex_lock(&sdata->local->mtx);
+
+ /* FIXME: check if hw scanning or associated and return -EBUSY */
+
+ if (local->periodic_req) {
+ ret = -EBUSY;
+ goto out;
+ }
+
+ if (!local->ops->periodic_start) {
+ ret = -ENOTSUPP;
+ goto out;
+ }
+
+ local->periodic_req = req;
+
+ ret = drv_periodic_start(local, sdata);
+ if (ret)
+ local->periodic_req = NULL;
+out:
+ mutex_unlock(&sdata->local->mtx);
+
+ return ret;
+}
+
+int ieee80211_request_periodic_stop(struct ieee80211_sub_if_data *sdata)
+{
+ struct ieee80211_local *local = sdata->local;
+ int ret = 0;
+
+ mutex_lock(&sdata->local->mtx);
+
+ if (!local->ops->periodic_stop) {
+ ret = -ENOTSUPP;
+ goto out;
+ }
+
+ if (local->periodic_req) {
+ ret = drv_periodic_stop(local, sdata);
+ local->periodic_req = NULL;
+ }
+
+out:
+ mutex_unlock(&sdata->local->mtx);
+
+ return ret;
+}
--
1.7.0.4


2010-11-04 20:54:06

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 00/15] Implementation of periodic scan

On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:

> This set doesn't support variable intervals, and the intervals
> need to be configure in the hw driver.

which is wrong -- you really want that to be configurable.

> This is an initial implementation and I'd like to get some comments before
> submitting the final version.
>
> I've split the implementation in many small patches, just to keep it clear
> and due to the zillions of times I've had to task switch while implementing
> this. I can merge some of them, if that makes things cleaner.

Absolutely, the patch splitting is total crap :-) Heck, you even write
code only to remove/change it again!

johannes


2010-11-11 16:00:09

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 06/15] mac80211: add support for HW periodic scan

On Thu, 2010-11-11 at 16:33 +0100, ext Gery Kahn wrote:
> On 11/05/2010 09:55 PM, Johannes Berg wrote:
> >
> > On Fri, 05 Nov 2010 21:59:37 +0200, Luciano Coelho
> > <[email protected]> wrote:
> >> I think the idea of using background is good. Something like bg_scan or
> >> something. The original idea was to call it background scan, but since
> >> wl1271 doesn't support this while connected, I thought calling it
> >> periodic scan would be slightly clearer about that. Background scan
> >> sounds like you do it while connected (to me at least).
> >
> > Come to think of it though, we also call what we do when connected
> > and trigger a scan manually a "background scan", so that's probably
> > not a good name here.
> >
> > Not sure ... don't really have a good idea right now.

> It may be sched_scan

Hmmm... Scheduled scan is a good idea. And sched_scan is a clear and
short abbreviation. What do you think, Johannes?

--
Cheers,
Luca.


2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 03/15] nl80211: alloc and free the periodic_req data

This patch adds code to allocate and deallocate the periodic request data
structure. This structure will be passed down when making the actual scan
call and it is also used to check whether a periodic scan is still running or
not.

Signed-off-by: Luciano Coelho <[email protected]>
---
net/wireless/nl80211.c | 28 +++++++++++++++++++++++++++-
1 files changed, 27 insertions(+), 1 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a2293ea..0884464 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3001,6 +3001,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
static int nl80211_start_periodic(struct sk_buff *skb,
struct genl_info *info)
{
+ struct cfg80211_periodic_request *request;
struct cfg80211_registered_device *rdev;
struct net_device *dev;
int err;
@@ -3018,6 +3019,22 @@ static int nl80211_start_periodic(struct sk_buff *skb,
goto out;
}

+ if (rdev->periodic_req) {
+ err = -EINPROGRESS;
+ goto out;
+ }
+
+ request = kzalloc(sizeof(*request), GFP_KERNEL);
+ if (!request) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ request->dev = dev;
+ request->wiphy = &rdev->wiphy;
+
+ rdev->periodic_req = request;
+
/* add actual calls here */

if (!err) {
@@ -3055,7 +3072,9 @@ static int nl80211_stop_periodic(struct sk_buff *skb,
goto out;
}

- /* add actual calls here */
+ if (rdev->periodic_req) {
+ /* add actual calls here */
+ }

if (!err) {
nl80211_send_periodic(rdev, dev,
@@ -3063,6 +3082,13 @@ static int nl80211_stop_periodic(struct sk_buff *skb,
dev_hold(dev);
}

+ /*
+ * FIXME: Can this stay here? How will the auto-complete and other
+ * cleanup cases work?
+ */
+ kfree(rdev->periodic_req);
+ rdev->periodic_req = NULL;
+
out:
cfg80211_unlock_rdev(rdev);
dev_put(dev);
--
1.7.0.4


2010-11-04 20:51:18

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 07/15] cfg80211: add periodic scan results handler

On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:

> +void cfg80211_periodic_results(struct cfg80211_periodic_request *req)
> +{
> + WARN_ON(req != wiphy_to_dev(req->wiphy)->periodic_req);
> +
> + queue_work(cfg80211_wq, &wiphy_to_dev(req->wiphy)->periodic_wk);
> +}

why even pass it in?

johannes


2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 05/15] nl80211: call periodic_start and periodic_stop

Now that cfg80211 has support for periodic scan, we call those ops in the
nl80211 code.

Signed-off-by: Luciano Coelho <[email protected]>
---
net/wireless/nl80211.c | 30 ++++++++++++++++++++----------
1 files changed, 20 insertions(+), 10 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 0884464..fd50186 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3014,6 +3014,11 @@ static int nl80211_start_periodic(struct sk_buff *skb,
if (err)
goto out_rtnl;

+ if (!rdev->ops->periodic_start) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
if (!netif_running(dev)) {
err = -ENETDOWN;
goto out;
@@ -3035,14 +3040,15 @@ static int nl80211_start_periodic(struct sk_buff *skb,

rdev->periodic_req = request;

- /* add actual calls here */
-
- if (!err) {
- nl80211_send_periodic(rdev, dev,
- NL80211_CMD_START_PERIODIC_SCAN);
- dev_hold(dev);
+ err = rdev->ops->periodic_start(&rdev->wiphy, dev, request);
+ if (err) {
+ kfree(request);
+ rdev->periodic_req = NULL;
+ goto out;
}

+ nl80211_send_periodic(rdev, dev,
+ NL80211_CMD_START_PERIODIC_SCAN);
out:
cfg80211_unlock_rdev(rdev);
dev_put(dev);
@@ -3067,20 +3073,24 @@ static int nl80211_stop_periodic(struct sk_buff *skb,
if (err)
goto out_rtnl;

+ if (!rdev->ops->periodic_stop) {
+ err = -EOPNOTSUPP;
+ goto out;
+ }
+
if (!netif_running(dev)) {
err = -ENETDOWN;
goto out;
}

if (rdev->periodic_req) {
- /* add actual calls here */
+ err = rdev->ops->periodic_stop(&rdev->wiphy, dev,
+ rdev->periodic_req);
}

- if (!err) {
+ if (!err)
nl80211_send_periodic(rdev, dev,
NL80211_CMD_STOP_PERIODIC_SCAN);
- dev_hold(dev);
- }

/*
* FIXME: Can this stay here? How will the auto-complete and other
--
1.7.0.4


2010-11-11 15:57:58

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 00/15] Implementation of periodic scan

Hi Gery,

On Thu, 2010-11-11 at 16:31 +0100, ext Gery Kahn wrote:
> The main idea is to have hw offloaded periodic scan while connected or not?

This can be used for both. The wl1271 firmware doesn't support this
periodic scan while connected, so at least for now I'll only add support
for it when not connected.

--
Cheers,
Luca.


2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 11/15] mac80211: pass cfg80211 periodic scan request structure down to the driver

Pass the cfg80211_periodic_request structure down to the driver. This
structure contains the channel information (and will have SSID and IE
information) to be passed to the driver.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/net/mac80211.h | 3 ++-
net/mac80211/driver-ops.h | 7 ++++---
net/mac80211/driver-trace.h | 5 +++--
net/mac80211/scan.c | 2 +-
4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 6b50780..901debb 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1760,7 +1760,8 @@ struct ieee80211_ops {
int (*hw_scan)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
struct cfg80211_scan_request *req);
int (*periodic_start)(struct ieee80211_hw *hw,
- struct ieee80211_vif *vif);
+ struct ieee80211_vif *vif,
+ struct cfg80211_periodic_request *req);
int (*periodic_stop)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif);
void (*sw_scan_start)(struct ieee80211_hw *hw);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index c425e1c..88b5f90 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -192,14 +192,15 @@ static inline int drv_hw_scan(struct ieee80211_local *local,
}

static inline int drv_periodic_start(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata)
+ struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_periodic_request *req)
{
int ret;

might_sleep();

- trace_drv_periodic_start(local, sdata);
- ret = local->ops->periodic_start(&local->hw, &sdata->vif);
+ trace_drv_periodic_start(local, sdata, req);
+ ret = local->ops->periodic_start(&local->hw, &sdata->vif, req);
trace_drv_return_int(local, ret);
return ret;
}
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 2acdc43..8d6c7e6 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -441,9 +441,10 @@ TRACE_EVENT(drv_hw_scan,

TRACE_EVENT(drv_periodic_start,
TP_PROTO(struct ieee80211_local *local,
- struct ieee80211_sub_if_data *sdata),
+ struct ieee80211_sub_if_data *sdata,
+ struct cfg80211_periodic_request *req),

- TP_ARGS(local, sdata),
+ TP_ARGS(local, sdata, req),

TP_STRUCT__entry(
LOCAL_ENTRY
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 9273ab0..fda8d41 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -846,7 +846,7 @@ int ieee80211_request_periodic_start(struct ieee80211_sub_if_data *sdata,

local->periodic_req = req;

- ret = drv_periodic_start(local, sdata);
+ ret = drv_periodic_start(local, sdata, req);
if (!ret)
__set_bit(SCAN_PERIODIC_SCANNING, &local->scanning);
else
--
1.7.0.4


2010-11-05 14:14:44

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 01/15] nl80211: add periodic scan commands

On Thu, 2010-11-04 at 16:42 +0100, ext Johannes Berg wrote:
> On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
>
> > + rtnl_lock();
> > +
> > + err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
> > + if (err)
> > + goto out_rtnl;
> > +
> > + if (!netif_running(dev)) {
> > + err = -ENETDOWN;
> > + goto out;
> > + }
>
> ahem. we have infrastructure for this now.

Yeah, I noticed this. My implementation was originally done so far in
the past that this wasn't available then. I hadn't bothered changing it
yet, but I'll do it now.


>
> > + .doit = nl80211_start_periodic,
>
> > + .doit = nl80211_stop_periodic,
>
> > +void nl80211_send_periodic(struct cfg80211_registered_device *rdev,
> > + struct net_device *netdev, u32 cmd);
>
> I think you should add _scan to all these names.

I had _scan in all the names, but they got way too long and I couldn't
find a better way to do it shorter. But since you seem to prefer the
longer version with _scan, I'll change it back.

--
Cheers,
Luca.


2010-11-11 15:31:24

by Kahn, Gery

[permalink] [raw]
Subject: Re: [RFC 00/15] Implementation of periodic scan

Hi Luca,

On 11/01/2010 01:52 PM, Luciano Coelho wrote:
> Hi,
>
> This patcheset implements initial support for hardware offloaded periodic
> scan support. When this is used, the hardware is able to perform scans
> automatically at certain intervals without waking up the host, which can
> potentially save power.
>
> The hardware can also automatically filter results and only report desired
> results to the host. Currently, this patchset supports only filtering on
> SSIDs. In the future, support for filtering on RSSI and SNR thresholds can
> be added. This set doesn't support variable intervals, and the intervals
> need to be configure in the hw driver.
>
> This functionality is based on the periodic scan feature supported by the
> wl1271 firmware.
>
> This is an initial implementation and I'd like to get some comments before
> submitting the final version.
>
> I've split the implementation in many small patches, just to keep it clear
> and due to the zillions of times I've had to task switch while implementing
> this. I can merge some of them, if that makes things cleaner.
>
> Cheers,
> Luca.
>
>
> Luciano Coelho (15):
> nl80211: add periodic scan commands
> cfg80211: add periodic scan request structure
> nl80211: alloc and free the periodic_req data
> cfg80211: add periodic scan start and stop ops
> nl80211: call periodic_start and periodic_stop
> mac80211: add support for HW periodic scan
> cfg80211: add periodic scan results handler
> nl80211: report periodic scan results
> cfg80211: add channel support to periodic scan
> nl80211: add channel support to the periodic scan
> mac80211: pass cfg80211 periodic scan request structure down to the
> driver
> cfg80211: add ssid support to periodic scan
> nl80211: add ssid filtering support to the periodic scan
> cfg80211: add ie support for periodic scans
> mac80211: create and pass the ies for each band in periodic scans
>
> include/linux/nl80211.h | 8 ++
> include/net/cfg80211.h | 44 +++++++
> include/net/mac80211.h | 15 +++
> net/mac80211/cfg.c | 26 ++++
> net/mac80211/driver-ops.h | 27 ++++
> net/mac80211/driver-trace.h | 63 ++++++++++
> net/mac80211/ieee80211_i.h | 8 ++
> net/mac80211/rx.c | 4 +-
> net/mac80211/scan.c | 82 +++++++++++++
> net/wireless/core.c | 1 +
> net/wireless/core.h | 3 +
> net/wireless/nl80211.c | 278 +++++++++++++++++++++++++++++++++++++++++++
> net/wireless/nl80211.h | 4 +
> net/wireless/scan.c | 20 +++
> 14 files changed, 582 insertions(+), 1 deletions(-)
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html

The main idea is to have hw offloaded periodic scan while connected or not?

2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 12/15] cfg80211: add ssid support to periodic scan

Just add ssids in the periodic_request structure. This is needed in order to
pass the desired ssids to filter down to the mac.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/net/cfg80211.h | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 218e59f..3ac6fc9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -721,12 +721,16 @@ struct cfg80211_scan_request {
/**
* struct cfg80211_periodic_request - periodic scan request description
*
+ * @ssids: SSIDs to report (other SSIDs will be filtered out)
+ * @n_ssids: number of SSIDs
* @n_channels: total number of channels to scan
* @wiphy: the wiphy this was for
* @dev: the interface
* @channels: channels to scan
*/
struct cfg80211_periodic_request {
+ struct cfg80211_ssid *ssids;
+ int n_ssids;
u32 n_channels;

/* internal */
@@ -1436,6 +1440,8 @@ struct ieee80211_txrx_stypes {
* @max_scan_ie_len: maximum length of user-controlled IEs device can
* add to probe request frames transmitted during a scan, must not
* include fixed IEs like supported rates
+ * @max_periodic_ssids: maximum number of SSIDs the device can use in
+ * periodic scans
* @coverage_class: current coverage class
* @fw_version: firmware version for ethtool reporting
* @hw_version: hardware version for ethtool reporting
@@ -1472,6 +1478,8 @@ struct wiphy {
u8 max_scan_ssids;
u16 max_scan_ie_len;

+ u8 max_periodic_ssids;
+
int n_cipher_suites;
const u32 *cipher_suites;

--
1.7.0.4


2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 15/15] mac80211: create and pass the ies for each band in periodic scans

Create the scan IEs for each band and pass to the driver as part of the
periodic scan op.

For now, we don't support IEs passed from the userspace.

Signed-off-by: Luciano Coelho <[email protected]>
---
net/mac80211/scan.c | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index fda8d41..2e7661f 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -828,7 +828,7 @@ int ieee80211_request_periodic_start(struct ieee80211_sub_if_data *sdata,
struct cfg80211_periodic_request *req)
{
struct ieee80211_local *local = sdata->local;
- int ret;
+ int ret, i;

mutex_lock(&sdata->local->mtx);

@@ -844,6 +844,16 @@ int ieee80211_request_periodic_start(struct ieee80211_sub_if_data *sdata,
goto out;
}

+ for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
+ req->ie[i] = kzalloc(2 + IEEE80211_MAX_SSID_LEN +
+ local->scan_ies_len, GFP_KERNEL);
+
+ req->ie_len[i] = ieee80211_build_preq_ies(local,
+ (u8 *) req->ie[i],
+ NULL, 0, i,
+ (u32) -1, 0);
+ }
+
local->periodic_req = req;

ret = drv_periodic_start(local, sdata, req);
@@ -860,7 +870,7 @@ out:
int ieee80211_request_periodic_stop(struct ieee80211_sub_if_data *sdata)
{
struct ieee80211_local *local = sdata->local;
- int ret = 0;
+ int ret = 0, i;

mutex_lock(&sdata->local->mtx);

@@ -870,6 +880,9 @@ int ieee80211_request_periodic_stop(struct ieee80211_sub_if_data *sdata)
}

if (local->periodic_req) {
+ for (i = 0; i < IEEE80211_NUM_BANDS; i++)
+ kfree(local->periodic_req->ie[i]);
+
ret = drv_periodic_stop(local, sdata);
local->periodic_req = NULL;
__clear_bit(SCAN_PERIODIC_SCANNING, &local->scanning);
--
1.7.0.4


2010-11-05 19:46:51

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 06/15] mac80211: add support for HW periodic scan

On Thu, 2010-11-04 at 16:45 +0100, ext Johannes Berg wrote:
> On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
>
> > + .periodic_start= ieee80211_periodic_start,
> > + .periodic_stop= ieee80211_periodic_stop,
>
> whitespace ... also, _scan really ...

Yeah, you're totally right. I was thinking more about this and Oz said
he discussed this with you a bit.

I think the idea of using background is good. Something like bg_scan or
something. The original idea was to call it background scan, but since
wl1271 doesn't support this while connected, I thought calling it
periodic scan would be slightly clearer about that. Background scan
sounds like you do it while connected (to me at least).

We should be able to do real background scans, connected or not. If
wl1271 doesn't support it while connected, too bad, it should return
-EBUSY. We shouldn't restrict other drivers from doing it while
connected just because wl1271 doesn't support it.

Actually I should try (again) to have TI change the firmware so that it
is possible while connected too.


> > + trace_drv_periodic_stop(local, sdata);
> > + ret = local->ops->periodic_stop(&local->hw, &sdata->vif);
> > + trace_drv_return_int(local, ret);
> > + return ret;
>
> why does this have a return value?

Good point. No need for it.


> > @@ -812,6 +812,7 @@ struct ieee80211_local {
> > struct cfg80211_ssid scan_ssid;
> > struct cfg80211_scan_request *int_scan_req;
> > struct cfg80211_scan_request *scan_req, *hw_scan_req;
> > + struct cfg80211_periodic_request *periodic_req;
>
> what do you need to store this for?

Ahmmm... Nothing? :) This seems unnecessary indeed and I'll recheck
this.


--
Cheers,
Luca.


2010-11-01 12:26:00

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 07/15] cfg80211: add periodic scan results handler

Add a function that the drivers need to call when they get scan results
during a periodic scan. It will send signals to the userspace informing that
new scan results are available.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/net/cfg80211.h | 7 +++++++
include/net/mac80211.h | 10 ++++++++++
net/mac80211/driver-trace.h | 18 ++++++++++++++++++
net/mac80211/ieee80211_i.h | 2 ++
net/mac80211/rx.c | 4 +++-
net/mac80211/scan.c | 17 ++++++++++++++++-
net/wireless/core.c | 1 +
net/wireless/core.h | 2 ++
net/wireless/scan.c | 20 ++++++++++++++++++++
9 files changed, 79 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index ac7b934..41e7dc4 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2140,6 +2140,13 @@ int cfg80211_wext_siwpmksa(struct net_device *dev,
void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted);

/**
+ * cfg80211_periodic_results - notify that new scan results are available
+ *
+ * @request: the corresponding periodic scan request
+ */
+void cfg80211_periodic_results(struct cfg80211_periodic_request *req);
+
+/**
* cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame
*
* @wiphy: the wiphy reporting the BSS
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 4ea2149..6b50780 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2322,6 +2322,16 @@ void ieee80211_wake_queues(struct ieee80211_hw *hw);
void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted);

/**
+ * ieee80211_periodic_results - got results from periodic scan
+ *
+ * When a periodic scan is running, this function needs to be called by the
+ * driver whenever there are new scan results availble.
+ *
+ * @hw: the hardware that is performing periodic scans
+ */
+void ieee80211_periodic_results(struct ieee80211_hw *hw);
+
+/**
* ieee80211_iterate_active_interfaces - iterate active interfaces
*
* This function iterates over the interfaces associated with a given
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index a09c17d..2acdc43 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -519,6 +519,24 @@ TRACE_EVENT(drv_sw_scan_complete,
)
);

+TRACE_EVENT(drv_periodic_results,
+ TP_PROTO(struct ieee80211_local *local),
+
+ TP_ARGS(local),
+
+ TP_STRUCT__entry(
+ LOCAL_ENTRY
+ ),
+
+ TP_fast_assign(
+ LOCAL_ASSIGN;
+ ),
+
+ TP_printk(
+ LOCAL_PR_FMT, LOCAL_PR_ARG
+ )
+);
+
TRACE_EVENT(drv_get_stats,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_low_level_stats *stats,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 305bd57..c8846a4 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -648,6 +648,7 @@ enum queue_stop_reason {
* that the scan completed.
* @SCAN_ABORTED: Set for our scan work function when the driver reported
* a scan complete for an aborted scan.
+ * @SCAN_PERIODIC_SCANNING: We're currently performing periodic scans
*/
enum {
SCAN_SW_SCANNING,
@@ -655,6 +656,7 @@ enum {
SCAN_OFF_CHANNEL,
SCAN_COMPLETED,
SCAN_ABORTED,
+ SCAN_PERIODIC_SCANNING,
};

/**
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 902b03e..56db997 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -392,7 +392,8 @@ ieee80211_rx_h_passive_scan(struct ieee80211_rx_data *rx)
if (likely(!(status->rx_flags & IEEE80211_RX_IN_SCAN)))
return RX_CONTINUE;

- if (test_bit(SCAN_HW_SCANNING, &local->scanning))
+ if (test_bit(SCAN_HW_SCANNING, &local->scanning) ||
+ test_bit(SCAN_PERIODIC_SCANNING, &local->scanning))
return ieee80211_scan_rx(rx->sdata, skb);

if (test_bit(SCAN_SW_SCANNING, &local->scanning)) {
@@ -2702,6 +2703,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
local->dot11ReceivedFragmentCount++;

if (unlikely(test_bit(SCAN_HW_SCANNING, &local->scanning) ||
+ test_bit(SCAN_PERIODIC_SCANNING, &local->scanning) ||
test_bit(SCAN_OFF_CHANNEL, &local->scanning)))
status->rx_flags |= IEEE80211_RX_IN_SCAN;

diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index fa73abe..9273ab0 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -847,7 +847,9 @@ int ieee80211_request_periodic_start(struct ieee80211_sub_if_data *sdata,
local->periodic_req = req;

ret = drv_periodic_start(local, sdata);
- if (ret)
+ if (!ret)
+ __set_bit(SCAN_PERIODIC_SCANNING, &local->scanning);
+ else
local->periodic_req = NULL;
out:
mutex_unlock(&sdata->local->mtx);
@@ -870,6 +872,7 @@ int ieee80211_request_periodic_stop(struct ieee80211_sub_if_data *sdata)
if (local->periodic_req) {
ret = drv_periodic_stop(local, sdata);
local->periodic_req = NULL;
+ __clear_bit(SCAN_PERIODIC_SCANNING, &local->scanning);
}

out:
@@ -877,3 +880,15 @@ out:

return ret;
}
+
+void ieee80211_periodic_results(struct ieee80211_hw *hw)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+
+ mutex_lock(&local->mtx);
+
+ cfg80211_periodic_results(local->periodic_req);
+
+ mutex_unlock(&local->mtx);
+}
+EXPORT_SYMBOL(ieee80211_periodic_results);
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 9c21ebf..b90ae7c 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -363,6 +363,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
spin_lock_init(&rdev->bss_lock);
INIT_LIST_HEAD(&rdev->bss_list);
INIT_WORK(&rdev->scan_done_wk, __cfg80211_scan_done);
+ INIT_WORK(&rdev->periodic_wk, __cfg80211_periodic_results);

#ifdef CONFIG_CFG80211_WEXT
rdev->wiphy.wext = &cfg80211_wext_handler;
diff --git a/net/wireless/core.h b/net/wireless/core.h
index bf4e348..de4578a 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -63,6 +63,7 @@ struct cfg80211_registered_device {
struct cfg80211_periodic_request *periodic_req; /* protected by RTNL */
unsigned long suspend_at;
struct work_struct scan_done_wk;
+ struct work_struct periodic_wk;

#ifdef CONFIG_NL80211_TESTMODE
struct genl_info *testmode_info;
@@ -384,6 +385,7 @@ void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
void cfg80211_sme_disassoc(struct net_device *dev, int idx);
void __cfg80211_scan_done(struct work_struct *wk);
void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
+void __cfg80211_periodic_results(struct work_struct *wk);
void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
struct net_device *dev, enum nl80211_iftype ntype,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 503ebb8..300876b 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -93,6 +93,26 @@ void cfg80211_scan_done(struct cfg80211_scan_request *request, bool aborted)
}
EXPORT_SYMBOL(cfg80211_scan_done);

+void __cfg80211_periodic_results(struct work_struct *wk)
+{
+ struct cfg80211_registered_device *rdev;
+
+ rdev = container_of(wk, struct cfg80211_registered_device,
+ periodic_wk);
+
+ cfg80211_lock_rdev(rdev);
+ nl80211_send_scan_done(rdev, rdev->periodic_req->dev);
+ cfg80211_unlock_rdev(rdev);
+}
+
+void cfg80211_periodic_results(struct cfg80211_periodic_request *req)
+{
+ WARN_ON(req != wiphy_to_dev(req->wiphy)->periodic_req);
+
+ queue_work(cfg80211_wq, &wiphy_to_dev(req->wiphy)->periodic_wk);
+}
+EXPORT_SYMBOL(cfg80211_periodic_results);
+
static void bss_release(struct kref *ref)
{
struct cfg80211_internal_bss *bss;
--
1.7.0.4


2010-11-05 19:55:05

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 06/15] mac80211: add support for HW periodic scan


On Fri, 05 Nov 2010 21:59:37 +0200, Luciano Coelho
<[email protected]> wrote:
> I think the idea of using background is good. Something like bg_scan or
> something. The original idea was to call it background scan, but since
> wl1271 doesn't support this while connected, I thought calling it
> periodic scan would be slightly clearer about that. Background scan
> sounds like you do it while connected (to me at least).

Come to think of it though, we also call what we do when connected
and trigger a scan manually a "background scan", so that's probably
not a good name here.

Not sure ... don't really have a good idea right now.

johannes

2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 02/15] cfg80211: add periodic scan request structure

Tihs patch adds the periodic scan request structure to cfg80211.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/net/cfg80211.h | 12 ++++++++++++
net/wireless/core.h | 1 +
2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 2a7936d..84518cc 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -719,6 +719,18 @@ struct cfg80211_scan_request {
};

/**
+ * struct cfg80211_periodic_request - periodic scan request description
+ *
+ * @wiphy: the wiphy this was for
+ * @dev: the interface
+ */
+struct cfg80211_periodic_request {
+ /* internal */
+ struct wiphy *wiphy;
+ struct net_device *dev;
+};
+
+/**
* enum cfg80211_signal_type - signal type
*
* @CFG80211_SIGNAL_TYPE_NONE: no signal strength information available
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 2d1d4c7..bf4e348 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -60,6 +60,7 @@ struct cfg80211_registered_device {
struct rb_root bss_tree;
u32 bss_generation;
struct cfg80211_scan_request *scan_req; /* protected by RTNL */
+ struct cfg80211_periodic_request *periodic_req; /* protected by RTNL */
unsigned long suspend_at;
struct work_struct scan_done_wk;

--
1.7.0.4


2010-11-04 21:47:28

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 00/15] Implementation of periodic scan

Thanks for your review, Johannes!

On Thu, 2010-11-04 at 16:51 +0100, ext Johannes Berg wrote:
> On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
>
> > This set doesn't support variable intervals, and the intervals
> > need to be configure in the hw driver.
>
> which is wrong -- you really want that to be configurable.

Yes, for sure I will. I'm already working on it. It's a requirement
for us.


> > This is an initial implementation and I'd like to get some comments before
> > submitting the final version.
> >
> > I've split the implementation in many small patches, just to keep it clear
> > and due to the zillions of times I've had to task switch while implementing
> > this. I can merge some of them, if that makes things cleaner.
>
> Absolutely, the patch splitting is total crap :-) Heck, you even write
> code only to remove/change it again!

Indeed! I would never have accepted patches split up like this
myself! :P My excuse is that I've been multitasking heavily lately and,
knowing how buggy the task-switching implementation is in my brain, I
reckoned it would be safer to commit often.

Tomorrow I'll fix these issues and send a new version.

--
Cheers,
Luca.


2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 08/15] nl80211: report periodic scan results

Add code to report periodic scan results whenever they are available. This
adds NL80211_CMD_PERIODIC_RESULTS to the API.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/linux/nl80211.h | 2 ++
net/wireless/nl80211.c | 19 +++++++++++++++++++
net/wireless/nl80211.h | 2 ++
net/wireless/scan.c | 2 +-
4 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index b3d1306..3206b8f 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -201,6 +201,7 @@
*
* @NL80211_CMD_START_PERIODIC_SCAN: start a periodic scan
* @NL80211_CMD_STOP_PERIODIC_SCAN: stop a periodic scan
+ * @NL80211_CMD_PERIODIC_RESULTS: there are periodic scan results available.
*
* @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
* or noise level
@@ -448,6 +449,7 @@ enum nl80211_commands {

NL80211_CMD_START_PERIODIC_SCAN,
NL80211_CMD_STOP_PERIODIC_SCAN,
+ NL80211_CMD_PERIODIC_RESULTS,

NL80211_CMD_REG_CHANGE,

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index fd50186..e1d7ab2 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -5151,6 +5151,25 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
nl80211_scan_mcgrp.id, GFP_KERNEL);
}

+void nl80211_send_periodic_results(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev)
+{
+ struct sk_buff *msg;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ if (nl80211_send_periodic_msg(msg, rdev, netdev, 0, 0, 0,
+ NL80211_CMD_PERIODIC_RESULTS) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_scan_mcgrp.id, GFP_KERNEL);
+}
+
void nl80211_send_periodic(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 cmd)
{
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 435d452..586fd1f 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -14,6 +14,8 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
void nl80211_send_periodic(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 cmd);
+void nl80211_send_periodic_results(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev);
void nl80211_send_reg_change_event(struct regulatory_request *request);
void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 300876b..925bdfb 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -101,7 +101,7 @@ void __cfg80211_periodic_results(struct work_struct *wk)
periodic_wk);

cfg80211_lock_rdev(rdev);
- nl80211_send_scan_done(rdev, rdev->periodic_req->dev);
+ nl80211_send_periodic_results(rdev, rdev->periodic_req->dev);
cfg80211_unlock_rdev(rdev);
}

--
1.7.0.4


2010-11-11 15:33:51

by Kahn, Gery

[permalink] [raw]
Subject: Re: [RFC 06/15] mac80211: add support for HW periodic scan

On 11/05/2010 09:55 PM, Johannes Berg wrote:
>
> On Fri, 05 Nov 2010 21:59:37 +0200, Luciano Coelho
> <[email protected]> wrote:
>> I think the idea of using background is good. Something like bg_scan or
>> something. The original idea was to call it background scan, but since
>> wl1271 doesn't support this while connected, I thought calling it
>> periodic scan would be slightly clearer about that. Background scan
>> sounds like you do it while connected (to me at least).
>
> Come to think of it though, we also call what we do when connected
> and trigger a scan manually a "background scan", so that's probably
> not a good name here.
>
> Not sure ... don't really have a good idea right now.
>
> johannes
> --
> To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
It may be sched_scan

2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 09/15] cfg80211: add channel support to periodic scan

Just add channels in the periodic_request structure. This is needed in order
to pass the desired channels to scan on down to the mac.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/net/cfg80211.h | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 41e7dc4..218e59f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -721,13 +721,20 @@ struct cfg80211_scan_request {
/**
* struct cfg80211_periodic_request - periodic scan request description
*
+ * @n_channels: total number of channels to scan
* @wiphy: the wiphy this was for
* @dev: the interface
+ * @channels: channels to scan
*/
struct cfg80211_periodic_request {
+ u32 n_channels;
+
/* internal */
struct wiphy *wiphy;
struct net_device *dev;
+
+ /* keep last */
+ struct ieee80211_channel *channels[0];
};

/**
--
1.7.0.4


2010-11-04 20:47:50

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 03/15] nl80211: alloc and free the periodic_req data

On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:

> + /*
> + * FIXME: Can this stay here? How will the auto-complete and other
> + * cleanup cases work?
> + */
> + kfree(rdev->periodic_req);
> + rdev->periodic_req = NULL;

No ... you want a new function that you call here, and also call the
stop into the device at netdev down from the notifier in core.c.

johannes


2010-11-04 20:50:09

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 06/15] mac80211: add support for HW periodic scan

On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:

> + .periodic_start= ieee80211_periodic_start,
> + .periodic_stop= ieee80211_periodic_stop,

whitespace ... also, _scan really ...


> + trace_drv_periodic_stop(local, sdata);
> + ret = local->ops->periodic_stop(&local->hw, &sdata->vif);
> + trace_drv_return_int(local, ret);
> + return ret;

why does this have a return value?


> @@ -812,6 +812,7 @@ struct ieee80211_local {
> struct cfg80211_ssid scan_ssid;
> struct cfg80211_scan_request *int_scan_req;
> struct cfg80211_scan_request *scan_req, *hw_scan_req;
> + struct cfg80211_periodic_request *periodic_req;

what do you need to store this for?

johannes



2010-11-01 12:29:08

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 01/15] nl80211: add periodic scan commands

Add NL80211_CMD_START_PERIODIC_SCAN and NL80211_CMD_STOP_PERIDIODIC_SCAN
commands to the nl80211 interface. This is just a skeleton and no actual
functionality is implemented.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/linux/nl80211.h | 6 ++
net/wireless/nl80211.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.h | 2 +
3 files changed, 134 insertions(+), 0 deletions(-)

diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 0edb256..b3d1306 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -199,6 +199,9 @@
* @NL80211_CMD_SCAN_ABORTED: scan was aborted, for unspecified reasons,
* partial scan results may be available
*
+ * @NL80211_CMD_START_PERIODIC_SCAN: start a periodic scan
+ * @NL80211_CMD_STOP_PERIODIC_SCAN: stop a periodic scan
+ *
* @NL80211_CMD_GET_SURVEY: get survey resuls, e.g. channel occupation
* or noise level
* @NL80211_CMD_NEW_SURVEY_RESULTS: survey data notification (as a reply to
@@ -443,6 +446,9 @@ enum nl80211_commands {
NL80211_CMD_NEW_SCAN_RESULTS,
NL80211_CMD_SCAN_ABORTED,

+ NL80211_CMD_START_PERIODIC_SCAN,
+ NL80211_CMD_STOP_PERIODIC_SCAN,
+
NL80211_CMD_REG_CHANGE,

NL80211_CMD_AUTHENTICATE,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index c506241..a2293ea 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2998,6 +2998,80 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
return err;
}

+static int nl80211_start_periodic(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev;
+ struct net_device *dev;
+ int err;
+
+ printk("nl80211_start_periodic\n");
+
+ rtnl_lock();
+
+ err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
+ if (err)
+ goto out_rtnl;
+
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ /* add actual calls here */
+
+ if (!err) {
+ nl80211_send_periodic(rdev, dev,
+ NL80211_CMD_START_PERIODIC_SCAN);
+ dev_hold(dev);
+ }
+
+out:
+ cfg80211_unlock_rdev(rdev);
+ dev_put(dev);
+out_rtnl:
+ rtnl_unlock();
+
+ return err;
+}
+
+static int nl80211_stop_periodic(struct sk_buff *skb,
+ struct genl_info *info)
+{
+ struct cfg80211_registered_device *rdev;
+ struct net_device *dev;
+ int err;
+
+ printk("nl80211_stop_periodic\n");
+
+ rtnl_lock();
+
+ err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
+ if (err)
+ goto out_rtnl;
+
+ if (!netif_running(dev)) {
+ err = -ENETDOWN;
+ goto out;
+ }
+
+ /* add actual calls here */
+
+ if (!err) {
+ nl80211_send_periodic(rdev, dev,
+ NL80211_CMD_STOP_PERIODIC_SCAN);
+ dev_hold(dev);
+ }
+
+out:
+ cfg80211_unlock_rdev(rdev);
+ dev_put(dev);
+out_rtnl:
+ rtnl_unlock();
+
+ return err;
+}
+
static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
struct cfg80211_registered_device *rdev,
struct wireless_dev *wdev,
@@ -4665,6 +4739,18 @@ static struct genl_ops nl80211_ops[] = {
.dumpit = nl80211_dump_scan,
},
{
+ .cmd = NL80211_CMD_START_PERIODIC_SCAN,
+ .doit = nl80211_start_periodic,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
+ .cmd = NL80211_CMD_STOP_PERIODIC_SCAN,
+ .doit = nl80211_stop_periodic,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ },
+ {
.cmd = NL80211_CMD_AUTHENTICATE,
.doit = nl80211_authenticate,
.policy = nl80211_policy,
@@ -4950,6 +5036,28 @@ static int nl80211_send_scan_msg(struct sk_buff *msg,
return -EMSGSIZE;
}

+static int nl80211_send_periodic_msg(struct sk_buff *msg,
+ struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ u32 pid, u32 seq, int flags,
+ u32 cmd)
+{
+ void *hdr;
+
+ hdr = nl80211hdr_put(msg, pid, seq, flags, cmd);
+ if (!hdr)
+ return -1;
+
+ NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, rdev->wiphy_idx);
+ NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, netdev->ifindex);
+
+ return genlmsg_end(msg, hdr);
+
+ nla_put_failure:
+ genlmsg_cancel(msg, hdr);
+ return -EMSGSIZE;
+}
+
void nl80211_send_scan_start(struct cfg80211_registered_device *rdev,
struct net_device *netdev)
{
@@ -5007,6 +5115,24 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
nl80211_scan_mcgrp.id, GFP_KERNEL);
}

+void nl80211_send_periodic(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, u32 cmd)
+{
+ struct sk_buff *msg;
+
+ msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ if (nl80211_send_periodic_msg(msg, rdev, netdev, 0, 0, 0, cmd) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_scan_mcgrp.id, GFP_KERNEL);
+}
+
/*
* This can happen on global regulatory changes or device specific settings
* based on custom world regulatory domains.
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 30d2f93..435d452 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -12,6 +12,8 @@ void nl80211_send_scan_done(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
struct net_device *netdev);
+void nl80211_send_periodic(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev, u32 cmd);
void nl80211_send_reg_change_event(struct regulatory_request *request);
void nl80211_send_rx_auth(struct cfg80211_registered_device *rdev,
struct net_device *netdev,
--
1.7.0.4


2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 10/15] nl80211: add channel support to the periodic scan

Parse and add channel information to the periodic scan request.

Signed-off-by: Luciano Coelho <[email protected]>
---
net/wireless/nl80211.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e1d7ab2..d5b9047 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3004,7 +3004,11 @@ static int nl80211_start_periodic(struct sk_buff *skb,
struct cfg80211_periodic_request *request;
struct cfg80211_registered_device *rdev;
struct net_device *dev;
- int err;
+ struct ieee80211_channel *channel;
+ struct nlattr *attr;
+ struct wiphy *wiphy;
+ int err, tmp, n_channels, i;
+ enum ieee80211_band band;

printk("nl80211_start_periodic\n");

@@ -3029,7 +3033,24 @@ static int nl80211_start_periodic(struct sk_buff *skb,
goto out;
}

- request = kzalloc(sizeof(*request), GFP_KERNEL);
+ wiphy = &rdev->wiphy;
+
+ if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
+ n_channels = validate_scan_freqs(
+ info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
+ if (!n_channels)
+ return -EINVAL;
+ } else {
+ n_channels = 0;
+
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++)
+ if (wiphy->bands[band])
+ n_channels += wiphy->bands[band]->n_channels;
+ }
+
+ request = kzalloc(sizeof(*request)
+ + sizeof(channel) * n_channels,
+ GFP_KERNEL);
if (!request) {
err = -ENOMEM;
goto out;
@@ -3040,8 +3061,56 @@ static int nl80211_start_periodic(struct sk_buff *skb,

rdev->periodic_req = request;

+ i = 0;
+ if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
+ /* user specified, bail out if channel not found */
+ nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) {
+ struct ieee80211_channel *chan;
+
+ chan = ieee80211_get_channel(wiphy, nla_get_u32(attr));
+
+ if (!chan) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ /* ignore disabled channels */
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ request->channels[i] = chan;
+ i++;
+ }
+ } else {
+ /* all channels */
+ for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
+ int j;
+ if (!wiphy->bands[band])
+ continue;
+ for (j = 0; j < wiphy->bands[band]->n_channels; j++) {
+ struct ieee80211_channel *chan;
+
+ chan = &wiphy->bands[band]->channels[j];
+
+ if (chan->flags & IEEE80211_CHAN_DISABLED)
+ continue;
+
+ request->channels[i] = chan;
+ i++;
+ }
+ }
+ }
+
+ if (!i) {
+ err = -EINVAL;
+ goto out_free;
+ }
+
+ request->n_channels = i;
+
err = rdev->ops->periodic_start(&rdev->wiphy, dev, request);
if (err) {
+out_free:
kfree(request);
rdev->periodic_req = NULL;
goto out;
--
1.7.0.4


2010-11-05 19:30:25

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 05/15] nl80211: call periodic_start and periodic_stop

On Thu, 2010-11-04 at 16:44 +0100, ext Johannes Berg wrote:
> On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
> > Now that cfg80211 has support for periodic scan, we call those ops in the
> > nl80211 code.
>
> Need to advertise these too in the wiphy cmd nl80211.

Yeps! Will do.

--
Cheers,
Luca.


2010-11-05 19:46:56

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 14/15] cfg80211: add ie support for periodic scans

On Thu, 2010-11-04 at 16:49 +0100, ext Johannes Berg wrote:
> On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
> > Add an array of pointers to ie (one element for each band) and the respective
> > array of ie lengths.
>
> Shouldn't this also be exposed to userspace?

Yes, it will be. I already started working on it. It should be
possible, like in normal scans, to pass extra IEs from userspace too.

--
Cheers,
Luca.


2010-11-04 20:48:33

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 05/15] nl80211: call periodic_start and periodic_stop

On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
> Now that cfg80211 has support for periodic scan, we call those ops in the
> nl80211 code.

Need to advertise these too in the wiphy cmd nl80211.

johannes


2010-11-04 20:47:00

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 01/15] nl80211: add periodic scan commands

On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:

> + rtnl_lock();
> +
> + err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
> + if (err)
> + goto out_rtnl;
> +
> + if (!netif_running(dev)) {
> + err = -ENETDOWN;
> + goto out;
> + }

ahem. we have infrastructure for this now.


> + .doit = nl80211_start_periodic,

> + .doit = nl80211_stop_periodic,

> +void nl80211_send_periodic(struct cfg80211_registered_device *rdev,
> + struct net_device *netdev, u32 cmd);

I think you should add _scan to all these names.

johannes


2010-11-05 14:17:07

by Luciano Coelho

[permalink] [raw]
Subject: Re: [RFC 03/15] nl80211: alloc and free the periodic_req data

On Thu, 2010-11-04 at 16:43 +0100, ext Johannes Berg wrote:
> On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
>
> > + /*
> > + * FIXME: Can this stay here? How will the auto-complete and other
> > + * cleanup cases work?
> > + */
> > + kfree(rdev->periodic_req);
> > + rdev->periodic_req = NULL;
>
> No ... you want a new function that you call here, and also call the
> stop into the device at netdev down from the notifier in core.c.

Sure! I'll change it.


--
Cheers,
Luca.


2010-11-04 20:52:13

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 14/15] cfg80211: add ie support for periodic scans

On Mon, 2010-11-01 at 13:52 +0200, Luciano Coelho wrote:
> Add an array of pointers to ie (one element for each band) and the respective
> array of ie lengths.

Shouldn't this also be exposed to userspace?

johannes


2010-11-01 12:25:59

by Luciano Coelho

[permalink] [raw]
Subject: [RFC 14/15] cfg80211: add ie support for periodic scans

Add an array of pointers to ie (one element for each band) and the respective
array of ie lengths.

Signed-off-by: Luciano Coelho <[email protected]>
---
include/net/cfg80211.h | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 3ac6fc9..fdc6b31 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -732,6 +732,8 @@ struct cfg80211_periodic_request {
struct cfg80211_ssid *ssids;
int n_ssids;
u32 n_channels;
+ const u8 *ie[IEEE80211_NUM_BANDS];
+ size_t ie_len[IEEE80211_NUM_BANDS];

/* internal */
struct wiphy *wiphy;
--
1.7.0.4


2010-11-05 19:51:00

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 05/15] nl80211: call periodic_start and periodic_stop


On Fri, 05 Nov 2010 21:44:46 +0200, Luciano Coelho
<[email protected]> wrote:
>> Need to advertise these too in the wiphy cmd nl80211.
>
> Yeps! Will do.

add a flag for it too so cfg80211 will advertise
it only for mac80211 drivers that support it, like
I did in

http://johannes.sipsolutions.net/patches/kernel/all/LATEST/026-nl80211-p2p-apis.patch

johannes