2012-11-27 19:01:51

by Simon Wunderlich

[permalink] [raw]
Subject: [RFC 0/3] Add spectral scan support for Atheros AR92xx/AR93xx

This patchset is a first request for comments for the upcoming spectral
scan feature. It adds a new attribute to nl80211 to ask for a spectral
scan while scanning, because we cycle through the channels anyway at
this time. If enabled by the driver, spectral scan results will be
collected. This feature has been enabled for AR92xx and AR93xx based
chipsets. As the FFT samples are very hardware dependent, they are only
provided via a debugfs file for further evaluation.

We've also written a visual evaluation program for these samples (see
screenshot [1] and sourcecode [2]).

Many details are not known due to the fact that I don't have access to
Atheros specifications and details. Many things are done by guessing
and might be wrong. I'm therefore requesting help from Qualcomm/Atheros
guys to confirm or correct my findings. Apart from that, after
discussion I think we could integrate this patchset to allow other
people to work on this as well, even if it is experimental now.

Questions from my end:
1. There are many TODOs/Comments in the patches regarding details,
please answer if you can. :)
2. The output format is very Atheros-dependent. If my finding that
byte n-4 is some kind of offset/exponent, I'd integrate this in
the debugfs output as well
3. The data length varies pretty much, there might be some false
positives/PHY errors which are not FFT data - what should be
the correct length?
4. Is there any special handling for HT40? At least the proprietary
driver symbol names suggest so [3]

(Possible) further work:
1. Integrate this patchset, confirm/correct findings
2. If anyone would like: Atheros proprietary driver seems to
support some kind of classification [3] (is this microwave? cordless
phone? whatever?)
3. If other devices also offer spectral scan support: define a
common interface to use it (not debugfs).


[1] http://packetmixer.de/sdl_spec_scan2.png
[2] https://github.com/simonwunderlich/FFT_eval
[3] http://www.wehavemorefun.de/fritzbox/Ath_spectral.ko#Symbole

Simon Wunderlich (3):
nl80211: add spec scan flag
mac80211: add spectral_scan function, hook it up in scanning
ath9k: add spectral scan feature

drivers/net/wireless/ath/ath9k/ar9002_phy.c | 37 +++++++++++++
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 37 +++++++++++++
drivers/net/wireless/ath/ath9k/ath9k.h | 12 ++++
drivers/net/wireless/ath/ath9k/debug.c | 79 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 4 ++
drivers/net/wireless/ath/ath9k/init.c | 13 +++++
drivers/net/wireless/ath/ath9k/mac.h | 7 ++-
drivers/net/wireless/ath/ath9k/main.c | 29 ++++++++++
drivers/net/wireless/ath/ath9k/recv.c | 34 ++++++++++++
include/net/cfg80211.h | 2 +
include/net/mac80211.h | 6 ++
include/uapi/linux/nl80211.h | 5 ++
net/mac80211/driver-ops.h | 10 ++++
net/mac80211/scan.c | 3 +
net/mac80211/trace.h | 5 ++
net/wireless/nl80211.c | 3 +
16 files changed, 284 insertions(+), 2 deletions(-)

--
1.7.10.4



2012-11-27 20:32:54

by Simon Wunderlich

[permalink] [raw]
Subject: Re: [RFC 0/3] Add spectral scan support for Atheros AR92xx/AR93xx

On Tue, Nov 27, 2012 at 08:49:52PM +0100, Simon Wunderlich wrote:
> [...]
>
> The goal of this was to create the spectral scan feature based on public
> information, so the results are probably not optimal yet, but I hope that
> this will help to move Qualcomm/Atheros disclosing some information (this seems
> to be planned anyway[2]). Otherwise, maybe other people can help
> reverse-engineering this. :)

Just to clarify: I don't mean anyone should disassemble proprietary object files
or use proprietary source code and re-use these findings without permission to
create this feature - this would probably be illegal anyway.

By reverse-engineering, I mean we can already dump data spectral scan data with
this patchset, but the hard part is to interpret this data correctly - as you'll
find in the patches, there are a lot of bits which we don't know what they
mean, and maybe there is even more info hidden in these bits. I've uploaded
some samples taken on my hardware to the github repo, so anyone can use my
program, matlab, or just stare at these heaps of bytes to find some patterns and
try to interpret it. Actually I was just staring at the bytes myself and wrote
this visualizer to get a better idea what they could mean.

Of course, if we can some docs or support from QCA officially, this would be even
better. :)

Cheers,
Simon


Attachments:
(No filename) (1.31 kB)
signature.asc (198.00 B)
Digital signature
Download all attachments

2012-11-27 19:50:02

by Simon Wunderlich

[permalink] [raw]
Subject: Re: [RFC 0/3] Add spectral scan support for Atheros AR92xx/AR93xx

On Tue, Nov 27, 2012 at 07:16:38PM +0000, Martin Schleier wrote:
> Simon Wunderlich <simon.wunderlich@...> writes:
>
> > This patchset is a first request for comments for the upcoming spectral
> > scan feature. It adds a new attribute to nl80211 to ask for a spectral
> > scan while scanning, because we cycle through the channels anyway at
> > this time. If enabled by the driver, spectral scan results will be
> > collected. This feature has been enabled for AR92xx and AR93xx based
> > chipsets. As the FFT samples are very hardware dependent, they are only
> > provided via a debugfs file for further evaluation.
> >
> > [3] http://www.wehavemorefun.de/fritzbox/Ath_spectral.ko#Symbole
>
> Erm. Just a quick question, since you mentioned this fritzbox ath_spectral.ko
> module... Is your "work" based or related to it, i.e.: did you peek at the
> assembler listings of it, or did someone else write a spec. and you just
> implemented it?

I didn't peek in assembler listings or anything, I've mostly followed
hints given on this mailing list or on the web and did some research who
else did implement spectrum scanning. Some of my sources:

http://permalink.gmane.org/gmane.linux.drivers.ath9k.devel/4834
http://comments.gmane.org/gmane.linux.drivers.ath9k.devel/8409
http://wiki.mikrotik.com/wiki/Manual:Spectrum_analyzer

From this, one can grasp that the AR_PHY_SPECTRAL_SCAN has to be used and
some phy errors have to be interpreted (phy error 5 and 38). The rest was
mostly trial and error, including the interpretation of the data - most of
this is guessing and comparing to the Ubiquiti AirView [1] Spectrum analyzer
USB dongle when using an analogue wireless camera. :)

The goal of this was to create the spectral scan feature based on public
information, so the results are probably not optimal yet, but I hope that
this will help to move Qualcomm/Atheros disclosing some information (this seems
to be planned anyway[2]). Otherwise, maybe other people can help
reverse-engineering this. :)

Cheers,
Simon

[1] http://www.ubnt.com/airview
[2] http://thread.gmane.org/gmane.linux.drivers.ath9k.devel/8409/focus=8411


Attachments:
(No filename) (2.08 kB)
signature.asc (198.00 B)
Digital signature
Download all attachments

2012-11-28 16:57:09

by Johannes Berg

[permalink] [raw]
Subject: Re: [ath9k-devel] [RFC 1/3] nl80211: add spec scan flag


> >Anyway, you'd suggest to use the NL80211 remain on channel command for
> >that?
>
> Yes.
>
> >Or add a new "spectral scan" nl80211 command to do a spectral scan on this
> >(or multiple) channels, and use the various functions from
> >mac80211/offchannel.c?
>
> I would rather add a flag to the existing r-o-c command to indicate that
> spectral scan functionality is to be enabled (well, assuming Johannes is
> fine with this).

Ultimately I don't really care all that much whether it's ROC-like or
SCAN-like, though it didn't seem like the timing mattered because all
the data was just collected inside the callback while it was running,
i.e. synchronously, and thus extended the scan timing?

For ROC I guess an argument could be made that it could just be a flag,
for SCAN I don't think so since none of the other scan functionality
applies. As far as the implementation is concerned, I don't really care,
but I do want to keep the userspace API clean.

scan could be more efficient since it doesn't always go back to the same
channel and can do multiple in a row, unlike ROC.


> >BTW, is there any limitation to remain on channel commands, like will they
> >work on AP ifaces, Ad-Hoc ifaces, MultiSSID in general, etc?
>
> I hope not. There may be some practical issues with not all drivers
> supporting this, but remain-on-channel is the mechanism we use for
> supporting concurrent operations (e.g., P2P negotiations or GAS/ANQP) and
> making this work in all combinations would be important regardless.

FWIW, right now our plan for iwlwifi is to only really support it with
the P2P Device wdev, but I'm not sure what implications that has in
terms of support for GAS/ANQP etc. We might have to revisit that.

Maybe we should start advertising where it's supported so wpa_s/hostapd
can disable/enable features appropriately?

johannes


2012-11-28 12:35:09

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 1/3] nl80211: add spec scan flag

On Tue, 2012-11-27 at 20:01 +0100, Simon Wunderlich wrote:
> This flag indicates that a spectrum scan is requested, if supported.

That "if supported" here is pretty problematic. There's no way to know.
Feature flag maybe?

Also, there are scan flags now. However, I don't see that this should
(ab)use the scan function. It doesn't seem likely that you want to do
this while you're sending probe requests, etc. OTOH, it seems likely
you'd want identical dwell times on all channels to have comparable
values, which isn't the case here.

I really think you need to decouple the API for this from scanning.

johannes


2012-11-28 19:39:19

by Simon Wunderlich

[permalink] [raw]
Subject: Re: [RFC 1/3] nl80211: add spec scan flag

On Wed, Nov 28, 2012 at 05:26:14PM +0100, Johannes Berg wrote:
>
> > > > That "if supported" here is pretty problematic. There's no way to know.
> > > > Feature flag maybe?
> >
> > Hmm, I could certainly add a WIPHY_FLAG for that.
>
> nl80211 feature flag would be better
>

OK, that would work too. Just that there are some Atheros Chips which don't
support spectral scan, like AR9160, but are supported by ath9k. I guess I'd
just set the feature if the chip revision is supported, from within ath9k.

> > > > Also, there are scan flags now. However, I don't see that this should
> > > > (ab)use the scan function. It doesn't seem likely that you want to do
> > > > this while you're sending probe requests, etc. OTOH, it seems likely
> > > > you'd want identical dwell times on all channels to have comparable
> > > > values, which isn't the case here.
> >
> > The times are not a big problem - at least for now, the spectral scan
> > is only done for a very short time [tm] when the channel is changed.
> >
> > The main reason why I wanted to use this function is that it can be used
> > while operation, that is sending power save, forbidding payload tx, etc.
>
> That's not an argument for using the scan API. That might be an argument
> for piggy-backing on the scan *implementation*, but that's an orthogonal
> issue. Note how I didn't comment on patch 2 -- I do think piggy-backing
> on the scan implementation would be acceptable.

OK

>
> > > So bottom line is that I think there are two choices:
> > > 1) for a proof of concept, implement it in debugfs only, in ath9k only,
> > > with e.g. a debugfs file that sets a flag that then triggers the
> > > spectral scan when you do a scan (using sw_scan_start, config hooks)
> > > --> no need to modify nl80211 at all
> >
> > So the idea is something like:
> > * open debugfs-file (e.g. with cat)
> > * start scan "normally", without any flags
> > * read debugfs results, and close it
> >
> > Mhm, this is definitely possible, although not too beautiful as well. :)
> >
> > It seems there is no way to trigger a scan from within ath9k/debugfs, right?
>
> No.
>
> > sw_scan_start() is currently undefined in ath9k, but we could add that.
> > By "config hooks" you mean the general config driver call to set the channel
> > etc?
>
> I meant to trigger the data collection there.
>
> > I could also cycle channels within ath9k, but the main problem I see is that
> > I can't turn off TX/go into power save mode from the driver, or would you see
> > anything feasible?
>
> Triggering it all from the driver doesn't seem possible, no. You could
> have the function take effect on the next scan, but it's still kinda
> hybrid. However, it wouldn't "pollute" nl80211 that way.
>

OK, so it could look like:

echo start > debugfs/ath9k/spectral_scan
iw dev wlan0 scan
cat debugfs/ath9k/spectral_scan
[... get output ...]
echo stop > debugfs/ath9k/spectral_scan

yeah, that's still hybrid, but still simple.

> > > 2) implement some well-defined API in nl80211, but don't tie it to
> > > scanning or a debugfs implementation of getting the data out, with
> > > versioning of the FFT data packets etc. so it can be updated later
> > > without breaking everything
> >
> > I guess if we implement this in iw, this would be done similarly to scan,
> > e.g. trigger the scan and wait on the socket for results? Or would we
> > use events instead?
> >
> > This would roughly mean:
> > * duplicate the mac80211 scan part for spectral scan to cycle channels/be quite
> > while doing this
>
> No, I didn't say this. I said the API should be different, the
> implementation in mac80211 could very well just be "either going to send
> probes & wait, or collect spectral scan data and continue to the next
> channel"
>
> > * duplicate iw scan (at least some parts), the interface could look very similar:
> > trigger scan, on receive scan results on another socket, wait for completion
> > (although iw still has this "warning, it's racy" thing inside. :] )
>
> Actually you need a separate application anyway, to interpret the
> results, so that application would
> * open a socket
> * send the spectral scan command
> * read the results on the socket

Ah OK, so we would have a new nl80211 spectral scan command which then calls
the mac80211/scan stuff, but with special flags which the normal scan wouldn't
do. It could then return the results, and the current scan command wouldn't be
harmed. I hope I got this right? :)

Also, putting all this into iw to dump the raw data would be feasible, no?
Right now I'm dumping the data on some AP, but display it on another computer
(with a screen :] ), so this intermediate step is needed anyways.

Actually, the ath9k-only way seems to be faster for now. I'm not sure about
the data interpretation (offset/exponents etc), and I'd like to have
this confirmed/corrected before exporting results via nl80211 - I don't want
to change the data format all the time. Maybe some ath9k fellow can comment
on that, or if they like the debugfs-only idea. :)

Thanks again,
Simon


Attachments:
(No filename) (4.99 kB)
signature.asc (198.00 B)
Digital signature
Download all attachments

2012-11-27 19:01:52

by Simon Wunderlich

[permalink] [raw]
Subject: [RFC] iw: add spectral scan attribute to scan function

Signed-off-by: Simon Wunderlich <[email protected]>
Signed-off-by: Mathias Kretschmer <[email protected]>
---
scan.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/scan.c b/scan.c
index 05bad0b..3e28722 100644
--- a/scan.c
+++ b/scan.c
@@ -70,7 +70,7 @@ static int handle_scan(struct nl80211_state *state,
DONE,
} parse = NONE;
int freq;
- bool passive = false, have_ssids = false, have_freqs = false;
+ bool passive = false, have_ssids = false, have_freqs = false, spec_scan = false;
size_t tmp;
unsigned char *ies;
int flags = 0;
@@ -115,6 +115,10 @@ static int handle_scan(struct nl80211_state *state,
parse = DONE;
passive = true;
break;
+ } else if (strcmp(argv[i], "spec-scan") == 0) {
+ parse = NONE;
+ spec_scan = true;
+ break;
}
case DONE:
return 1;
@@ -151,6 +155,8 @@ static int handle_scan(struct nl80211_state *state,
nla_put_nested(msg, NL80211_ATTR_SCAN_FREQUENCIES, freqs);
if (flags)
NLA_PUT_U32(msg, NL80211_ATTR_SCAN_FLAGS, flags);
+ if (spec_scan)
+ NLA_PUT_FLAG(msg, NL80211_ATTR_TX_SPEC_SCAN);

err = 0;
nla_put_failure:
@@ -1450,7 +1456,7 @@ static int handle_scan_combined(struct nl80211_state *state,
dump_argv[0] = argv[0];
return handle_cmd(state, id, dump_argc, dump_argv);
}
-TOPLEVEL(scan, "[-u] [freq <freq>*] [ies <hex as 00:11:..>] [lowpri,flush,ap-force] [ssid <ssid>*|passive]", 0, 0,
+TOPLEVEL(scan, "[-u] [freq <freq>*] [ies <hex as 00:11:..>] [lowpri,flush,ap-force,spec-scan] [ssid <ssid>*|passive]", 0, 0,
CIB_NETDEV, handle_scan_combined,
"Scan on the given frequencies and probe for the given SSIDs\n"
"(or wildcard if not given) unless passive scanning is requested.\n"
@@ -1460,7 +1466,7 @@ COMMAND(scan, dump, "[-u]",
NL80211_CMD_GET_SCAN, NLM_F_DUMP, CIB_NETDEV, handle_scan_dump,
"Dump the current scan results. If -u is specified, print unknown\n"
"data in scan results.");
-COMMAND(scan, trigger, "[freq <freq>*] [ies <hex as 00:11:..>] [lowpri,flush,ap-force] [ssid <ssid>*|passive]",
+COMMAND(scan, trigger, "[freq <freq>*] [ies <hex as 00:11:..>] [lowpri,flush,ap-force,spec-scan] [ssid <ssid>*|passive]",
NL80211_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, handle_scan,
"Trigger a scan on the given frequencies with probing for the given\n"
"SSIDs (or wildcard if not given) unless passive scanning is requested.");
--
1.7.10.4


2012-11-28 16:25:53

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 1/3] nl80211: add spec scan flag


> > > That "if supported" here is pretty problematic. There's no way to know.
> > > Feature flag maybe?
>
> Hmm, I could certainly add a WIPHY_FLAG for that.

nl80211 feature flag would be better

> > > Also, there are scan flags now. However, I don't see that this should
> > > (ab)use the scan function. It doesn't seem likely that you want to do
> > > this while you're sending probe requests, etc. OTOH, it seems likely
> > > you'd want identical dwell times on all channels to have comparable
> > > values, which isn't the case here.
>
> The times are not a big problem - at least for now, the spectral scan
> is only done for a very short time [tm] when the channel is changed.
>
> The main reason why I wanted to use this function is that it can be used
> while operation, that is sending power save, forbidding payload tx, etc.

That's not an argument for using the scan API. That might be an argument
for piggy-backing on the scan *implementation*, but that's an orthogonal
issue. Note how I didn't comment on patch 2 -- I do think piggy-backing
on the scan implementation would be acceptable.

> > So bottom line is that I think there are two choices:
> > 1) for a proof of concept, implement it in debugfs only, in ath9k only,
> > with e.g. a debugfs file that sets a flag that then triggers the
> > spectral scan when you do a scan (using sw_scan_start, config hooks)
> > --> no need to modify nl80211 at all
>
> So the idea is something like:
> * open debugfs-file (e.g. with cat)
> * start scan "normally", without any flags
> * read debugfs results, and close it
>
> Mhm, this is definitely possible, although not too beautiful as well. :)
>
> It seems there is no way to trigger a scan from within ath9k/debugfs, right?

No.

> sw_scan_start() is currently undefined in ath9k, but we could add that.
> By "config hooks" you mean the general config driver call to set the channel
> etc?

I meant to trigger the data collection there.

> I could also cycle channels within ath9k, but the main problem I see is that
> I can't turn off TX/go into power save mode from the driver, or would you see
> anything feasible?

Triggering it all from the driver doesn't seem possible, no. You could
have the function take effect on the next scan, but it's still kinda
hybrid. However, it wouldn't "pollute" nl80211 that way.

> > 2) implement some well-defined API in nl80211, but don't tie it to
> > scanning or a debugfs implementation of getting the data out, with
> > versioning of the FFT data packets etc. so it can be updated later
> > without breaking everything
>
> I guess if we implement this in iw, this would be done similarly to scan,
> e.g. trigger the scan and wait on the socket for results? Or would we
> use events instead?
>
> This would roughly mean:
> * duplicate the mac80211 scan part for spectral scan to cycle channels/be quite
> while doing this

No, I didn't say this. I said the API should be different, the
implementation in mac80211 could very well just be "either going to send
probes & wait, or collect spectral scan data and continue to the next
channel"

> * duplicate iw scan (at least some parts), the interface could look very similar:
> trigger scan, on receive scan results on another socket, wait for completion
> (although iw still has this "warning, it's racy" thing inside. :] )

Actually you need a separate application anyway, to interpret the
results, so that application would
* open a socket
* send the spectral scan command
* read the results on the socket

johannes


2012-11-27 19:01:51

by Simon Wunderlich

[permalink] [raw]
Subject: [RFC 1/3] nl80211: add spec scan flag

This flag indicates that a spectrum scan is requested, if supported.

Signed-off-by: Simon Wunderlich <[email protected]>
Signed-off-by: Mathias Kretschmer <[email protected]>
---
include/net/cfg80211.h | 2 ++
include/uapi/linux/nl80211.h | 5 +++++
net/wireless/nl80211.c | 3 +++
3 files changed, 10 insertions(+)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 8a1aec5..ce19e59 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1009,6 +1009,7 @@ struct cfg80211_ssid {
* @wdev: the wireless device to scan for
* @aborted: (internal) scan request was notified as aborted
* @no_cck: used to send probe requests at non CCK rate in 2GHz band
+ * @spec_scan: indicates that spectral scan is requested while scanning.
*/
struct cfg80211_scan_request {
struct cfg80211_ssid *ssids;
@@ -1027,6 +1028,7 @@ struct cfg80211_scan_request {
unsigned long scan_start;
bool aborted;
bool no_cck;
+ bool spec_scan;

/* keep last */
struct ieee80211_channel *channels[0];
diff --git a/include/uapi/linux/nl80211.h b/include/uapi/linux/nl80211.h
index 1a9a819..7da847f 100644
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1292,6 +1292,9 @@ enum nl80211_commands {
*
* @NL80211_ATTR_SCAN_FLAGS: scan request control flags (u32)
*
+ * @NL80211_ATTR_TX_SPEC_SCAN: Indicates whether a spectrum scan should be
+ * performed while scanning. Used with %NL80211_CMD_TRIGGER_SCAN command.
+ *
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -1555,6 +1558,8 @@ enum nl80211_attrs {

NL80211_ATTR_SCAN_FLAGS,

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

__NL80211_ATTR_AFTER_LAST,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4c427fa..2524509 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -337,6 +337,7 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
[NL80211_ATTR_ROAM_SUPPORT] = { .type = NLA_FLAG },
[NL80211_ATTR_SCHED_SCAN_MATCH] = { .type = NLA_NESTED },
[NL80211_ATTR_TX_NO_CCK_RATE] = { .type = NLA_FLAG },
+ [NL80211_ATTR_TX_SPEC_SCAN] = { .type = NLA_FLAG },
[NL80211_ATTR_TDLS_ACTION] = { .type = NLA_U8 },
[NL80211_ATTR_TDLS_DIALOG_TOKEN] = { .type = NLA_U8 },
[NL80211_ATTR_TDLS_OPERATION] = { .type = NLA_U8 },
@@ -4396,6 +4397,8 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)

request->no_cck =
nla_get_flag(info->attrs[NL80211_ATTR_TX_NO_CCK_RATE]);
+ request->spec_scan =
+ nla_get_flag(info->attrs[NL80211_ATTR_TX_SPEC_SCAN]);

request->wdev = wdev;
request->wiphy = &rdev->wiphy;
--
1.7.10.4


2012-11-28 16:50:00

by Jouni Malinen

[permalink] [raw]
Subject: Re: [ath9k-devel] [RFC 1/3] nl80211: add spec scan flag



On 11/28/12 8:12 AM, "Simon Wunderlich"
<[email protected]> wrote:

>Hmm, that would be possible as well ... Using the scan function is very
>convenient as I don't have to think about cycling, channel lists, etc.
>But putting more control to userspace is also possible, if we can ask the
>driver to just have a "quick spectral peek" on another channel.

Well, you may not need to think about channel cycling etc. for scan
operations, but you won't get much control over the timing or dwell
duration for that matter. Remain-on-channel gives you that.

>Anyway, you'd suggest to use the NL80211 remain on channel command for
>that?

Yes.

>Or add a new "spectral scan" nl80211 command to do a spectral scan on this
>(or multiple) channels, and use the various functions from
>mac80211/offchannel.c?

I would rather add a flag to the existing r-o-c command to indicate that
spectral scan functionality is to be enabled (well, assuming Johannes is
fine with this).

>BTW, is there any limitation to remain on channel commands, like will they
>work on AP ifaces, Ad-Hoc ifaces, MultiSSID in general, etc?

I hope not. There may be some practical issues with not all drivers
supporting this, but remain-on-channel is the mechanism we use for
supporting concurrent operations (e.g., P2P negotiations or GAS/ANQP) and
making this work in all combinations would be important regardless.

- Jouni


2012-11-28 17:06:41

by Jouni Malinen

[permalink] [raw]
Subject: Re: [ath9k-devel] [RFC 1/3] nl80211: add spec scan flag



On 11/28/12 8:57 AM, "Johannes Berg" <[email protected]> wrote:

>>>BTW, is there any limitation to remain on channel commands, like will
>>>they
>> >work on AP ifaces, Ad-Hoc ifaces, MultiSSID in general, etc?
>>
>> I hope not. There may be some practical issues with not all drivers
>> supporting this, but remain-on-channel is the mechanism we use for
>> supporting concurrent operations (e.g., P2P negotiations or GAS/ANQP)
>>and
>> making this work in all combinations would be important regardless.
>
>FWIW, right now our plan for iwlwifi is to only really support it with
>the P2P Device wdev, but I'm not sure what implications that has in
>terms of support for GAS/ANQP etc. We might have to revisit that.

GAS/ANQP is pre-association if that makes any difference. Anyway, quite a
few new things will start depending on off channel Action frames and
everything I'm working on this area will most likely be using r-o-c..

>Maybe we should start advertising where it's supported so wpa_s/hostapd
>can disable/enable features appropriately?

Yeah, sounds reasonable. I guess you could also reject the r-o-c command,
but it is cleaner if this can be determined beforehand.

- Jouni


2012-11-28 10:37:18

by Simon Wunderlich

[permalink] [raw]
Subject: Re: [RFC 0/3] Add spectral scan support for Atheros AR92xx/AR93xx

Hello Johnathan,

On Tue, Nov 27, 2012 at 04:01:39PM -0500, Jonathan Bither wrote:
> Hi Simon,
>
> On 11/27/2012 03:32 PM, Simon Wunderlich wrote:
> >On Tue, Nov 27, 2012 at 08:49:52PM +0100, Simon Wunderlich wrote:
> >>[...]
> >>
> >>The goal of this was to create the spectral scan feature based on public
> >>information, so the results are probably not optimal yet, but I hope that
> >>this will help to move Qualcomm/Atheros disclosing some information (this seems
> >>to be planned anyway[2]). Otherwise, maybe other people can help
> >>reverse-engineering this. :)
> >Just to clarify: I don't mean anyone should disassemble proprietary object files
> >or use proprietary source code and re-use these findings without permission to
> >create this feature - this would probably be illegal anyway.
> >
> >By reverse-engineering, I mean we can already dump data spectral scan data with
> >this patchset, but the hard part is to interpret this data correctly - as you'll
> >find in the patches, there are a lot of bits which we don't know what they
> >mean, and maybe there is even more info hidden in these bits. I've uploaded
> >some samples taken on my hardware to the github repo, so anyone can use my
> >program, matlab, or just stare at these heaps of bytes to find some patterns and
> >try to interpret it. Actually I was just staring at the bytes myself and wrote
> >this visualizer to get a better idea what they could mean.
> >
> >Of course, if we can some docs or support from QCA officially, this would be even
> >better. :)
> >
> >Cheers,
> > Simon
> A search brought me to their patent application. The Drawings on
> their patent application contain some more information on the signal
> classifications. Hopefully this will be able to help you or someone
> else.
>
> http://www.google.com/patents/US7929508
>

thanks for pointing that out! This doc gives a pretty good general idea
how things are working, although it isn't too helpful in details. It also
describes some pattern matching related things.

If you anyone is interested in the pattern matching things, also the
airshark paper is definitely worth to be read:

http://pages.cs.wisc.edu/~suman/pubs/airshark.pdf
(some AR9280 details are to be found at section 3.1)

Cheers,
Simon


Attachments:
(No filename) (2.21 kB)
signature.asc (198.00 B)
Digital signature
Download all attachments

2012-11-27 21:01:42

by Jonathan Bither

[permalink] [raw]
Subject: Re: [RFC 0/3] Add spectral scan support for Atheros AR92xx/AR93xx

Hi Simon,

On 11/27/2012 03:32 PM, Simon Wunderlich wrote:
> On Tue, Nov 27, 2012 at 08:49:52PM +0100, Simon Wunderlich wrote:
>> [...]
>>
>> The goal of this was to create the spectral scan feature based on public
>> information, so the results are probably not optimal yet, but I hope that
>> this will help to move Qualcomm/Atheros disclosing some information (this seems
>> to be planned anyway[2]). Otherwise, maybe other people can help
>> reverse-engineering this. :)
> Just to clarify: I don't mean anyone should disassemble proprietary object files
> or use proprietary source code and re-use these findings without permission to
> create this feature - this would probably be illegal anyway.
>
> By reverse-engineering, I mean we can already dump data spectral scan data with
> this patchset, but the hard part is to interpret this data correctly - as you'll
> find in the patches, there are a lot of bits which we don't know what they
> mean, and maybe there is even more info hidden in these bits. I've uploaded
> some samples taken on my hardware to the github repo, so anyone can use my
> program, matlab, or just stare at these heaps of bytes to find some patterns and
> try to interpret it. Actually I was just staring at the bytes myself and wrote
> this visualizer to get a better idea what they could mean.
>
> Of course, if we can some docs or support from QCA officially, this would be even
> better. :)
>
> Cheers,
> Simon
A search brought me to their patent application. The Drawings on their
patent application contain some more information on the signal
classifications. Hopefully this will be able to help you or someone else.

http://www.google.com/patents/US7929508

2012-11-28 15:39:59

by Jouni Malinen

[permalink] [raw]
Subject: Re: [ath9k-devel] [RFC 1/3] nl80211: add spec scan flag



On 11/28/12 7:19 AM, "Simon Wunderlich"
<[email protected]> wrote:

>The main reason why I wanted to use this function is that it can be used
>while operation, that is sending power save, forbidding payload tx, etc.

Have you looked at the remain-on-channel commands?

>It seems there is no way to trigger a scan from within ath9k/debugfs,
>right?

I don't think there is nor that there should be.. Do you really need scan
operating for this? I would use remain-on-channel commands from a user
space app to go through the channels you want to analyze.

>I could also cycle channels within ath9k, but the main problem I see is
>that
>I can't turn off TX/go into power save mode from the driver, or would you
>see
>anything feasible?

Remain-on-channel should take care of that, but yes, that would not be
triggered from ath9k, but from user space.

- Jouni


2012-11-28 16:12:32

by Simon Wunderlich

[permalink] [raw]
Subject: Re: [ath9k-devel] [RFC 1/3] nl80211: add spec scan flag

Hey Jouni,

On Wed, Nov 28, 2012 at 03:29:36PM +0000, Malinen, Jouni wrote:
>
>
> On 11/28/12 7:19 AM, "Simon Wunderlich"
> <[email protected]> wrote:
>
> >The main reason why I wanted to use this function is that it can be used
> >while operation, that is sending power save, forbidding payload tx, etc.
>
> Have you looked at the remain-on-channel commands?
>

TBH, today was the first time I've had a more close look. :)

> >It seems there is no way to trigger a scan from within ath9k/debugfs,
> >right?
>
> I don't think there is nor that there should be.. Do you really need scan
> operating for this? I would use remain-on-channel commands from a user
> space app to go through the channels you want to analyze.
>

Hmm, that would be possible as well ... Using the scan function is very
convenient as I don't have to think about cycling, channel lists, etc.
But putting more control to userspace is also possible, if we can ask the
driver to just have a "quick spectral peek" on another channel.

Anyway, you'd suggest to use the NL80211 remain on channel command for that?
Or add a new "spectral scan" nl80211 command to do a spectral scan on this
(or multiple) channels, and use the various functions from mac80211/offchannel.c?

BTW, is there any limitation to remain on channel commands, like will they
work on AP ifaces, Ad-Hoc ifaces, MultiSSID in general, etc?

> >I could also cycle channels within ath9k, but the main problem I see is
> >that
> >I can't turn off TX/go into power save mode from the driver, or would you
> >see
> >anything feasible?
>
> Remain-on-channel should take care of that, but yes, that would not be
> triggered from ath9k, but from user space.

That sounds good. :)

Thanks for the hint!
Simon


Attachments:
(No filename) (1.72 kB)
signature.asc (198.00 B)
Digital signature
Download all attachments

2012-11-27 19:01:54

by Simon Wunderlich

[permalink] [raw]
Subject: [RFC 3/3] ath9k: add spectral scan feature

Adds the spectral scan feature for ath9k. AR92xx and AR93xx chips
are supported for now. The spectral scan is triggered within a
channel scan from mac80211, results can be gathered via debugfs.

Signed-off-by: Simon Wunderlich <[email protected]>
Signed-off-by: Mathias Kretschmer <[email protected]>
---
drivers/net/wireless/ath/ath9k/ar9002_phy.c | 37 +++++++++++++
drivers/net/wireless/ath/ath9k/ar9003_phy.c | 37 +++++++++++++
drivers/net/wireless/ath/ath9k/ath9k.h | 12 ++++
drivers/net/wireless/ath/ath9k/debug.c | 79 +++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/hw.h | 4 ++
drivers/net/wireless/ath/ath9k/init.c | 13 +++++
drivers/net/wireless/ath/ath9k/mac.h | 7 ++-
drivers/net/wireless/ath/ath9k/main.c | 29 ++++++++++
drivers/net/wireless/ath/ath9k/recv.c | 34 ++++++++++++
9 files changed, 250 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/ar9002_phy.c b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
index 846dd79..9d8199d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.c
@@ -555,6 +555,42 @@ static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
}

+void ar9002_hw_spectral_scan(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
+
+ /* NOTE: this will generate a few samples ... lacking documentation,
+ * I'm not really sure what these parameters mean.
+ */
+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_COUNT, 8);
+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_PERIOD, 0xF);
+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, 0xFF);
+
+ /* Activate spectral scan */
+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_ACTIVE);
+
+ /* Poll for spectral scan complete */
+ if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_ACTIVE,
+ 0, AH_WAIT_TIMEOUT)) {
+ ath_err(common, "spectral scan wait failed\n");
+ return;
+ }
+
+ /* Disable spectral scan */
+ REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_ENABLE);
+}
+
void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -571,6 +607,7 @@ void ar9002_hw_attach_phy_ops(struct ath_hw *ah)

ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
+ ops->spectral_scan = ar9002_hw_spectral_scan;

ar9002_hw_set_nf_limits(ah);
}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index ce19c09..c79d701 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1450,6 +1450,42 @@ set_rfmode:
return 0;
}

+void ar9003_hw_spectral_scan(struct ath_hw *ah)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
+
+ /* NOTE: this will generate a few samples ... lacking documentation,
+ * I'm not really sure what these parameters mean.
+ */
+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_COUNT, 8);
+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_PERIOD, 0xF);
+ REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, 0xFF);
+
+ /* Activate spectral scan */
+ REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_ACTIVE);
+
+ /* Poll for spectral scan complete */
+ if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_ACTIVE,
+ 0, AH_WAIT_TIMEOUT)) {
+ ath_err(common, "spectral scan wait failed\n");
+ return;
+ }
+
+ /* Disable spectral scan */
+ REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
+ AR_PHY_SPECTRAL_SCAN_ENABLE);
+}
+
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1483,6 +1519,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
ops->antctrl_shared_chain_lnadiv = ar9003_hw_antctrl_shared_chain_lnadiv;
+ ops->spectral_scan = ar9003_hw_spectral_scan;

ar9003_hw_set_nf_limits(ah);
ar9003_hw_set_radar_conf(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 80bab1b..3a7789a 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -738,6 +738,8 @@ struct ath_softc {
u8 ant_tx, ant_rx;
struct dfs_pattern_detector *dfs_detector;
u32 wow_enabled;
+ struct list_head fft_list;
+ int fft_list_n;

#ifdef CONFIG_PM_SLEEP
atomic_t wow_got_bmiss_intr;
@@ -746,6 +748,16 @@ struct ath_softc {
#endif
};

+struct fft_sample {
+ struct list_head list;
+ u16 freq;
+ u8 rssi;
+ u8 ext_rssi;
+ u8 noise;
+ u8 *data;
+ s16 size;
+};
+
void ath9k_tasklet(unsigned long data);
int ath_cabq_update(struct ath_softc *);

diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 939308c..3576778 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -966,6 +966,83 @@ static const struct file_operations fops_recv = {
.llseek = default_llseek,
};

+static ssize_t read_file_spectral_scan(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ unsigned int len;
+ char buf[64];
+ struct fft_sample *fft_sample;
+ int i, ret, tlen = 0;
+
+ /* fft_samples are added within the same spinlock */
+ spin_lock_bh(&sc->rx.rxbuflock);
+ if (list_empty(&sc->fft_list)) {
+ spin_unlock_bh(&sc->rx.rxbuflock);
+ return 0;
+ }
+
+ fft_sample = list_first_entry(&sc->fft_list, struct fft_sample, list);
+ list_del(&fft_sample->list);
+ sc->fft_list_n--;
+ spin_unlock_bh(&sc->rx.rxbuflock);
+
+ /* print some additional information, like frequency, rssi, */
+ len = sprintf(buf, "%04d %03d %03d %03d ",
+ fft_sample->freq, fft_sample->rssi,
+ fft_sample->ext_rssi, fft_sample->noise);
+
+ /* wouldn't be able to fill header and data */
+ if ((tlen + len + 5 * fft_sample->size + 1) > count)
+ return 0;
+
+ ret = copy_to_user(user_buf + tlen, buf, len);
+ tlen += len - ret;
+ *ppos += len - ret;
+
+ /* TODO: anyone with the spectral scan specs, please confirm/explain!
+ *
+ * the last 7 bytes seem to have a special meaning.
+ *
+ * byte 0 to n-8: spectral scan data, length varies
+ * byte n-1: this might be bwinfo according to DFS, usually 0x10 or
+ * 0x11
+ * byte n-2: always 0 in my dumps, pulse-length-ext in dfs code
+ * byte n-3: always 0 on my AR9003, mostly 15, 16 or something bigger
+ * on my AR9002
+ * byte n-4: appears to be some kind of offset (exponent?)
+ * byte n-5: no clue
+ * byte n-6: no clue, but appears to have something to do with RSSI
+ * byte n-7: lower 6 bit seem to hold some value which is higher on
+ * AR9002 when there is no real signal
+ */
+
+ /* dump the packet content here */
+ for (i = 0; i < fft_sample->size; i++) {
+ len = sprintf(buf, "0x%02x ", fft_sample->data[i]);
+ ret = copy_to_user(user_buf + tlen, buf, len);
+ tlen += len - ret;
+ *ppos += len - ret;
+ }
+ len = sprintf(buf, "\n");
+ ret = copy_to_user(user_buf + tlen, buf, len);
+ tlen += len - ret;
+ *ppos += len - ret;
+
+ kfree(fft_sample->data);
+ kfree(fft_sample);
+
+ return tlen;
+}
+
+static const struct file_operations fops_spectral_scan = {
+ .read = read_file_spectral_scan,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+
static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -1571,6 +1648,8 @@ int ath9k_init_debug(struct ath_hw *ah)
&fops_base_eeprom);
debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_modal_eeprom);
+ debugfs_create_file("spectral_scan", S_IRUSR, sc->debug.debugfs_phy,
+ sc, &fops_spectral_scan);
#ifdef CONFIG_ATH9K_MAC_DEBUG
debugfs_create_file("samples", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_samps);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 3636dab..7f5a917 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -20,6 +20,7 @@
#include <linux/if_ether.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/list.h>

#include "mac.h"
#include "ani.h"
@@ -666,6 +667,8 @@ struct ath_hw_private_ops {
*
* @config_pci_powersave:
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
+ *
+ * @spectral_scan: initiate a spectral scan on the current channel
*/
struct ath_hw_ops {
void (*config_pci_powersave)(struct ath_hw *ah,
@@ -686,6 +689,7 @@ struct ath_hw_ops {
void (*antdiv_comb_conf_set)(struct ath_hw *ah,
struct ath_hw_antcomb_conf *antconf);
void (*antctrl_shared_chain_lnadiv)(struct ath_hw *hw, bool enable);
+ void (*spectral_scan)(struct ath_hw *ah);
};

struct ath_nf_limits {
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 80cae53..e4384a8 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -528,6 +528,8 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
sc->sc_ah = ah;

sc->dfs_detector = dfs_pattern_detector_init(NL80211_DFS_UNSET);
+ INIT_LIST_HEAD(&sc->fft_list);
+ sc->fft_list_n = 0;

if (!pdata) {
ah->ah_flags |= AH_USE_EEPROM;
@@ -878,6 +880,17 @@ static void ath9k_deinit_softc(struct ath_softc *sc)
if (ATH_TXQ_SETUP(sc, i))
ath_tx_cleanupq(sc, &sc->tx.txq[i]);

+ while (!list_empty(&sc->fft_list)) {
+ struct fft_sample *fft_sample;
+ fft_sample = list_first_entry(&sc->fft_list,
+ struct fft_sample,
+ list);
+ list_del(&fft_sample->list);
+ kfree(fft_sample->data);
+ kfree(fft_sample);
+ }
+
+ INIT_LIST_HEAD(&sc->fft_list);
ath9k_hw_deinit(sc->sc_ah);
if (sc->dfs_detector != NULL)
sc->dfs_detector->exit(sc->dfs_detector);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 4a745e6..5cad975 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -225,8 +225,11 @@ enum ath9k_phyerr {
ATH9K_PHYERR_HT_CRC_ERROR = 34,
ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35,
ATH9K_PHYERR_HT_RATE_ILLEGAL = 36,
-
- ATH9K_PHYERR_MAX = 37,
+ ATH9K_PHYERR_FFT_REPORT = 38, /* can anyone with the specs
+ * confirm this please?
+ * Obviously AR9003 only.
+ */
+ ATH9K_PHYERR_MAX = 39,
};

struct ath_desc {
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 0653dbc..8f64415 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -2365,6 +2365,33 @@ static void ath9k_set_wakeup(struct ieee80211_hw *hw, bool enabled)

#endif

+static void ath9k_spectral_scan(struct ieee80211_hw *hw)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ u32 rxfilter;
+
+ if (!ath9k_hw_ops(ah)->spectral_scan) {
+ ath_err(common, "spectrum analyzer not implemented on this hardware\n");
+ return;
+ }
+
+ ath9k_ps_wakeup(sc);
+ rxfilter = ath9k_hw_getrxfilter(ah);
+ ath9k_hw_setrxfilter(ah, rxfilter |
+ ATH9K_RX_FILTER_PHYRADAR |
+ ATH9K_RX_FILTER_PHYERR);
+ ath9k_ps_restore(sc);
+
+ ath9k_hw_ops(ah)->spectral_scan(ah);
+
+ /* restore rxfilter */
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_setrxfilter(sc->sc_ah, rxfilter);
+ ath9k_ps_restore(sc);
+}
+
struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx,
.start = ath9k_start,
@@ -2405,4 +2432,6 @@ struct ieee80211_ops ath9k_ops = {
.get_et_stats = ath9k_get_et_stats,
.get_et_strings = ath9k_get_et_strings,
#endif
+
+ .spectral_scan = ath9k_spectral_scan,
};
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 6aafbb7..793fc91 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -1034,6 +1034,35 @@ static void ath9k_rx_skb_postprocess(struct ath_common *common,
rxs->flag &= ~RX_FLAG_DECRYPTED;
}

+static void ath_process_fft(struct ath_softc *sc, struct ieee80211_hdr *hdr,
+ struct ath_rx_status *rs)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ struct fft_sample *fft_sample;
+
+ /* too short data is probably something else */
+ if (rs->rs_datalen < 30)
+ return;
+
+ /* don't bloat memory if userspace is lazy collecting fft data */
+ if (sc->fft_list_n > 10000)
+ return;
+
+ fft_sample = kmalloc(sizeof(*fft_sample), GFP_ATOMIC);
+ INIT_LIST_HEAD(&fft_sample->list);
+
+ fft_sample->freq = ah->curchan->chan->center_freq;
+ fft_sample->size = rs->rs_datalen;
+ fft_sample->rssi = rs->rs_rssi_ctl0;
+ fft_sample->ext_rssi = rs->rs_rssi_ext0;
+ fft_sample->noise = ah->noise;
+ fft_sample->data = kmalloc(fft_sample->size, GFP_ATOMIC);
+ memcpy(fft_sample->data, (u8 *)hdr, fft_sample->size);
+
+ list_add_tail(&fft_sample->list, &sc->fft_list);
+ sc->fft_list_n++;
+}
+
int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
{
struct ath_buf *bf;
@@ -1131,6 +1160,11 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
unlikely(tsf_lower - rs.rs_tstamp > 0x10000000))
rxs->mactime += 0x100000000ULL;

+ if ((rs.rs_status & ATH9K_RXERR_PHY) &&
+ (rs.rs_phyerr == ATH9K_PHYERR_RADAR ||
+ rs.rs_phyerr == ATH9K_PHYERR_FFT_REPORT))
+ ath_process_fft(sc, hdr, &rs);
+
retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
rxs, &decrypt_error);
if (retval)
--
1.7.10.4


2012-11-28 12:43:12

by Johannes Berg

[permalink] [raw]
Subject: Re: [RFC 1/3] nl80211: add spec scan flag

On Wed, 2012-11-28 at 13:35 +0100, Johannes Berg wrote:
> On Tue, 2012-11-27 at 20:01 +0100, Simon Wunderlich wrote:
> > This flag indicates that a spectrum scan is requested, if supported.
>
> That "if supported" here is pretty problematic. There's no way to know.
> Feature flag maybe?
>
> Also, there are scan flags now. However, I don't see that this should
> (ab)use the scan function. It doesn't seem likely that you want to do
> this while you're sending probe requests, etc. OTOH, it seems likely
> you'd want identical dwell times on all channels to have comparable
> values, which isn't the case here.
>
> I really think you need to decouple the API for this from scanning.

And then you can also define APIs to get the data out. While I realize
that the data is implementation-dependent, you could have an enum that
indicates the data format and describes it:

@NL80211_SPECTRAL_DATA_ATHEROS: u8 rssi,ext_rssi,noise,fft_data[] ...

enum nl80211_spectral_data {
NL80211_SPECTRAL_DATA_ATHEROS,
...
};

Then you can define a function to send the data to the userspace socket
that asked for it (yes, if you have a separate command you can send it
only to that app... wohoo! :P ) and don't even have to store it in the
kernel...

So bottom line is that I think there are two choices:
1) for a proof of concept, implement it in debugfs only, in ath9k only,
with e.g. a debugfs file that sets a flag that then triggers the
spectral scan when you do a scan (using sw_scan_start, config hooks)
--> no need to modify nl80211 at all
2) implement some well-defined API in nl80211, but don't tie it to
scanning or a debugfs implementation of getting the data out, with
versioning of the FFT data packets etc. so it can be updated later
without breaking everything

This hybrid isn't a good approach at all.

johannes


2012-11-27 19:16:50

by Martin Schleier

[permalink] [raw]
Subject: Re: [RFC 0/3] Add spectral scan support for Atheros AR92xx/AR93xx

Simon Wunderlich <simon.wunderlich@...> writes:

> This patchset is a first request for comments for the upcoming spectral
> scan feature. It adds a new attribute to nl80211 to ask for a spectral
> scan while scanning, because we cycle through the channels anyway at
> this time. If enabled by the driver, spectral scan results will be
> collected. This feature has been enabled for AR92xx and AR93xx based
> chipsets. As the FFT samples are very hardware dependent, they are only
> provided via a debugfs file for further evaluation.
>
> [3] http://www.wehavemorefun.de/fritzbox/Ath_spectral.ko#Symbole

Erm. Just a quick question, since you mentioned this fritzbox ath_spectral.ko
module... Is your "work" based or related to it, i.e.: did you peek at the
assembler listings of it, or did someone else write a spec. and you just
implemented it?



2012-11-27 19:01:51

by Simon Wunderlich

[permalink] [raw]
Subject: [RFC 2/3] mac80211: add spectral_scan function, hook it up in scanning

Add spectral_scan function to driver functions, and hook it up
in the scanning code.

Using the spectral scan from within the scan function has the charme
that it already does all the channel surfing for us.

Signed-off-by: Simon Wunderlich <[email protected]>
Signed-off-by: Mathias Kretschmer <[email protected]>
---
include/net/mac80211.h | 6 ++++++
net/mac80211/driver-ops.h | 10 ++++++++++
net/mac80211/scan.c | 3 +++
net/mac80211/trace.h | 5 +++++
4 files changed, 24 insertions(+)

diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index e1293c7..8104b7d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2428,6 +2428,10 @@ enum ieee80211_rate_control_changed {
* @restart_complete: Called after a call to ieee80211_restart_hw(), when the
* reconfiguration has completed. This can help the driver implement the
* reconfiguration step. This callback may sleep.
+ *
+ * @spectral_scan: Asks the driver to perform a spectral scan on the currently
+ * selected channel. Results are stored in the drivers internal structures
+ * currently.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -2602,6 +2606,8 @@ struct ieee80211_ops {
struct ieee80211_chanctx_conf *ctx);

void (*restart_complete)(struct ieee80211_hw *hw);
+
+ void (*spectral_scan)(struct ieee80211_hw *hw);
};

/**
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 68c27aa..df6d582 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1004,4 +1004,14 @@ static inline void drv_restart_complete(struct ieee80211_local *local)
trace_drv_return_void(local);
}

+static inline void drv_spectral_scan(struct ieee80211_local *local)
+{
+ might_sleep();
+
+ trace_drv_spectral_scan(local);
+ if (local->ops->spectral_scan)
+ local->ops->spectral_scan(&local->hw);
+ trace_drv_return_void(local);
+}
+
#endif /* __MAC80211_DRIVER_OPS */
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 8e9bb168..cd8a17b 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -665,6 +665,9 @@ static void ieee80211_scan_state_set_channel(struct ieee80211_local *local,
return;
}

+ if (local->scan_req->spec_scan && local->ops->spectral_scan)
+ drv_spectral_scan(local);
+
/*
* Probe delay is used to update the NAV, cf. 11.1.3.2.2
* (which unfortunately doesn't say _why_ step a) is done,
diff --git a/net/mac80211/trace.h b/net/mac80211/trace.h
index e9579b7..7efd325 100644
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -1421,6 +1421,11 @@ DEFINE_EVENT(local_only_evt, drv_restart_complete,
TP_ARGS(local)
);

+DEFINE_EVENT(local_only_evt, drv_spectral_scan,
+ TP_PROTO(struct ieee80211_local *local),
+ TP_ARGS(local)
+);
+
/*
* Tracing for API calls that drivers call.
*/
--
1.7.10.4


2012-11-28 15:19:30

by Simon Wunderlich

[permalink] [raw]
Subject: Re: [RFC 1/3] nl80211: add spec scan flag

Hello Johannes,

On Wed, Nov 28, 2012 at 01:43:36PM +0100, Johannes Berg wrote:
> On Wed, 2012-11-28 at 13:35 +0100, Johannes Berg wrote:
> > On Tue, 2012-11-27 at 20:01 +0100, Simon Wunderlich wrote:
> > > This flag indicates that a spectrum scan is requested, if supported.
> >
> > That "if supported" here is pretty problematic. There's no way to know.
> > Feature flag maybe?

Hmm, I could certainly add a WIPHY_FLAG for that.

> >
> > Also, there are scan flags now. However, I don't see that this should
> > (ab)use the scan function. It doesn't seem likely that you want to do
> > this while you're sending probe requests, etc. OTOH, it seems likely
> > you'd want identical dwell times on all channels to have comparable
> > values, which isn't the case here.

The times are not a big problem - at least for now, the spectral scan
is only done for a very short time [tm] when the channel is changed.

The main reason why I wanted to use this function is that it can be used
while operation, that is sending power save, forbidding payload tx, etc.

> >
> > I really think you need to decouple the API for this from scanning.
>
> And then you can also define APIs to get the data out. While I realize
> that the data is implementation-dependent, you could have an enum that
> indicates the data format and describes it:
>
> @NL80211_SPECTRAL_DATA_ATHEROS: u8 rssi,ext_rssi,noise,fft_data[] ...
>
> enum nl80211_spectral_data {
> NL80211_SPECTRAL_DATA_ATHEROS,
> ...
> };
>
> Then you can define a function to send the data to the userspace socket
> that asked for it (yes, if you have a separate command you can send it
> only to that app... wohoo! :P ) and don't even have to store it in the
> kernel...

Calling the spectral scan and RX the FFT data are different things, but
yes, having everything in one application would be much better than
"trigger at X, receive at Y".
>
> So bottom line is that I think there are two choices:
> 1) for a proof of concept, implement it in debugfs only, in ath9k only,
> with e.g. a debugfs file that sets a flag that then triggers the
> spectral scan when you do a scan (using sw_scan_start, config hooks)
> --> no need to modify nl80211 at all

So the idea is something like:
* open debugfs-file (e.g. with cat)
* start scan "normally", without any flags
* read debugfs results, and close it

Mhm, this is definitely possible, although not too beautiful as well. :)

It seems there is no way to trigger a scan from within ath9k/debugfs, right?

sw_scan_start() is currently undefined in ath9k, but we could add that.
By "config hooks" you mean the general config driver call to set the channel
etc?

I could also cycle channels within ath9k, but the main problem I see is that
I can't turn off TX/go into power save mode from the driver, or would you see
anything feasible?

> 2) implement some well-defined API in nl80211, but don't tie it to
> scanning or a debugfs implementation of getting the data out, with
> versioning of the FFT data packets etc. so it can be updated later
> without breaking everything

I guess if we implement this in iw, this would be done similarly to scan,
e.g. trigger the scan and wait on the socket for results? Or would we
use events instead?

This would roughly mean:
* duplicate the mac80211 scan part for spectral scan to cycle channels/be quite
while doing this
* duplicate iw scan (at least some parts), the interface could look very similar:
trigger scan, on receive scan results on another socket, wait for completion
(although iw still has this "warning, it's racy" thing inside. :] )

This looks like a whole lot of work, and would duplicate some code which
we need for scan and spec_scan (at least it looks like it). On the plus side,
this would be easier to change in the future (e.g. adding parameters for spec
scan, etc).

>
> This hybrid isn't a good approach at all.

I don't like hybrid approach as well, but hoped that it could be "good enough"
for a proof of concept. If someone ever implements pattern matching, the
interface will probably change again as well.

Maybe you could find this idea acceptable: Keep on using the scan command plus
some flag/and or attribute, but send "FFT result" as events or within the scan
socket instead of using debugfs. What do you think?

Thanks for your review and suggestions! I'd like to discuss the alternatives
to fully understand them and then choose one. :)

Cheers,
Simon


Attachments:
(No filename) (4.36 kB)
signature.asc (198.00 B)
Digital signature
Download all attachments

2012-11-28 17:09:03

by Johannes Berg

[permalink] [raw]
Subject: Re: [ath9k-devel] [RFC 1/3] nl80211: add spec scan flag

On Wed, 2012-11-28 at 17:06 +0000, Malinen, Jouni wrote:

> >FWIW, right now our plan for iwlwifi is to only really support it with
> >the P2P Device wdev, but I'm not sure what implications that has in
> >terms of support for GAS/ANQP etc. We might have to revisit that.
>
> GAS/ANQP is pre-association if that makes any difference. Anyway, quite a
> few new things will start depending on off channel Action frames and
> everything I'm working on this area will most likely be using r-o-c..

Yes, pre-association might make a difference. I think it's entirely
reasonable to implement it all using ROC, I just don't know whether or
not we can support it right now out of the box.

> >Maybe we should start advertising where it's supported so wpa_s/hostapd
> >can disable/enable features appropriately?
>
> Yeah, sounds reasonable. I guess you could also reject the r-o-c command,
> but it is cleaner if this can be determined beforehand.

We do that today. Actually, in the current driver we do allow it but
it's rather messy so I might remove the ability once we have P2P Device
support, not sure. In the future we'll have it only on P2P Device,
though making it work on unassociated interfaces should not be a big
issue.

johannes


2012-12-05 11:38:25

by Felix Fietkau

[permalink] [raw]
Subject: Re: [RFC 3/3] ath9k: add spectral scan feature

On 2012-12-05 11:40 AM, Simon Wunderlich wrote:
>> I suggest experimenting around with those particular parameters. You
>> should be able to coax out specific numbers of spectral scan events
>> when you set the COUNT parameter to something other than 8. But
>> polling that bit isn't needed. It should be asynchronous.
>
> As I said, on AR9220 it appears I get 8 samples when doing setting
> AR_PHY_SPECTRAL_SCAN_COUNT to 8 (plus maybe some other "stuff"/non-samples).
> On AR9380 I'm not so sure. Probably need to play with it a little
> more. Also, I don't know what "SHORT REPEAT" is supposed to mean, etc.
>
> About polling, you mean the SCAN_ACTIVE bit? It is probably only
> needed when I want to trigger for few samples and want to be informed when
> it's finished - which is a good thing when doing spectral scan (change channel,
> start and wait for samples, change again). But we probably don't need to wait
> for the "background spectral scanning" mode, that's right. If someone wants
> to implement detection for interfering radio users, that mode would be useful.
> I don't need it, but can prepare the neccesary functions.
>
> So I'd repost then:
> * ath9k/debugfs only patch for now, as Johannes suggested - I think we
> should concentrate on this for now (their are still a lot of open
> questions in my initial mail regarding sample interpretation etc)
> * split commands into enable/disable/configure/trigger
> * maybe add some defines for magic values (if I find any)
>
> I'd like this patchset to make the graphical spectral scan possible (as
> a Ubiquiti Airview), and give others the opportunity to add own features
> (pattern matching etc) on top of it. However I (currently) don't plan to
> do the latter myself.
How about using relay (Documentation/filesystems/relay.txt) to stream
sample data to user space via the debugfs file?
That way you don't have to keep a linked list of small struct fft_sample
buffers in the kernel and you can stream much more data efficiently with
little kernel side overhead.
It also makes pushing the streaming data to a network socket via
sendfile much more efficient.

- Felix

2012-12-01 04:00:54

by Adrian Chadd

[permalink] [raw]
Subject: Re: [RFC 3/3] ath9k: add spectral scan feature

Not that I'm specifically getting into this in any deep way right now, but..

On 27 November 2012 11:01, Simon Wunderlich
<[email protected]> wrote:

[snip] - this should apply to AR9380 and later I think.

> +void ar9002_hw_spectral_scan(struct ath_hw *ah)
> +{
> + struct ath_common *common = ath9k_hw_common(ah);
> +
> + REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
> +
> + /* NOTE: this will generate a few samples ... lacking documentation,
> + * I'm not really sure what these parameters mean.
> + */
> + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
> + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
> + AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
> + REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
> + AR_PHY_SPECTRAL_SCAN_COUNT, 8);
> + REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
> + AR_PHY_SPECTRAL_SCAN_PERIOD, 0xF);
> + REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
> + AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, 0xFF);
> +
> + /* Activate spectral scan */
> + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
> + AR_PHY_SPECTRAL_SCAN_ACTIVE);
> +
> + /* Poll for spectral scan complete */
> + if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
> + AR_PHY_SPECTRAL_SCAN_ACTIVE,
> + 0, AH_WAIT_TIMEOUT)) {
> + ath_err(common, "spectral scan wait failed\n");
> + return;
> + }
> +
> + /* Disable spectral scan */
> + REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
> + AR_PHY_SPECTRAL_SCAN_ENABLE);
> +}
> +

You shouldn't have to do this. There's two spectral scan modes (well, three) -

* when you're not decoding things, and you meet these parameters,
please send me some events (I think the patent mentions this);
* trigger _now_ and send me "X" events; then clear the spectral scan bit;
* trigger _now_ and just send me infinite events - on earlier chips
(AR9280 I think) the magic value may be 0; on the later values it may
be 255. Someone should experiment.

I suggest you separate out "configure/enable/disable" and "trigger" as options.

Grr, mumble mumble open source developers mumble mumble.. :-)

I suggest experimenting around with those particular parameters. You
should be able to coax out specific numbers of spectral scan events
when you set the COUNT parameter to something other than 8. But
polling that bit isn't needed. It should be asynchronous.

Good luck,



Adrian



Adrian

2012-12-05 10:40:18

by Simon Wunderlich

[permalink] [raw]
Subject: Re: [RFC 3/3] ath9k: add spectral scan feature

Adrian,

thanks a lot for your feedback!

On Fri, Nov 30, 2012 at 08:00:51PM -0800, Adrian Chadd wrote:
> Not that I'm specifically getting into this in any deep way right now, but..
>
> On 27 November 2012 11:01, Simon Wunderlich
> <[email protected]> wrote:
>
> [snip] - this should apply to AR9380 and later I think.
>

Actually I have pretty much the same code in both ar9002_phy.c and ar9003_phy.c,
because they get different register definitions (addresses etc) from their respective
header files.

You think that this wouldn't apply for AR9280? Is there something wrong or different
with the register access?

I have put scan count of 8 in here, but on AR9380 I get much more samples (more like
256). I haven't played with this very much, because "a couple" of samples was all I
needed for my graphical analyzer.

> > +void ar9002_hw_spectral_scan(struct ath_hw *ah)
> > +{
> > + struct ath_common *common = ath9k_hw_common(ah);
> > +
> > + REG_SET_BIT(ah, AR_PHY_RADAR_0, AR_PHY_RADAR_0_FFT_ENA);
> > +
> > + /* NOTE: this will generate a few samples ... lacking documentation,
> > + * I'm not really sure what these parameters mean.
> > + */
> > + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN, AR_PHY_SPECTRAL_SCAN_ENABLE);
> > + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
> > + AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT);
> > + REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
> > + AR_PHY_SPECTRAL_SCAN_COUNT, 8);
> > + REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
> > + AR_PHY_SPECTRAL_SCAN_PERIOD, 0xF);
> > + REG_RMW_FIELD(ah, AR_PHY_SPECTRAL_SCAN,
> > + AR_PHY_SPECTRAL_SCAN_FFT_PERIOD, 0xFF);
> > +
> > + /* Activate spectral scan */
> > + REG_SET_BIT(ah, AR_PHY_SPECTRAL_SCAN,
> > + AR_PHY_SPECTRAL_SCAN_ACTIVE);
> > +
> > + /* Poll for spectral scan complete */
> > + if (!ath9k_hw_wait(ah, AR_PHY_SPECTRAL_SCAN,
> > + AR_PHY_SPECTRAL_SCAN_ACTIVE,
> > + 0, AH_WAIT_TIMEOUT)) {
> > + ath_err(common, "spectral scan wait failed\n");
> > + return;
> > + }
> > +
> > + /* Disable spectral scan */
> > + REG_CLR_BIT(ah, AR_PHY_SPECTRAL_SCAN,
> > + AR_PHY_SPECTRAL_SCAN_ENABLE);
> > +}
> > +
>
> You shouldn't have to do this. There's two spectral scan modes (well, three) -
>
> * when you're not decoding things, and you meet these parameters,
> please send me some events (I think the patent mentions this);
> * trigger _now_ and send me "X" events; then clear the spectral scan bit;
> * trigger _now_ and just send me infinite events - on earlier chips
> (AR9280 I think) the magic value may be 0; on the later values it may
> be 255. Someone should experiment.
>
> I suggest you separate out "configure/enable/disable" and "trigger" as options.

OK, yeah I can do that - guess we should have different function calls for this
then, too. Don't know if all of this should be callable from mac80211 as well.

>
> Grr, mumble mumble open source developers mumble mumble.. :-)

What are you muttering about? :D

Should we rather keep this wonderful feature to the closed source world?
I don't think so :)

>
> I suggest experimenting around with those particular parameters. You
> should be able to coax out specific numbers of spectral scan events
> when you set the COUNT parameter to something other than 8. But
> polling that bit isn't needed. It should be asynchronous.

As I said, on AR9220 it appears I get 8 samples when doing setting
AR_PHY_SPECTRAL_SCAN_COUNT to 8 (plus maybe some other "stuff"/non-samples).
On AR9380 I'm not so sure. Probably need to play with it a little
more. Also, I don't know what "SHORT REPEAT" is supposed to mean, etc.

About polling, you mean the SCAN_ACTIVE bit? It is probably only
needed when I want to trigger for few samples and want to be informed when
it's finished - which is a good thing when doing spectral scan (change channel,
start and wait for samples, change again). But we probably don't need to wait
for the "background spectral scanning" mode, that's right. If someone wants
to implement detection for interfering radio users, that mode would be useful.
I don't need it, but can prepare the neccesary functions.

So I'd repost then:
* ath9k/debugfs only patch for now, as Johannes suggested - I think we
should concentrate on this for now (their are still a lot of open
questions in my initial mail regarding sample interpretation etc)
* split commands into enable/disable/configure/trigger
* maybe add some defines for magic values (if I find any)

I'd like this patchset to make the graphical spectral scan possible (as
a Ubiquiti Airview), and give others the opportunity to add own features
(pattern matching etc) on top of it. However I (currently) don't plan to
do the latter myself.

>
> Good luck,
>
>
>
> Adrian

Thanks!
Simon


Attachments:
(No filename) (4.89 kB)
signature.asc (198.00 B)
Digital signature
Download all attachments

2012-12-05 12:05:30

by Adrian Chadd

[permalink] [raw]
Subject: Re: [RFC 3/3] ath9k: add spectral scan feature

On 5 December 2012 03:38, Felix Fietkau <[email protected]> wrote:

> How about using relay (Documentation/filesystems/relay.txt) to stream
> sample data to user space via the debugfs file?
> That way you don't have to keep a linked list of small struct fft_sample
> buffers in the kernel and you can stream much more data efficiently with
> little kernel side overhead.
> It also makes pushing the streaming data to a network socket via
> sendfile much more efficient.

Yes, please do this.

When *cough* I do this for FreeBSD, I'll just have people expose this
via BPF. I already have code to pull radar PHY errors out via BPF, so
this becomes just as trivial to do.



Adrian

2012-12-17 20:08:20

by Adrian Chadd

[permalink] [raw]
Subject: Re: [RFC 3/3] ath9k: add spectral scan feature

Hi,

I'll repost this, as it seems emailing lists.ath9k.org doesn't seem to work out.

The formats are as follows. Please note that if a pulse terminates
during an FFT, the final entry may be truncated. So yes, you may not
always get an integer multiple of the relevant frame length.

Note that you shift each of the readings by max_exp to get a total
reading. max_index and max_magnitude I think are just derived from the
existing dataset; they're just a shortcut for software so it doesn't
have to parse the whole frame looking for the peak.

Static 20 mode:

0 bin -28 magnitude[7:0] = (|i| + |q|) >> max_exp
1 bin -27 magnitude[7:0] = (|i| + |q|) >> max_exp
2 - 53 ?
54 bin 26 magnitude[7:0] = (|i| + |q|) >> max_exp
55 bin 27 magnitude[7:0] = (|i| + |q|) >> max_exp
56 [7:0]: all bins {max_magnitude[1:0], bitmap_weight[5:0]}
57 [7:0]: all bins max_magnitude[9:2]
58 [7:0]: all bins {max_index[5:0], max_magnitude[11:10]}
59 [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)

Dynamic 20/40 mode:

0 bin -64 magnitude[7:0] = (|i| + |q|) >> max_exp or power (in dBm)
1 bin -63 magnitude[7:0] = (|i| + |q|) >> max_exp or power (in dBm)
2 - 125 ?
126 bin 62 magnitude[7:0] = (|i| + |q|) >> max_exp or power (in dBm)
127 bin 63 magnitude[7:0] = (|i| + |q|) >> max_exp or power (in dBm)
128 [7:0]: lower bins {max_magnitude[1:0], bitmap_weight[5:0]}
Baseband DFS 2 (Radar) Micro-Architecture
129 [7:0]: lower bins max_magnitude[9:2]
130 [7:0]: lower bins {max_index[5:0], max_magnitude[11:10]}
131 [7:0]: upper bins {max_magnitude[1:0], bitmap_weight[5:0]}
132 [7:0]: upper bins max_magnitude[9:2]
133 [7:0]: upper bins {max_index[5:0], max_magnitude[11:10]}
134 [3:0]: max_exp (shift amount to size max bin to 8-bit unsigned)

Ok, now for radar it's a tad different. There's a bit that is set if
the signal is above a certain threshold. If so, the bit is set to 1.
There's also a 3 bit magnitude value which is calculated against the
maximum magnitude value (floor(m(i) * 8 / max magnitude.)




Adrian