To be able to stop a triggered scan earlier (when one finds the desired
amount of scan results or some specific BSSID), the user needs to be
notified with intermediate scan result on reception of each new beacon/probe
response during the scan process.
Next patches adding the ability:
1. To stop a running scan with new 'scan cancel' command,
this v2 patch has mostly cosmetic changes.
2. To get new intermediate scan result event, during running scan.
3. To setup min RSSI threshold for intermediate scan events, which will
reduce significantly irrelevant intermediate scan result notification
(i.e. kernel-user traffic).
Victor Goldenshtein (5):
nl80211/cfg80211: adding 'scan_cancel' command.
mac80211: adding 'scan_cancel' command.
nl80211/cfg80211: adding intermediate scan result event.
mac80211: adding intermediate scan result event call.
nl80211/cfg80211: adding intermediate scan result filter.
include/linux/nl80211.h | 29 ++++++++++++++++++
include/net/cfg80211.h | 12 +++++++
net/mac80211/cfg.c | 8 +++++
net/mac80211/scan.c | 6 +++-
net/wireless/core.h | 12 +++++++
net/wireless/nl80211.c | 74 +++++++++++++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.h | 3 ++
net/wireless/scan.c | 63 ++++++++++++++++++++++++++++++++++++++++
net/wireless/util.c | 3 ++
9 files changed, 209 insertions(+), 1 deletions(-)
On Thu, Sep 08, 2011 at 09:31:01AM +0300, Victor Goldenshtein wrote:
> You're right, cfg80211 drivers will not support it. As I couldn't
> find a way to know whether it mac or cfg based driver, I can add
> also IEEE80211_HW_SUPPORTS_IM_RESULT" flag (as with cancel_scan) and
> then will advertise the nl80211 command if it set, is it OK?
Why would cfg80211 drivers not support this? There is already a pending
patch set to make ath6kl report scan results during the scan with
cfg80211_inform_bss_frame() so all it would need to do is to add another
call for cfg80211_send_intermediate_result() to support this... That
brings up a question: Do we need to have this new function or would it
be feasible for cfg80211 to generate the intermediate reports
automatically based on cfg80211_inform_bss{,_frame}() calls during the
scan?
--
Jouni Malinen PGP id EFC895FA
On Wed, 2011-09-21 at 12:03 +0300, Luciano Coelho wrote:
> > advantages of 1:
> > + info is directly available
> > + very fine-grained
> >
> > disadvantages of 1:
> > - lots of context switches, fairly expensive
>
> I just want to mention that these context switches will be there
> regardless of whether the full BSS info is passed or not.
Of course, but sending half the info is not really an option I'm willing
to consider :-)
> > advantages of 2:
> > + adds more generic filtering capability
>
> What do you mean here? I think we can have quite generic filtering in
> both cases.
True, but we won't do it if we don't need it here ;-)
> > + fewer context switches since retrieving BSS dump is limited & only
> > needs very few messages
>
> Indeed the number of switches will be smaller. To improve it further,
> as we discussed on IRC, we should also implement a per-channel BSS dump,
> otherwise we would have to retrieve the same data over an over again.
That's what I meant by the filtering.
> > disadvantages of 2:
> > - not quite as fine-grained
>
> One more:
> - this requires HW support (which we don't have in wl12xx ;), unless SW
> scan is used
Oh, that might be true. You might be able to fake it but that seems
complex.
> I see your point about reducing the context switches while still
> increasing the granularity of scan results with this option 2, but I
> think it's not going to be that helpful. Sure we can stop the scan
> earlier if we find what we want, but the possibilities will be smaller.
>
> Also, with option 2, you may have more context switches too, if you're
> scanning on not-so-crowded areas. If we report results per-channel, we
> will always have at least 37 events (with 11a and 11bg), each triggering
> at least 3 context switches, because userspace requests the BSS dump
> separately. If we use per-results events, including all BSS info, we
> will have just as many context switches as there are results available.
>
> Thus, I think passing intermediate result events, as they come, is more
> flexible and efficient in normal situations. And if we really want to
> reduce the context switches and data copied from kernel to userspace, we
> also have the option of improving results filtering. We could make some
> similar "match" filters as I have recently implemented for sched_scans.
Good points! I'm convinced :-)
johannes
On Mon, 2011-09-05 at 15:02 +0300, Victor Goldenshtein wrote:
> Mostly from an energy consumption and cpu load perspective,
> it can be useful to stop a triggered scan earlier, when one
> finds the desired scan results.
> Adding the ability to stop a scan from user space by exposing
> new NL80211_CMD_SCAN_CANCEL API.
Would be nice to advertise availability, possibly through mac80211?
johannes
On 08/09/2011 12:27, Johannes Berg wrote:
> On Thu, 2011-09-08 at 11:56 +0300, Victor Goldenshtein wrote:
>
>> If I understood you correctly.. I can create new
>> NL80211_ATTR_HW_CAPABILITY (u32) attribute which will advertise all
>> capabilities with "dev->wiphy.flags".
>
> No, I don't think you can advertise wiphy.flags since those flags are
> internal -- you'll have to map single wiphy flags to single capability
> flags which are also defined in nl80211.h.
>
> I'd call it "NL80211_ATTR_CAPABILITIES" to sidestep the issue of it
> being a driver of HW or whatever capability.
>
> johannes
>
Sorry, I'm not sure that I'm entirely understand, you mean to create
*nested* "NL80211_ATTR_CAPABILITIES" attribute which will contain all
new capability flags, mapped from wiphy.flags? and to do it within
existing nl80211_send_wiphy() function?
Thanks,
Victor.
On 07/09/2011 12:26, Johannes Berg wrote:
>> The intermediate scan event is not HW dependent, so there is no need to
>> advertise it..
>
> Not with mac80211 drivers, but with cfg80211 drivers?
>
> johannes
>
You're right, cfg80211 drivers will not support it. As I couldn't find a
way to know whether it mac or cfg based driver, I can add also
IEEE80211_HW_SUPPORTS_IM_RESULT" flag (as with cancel_scan) and then
will advertise the nl80211 command if it set, is it OK?
Thanks,
Victor.
On Mon, 2011-09-05 at 15:02 +0300, Victor Goldenshtein wrote:
> Adding intermediate scan result event by exposing new
> NL80211_CMD_IM_SCAN_RESULT event, which will contain
> NL80211_BSS_BSSID to specify the BSSID of received scan result and
> NL80211_BSS_SIGNAL_MBM to indicate signal strength.
>
> This event might be optionally enabled during
> NL80211_CMD_TRIGGER_SCAN, with NL80211_ATTR_IM_SCAN_RESULT
> flag attribute.
Also, this feature needs to be discoverable somehow, I think?
johannes
On Wed, 2011-09-21 at 11:19 +0300, Victor Goldenshtein wrote:
> Just talked with Luciano, and we though to make this event more generic
> and to pass the whole BSS info instead of just BSSID and rssi, what do
> you think?
I think there are two choices:
1) do what you say, and send the whole BSS info in the event
2) send a per-channel "scanned this channel" event, and allow filtering
the BSS dump per channel
There are a few trade-offs here:
advantages of 1:
+ info is directly available
+ very fine-grained
disadvantages of 1:
- lots of context switches, fairly expensive
advantages of 2:
+ adds more generic filtering capability
+ fewer context switches since retrieving BSS dump is limited & only
needs very few messages
disadvantages of 2:
- not quite as fine-grained
Personally, I prefer 2 because of the context switches issue, and
because I think there's little point in having so fine-grained
information. But I'm willing to concede that there may be a point in it,
more easily if you could explain why that's useful :-)
johannes
On Mon, 2011-09-05 at 15:02 +0300, Victor Goldenshtein wrote:
> +static void ieee80211_scan_cancel_req(struct wiphy *wiphy,
> + struct net_device *dev)
> +{
> + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
> + ieee80211_scan_cancel(sdata->local);
See my first mail -- scan_cancel() here isn't guaranteed to really do
anything at all.
johannes
On 21/09/2011 18:45, Luciano Coelho wrote:
> On Wed, 2011-09-21 at 18:31 +0300, Jouni Malinen wrote:
>> On Thu, Sep 08, 2011 at 09:31:01AM +0300, Victor Goldenshtein wrote:
>> That brings up a question: Do we need to have this new function or would it
>> be feasible for cfg80211 to generate the intermediate reports
>> automatically based on cfg80211_inform_bss{,_frame}() calls during the
>> scan?
>
> Very good point! Thinking of it, there is not need to add this new
> function and have the drivers call it. cfg80211 can find out when to
> send the results by itself, whenever someone calls
> cfg80211_inform_bss_frame(), by checking whether intermediate results
> are enabled or not.
>
> This will simplify the code. :) Thanks for your comments!
>
This could be a little bit problematic, since we need the
rdev->event_work, for the queue_work(), and wdev->event_list to save a
copy of the BSS, or just the mac which will be used to fetch the BSS
before the transmission (still not sure about it ..), and it seems like
these two can be obtained form sdata->dev, so it's look like that we
need this function and it should be in ieee80211_scan_rx.
Thanks,
Victor.
On 08/09/2011 09:49, Johannes Berg wrote:
> On Thu, 2011-09-08 at 09:31 +0300, Victor Goldenshtein wrote:
>> On 07/09/2011 12:26, Johannes Berg wrote:
>>>> The intermediate scan event is not HW dependent, so there is no need to
>>>> advertise it..
>>>
>>> Not with mac80211 drivers, but with cfg80211 drivers?
>>>
>>> johannes
>>>
>>
>> You're right, cfg80211 drivers will not support it. As I couldn't find a
>> way to know whether it mac or cfg based driver, I can add also
>> IEEE80211_HW_SUPPORTS_IM_RESULT" flag (as with cancel_scan) and then
>> will advertise the nl80211 command if it set, is it OK?
>
> I'd prefer not advertising the command, since so far we've only
> advertised supported commands as supported -- a new nl80211 flag would
> be nicer I think.
>
> Come to think of it, maybe it's time to bundle capability flags
> together. We seem to acquire new ones all the time, so maybe we should
> have a HW_CAPABILITY nl80211 attribute that can simply grow as
> needed ...
>
> johannes
>
If I understood you correctly.. I can create new
NL80211_ATTR_HW_CAPABILITY (u32) attribute which will advertise all
capabilities with "dev->wiphy.flags".
Thanks,
Victor.
On 21/09/2011 19:38, Johannes Berg wrote:
>> This could be a little bit problematic, since we need the
>> rdev->event_work, for the queue_work(), and wdev->event_list to save a
>> copy of the BSS, or just the mac which will be used to fetch the BSS
>> before the transmission (still not sure about it ..), and it seems like
>> these two can be obtained form sdata->dev, so it's look like that we
>> need this function and it should be in ieee80211_scan_rx.
>
> It is not an issue to send a genl message with GFP_ATOMIC.
>
The GFP_ATOMIC is for the event info allocation, and not for the genl
message, it have to be "GFP_ATOMIC" otherwise we will get kernel warnings.
Victor.
Adding intermediate scan result event by exposing new
NL80211_CMD_IM_SCAN_RESULT event, which will contain
NL80211_BSS_BSSID to specify the BSSID of received scan result and
NL80211_BSS_SIGNAL_MBM to indicate signal strength.
This event might be optionally enabled during
NL80211_CMD_TRIGGER_SCAN, with NL80211_ATTR_IM_SCAN_RESULT
flag attribute.
Signed-off-by: Victor Goldenshtein <[email protected]>
---
include/linux/nl80211.h | 17 +++++++++++++++
include/net/cfg80211.h | 10 +++++++++
net/wireless/core.h | 10 +++++++++
net/wireless/nl80211.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++
net/wireless/nl80211.h | 3 ++
net/wireless/scan.c | 43 +++++++++++++++++++++++++++++++++++++++
net/wireless/util.c | 3 ++
7 files changed, 137 insertions(+), 0 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 2fee93a..5a10ec0 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -504,6 +504,14 @@
* event, partial scan results will be available. Returns -ENOENT
* if scan is not running.
*
+ * @NL80211_CMD_IM_SCAN_RESULT: Intermediate scan result notification event,
+ * this event could be enabled with @NL80211_ATTR_IM_SCAN_RESULT
+ * flag during @NL80211_CMD_TRIGGER_SCAN. This event contains
+ * %NL80211_BSS_BSSID which is used to specify the BSSID of received
+ * scan result and %NL80211_BSS_SIGNAL_MBM to indicate signal strength.
+ * On reception of this notification, userspace may decide to stop earlier
+ * currently running scan with (@NL80211_CMD_SCAN_CANCEL).
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -630,6 +638,8 @@ enum nl80211_commands {
NL80211_CMD_SCAN_CANCEL,
+ NL80211_CMD_IM_SCAN_RESULT,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
@@ -1049,6 +1059,11 @@ enum nl80211_commands {
* (Re)Association Response frames when the driver (or firmware) replies to
* (Re)Association Request frames.
*
+ * @%NL80211_ATTR_IM_SCAN_RESULT: Flag attribute to enable intermediate
+ * scan result notification event (%NL80211_CMD_IM_SCAN_RESULT)
+ * for the %NL80211_CMD_TRIGGER_SCAN command.
+ * When set: will notify on each new scan result in the cache.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1259,6 +1274,8 @@ enum nl80211_attrs {
NL80211_ATTR_IE_PROBE_RESP,
NL80211_ATTR_IE_ASSOC_RESP,
+ NL80211_ATTR_IM_SCAN_RESULT,
+
/* 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 7b0c31e..967d385 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2527,6 +2527,16 @@ void cfg80211_sched_scan_results(struct wiphy *wiphy);
void cfg80211_sched_scan_stopped(struct wiphy *wiphy);
/**
+ * cfg80211_send_intermediate_result - inform userspace about new
+ * scan result.
+ *
+ * @dev: network device
+ * @cbss: bss info to report.
+ */
+void cfg80211_send_intermediate_result(struct net_device *dev,
+ struct cfg80211_bss *cbss);
+
+/**
* cfg80211_inform_bss_frame - inform cfg80211 of a received BSS frame
*
* @wiphy: the wiphy reporting the BSS
diff --git a/net/wireless/core.h b/net/wireless/core.h
index af22fe3..7484255 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -76,6 +76,9 @@ struct cfg80211_registered_device {
struct cfg80211_wowlan *wowlan;
+ /* intermediate scan result configuration */
+ bool im_scan_result;
+
/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
@@ -231,6 +234,7 @@ enum cfg80211_event_type {
EVENT_ROAMED,
EVENT_DISCONNECTED,
EVENT_IBSS_JOINED,
+ EVENT_IM_SCAN_RESULT,
};
struct cfg80211_event {
@@ -262,6 +266,10 @@ struct cfg80211_event {
struct {
u8 bssid[ETH_ALEN];
} ij;
+ struct {
+ u8 bssid[ETH_ALEN];
+ s32 signal;
+ } im;
};
};
@@ -421,6 +429,8 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
void __cfg80211_sched_scan_results(struct work_struct *wk);
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
bool driver_initiated);
+void __cfg80211_send_intermediate_result(struct net_device *dev,
+ struct cfg80211_event *ev);
int cfg80211_scan_cancel(struct cfg80211_registered_device *rdev);
void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index f9f239f..9e60b48 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -189,6 +189,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
+ [NL80211_ATTR_IM_SCAN_RESULT] = { .type = NLA_FLAG },
};
/* policy for the key attributes */
@@ -3557,6 +3558,11 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
}
}
+ if (info->attrs[NL80211_ATTR_IM_SCAN_RESULT])
+ rdev->im_scan_result = 1;
+ else
+ rdev->im_scan_result = 0;
+
request->dev = dev;
request->wiphy = &rdev->wiphy;
@@ -6296,6 +6302,31 @@ nl80211_send_sched_scan_msg(struct sk_buff *msg,
return -EMSGSIZE;
}
+static int nl80211_send_intermediate_msg(struct sk_buff *msg,
+ struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ u32 pid, u32 seq, int flags,
+ struct cfg80211_event *ev, 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);
+ NLA_PUT_U32(msg, NL80211_BSS_SIGNAL_MBM, ev->im.signal);
+ if (!is_zero_ether_addr(ev->im.bssid))
+ NLA_PUT(msg, NL80211_BSS_BSSID, ETH_ALEN, ev->im.bssid);
+
+ 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)
{
@@ -6353,6 +6384,26 @@ void nl80211_send_scan_aborted(struct cfg80211_registered_device *rdev,
nl80211_scan_mcgrp.id, GFP_KERNEL);
}
+void nl80211_send_intermediate_result(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ struct cfg80211_event *ev)
+{
+ struct sk_buff *msg;
+
+ msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
+ if (!msg)
+ return;
+
+ if (nl80211_send_intermediate_msg(msg, rdev, netdev, 0, 0, 0, ev,
+ NL80211_CMD_IM_SCAN_RESULT) < 0) {
+ nlmsg_free(msg);
+ return;
+ }
+
+ genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
+ nl80211_scan_mcgrp.id, GFP_KERNEL);
+}
+
void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
struct net_device *netdev)
{
diff --git a/net/wireless/nl80211.h b/net/wireless/nl80211.h
index 5d69c56..e0ea1b7 100644
--- a/net/wireless/nl80211.h
+++ b/net/wireless/nl80211.h
@@ -12,6 +12,9 @@ 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_intermediate_result(struct cfg80211_registered_device *rdev,
+ struct net_device *netdev,
+ struct cfg80211_event *ev);
void nl80211_send_sched_scan(struct cfg80211_registered_device *rdev,
struct net_device *netdev, u32 cmd);
void nl80211_send_sched_scan_results(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index bb4a991..9be42c3 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -156,6 +156,49 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
return 0;
}
+void __cfg80211_send_intermediate_result(struct net_device *dev,
+ struct cfg80211_event *ev)
+{
+ struct wireless_dev *wdev;
+ struct cfg80211_registered_device *rdev;
+
+ if (!dev)
+ return;
+
+ wdev = dev->ieee80211_ptr;
+ rdev = wiphy_to_dev(wdev->wiphy);
+
+ if (rdev->scan_req)
+ nl80211_send_intermediate_result(rdev, dev, ev);
+}
+
+void cfg80211_send_intermediate_result(struct net_device *dev,
+ struct cfg80211_bss *cbss)
+{
+ struct cfg80211_event *ev;
+ unsigned long flags;
+ struct wireless_dev *wdev = dev->ieee80211_ptr;
+ struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
+
+ if ((!rdev->im_scan_result) || (!rdev->scan_req) || (!cbss))
+ return;
+
+ ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+ if (!ev)
+ return;
+
+ ev->type = EVENT_IM_SCAN_RESULT;
+ ev->im.signal = cbss->signal;
+ if (cbss->bssid)
+ memcpy(ev->im.bssid, cbss->bssid, ETH_ALEN);
+
+ spin_lock_irqsave(&wdev->event_lock, flags);
+ list_add_tail(&ev->list, &wdev->event_list);
+ spin_unlock_irqrestore(&wdev->event_lock, flags);
+ queue_work(cfg80211_wq, &rdev->event_work);
+}
+EXPORT_SYMBOL(cfg80211_send_intermediate_result);
+
int cfg80211_scan_cancel(struct cfg80211_registered_device *rdev)
{
struct net_device *dev;
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 844ddb0..ad421ad 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -759,6 +759,9 @@ static void cfg80211_process_wdev_events(struct wireless_dev *wdev)
case EVENT_IBSS_JOINED:
__cfg80211_ibss_joined(wdev->netdev, ev->ij.bssid);
break;
+ case EVENT_IM_SCAN_RESULT:
+ __cfg80211_send_intermediate_result(wdev->netdev, ev);
+ break;
}
wdev_unlock(wdev);
--
1.7.0.4
User might want to be notified with intermediate scan results only
above some minimal RSSI. Adding new NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI
u32 attribute for the intermediate scan results RSSI filtering mechanism,
which will significantly reduce unnecessary Kernel-User traffic.
It might be optionally enabled during NL80211_CMD_TRIGGER_SCAN.
Signed-off-by: Victor Goldenshtein <[email protected]>
---
include/linux/nl80211.h | 5 +++++
net/wireless/core.h | 1 +
net/wireless/nl80211.c | 13 +++++++++++--
net/wireless/scan.c | 4 ++++
4 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 5a10ec0..44cc394 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -1063,6 +1063,10 @@ enum nl80211_commands {
* scan result notification event (%NL80211_CMD_IM_SCAN_RESULT)
* for the %NL80211_CMD_TRIGGER_SCAN command.
* When set: will notify on each new scan result in the cache.
+ * @%NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI: Intermediate event filtering.
+ * When set: will notify only those new scan result whose signal
+ * strength of probe response/beacon (in dBm) is stronger than this
+ * negative value (usually: -20 dBm > X > -95 dBm).
*
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -1275,6 +1279,7 @@ enum nl80211_attrs {
NL80211_ATTR_IE_ASSOC_RESP,
NL80211_ATTR_IM_SCAN_RESULT,
+ NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI,
/* add attributes here, update the policy in nl80211.c */
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 7484255..bacd5b3 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -78,6 +78,7 @@ struct cfg80211_registered_device {
/* intermediate scan result configuration */
bool im_scan_result;
+ s32 im_scan_result_min_rssi_mbm;
/* must be last because of the way we do wiphy_priv(),
* and it should at least be aligned to NETDEV_ALIGN */
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 9e60b48..82c7b40 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -190,6 +190,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_IE_ASSOC_RESP] = { .type = NLA_BINARY,
.len = IEEE80211_MAX_DATA_LEN },
[NL80211_ATTR_IM_SCAN_RESULT] = { .type = NLA_FLAG },
+ [NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI] = { .type = NLA_U32 },
};
/* policy for the key attributes */
@@ -3558,10 +3559,18 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
}
}
- if (info->attrs[NL80211_ATTR_IM_SCAN_RESULT])
+ if (info->attrs[NL80211_ATTR_IM_SCAN_RESULT]) {
rdev->im_scan_result = 1;
- else
+ if (info->attrs[NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI]) {
+ attr = info->attrs[NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI];
+ rdev->im_scan_result_min_rssi_mbm =
+ DBM_TO_MBM(nla_get_u32(attr));
+ } else {
+ rdev->im_scan_result_min_rssi_mbm = 0;
+ }
+ } else {
rdev->im_scan_result = 0;
+ }
request->dev = dev;
request->wiphy = &rdev->wiphy;
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 9be42c3..257c70a 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -183,6 +183,10 @@ void cfg80211_send_intermediate_result(struct net_device *dev,
if ((!rdev->im_scan_result) || (!rdev->scan_req) || (!cbss))
return;
+ if ((rdev->im_scan_result_min_rssi_mbm) &&
+ (rdev->im_scan_result_min_rssi_mbm > cbss->signal))
+ return;
+
ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
if (!ev)
return;
--
1.7.0.4
On Thu, 2011-09-08 at 17:39 +0300, Victor Goldenshtein wrote:
> > No, I don't think you can advertise wiphy.flags since those flags are
> > internal -- you'll have to map single wiphy flags to single capability
> > flags which are also defined in nl80211.h.
> >
> > I'd call it "NL80211_ATTR_CAPABILITIES" to sidestep the issue of it
> > being a driver of HW or whatever capability.
> Sorry, I'm not sure that I'm entirely understand, you mean to create
> *nested* "NL80211_ATTR_CAPABILITIES" attribute which will contain all
> new capability flags, mapped from wiphy.flags? and to do it within
> existing nl80211_send_wiphy() function?
No, I mean just add a U32 NL80211_ATTR_CAPABILITIES and put new flags
there, like this in nl80211.h:
enum nl80211_device_capabilities {
NL80211_DEV_CAPA_XXX = (1<<0);
etc...
};
Just don't use wiphy.flags directly since that's internal flags.
johannes
Mostly from an energy consumption and cpu load perspective,
it can be useful to stop a triggered scan earlier, when one
finds the desired scan results.
Adding the ability to stop a scan from user space by exposing
new NL80211_CMD_SCAN_CANCEL API.
Signed-off-by: Victor Goldenshtein <[email protected]>
---
include/linux/nl80211.h | 7 +++++++
include/net/cfg80211.h | 2 ++
net/wireless/core.h | 1 +
net/wireless/nl80211.c | 13 +++++++++++++
net/wireless/scan.c | 16 ++++++++++++++++
5 files changed, 39 insertions(+), 0 deletions(-)
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 89dec16..2fee93a 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -499,6 +499,11 @@
* this command may also be sent by the driver as an MLME event to
* inform userspace of the new replay counter.
*
+ * @NL80211_CMD_SCAN_CANCEL: Stop currently running scan (both sw and hw).
+ * This operation will eventually invoke %NL80211_CMD_SCAN_ABORTED
+ * event, partial scan results will be available. Returns -ENOENT
+ * if scan is not running.
+ *
* @NL80211_CMD_MAX: highest used command number
* @__NL80211_CMD_AFTER_LAST: internal use
*/
@@ -623,6 +628,8 @@ enum nl80211_commands {
NL80211_CMD_SET_REKEY_OFFLOAD,
+ NL80211_CMD_SCAN_CANCEL,
+
/* add new commands above here */
/* used to define NL80211_CMD_MAX below */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index d86a15d..7b0c31e 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1298,6 +1298,7 @@ struct cfg80211_gtk_rekey_data {
* the driver, and will be valid until passed to cfg80211_scan_done().
* For scan results, call cfg80211_inform_bss(); you can call this outside
* the scan/scan_done bracket too.
+ * @scan_cancel: Stop currently running scan (both sw and hw).
*
* @auth: Request to authenticate with the specified peer
* @assoc: Request to (re)associate with the specified peer
@@ -1465,6 +1466,7 @@ struct cfg80211_ops {
int (*scan)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_scan_request *request);
+ void (*scan_cancel)(struct wiphy *wiphy, struct net_device *dev);
int (*auth)(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_auth_request *req);
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 8672e02..af22fe3 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -421,6 +421,7 @@ void ___cfg80211_scan_done(struct cfg80211_registered_device *rdev, bool leak);
void __cfg80211_sched_scan_results(struct work_struct *wk);
int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
bool driver_initiated);
+int cfg80211_scan_cancel(struct cfg80211_registered_device *rdev);
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/nl80211.c b/net/wireless/nl80211.c
index 2aa6a21..f9f239f 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -3766,6 +3766,11 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
return err;
}
+static int nl80211_scan_cancel(struct sk_buff *skb, struct genl_info *info)
+{
+ return cfg80211_scan_cancel(info->user_ptr[0]);
+}
+
static int nl80211_send_bss(struct sk_buff *msg, struct netlink_callback *cb,
u32 seq, int flags,
struct cfg80211_registered_device *rdev,
@@ -5906,6 +5911,14 @@ static struct genl_ops nl80211_ops[] = {
NL80211_FLAG_NEED_RTNL,
},
{
+ .cmd = NL80211_CMD_SCAN_CANCEL,
+ .doit = nl80211_scan_cancel,
+ .policy = nl80211_policy,
+ .flags = GENL_ADMIN_PERM,
+ .internal_flags = NL80211_FLAG_NEED_NETDEV_UP |
+ NL80211_FLAG_NEED_RTNL,
+ },
+ {
.cmd = NL80211_CMD_GET_SCAN,
.policy = nl80211_policy,
.dumpit = nl80211_dump_scan,
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index b0f0039..bb4a991 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -156,6 +156,22 @@ int __cfg80211_stop_sched_scan(struct cfg80211_registered_device *rdev,
return 0;
}
+int cfg80211_scan_cancel(struct cfg80211_registered_device *rdev)
+{
+ struct net_device *dev;
+
+ ASSERT_RDEV_LOCK(rdev);
+
+ if (!rdev->ops->scan_cancel)
+ return -EOPNOTSUPP;
+ if (!rdev->scan_req)
+ return -ENOENT;
+
+ dev = rdev->scan_req->dev;
+ rdev->ops->scan_cancel(&rdev->wiphy, dev);
+ return 0;
+}
+
static void bss_release(struct kref *ref)
{
struct cfg80211_internal_bss *bss;
--
1.7.0.4
On Thu, 2011-09-22 at 10:13 +0300, Victor Goldenshtein wrote:
> On 22/09/2011 09:49, Luciano Coelho wrote:
>
> > I guess what Johannes meant is that you can send the genl message in
> > atomic context, so you don't need to save stuff and use the event work.
> > You can just send it immediately when cfg80211_inform_bss() and
> > cfg80211_inform_bss_frame() are called.
> >
> > I'm not really sure you can send genl messages while atomic, I think I
> > had problems with that earlier, but you can try. ;)
> >
>
> ;)
>
> Well I already did, and it's not working, when you"ll try to send genl
> messages while atomic, you will get kernel warning regarding "sleeping
> function called from invalid context".
That's what I thought. Johannes?
--
Cheers,
Luca.
On 22/09/2011 09:49, Luciano Coelho wrote:
> I guess what Johannes meant is that you can send the genl message in
> atomic context, so you don't need to save stuff and use the event work.
> You can just send it immediately when cfg80211_inform_bss() and
> cfg80211_inform_bss_frame() are called.
>
> I'm not really sure you can send genl messages while atomic, I think I
> had problems with that earlier, but you can try. ;)
>
;)
Well I already did, and it's not working, when you"ll try to send genl
messages while atomic, you will get kernel warning regarding "sleeping
function called from invalid context".
Thanks,
Victor.
On 05/09/2011 15:02, Victor Goldenshtein wrote:
> Adding intermediate scan result event by exposing new
> NL80211_CMD_IM_SCAN_RESULT event, which will contain
> NL80211_BSS_BSSID to specify the BSSID of received scan result and
> NL80211_BSS_SIGNAL_MBM to indicate signal strength.
>
Hi,
Just talked with Luciano, and we though to make this event more generic
and to pass the whole BSS info instead of just BSSID and rssi, what do
you think?
Thanks,
Victor.
On Thu, 2011-09-22 at 09:41 +0300, Victor Goldenshtein wrote:
> On 21/09/2011 19:38, Johannes Berg wrote:
>
> >> This could be a little bit problematic, since we need the
> >> rdev->event_work, for the queue_work(), and wdev->event_list to save a
> >> copy of the BSS, or just the mac which will be used to fetch the BSS
> >> before the transmission (still not sure about it ..), and it seems like
> >> these two can be obtained form sdata->dev, so it's look like that we
> >> need this function and it should be in ieee80211_scan_rx.
> >
> > It is not an issue to send a genl message with GFP_ATOMIC.
> >
>
>
> The GFP_ATOMIC is for the event info allocation, and not for the genl
> message, it have to be "GFP_ATOMIC" otherwise we will get kernel warnings.
I guess what Johannes meant is that you can send the genl message in
atomic context, so you don't need to save stuff and use the event work.
You can just send it immediately when cfg80211_inform_bss() and
cfg80211_inform_bss_frame() are called.
I'm not really sure you can send genl messages while atomic, I think I
had problems with that earlier, but you can try. ;)
--
Cheers,
Luca.
On Wed, 2011-09-21 at 19:28 +0300, Victor Goldenshtein wrote:
> On 21/09/2011 18:45, Luciano Coelho wrote:
> > On Wed, 2011-09-21 at 18:31 +0300, Jouni Malinen wrote:
> >> On Thu, Sep 08, 2011 at 09:31:01AM +0300, Victor Goldenshtein wrote:
> >> That brings up a question: Do we need to have this new function or would it
> >> be feasible for cfg80211 to generate the intermediate reports
> >> automatically based on cfg80211_inform_bss{,_frame}() calls during the
> >> scan?
> >
> > Very good point! Thinking of it, there is not need to add this new
> > function and have the drivers call it. cfg80211 can find out when to
> > send the results by itself, whenever someone calls
> > cfg80211_inform_bss_frame(), by checking whether intermediate results
> > are enabled or not.
> >
> > This will simplify the code. :) Thanks for your comments!
> >
>
> This could be a little bit problematic, since we need the
> rdev->event_work, for the queue_work(), and wdev->event_list to save a
> copy of the BSS, or just the mac which will be used to fetch the BSS
> before the transmission (still not sure about it ..), and it seems like
> these two can be obtained form sdata->dev, so it's look like that we
> need this function and it should be in ieee80211_scan_rx.
It is not an issue to send a genl message with GFP_ATOMIC.
johannes
On Thu, 2011-09-08 at 09:31 +0300, Victor Goldenshtein wrote:
> On 07/09/2011 12:26, Johannes Berg wrote:
> >> The intermediate scan event is not HW dependent, so there is no need to
> >> advertise it..
> >
> > Not with mac80211 drivers, but with cfg80211 drivers?
> >
> > johannes
> >
>
> You're right, cfg80211 drivers will not support it. As I couldn't find a
> way to know whether it mac or cfg based driver, I can add also
> IEEE80211_HW_SUPPORTS_IM_RESULT" flag (as with cancel_scan) and then
> will advertise the nl80211 command if it set, is it OK?
I'd prefer not advertising the command, since so far we've only
advertised supported commands as supported -- a new nl80211 flag would
be nicer I think.
Come to think of it, maybe it's time to bundle capability flags
together. We seem to acquire new ones all the time, so maybe we should
have a HW_CAPABILITY nl80211 attribute that can simply grow as
needed ...
johannes
On Thu, 2011-09-22 at 10:13 +0300, Victor Goldenshtein wrote:
> On 22/09/2011 09:49, Luciano Coelho wrote:
>
> > I guess what Johannes meant is that you can send the genl message in
> > atomic context, so you don't need to save stuff and use the event work.
> > You can just send it immediately when cfg80211_inform_bss() and
> > cfg80211_inform_bss_frame() are called.
> >
> > I'm not really sure you can send genl messages while atomic, I think I
> > had problems with that earlier, but you can try. ;)
> >
>
> ;)
>
> Well I already did, and it's not working, when you"ll try to send genl
> messages while atomic, you will get kernel warning regarding "sleeping
> function called from invalid context".
Where? We do that a lot, e.g. nl80211_send_mlme_event().
johannes
Implementing the scan_cancel operation in the mac80211,
by calling existing ieee80211_scan_cancel() function.
Signed-off-by: Victor Goldenshtein <[email protected]>
---
net/mac80211/cfg.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index c1fa577..7c3a473 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1389,6 +1389,13 @@ ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
return ieee80211_request_sched_scan_stop(sdata);
}
+static void ieee80211_scan_cancel_req(struct wiphy *wiphy,
+ struct net_device *dev)
+{
+ struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
+ ieee80211_scan_cancel(sdata->local);
+}
+
static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
struct cfg80211_auth_request *req)
{
@@ -2119,6 +2126,7 @@ struct cfg80211_ops mac80211_config_ops = {
.suspend = ieee80211_suspend,
.resume = ieee80211_resume,
.scan = ieee80211_scan,
+ .scan_cancel = ieee80211_scan_cancel_req,
.sched_scan_start = ieee80211_sched_scan_start,
.sched_scan_stop = ieee80211_sched_scan_stop,
.auth = ieee80211_auth,
--
1.7.0.4
On Mon, 2011-09-05 at 15:02 +0300, Victor Goldenshtein wrote:
> User might want to be notified with intermediate scan results only
> above some minimal RSSI. Adding new NL80211_ATTR_IM_SCAN_RESULT_MIN_RSSI
> u32 attribute for the intermediate scan results RSSI filtering mechanism,
> which will significantly reduce unnecessary Kernel-User traffic.
> It might be optionally enabled during NL80211_CMD_TRIGGER_SCAN.
I think unicasting the responses will be a better reduction in traffic
-- is this really worth the complexity?
Also -- I don't like your subjects much. IMHO they shouldn't have a . at
the end and should worded in "simple present" rather than "present
continuous" tense [1]: "add intermediate ..." rather than "adding
intermediate".
johannes
[1] http://www.englishpage.com/verbpage/simplepresent.html
On Mon, 2011-09-05 at 15:02 +0300, Victor Goldenshtein wrote:
> +void nl80211_send_intermediate_result(struct cfg80211_registered_device *rdev,
> + struct net_device *netdev,
> + struct cfg80211_event *ev)
> +{
> + struct sk_buff *msg;
> +
> + msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
> + if (!msg)
> + return;
> +
> + if (nl80211_send_intermediate_msg(msg, rdev, netdev, 0, 0, 0, ev,
> + NL80211_CMD_IM_SCAN_RESULT) < 0) {
> + nlmsg_free(msg);
> + return;
> + }
> +
> + genlmsg_multicast_netns(wiphy_net(&rdev->wiphy), msg, 0,
> + nl80211_scan_mcgrp.id, GFP_KERNEL);
> +}
This will generate LOTS of messages. Maybe it'd be worthwhile to not
multicast them but unicast them to the socket that requested the scan?
johannes
On Wed, 2011-09-07 at 12:18 +0300, Victor Goldenshtein wrote:
> On 05/09/2011 15:08, Johannes Berg wrote:
>
> > Also, this feature needs to be discoverable somehow, I think?
> >
> > johannes
> >
>
> The intermediate scan event is not HW dependent, so there is no need to
> advertise it..
Not with mac80211 drivers, but with cfg80211 drivers?
johannes
On Wed, 2011-09-21 at 10:35 +0200, Johannes Berg wrote:
> On Wed, 2011-09-21 at 11:19 +0300, Victor Goldenshtein wrote:
>
> > Just talked with Luciano, and we though to make this event more generic
> > and to pass the whole BSS info instead of just BSSID and rssi, what do
> > you think?
>
> I think there are two choices:
>
> 1) do what you say, and send the whole BSS info in the event
>
> 2) send a per-channel "scanned this channel" event, and allow filtering
> the BSS dump per channel
>
>
> There are a few trade-offs here:
>
> advantages of 1:
> + info is directly available
> + very fine-grained
>
> disadvantages of 1:
> - lots of context switches, fairly expensive
I just want to mention that these context switches will be there
regardless of whether the full BSS info is passed or not.
> advantages of 2:
> + adds more generic filtering capability
What do you mean here? I think we can have quite generic filtering in
both cases.
> + fewer context switches since retrieving BSS dump is limited & only
> needs very few messages
Indeed the number of switches will be smaller. To improve it further,
as we discussed on IRC, we should also implement a per-channel BSS dump,
otherwise we would have to retrieve the same data over an over again.
> disadvantages of 2:
> - not quite as fine-grained
One more:
- this requires HW support (which we don't have in wl12xx ;), unless SW
scan is used
> Personally, I prefer 2 because of the context switches issue, and
> because I think there's little point in having so fine-grained
> information. But I'm willing to concede that there may be a point in it,
> more easily if you could explain why that's useful :-)
I see your point about reducing the context switches while still
increasing the granularity of scan results with this option 2, but I
think it's not going to be that helpful. Sure we can stop the scan
earlier if we find what we want, but the possibilities will be smaller.
Also, with option 2, you may have more context switches too, if you're
scanning on not-so-crowded areas. If we report results per-channel, we
will always have at least 37 events (with 11a and 11bg), each triggering
at least 3 context switches, because userspace requests the BSS dump
separately. If we use per-results events, including all BSS info, we
will have just as many context switches as there are results available.
Thus, I think passing intermediate result events, as they come, is more
flexible and efficient in normal situations. And if we really want to
reduce the context switches and data copied from kernel to userspace, we
also have the option of improving results filtering. We could make some
similar "match" filters as I have recently implemented for sched_scans.
--
Cheers,
Luca.
On Thu, 2011-09-08 at 11:56 +0300, Victor Goldenshtein wrote:
> If I understood you correctly.. I can create new
> NL80211_ATTR_HW_CAPABILITY (u32) attribute which will advertise all
> capabilities with "dev->wiphy.flags".
No, I don't think you can advertise wiphy.flags since those flags are
internal -- you'll have to map single wiphy flags to single capability
flags which are also defined in nl80211.h.
I'd call it "NL80211_ATTR_CAPABILITIES" to sidestep the issue of it
being a driver of HW or whatever capability.
johannes
Adding "cfg80211_send_intermediate_result" call on reception
of new beacon/probe response.
Signed-off-by: Victor Goldenshtein <[email protected]>
---
net/mac80211/scan.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 6f09eca..1204165 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -159,6 +159,7 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
__le16 fc;
bool presp, beacon = false;
struct ieee802_11_elems elems;
+ struct cfg80211_bss *cbss = NULL;
if (skb->len < 2)
return RX_DROP_UNUSABLE;
@@ -209,8 +210,11 @@ ieee80211_scan_rx(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
bss = ieee80211_bss_info_update(sdata->local, rx_status,
mgmt, skb->len, &elems,
channel, beacon);
- if (bss)
+ if (bss) {
+ cbss = container_of((void *)bss, struct cfg80211_bss, priv);
+ cfg80211_send_intermediate_result(sdata->dev, cbss);
ieee80211_rx_bss_put(sdata->local, bss);
+ }
/* If we are on-operating-channel, and this packet is for the
* current channel, pass the pkt on up the stack so that
--
1.7.0.4
On Wed, 2011-09-21 at 18:31 +0300, Jouni Malinen wrote:
> On Thu, Sep 08, 2011 at 09:31:01AM +0300, Victor Goldenshtein wrote:
> > You're right, cfg80211 drivers will not support it. As I couldn't
> > find a way to know whether it mac or cfg based driver, I can add
> > also IEEE80211_HW_SUPPORTS_IM_RESULT" flag (as with cancel_scan) and
> > then will advertise the nl80211 command if it set, is it OK?
>
> Why would cfg80211 drivers not support this? There is already a pending
> patch set to make ath6kl report scan results during the scan with
> cfg80211_inform_bss_frame() so all it would need to do is to add another
> call for cfg80211_send_intermediate_result() to support this...
Yeah, I guess he didn't mean that no cfg80211 drivers support it, but
that some drivers may not support it. At least this was what we
discussed privately. ;)
> That brings up a question: Do we need to have this new function or would it
> be feasible for cfg80211 to generate the intermediate reports
> automatically based on cfg80211_inform_bss{,_frame}() calls during the
> scan?
Very good point! Thinking of it, there is not need to add this new
function and have the drivers call it. cfg80211 can find out when to
send the results by itself, whenever someone calls
cfg80211_inform_bss_frame(), by checking whether intermediate results
are enabled or not.
This will simplify the code. :) Thanks for your comments!
--
Cheers,
Luca.