Add spectral scan support for Atheros AR92xx/AR93xx
cover 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(-)
Signature · 1 line
1.7.10.4
RFC 1/3 nl80211: add spec scan flag
This flag indicates that a spectrum scan is requested, if supported.
--- include/net/cfg80211.h | 2 ++ include/uapi/linux/nl80211.h | 5 +++++ net/wireless/nl80211.c | 3 +++ 3 files changed, 10 insertions(+)
include/net/cfg80211.h +2 -0
@@ -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 ];
include/uapi/linux/nl80211.h +5 -0
@@ -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,
net/wireless/nl80211.c +3 -0
@@ -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;
Signature · 1 line
1.7.10.4
Johannes Berg
maintainerRFC 1/3 nl80211: add spec scan flag
Quoted 1 line · Simon Wunderlich
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
Johannes Berg
maintainerRFC 1/3 nl80211: add spec scan flag
Quoted 6 lines · Johannes Berg
Quoted 1 line · Simon Wunderlich
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?
Quoted 7 lines
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
RFC 1/3 nl80211: add spec scan flag
Hello Johannes,
Quoted 6 lines · Johannes Berg
Quoted 5 lines · Johannes Berg
Quoted 1 line · Simon Wunderlich
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.
Quoted 6 lines
Quoted 6 lines
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.
Quoted 14 lines
Quoted 2 lines
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, ... };
Quoted 4 lines
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".
Quoted 6 lines
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 (usingsw_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?
Quoted 4 lines
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).
Quoted 2 lines
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
Url : http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20121128/2405002c/attachment.pgp
Malinen
RFC 1/3 nl80211: add spec scan flag
Quoted 2 lines · Simon Wunderlich
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?
Quoted 2 lines
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.
Quoted 5 lines
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
RFC 1/3 nl80211: add spec scan flag
Hey Jouni,
Quoted 10 lines · Jouni
Quoted 2 lines · Simon Wunderlich
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. :)
Quoted 7 lines
Quoted 2 lines
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?
Quoted 8 lines
Quoted 5 lines
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
Url : http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20121128/84b18988/attachment.pgp
Malinen
RFC 1/3 nl80211: add spec scan flag
Quoted 4 lines · Simon Wunderlich
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.
Quoted 2 lines
Anyway, you'd suggest to use the NL80211 remain on channel command for that?
Yes.
Quoted 3 lines
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).
Quoted 2 lines
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
Johannes Berg
maintainerRFC 1/3 nl80211: add spec scan flag
Quoted 6 lines
Quoted 3 lines
Anyway, you'd suggest to use the NL80211 remain on channel command for that?
Yes.
Quoted 7 lines
Quoted 3 lines
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.
Quoted 7 lines
Quoted 2 lines
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
Malinen
RFC 1/3 nl80211: add spec scan flag
Quoted 10 lines · Johannes Berg
Quoted 9 lines
Quoted 3 lines
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.
Quoted 3 lines
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..
Quoted 2 lines
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
Johannes Berg
maintainerRFC 1/3 nl80211: add spec scan flag
Quoted 7 lines · Jouni
Quoted 3 lines
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.
Quoted 5 lines
Quoted 2 lines
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
Johannes Berg
maintainerRFC 1/3 nl80211: add spec scan flag
In reply to Simon WunderlichQuoted 5 lines
Quoted 3 lines
Quoted 3 lines
That "if supported" here is pretty problematic. There's no way to know. Feature flag maybe?
Hmm, I could certainly add a
WIPHY_FLAGfor that.
nl80211 feature flag would be better
Quoted 11 lines
Quoted 5 lines
Quoted 5 lines
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.
Quoted 6 lines
Quoted 5 lines
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 (usingsw_scan_start, config hooks) --> no need to modify nl80211 at all
Quoted 8 lines
So the idea is something like:
* open debugfs-file (e.g. with cat)
* start scan "normally", without any flags
* read debugfs results, and close itMhm, 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.
Quoted 3 lines
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.
Quoted 3 lines
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.
Quoted 5 lines
Quoted 4 lines
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
Quoted 7 lines
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"
Quoted 3 lines
* 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
RFC 1/3 nl80211: add spec scan flag
Quoted 8 lines · Johannes Berg
Quoted 5 lines
Quoted 3 lines
Quoted 3 lines
That "if supported" here is pretty problematic. There's no way to know. Feature flag maybe?
Hmm, I could certainly add a
WIPHY_FLAGfor 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.
Quoted 9 lines
Quoted 9 lines
Quoted 5 lines
Quoted 5 lines
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.
Quoted 7 lines
Quoted 2 lines
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
Quoted 24 lines
Quoted 7 lines
Quoted 6 lines
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 (usingsw_scan_start, config hooks) --> no need to modify nl80211 at allQuoted 8 lines
So the idea is something like:
* open debugfs-file (e.g. with cat)
* start scan "normally", without any flags
* read debugfs results, and close itMhm, 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.
Quoted 3 lines
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.
Quoted 8 lines
Quoted 3 lines
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.
Quoted 22 lines
Quoted 5 lines
Quoted 4 lines
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
Quoted 7 lines
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 thisNo, 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"
Quoted 3 lines
* 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. :] )
Quoted 5 lines
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
Url : http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20121128/c329a1e6/attachment-0001.pgp
RFC 2/3 mac80211: add spectral_scan function, hook it up in scanning
In reply to Simon WunderlichAdd 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.
--- 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(+)
include/net/mac80211.h +6 -0
@@ -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); };/**
net/mac80211/driver-ops.h +10 -0
@@ -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 */
net/mac80211/scan.c +3 -0
@@ -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,
net/mac80211/trace.h +5 -0
@@ -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. */
Signature · 1 line
1.7.10.4
RFC 3/3 ath9k: add spectral scan feature
In reply to Simon WunderlichAdds 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.
--- 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(-)
drivers/net/wireless/ath/ath9k/ar9002_phy.c +37 -0
@@ -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); }
drivers/net/wireless/ath/ath9k/ar9003_phy.c +37 -0
@@ -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);
drivers/net/wireless/ath/ath9k/ath9k.h +12 -0
@@ -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 *);
drivers/net/wireless/ath/ath9k/debug.c +79 -0
91 lines not on this page · raw message
drivers/net/wireless/ath/ath9k/hw.h +4 -0
@@ -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 {
drivers/net/wireless/ath/ath9k/init.c +13 -0
@@ -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);
drivers/net/wireless/ath/ath9k/mac.h +5 -2
@@ -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 {
drivers/net/wireless/ath/ath9k/main.c +29 -0
@@ -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, };
drivers/net/wireless/ath/ath9k/recv.c +34 -0
@@ -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)
Signature · 1 line
1.7.10.4
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.
Quoted 26 lines
drivers/net/wireless/ath/ath9k/ar9002_phy.c +26
-0+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,
drivers/net/wireless/ath/ath9k/ar9002_phy.c static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah, · line 593
Quoted 10 lines
drivers/net/wireless/ath/ath9k/ar9002_phy.c +10
-0+ 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
RFC 3/3 ath9k: add spectral scan feature
Adrian,
thanks a lot for your feedback!
Quoted 7 lines · Adrian Chadd
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.
Quoted 39 lines
Quoted 26 lines
drivers/net/wireless/ath/ath9k/ar9002_phy.c +26
-0+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,drivers/net/wireless/ath/ath9k/ar9002_phy.c static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah, · line 593
Quoted 10 lines
drivers/net/wireless/ath/ath9k/ar9002_phy.c +10
-0+ 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) -
Quoted 8 lines
* 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.
Quoted 2 lines
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 :)
Quoted 5 lines
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.
Quoted 6 lines
Good luck,
Adrian
Thanks!
Simon
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 198 bytes
Desc: Digital signature
Url : http://lists.ath9k.org/pipermail/ath9k-devel/attachments/20121205/70112a57/attachment.pgp
RFC 3/3 ath9k: add spectral scan feature
Quoted 25 lines · Simon Wunderlich
Quoted 4 lines
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_COUNTto 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_ACTIVEbit? 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)
Quoted 4 lines
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
RFC 3/3 ath9k: add spectral scan feature
Quoted 7 lines · Felix Fietkau
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 structfft_samplebuffers 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
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
RFC 1/1 iw: add spectral scan attribute to scan function
In reply to Simon Wunderlich--- scan.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
scan.c +9 -3
@@ -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." );
Signature · 1 line
1.7.10.4
Quoted 9 lines · Simon Wunderlich
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?
Quoted 10 lines · Martin Schleier
Quoted 8 lines · Simon Wunderlich
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.
Quoted 6 lines
Quoted 1 line
[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
Quoted 7 lines · Simon Wunderlich
[...]
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
Hi Simon,
Quoted 21 lines · Simon Wunderlich
Quoted 7 lines · Simon Wunderlich
[...]
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.
Quoted 5 lines
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.
Hello Johnathan,
Quoted 27 lines · Jonathan Bither
Hi Simon,
Quoted 24 lines · Simon Wunderlich
Quoted 7 lines · Simon Wunderlich
[...]
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. :)
Quoted 9 lines
Quoted 2 lines
Cheers,
SimonA 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.
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