2011-11-08 16:34:11

by Zefir Kurtisi

[permalink] [raw]
Subject: [PATCH 0/2] ath9k: DFS radar detection

This patch series proposes DFS radar pulse detection for ath9k.

The first patch adds a new DFS module, the second turns those
knobs to enable the HW to detect radar pulses and forward them
to the new module.

Here, sanity and plausibility checks that are HW dependent are
performed and resulting radar events are passed to higher level
generic pattern detectors for further processing (spectrum
management, etc.).

DFS support is limited to newer chip-sets (for now 9280 and later).

So far, AP operation on DFS channels is not supported by
mac80211/hostapd. Testing the proposed pulse detection is done in
monitor mode.

Zefir Kurtisi (2):
ath9k: add DFS radar pulse processing
ath9k: integrate initial DFS module

drivers/net/wireless/ath/ath.h | 2 +
drivers/net/wireless/ath/ath9k/Makefile | 2 +
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/debug.c | 3 +
drivers/net/wireless/ath/ath9k/debug.h | 2 +
drivers/net/wireless/ath/ath9k/dfs.c | 203 ++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/dfs.h | 38 +++++
drivers/net/wireless/ath/ath9k/dfs_debug.c | 89 ++++++++++++
drivers/net/wireless/ath/ath9k/dfs_debug.h | 59 ++++++++
drivers/net/wireless/ath/ath9k/hw-ops.h | 9 ++
drivers/net/wireless/ath/ath9k/hw.c | 7 +
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/main.c | 16 +++
drivers/net/wireless/ath/ath9k/recv.c | 19 ++-
14 files changed, 446 insertions(+), 5 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath9k/dfs.c
create mode 100644 drivers/net/wireless/ath/ath9k/dfs.h
create mode 100644 drivers/net/wireless/ath/ath9k/dfs_debug.c
create mode 100644 drivers/net/wireless/ath/ath9k/dfs_debug.h

--
1.7.4.1



2011-11-16 14:50:47

by Zefir Kurtisi

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath9k: integrate initial DFS module

Hi Luis,

thanks for the feedback.

This series went through several RFCs before I posted it as patch. Now that there are still some general concerns open, would you prefer to go back to RFC or are you ok with PATCH_v2?


On 11/15/2011 05:45 PM, Luis R. Rodriguez wrote:
> On Tue, Nov 8, 2011 at 8:34 AM, Zefir Kurtisi <[email protected]> wrote:
>> This patch integrates the DFS module into ath9k, including
>> * build the module into ath9k_hw
>> [...]
>> diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
>> index 7ab7a1e..de0309e 100644
>> --- a/drivers/net/wireless/ath/ath9k/ath9k.h
>> +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
>> @@ -563,6 +563,7 @@ struct ath_ant_comb {
>> #define SC_OP_BT_SCAN BIT(13)
>> #define SC_OP_ANI_RUN BIT(14)
>> #define SC_OP_PRIM_STA_VIF BIT(15)
>> +#define SC_OP_DFS BIT(16)
>
> The way you use this is to set the bit when a DFS channel is found on
> the mac80211 config() callback so that upon ath_complete_reset() we
> call ath9k_hw_set_radar_params() with the params captured in
> ath_calcrxfilter(). This seems fair... but have you considered all the
> other cases that will call ath_complete_reset() that do come through
> the mac80211 config() callback? What got me thinking about this was
> the actual declaration of this bit, is it really necessary? It seems
> to reflect a state from a small state machine that you need to ensure
> is respected. If this is true you just need then to guarantee that
> that the ath9k_hw_set_radar_params() will get called properly for all
> the cases that you do need. Its not clear from the current
> implementation that this is the case right now, it seems a bit
> fragile. Consider all the idle() and non-idle() calls that mac80211
> could use to call on the driver. Granted, the idle stuff is mostly
> observed on the client side, but its just one case I am thinking off
> the top of my head based on a quick review of this patch.
>
We need to ensure two things to get the pulse reporting done:
1. write the configuration params to the DFS detector regs via ath9k_hw_set_radar_params() after chip reset
2. set the PHYRADAR bit in RX filter, i.e. let ath_calcrxfilter() add this bit in its mask returned to be correctly set with the following ath9k_hw_setrxfilter()

In my RFC_v2 I proposed to set the radar parameters when the device is set to a DFS channel and to preserve the PHYRADAR bit in the RX filter register. Felix pointed out that we can not rely on the register value being always valid (e.g. during reset) and we need to keep the information about DFS channel operation in higher layers.

Defining a DFS opmode flag for that is arguable (since we have the information from (curchan->flags & IEEE80211_CHAN_RADAR)), but for sure improves readability.

As for your concern about ath_complete_reset() being called from wherever: right now, it is called from three locations that end to be all in the processing path of either device initialization or configuration. From there, worst thing that can happen is that the device is reconfigured with the channel unchanged - resulting in a redundant write of radar configuration. I expect writing those handful registers twice being irrelevant to performance, or did you mean something else?

>> [...]
>> diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
>> index 76dbc85..c9ba80d 100644
>> --- a/drivers/net/wireless/ath/ath9k/hw.c
>> +++ b/drivers/net/wireless/ath/ath9k/hw.c
>> @@ -2333,6 +2333,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
>> pCap->pcie_lcr_offset = 0x80;
>> }
>>
>> + if (AR_SREV_9280_20_OR_LATER(ah)) {
>> + /*
>> + * TODO: check for which chip-sets we want to support DFS
>> + */
>> + pCap->hw_caps |= ATH9K_HW_CAP_DFS;
>> + }
>> +
>
> Please change to AR_SREV_9300_20_OR_LATER(), its the only family that
> we can likely get resources to support, validate and test for. I'm
> even having a hard time getting support, etc for AR9003 but I think
> its fair to at least get this chugging for AR9003. If someone wants to
> pick up support, validation and testing for AR9002 then great, but
> this is not trivial to commit to. I rather deal only with what we can
> get commitment to properly test and validate.
>
> In fact I will need to verify our test plan for this. I'll start on
> that while you review my comments.
>
Thanks for that. I remember Felix was asking to include support for AR9002 and after I tested pulse detection is working with 9280 I let it in. But sure, seeing it working somewhat and committing to support it in the long run are not the same.

I'm fine with reducing support to 9300_20_OR_LATER in v2.

>> [...]
>> @@ -1722,9 +1726,21 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
>> memset(&sc->survey[pos], 0, sizeof(struct survey_info));
>> }
>>
>> + if (curchan->flags & IEEE80211_CHAN_RADAR) {
>> + if (!(ah->caps.hw_caps & ATH9K_HW_CAP_DFS)) {
>> + ath_err(common, "HW does not support DFS\n");
>> + mutex_unlock(&sc->mutex);
>> + return -EINVAL;
>
> Seems like a wrong place for this, shouldn't cfg80211 deal with this
> check for us? That is, export a cfg80211 DFS capability and cfg80211
> would deny using any DFS channel unless the wiphy declares itself
> capable.
>
Thats ideally true. Problem is that the DFS managing component (which capability handling is part of) is not ready yet (big hello to TI guys) and I don't want to mess around with some half-baked capability handling in cfg/mac80211.

For now, lack of master support for DFS channels in mac80211/hostapd ensures that we are regulatory compliant here, since DFS channels will only be set in monitor mode.

I'd opt to take it as it is, maybe replace the above check with a WARN_ON until capability handling at upper layer is fully tested. Agree?

>> [...]
>> @@ -1855,11 +1858,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
>> if (sc->sc_flags & SC_OP_RXFLUSH)
>> goto requeue_drop_frag;
>>
>> - retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
>> - rxs, &decrypt_error);
>> - if (retval)
>> - goto requeue_drop_frag;
>> -
>> rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
>> if (rs.rs_tstamp > tsf_lower &&
>> unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
>> @@ -1869,6 +1867,17 @@ 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)) {
>> + /* DFS: check for radar pulse */
>> + ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
>> + }
>> +
>> + retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
>> + rxs, &decrypt_error);
>> + if (retval)
>> + goto requeue_drop_frag;
>> +
>
> As noted in the other e-mail please split the move of the check to
> another patch, the new code can be kept here.

Done: [PATCH] ath9k: trivial: reorder rx_tasklet processing

>
> Luis

Thanks,
Zefir

2011-11-16 04:16:33

by Mohammed Shafi

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath9k: integrate initial DFS module

>>> @@ -1869,6 +1867,17 @@ 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)) {
>>> + ? ? ? ? ? ? ? ? ? ? ? /* DFS: check for radar pulse */
>>> + ? ? ? ? ? ? ? ? ? ? ? ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
>>> + ? ? ? ? ? ? ? }
>>> +
>>> + ? ? ? ? ? ? ? retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?rxs, &decrypt_error);
>>> + ? ? ? ? ? ? ? if (retval)
>>> + ? ? ? ? ? ? ? ? ? ? ? goto requeue_drop_frag;
>>
>> does the above fixes any bug related to mactime displayed in sniffer
>>
>>
>
> Hi Mohammed,
>
> no, like all other modifications within this patch the above does not fix anything (at least not intentionally) ;)
>
> What it does is moving the calculation of rxs->mactime before ath9k_rx_skb_preprocess(), since the mactime is needed to stamp the radar event. So, the five lines marked as removals are actually moved further down which shouldn't have any side effects.

sure, thanks a lot for your explanation ;)

>
>
> Thanks
> Zefir
>



--
shafi

2011-11-24 09:04:07

by Zefir Kurtisi

[permalink] [raw]
Subject: Re: [PATCH 0/2] ath9k: DFS radar detection

On 11/24/2011 09:40 AM, Adrian Chadd wrote:
> On 24 November 2011 00:11, Zefir Kurtisi <[email protected]> wrote:
>> Luis,
>>
>> any pending concerns or feedback before I start working on v2?
>
> What's your ETA for getting the radar classification stuff done?
>
> I'd like to evaluate the radar classification code and how it all ties
> together. :)
>
> Thanks,
>
>
> adrian

Hi Adrian,

I'm stuck in my step-by-step approach, i.e. to get the pulse detection upstream first and then get back to the detection stuff. Just under-estimated how long it takes to get those few lines accepted...

Hopefully we'll have something to evaluate soon.



Zefir


2011-11-15 15:25:01

by Mohammed Shafi

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath9k: integrate initial DFS module

Hi Zefir,

just few doubt, sorry for the late reply

On Tue, Nov 8, 2011 at 10:04 PM, Zefir Kurtisi
<[email protected]> wrote:
> This patch integrates the DFS module into ath9k, including
> ?* build the module into ath9k_hw
> ?* set up DFS debugfs
> ?* define HW capability flag for DFS support
> ? (so far: AR_SREV_9280_20_OR_LATER, TBC)
> ?* define and set DFS opmode flag when on DFS channel
> ? * configure radar params after reset
> ? * provide radar RX filter flag in ath_calcrxfilter()
> ?* forward radar PHY errors to DFS module
>
> This is WIP and at its current stage is limited to test ath9k
> pulse detection capabilities. The DFS pattern matching is
> TBD in the higher layers and not part of this patch.
>
> Signed-off-by: Zefir Kurtisi <[email protected]>
> ---
> ?drivers/net/wireless/ath/ath9k/Makefile | ? ?2 ++
> ?drivers/net/wireless/ath/ath9k/ath9k.h ?| ? ?1 +
> ?drivers/net/wireless/ath/ath9k/debug.c ?| ? ?3 +++
> ?drivers/net/wireless/ath/ath9k/debug.h ?| ? ?2 ++
> ?drivers/net/wireless/ath/ath9k/hw-ops.h | ? ?9 +++++++++
> ?drivers/net/wireless/ath/ath9k/hw.c ? ? | ? ?7 +++++++
> ?drivers/net/wireless/ath/ath9k/hw.h ? ? | ? ?1 +
> ?drivers/net/wireless/ath/ath9k/main.c ? | ? 16 ++++++++++++++++
> ?drivers/net/wireless/ath/ath9k/recv.c ? | ? 19 ++++++++++++++-----
> ?9 files changed, 55 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
> index 36ed3c4..1f260a5 100644
> --- a/drivers/net/wireless/ath/ath9k/Makefile
> +++ b/drivers/net/wireless/ath/ath9k/Makefile
> @@ -29,6 +29,8 @@ ath9k_hw-y:= ?\
> ? ? ? ? ? ? ? ?eeprom_9287.o \
> ? ? ? ? ? ? ? ?ani.o \
> ? ? ? ? ? ? ? ?btcoex.o \
> + ? ? ? ? ? ? ? dfs.o \
> + ? ? ? ? ? ? ? dfs_debug.o \
> ? ? ? ? ? ? ? ?mac.o \
> ? ? ? ? ? ? ? ?ar9002_mac.o \
> ? ? ? ? ? ? ? ?ar9003_mac.o \
> diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
> index 7ab7a1e..de0309e 100644
> --- a/drivers/net/wireless/ath/ath9k/ath9k.h
> +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
> @@ -563,6 +563,7 @@ struct ath_ant_comb {
> ?#define SC_OP_BT_SCAN ? ? ? ? ? ? ? BIT(13)
> ?#define SC_OP_ANI_RUN ? ? ? ? ? ? ? BIT(14)
> ?#define SC_OP_PRIM_STA_VIF ? ? ? ? ?BIT(15)
> +#define SC_OP_DFS ? ? ? ? ? ? ? ? ? BIT(16)
>
> ?/* Powersave flags */
> ?#define PS_WAIT_FOR_BEACON ? ? ? ?BIT(0)
> diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
> index 138ae09..6642108 100644
> --- a/drivers/net/wireless/ath/ath9k/debug.c
> +++ b/drivers/net/wireless/ath/ath9k/debug.c
> @@ -1633,6 +1633,9 @@ int ath9k_init_debug(struct ath_hw *ah)
> ? ? ? ?debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ?sc, &fops_debug);
> ?#endif
> +
> + ? ? ? ath9k_dfs_init_debug(sc);
> +
> ? ? ? ?debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ?&fops_dma);
> ? ? ? ?debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
> diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
> index 4f6c939..f70735a 100644
> --- a/drivers/net/wireless/ath/ath9k/debug.h
> +++ b/drivers/net/wireless/ath/ath9k/debug.h
> @@ -19,6 +19,7 @@
>
> ?#include "hw.h"
> ?#include "rc.h"
> +#include "dfs_debug.h"
>
> ?struct ath_txq;
> ?struct ath_buf;
> @@ -180,6 +181,7 @@ struct ath_stats {
> ? ? ? ?struct ath_interrupt_stats istats;
> ? ? ? ?struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
> ? ? ? ?struct ath_rx_stats rxstats;
> + ? ? ? struct ath_dfs_stats dfs_stats;
> ? ? ? ?u32 reset[__RESET_TYPE_MAX];
> ?};
>
> diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
> index e74c233..c4ad0b0 100644
> --- a/drivers/net/wireless/ath/ath9k/hw-ops.h
> +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
> @@ -212,4 +212,13 @@ static inline int ath9k_hw_fast_chan_change(struct ath_hw *ah,
> ? ? ? ?return ath9k_hw_private_ops(ah)->fast_chan_change(ah, chan,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?ini_reloaded);
> ?}
> +
> +static inline void ath9k_hw_set_radar_params(struct ath_hw *ah)
> +{
> + ? ? ? if (!ath9k_hw_private_ops(ah)->set_radar_params)
> + ? ? ? ? ? ? ? return;
> +
> + ? ? ? ath9k_hw_private_ops(ah)->set_radar_params(ah, &ah->radar_conf);
> +}
> +
> ?#endif /* ATH9K_HW_OPS_H */
> diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
> index 76dbc85..c9ba80d 100644
> --- a/drivers/net/wireless/ath/ath9k/hw.c
> +++ b/drivers/net/wireless/ath/ath9k/hw.c
> @@ -2333,6 +2333,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
> ? ? ? ? ? ? ? ?pCap->pcie_lcr_offset = 0x80;
> ? ? ? ?}
>
> + ? ? ? if (AR_SREV_9280_20_OR_LATER(ah)) {
> + ? ? ? ? ? ? ? /*
> + ? ? ? ? ? ? ? ?* TODO: check for which chip-sets we want to support DFS
> + ? ? ? ? ? ? ? ?*/
> + ? ? ? ? ? ? ? pCap->hw_caps |= ATH9K_HW_CAP_DFS;
> + ? ? ? }
> +
> ? ? ? ?tx_chainmask = pCap->tx_chainmask;
> ? ? ? ?rx_chainmask = pCap->rx_chainmask;
> ? ? ? ?while (tx_chainmask || rx_chainmask) {
> diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
> index 9dbc3cd..4f02f83 100644
> --- a/drivers/net/wireless/ath/ath9k/hw.h
> +++ b/drivers/net/wireless/ath/ath9k/hw.h
> @@ -204,6 +204,7 @@ enum ath9k_hw_caps {
> ? ? ? ?ATH9K_HW_CAP_5GHZ ? ? ? ? ? ? ? ? ? ? ? = BIT(14),
> ? ? ? ?ATH9K_HW_CAP_APM ? ? ? ? ? ? ? ? ? ? ? ?= BIT(15),
> ? ? ? ?ATH9K_HW_CAP_RTT ? ? ? ? ? ? ? ? ? ? ? ?= BIT(16),
> + ? ? ? ATH9K_HW_CAP_DFS ? ? ? ? ? ? ? ? ? ? ? ?= BIT(17),
> ?};
>
> ?struct ath9k_hw_capabilities {
> diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> index d3b92ce..e86d820 100644
> --- a/drivers/net/wireless/ath/ath9k/main.c
> +++ b/drivers/net/wireless/ath/ath9k/main.c
> @@ -305,6 +305,10 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
> ? ? ? ? ? ? ? ?ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf);
> ? ? ? ?}
>
> + ? ? ? /* set radar parameters if in DFS mode */
> + ? ? ? if (sc->sc_flags & SC_OP_DFS)
> + ? ? ? ? ? ? ? ath9k_hw_set_radar_params(ah);
> +
> ? ? ? ?ieee80211_wake_queues(sc->hw);
>
> ? ? ? ?return true;
> @@ -1722,9 +1726,21 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
> ? ? ? ? ? ? ? ? ? ? ? ?memset(&sc->survey[pos], 0, sizeof(struct survey_info));
> ? ? ? ? ? ? ? ?}
>
> + ? ? ? ? ? ? ? if (curchan->flags & IEEE80211_CHAN_RADAR) {
> + ? ? ? ? ? ? ? ? ? ? ? if (!(ah->caps.hw_caps & ATH9K_HW_CAP_DFS)) {
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ath_err(common, "HW does not support DFS\n");
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? mutex_unlock(&sc->mutex);
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? ? ? ? ? ? ? ? ? }
> + ? ? ? ? ? ? ? ? ? ? ? sc->sc_flags |= SC_OP_DFS;
> + ? ? ? ? ? ? ? } else
> + ? ? ? ? ? ? ? ? ? ? ? sc->sc_flags &= ~SC_OP_DFS;
> +
> ? ? ? ? ? ? ? ?if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
> ? ? ? ? ? ? ? ? ? ? ? ?ath_err(common, "Unable to set channel\n");
> ? ? ? ? ? ? ? ? ? ? ? ?mutex_unlock(&sc->mutex);
> + ? ? ? ? ? ? ? ? ? ? ? /* clear DFS operation flag on failure */
> + ? ? ? ? ? ? ? ? ? ? ? sc->sc_flags &= ~SC_OP_DFS;
> ? ? ? ? ? ? ? ? ? ? ? ?return -EINVAL;
> ? ? ? ? ? ? ? ?}
>
> diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
> index 0d5f275..76d804c 100644
> --- a/drivers/net/wireless/ath/ath9k/recv.c
> +++ b/drivers/net/wireless/ath/ath9k/recv.c
> @@ -17,6 +17,7 @@
> ?#include <linux/dma-mapping.h>
> ?#include "ath9k.h"
> ?#include "ar9003_mac.h"
> +#include "dfs.h"
>
> ?#define SKB_CB_ATHBUF(__skb) ? (*((struct ath_buf **)__skb->cb))
>
> @@ -473,6 +474,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
> ? ? ? ? ? ? ? ?rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
> ? ? ? ?}
>
> + ? ? ? if (sc->sc_flags & SC_OP_DFS)
> + ? ? ? ? ? ? ? rfilt |= ATH9K_RX_FILTER_PHYRADAR;
> ? ? ? ?return rfilt;
>
> ?#undef RX_FILTER_PRESERVE
> @@ -1855,11 +1858,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
> ? ? ? ? ? ? ? ?if (sc->sc_flags & SC_OP_RXFLUSH)
> ? ? ? ? ? ? ? ? ? ? ? ?goto requeue_drop_frag;
>
> - ? ? ? ? ? ? ? retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?rxs, &decrypt_error);
> - ? ? ? ? ? ? ? if (retval)
> - ? ? ? ? ? ? ? ? ? ? ? goto requeue_drop_frag;
> -
> ? ? ? ? ? ? ? ?rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
> ? ? ? ? ? ? ? ?if (rs.rs_tstamp > tsf_lower &&
> ? ? ? ? ? ? ? ? ? ?unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
> @@ -1869,6 +1867,17 @@ 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)) {
> + ? ? ? ? ? ? ? ? ? ? ? /* DFS: check for radar pulse */
> + ? ? ? ? ? ? ? ? ? ? ? ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?rxs, &decrypt_error);
> + ? ? ? ? ? ? ? if (retval)
> + ? ? ? ? ? ? ? ? ? ? ? goto requeue_drop_frag;

does the above fixes any bug related to mactime displayed in sniffer

+
> ? ? ? ? ? ? ? ?/* Ensure we always have an skb to requeue once we are done
> ? ? ? ? ? ? ? ? * processing the current buffer's skb */
> ? ? ? ? ? ? ? ?requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC);
> --
> 1.7.4.1
>
>



--
shafi

2011-11-15 16:28:08

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath9k: integrate initial DFS module

On Tue, Nov 15, 2011 at 7:52 AM, Zefir Kurtisi
<[email protected]> wrote:
> On 11/15/2011 04:24 PM, Mohammed Shafi wrote:
>> Hi Zefir,
>>
>> just few doubt, sorry for the late reply
>>
>> On Tue, Nov 8, 2011 at 10:04 PM, Zefir Kurtisi
>> <[email protected]> wrote:
>>> This patch integrates the DFS module into ath9k, including
>>>  * build the module into ath9k_hw
>>>  * set up DFS debugfs
>>> @@ -1855,11 +1858,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
>>>                if (sc->sc_flags & SC_OP_RXFLUSH)
>>>                        goto requeue_drop_frag;
>>>
>>> -               retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
>>> -                                                rxs, &decrypt_error);
>>> -               if (retval)
>>> -                       goto requeue_drop_frag;
>>> -
>>>                rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
>>>                if (rs.rs_tstamp > tsf_lower &&
>>>                    unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
>>> @@ -1869,6 +1867,17 @@ 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)) {
>>> +                       /* DFS: check for radar pulse */
>>> +                       ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
>>> +               }
>>> +
>>> +               retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
>>> +                                                rxs, &decrypt_error);
>>> +               if (retval)
>>> +                       goto requeue_drop_frag;
>>
>> does the above fixes any bug related to mactime displayed in sniffer
>>
>>
>
> Hi Mohammed,
>
> no, like all other modifications within this patch the above does not fix anything (at least not intentionally) ;)
>
> What it does is moving the calculation of rxs->mactime before ath9k_rx_skb_preprocess(), since the mactime is needed to stamp the radar event. So, the five lines marked as removals are actually moved further down which shouldn't have any side effects.

Zefir, can you split the patch so that the move of
ath9k_rx_skb_preprocess() call can clearly be marked as a separate
change, if a regressions should be introduced by the move the move
itself would be single regression instead of the entire DFS patch.

Luis

2011-11-15 14:45:33

by John W. Linville

[permalink] [raw]
Subject: Re: [PATCH 0/2] ath9k: DFS radar detection

On Tue, Nov 08, 2011 at 05:34:02PM +0100, Zefir Kurtisi wrote:
> This patch series proposes DFS radar pulse detection for ath9k.
>
> The first patch adds a new DFS module, the second turns those
> knobs to enable the HW to detect radar pulses and forward them
> to the new module.
>
> Here, sanity and plausibility checks that are HW dependent are
> performed and resulting radar events are passed to higher level
> generic pattern detectors for further processing (spectrum
> management, etc.).
>
> DFS support is limited to newer chip-sets (for now 9280 and later).
>
> So far, AP operation on DFS channels is not supported by
> mac80211/hostapd. Testing the proposed pulse detection is done in
> monitor mode.
>
> Zefir Kurtisi (2):
> ath9k: add DFS radar pulse processing
> ath9k: integrate initial DFS module

Any comments from the ath9k guys on this?

--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.

2011-11-24 08:40:21

by Adrian Chadd

[permalink] [raw]
Subject: Re: [PATCH 0/2] ath9k: DFS radar detection

On 24 November 2011 00:11, Zefir Kurtisi <[email protected]> wrote:
> Luis,
>
> any pending concerns or feedback before I start working on v2?

What's your ETA for getting the radar classification stuff done?

I'd like to evaluate the radar classification code and how it all ties
together. :)

Thanks,


adrian

2011-11-23 16:11:49

by Zefir Kurtisi

[permalink] [raw]
Subject: Re: [PATCH 0/2] ath9k: DFS radar detection

Luis,

any pending concerns or feedback before I start working on v2?


Zefir

On 11/15/2011 05:46 PM, Luis R. Rodriguez wrote:
> On Tue, Nov 15, 2011 at 6:37 AM, John W. Linville
> <[email protected]> wrote:
>> On Tue, Nov 08, 2011 at 05:34:02PM +0100, Zefir Kurtisi wrote:
>>> This patch series proposes DFS radar pulse detection for ath9k.
>>>
>>> The first patch adds a new DFS module, the second turns those
>>> knobs to enable the HW to detect radar pulses and forward them
>>> to the new module.
>>>
>>> Here, sanity and plausibility checks that are HW dependent are
>>> performed and resulting radar events are passed to higher level
>>> generic pattern detectors for further processing (spectrum
>>> management, etc.).
>>>
>>> DFS support is limited to newer chip-sets (for now 9280 and later).
>>>
>>> So far, AP operation on DFS channels is not supported by
>>> mac80211/hostapd. Testing the proposed pulse detection is done in
>>> monitor mode.
>>>
>>> Zefir Kurtisi (2):
>>> ath9k: add DFS radar pulse processing
>>> ath9k: integrate initial DFS module
>>
>> Any comments from the ath9k guys on this?
>
> Just sent my initial set of comments.
>
> Luis


2011-11-15 16:46:47

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 0/2] ath9k: DFS radar detection

On Tue, Nov 15, 2011 at 6:37 AM, John W. Linville
<[email protected]> wrote:
> On Tue, Nov 08, 2011 at 05:34:02PM +0100, Zefir Kurtisi wrote:
>> This patch series proposes DFS radar pulse detection for ath9k.
>>
>> The first patch adds a new DFS module, the second turns those
>> knobs to enable the HW to detect radar pulses and forward them
>> to the new module.
>>
>> Here, sanity and plausibility checks that are HW dependent are
>> performed and resulting radar events are passed to higher level
>> generic pattern detectors for further processing (spectrum
>> management, etc.).
>>
>> DFS support is limited to newer chip-sets (for now 9280 and later).
>>
>> So far, AP operation on DFS channels is not supported by
>> mac80211/hostapd. Testing the proposed pulse detection is done in
>> monitor mode.
>>
>> Zefir Kurtisi (2):
>>   ath9k: add DFS radar pulse processing
>>   ath9k: integrate initial DFS module
>
> Any comments from the ath9k guys on this?

Just sent my initial set of comments.

Luis

2011-11-08 16:34:12

by Zefir Kurtisi

[permalink] [raw]
Subject: [PATCH 2/2] ath9k: integrate initial DFS module

This patch integrates the DFS module into ath9k, including
* build the module into ath9k_hw
* set up DFS debugfs
* define HW capability flag for DFS support
(so far: AR_SREV_9280_20_OR_LATER, TBC)
* define and set DFS opmode flag when on DFS channel
* configure radar params after reset
* provide radar RX filter flag in ath_calcrxfilter()
* forward radar PHY errors to DFS module

This is WIP and at its current stage is limited to test ath9k
pulse detection capabilities. The DFS pattern matching is
TBD in the higher layers and not part of this patch.

Signed-off-by: Zefir Kurtisi <[email protected]>
---
drivers/net/wireless/ath/ath9k/Makefile | 2 ++
drivers/net/wireless/ath/ath9k/ath9k.h | 1 +
drivers/net/wireless/ath/ath9k/debug.c | 3 +++
drivers/net/wireless/ath/ath9k/debug.h | 2 ++
drivers/net/wireless/ath/ath9k/hw-ops.h | 9 +++++++++
drivers/net/wireless/ath/ath9k/hw.c | 7 +++++++
drivers/net/wireless/ath/ath9k/hw.h | 1 +
drivers/net/wireless/ath/ath9k/main.c | 16 ++++++++++++++++
drivers/net/wireless/ath/ath9k/recv.c | 19 ++++++++++++++-----
9 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 36ed3c4..1f260a5 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -29,6 +29,8 @@ ath9k_hw-y:= \
eeprom_9287.o \
ani.o \
btcoex.o \
+ dfs.o \
+ dfs_debug.o \
mac.o \
ar9002_mac.o \
ar9003_mac.o \
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 7ab7a1e..de0309e 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -563,6 +563,7 @@ struct ath_ant_comb {
#define SC_OP_BT_SCAN BIT(13)
#define SC_OP_ANI_RUN BIT(14)
#define SC_OP_PRIM_STA_VIF BIT(15)
+#define SC_OP_DFS BIT(16)

/* Powersave flags */
#define PS_WAIT_FOR_BEACON BIT(0)
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 138ae09..6642108 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1633,6 +1633,9 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
sc, &fops_debug);
#endif
+
+ ath9k_dfs_init_debug(sc);
+
debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_dma);
debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 4f6c939..f70735a 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -19,6 +19,7 @@

#include "hw.h"
#include "rc.h"
+#include "dfs_debug.h"

struct ath_txq;
struct ath_buf;
@@ -180,6 +181,7 @@ struct ath_stats {
struct ath_interrupt_stats istats;
struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
struct ath_rx_stats rxstats;
+ struct ath_dfs_stats dfs_stats;
u32 reset[__RESET_TYPE_MAX];
};

diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index e74c233..c4ad0b0 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -212,4 +212,13 @@ static inline int ath9k_hw_fast_chan_change(struct ath_hw *ah,
return ath9k_hw_private_ops(ah)->fast_chan_change(ah, chan,
ini_reloaded);
}
+
+static inline void ath9k_hw_set_radar_params(struct ath_hw *ah)
+{
+ if (!ath9k_hw_private_ops(ah)->set_radar_params)
+ return;
+
+ ath9k_hw_private_ops(ah)->set_radar_params(ah, &ah->radar_conf);
+}
+
#endif /* ATH9K_HW_OPS_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 76dbc85..c9ba80d 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2333,6 +2333,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
pCap->pcie_lcr_offset = 0x80;
}

+ if (AR_SREV_9280_20_OR_LATER(ah)) {
+ /*
+ * TODO: check for which chip-sets we want to support DFS
+ */
+ pCap->hw_caps |= ATH9K_HW_CAP_DFS;
+ }
+
tx_chainmask = pCap->tx_chainmask;
rx_chainmask = pCap->rx_chainmask;
while (tx_chainmask || rx_chainmask) {
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9dbc3cd..4f02f83 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -204,6 +204,7 @@ enum ath9k_hw_caps {
ATH9K_HW_CAP_5GHZ = BIT(14),
ATH9K_HW_CAP_APM = BIT(15),
ATH9K_HW_CAP_RTT = BIT(16),
+ ATH9K_HW_CAP_DFS = BIT(17),
};

struct ath9k_hw_capabilities {
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index d3b92ce..e86d820 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -305,6 +305,10 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf);
}

+ /* set radar parameters if in DFS mode */
+ if (sc->sc_flags & SC_OP_DFS)
+ ath9k_hw_set_radar_params(ah);
+
ieee80211_wake_queues(sc->hw);

return true;
@@ -1722,9 +1726,21 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
memset(&sc->survey[pos], 0, sizeof(struct survey_info));
}

+ if (curchan->flags & IEEE80211_CHAN_RADAR) {
+ if (!(ah->caps.hw_caps & ATH9K_HW_CAP_DFS)) {
+ ath_err(common, "HW does not support DFS\n");
+ mutex_unlock(&sc->mutex);
+ return -EINVAL;
+ }
+ sc->sc_flags |= SC_OP_DFS;
+ } else
+ sc->sc_flags &= ~SC_OP_DFS;
+
if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
ath_err(common, "Unable to set channel\n");
mutex_unlock(&sc->mutex);
+ /* clear DFS operation flag on failure */
+ sc->sc_flags &= ~SC_OP_DFS;
return -EINVAL;
}

diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 0d5f275..76d804c 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -17,6 +17,7 @@
#include <linux/dma-mapping.h>
#include "ath9k.h"
#include "ar9003_mac.h"
+#include "dfs.h"

#define SKB_CB_ATHBUF(__skb) (*((struct ath_buf **)__skb->cb))

@@ -473,6 +474,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
}

+ if (sc->sc_flags & SC_OP_DFS)
+ rfilt |= ATH9K_RX_FILTER_PHYRADAR;
return rfilt;

#undef RX_FILTER_PRESERVE
@@ -1855,11 +1858,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
if (sc->sc_flags & SC_OP_RXFLUSH)
goto requeue_drop_frag;

- retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
- rxs, &decrypt_error);
- if (retval)
- goto requeue_drop_frag;
-
rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
if (rs.rs_tstamp > tsf_lower &&
unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
@@ -1869,6 +1867,17 @@ 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)) {
+ /* DFS: check for radar pulse */
+ ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
+ }
+
+ retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
+ rxs, &decrypt_error);
+ if (retval)
+ goto requeue_drop_frag;
+
/* Ensure we always have an skb to requeue once we are done
* processing the current buffer's skb */
requeue_skb = ath_rxbuf_alloc(common, common->rx_bufsize, GFP_ATOMIC);
--
1.7.4.1


2011-11-08 16:34:12

by Zefir Kurtisi

[permalink] [raw]
Subject: [PATCH 1/2] ath9k: add DFS radar pulse processing

This initial DFS module provides basic functionality to deal with
radar pulses reported by the DFS HW pulse detector.

The reported data is evaluated and basic plausibility checks are
performed to filter false pulses. Passing radar pulses are
forwarded to pattern detectors (not part of this patch).

The patch also includes
* new debug level ATH_DBG_DFS
* debugfs DFS radar statistics

Signed-off-by: Zefir Kurtisi <[email protected]>
---
drivers/net/wireless/ath/ath.h | 2 +
drivers/net/wireless/ath/ath9k/dfs.c | 203 ++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath9k/dfs.h | 38 +++++
drivers/net/wireless/ath/ath9k/dfs_debug.c | 89 ++++++++++++
drivers/net/wireless/ath/ath9k/dfs_debug.h | 59 ++++++++
5 files changed, 391 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/wireless/ath/ath9k/dfs.c
create mode 100644 drivers/net/wireless/ath/ath9k/dfs.h
create mode 100644 drivers/net/wireless/ath/ath9k/dfs_debug.c
create mode 100644 drivers/net/wireless/ath/ath9k/dfs_debug.h

diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 46d6926..e38fcad 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -215,6 +215,7 @@ do { \
* @ATH_DBG_HWTIMER: hardware timer handling
* @ATH_DBG_BTCOEX: bluetooth coexistance
* @ATH_DBG_BSTUCK: stuck beacons
+ * @ATH_DBG_DFS: radar datection
* @ATH_DBG_ANY: enable all debugging
*
* The debug level is used to control the amount and type of debugging output
@@ -240,6 +241,7 @@ enum ATH_DEBUG {
ATH_DBG_BTCOEX = 0x00002000,
ATH_DBG_WMI = 0x00004000,
ATH_DBG_BSTUCK = 0x00008000,
+ ATH_DBG_DFS = 0x00010000,
ATH_DBG_ANY = 0xffffffff
};

diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c
new file mode 100644
index 0000000..c6d2eea
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ * Copyright (c) 2011 Neratec Solutions AG
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "hw.h"
+#include "hw-ops.h"
+#include "ath9k.h"
+#include "dfs.h"
+#include "dfs_debug.h"
+
+/* convert pulse duration to usecs, considering clock mode */
+static u32 dur_to_usecs(struct ath_hw *ah, u32 dur)
+{
+ const u32 AR93X_NSECS_PER_DUR = 800;
+ const u32 AR93X_NSECS_PER_DUR_FAST = (8000 / 11);
+ u32 nsecs;
+ if (IS_CHAN_A_FAST_CLOCK(ah, ah->curchan))
+ nsecs = dur * AR93X_NSECS_PER_DUR_FAST;
+ else
+ nsecs = dur * AR93X_NSECS_PER_DUR;
+
+ return (nsecs + 500) / 1000;
+}
+
+/* internal struct to pass radar data */
+struct ath_radar_data {
+ u8 pulse_bw_info;
+ u8 rssi;
+ u8 ext_rssi;
+ u8 pulse_length_ext;
+ u8 pulse_length_pri;
+};
+
+/* TODO: move into or synchronize this with generic header
+ * as soon as IF is defined */
+struct dfs_radar_pulse {
+ u16 freq;
+ u64 ts;
+ u32 width;
+ u8 rssi;
+};
+
+#define PRI_CH_RADAR_FOUND 0x01
+#define EXT_CH_RADAR_FOUND 0x02
+static bool ath9k_postprocess_radar_event(struct ath_softc *sc,
+ struct ath_radar_data *are, struct dfs_radar_pulse *drp)
+{
+ u8 rssi;
+ u16 dur;
+
+ ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_DFS,
+ "pulse_bw_info=0x%x, pri,ext len/rssi=(%u/%u, %u/%u)\n",
+ are->pulse_bw_info,
+ are->pulse_length_pri, are->rssi,
+ are->pulse_length_ext, are->ext_rssi);
+
+ /* Only the last 2 bits of the BW info are relevant, they indicate
+ which channel the radar was detected in.*/
+ are->pulse_bw_info &= 0x03;
+
+ switch (are->pulse_bw_info) {
+ case PRI_CH_RADAR_FOUND:
+ /* radar in ctrl channel */
+ dur = are->pulse_length_pri;
+ DFS_STAT_INC(sc, pri_phy_errors);
+ /* cannot use ctrl channel RSSI
+ * if extension channel is stronger */
+ rssi = (are->ext_rssi >= (are->rssi + 3)) ? 0 : are->rssi;
+ break;
+ case EXT_CH_RADAR_FOUND:
+ /* radar in extension channel */
+ dur = are->pulse_length_ext;
+ DFS_STAT_INC(sc, ext_phy_errors);
+ /* cannot use extension channel RSSI
+ * if control channel is stronger */
+ rssi = (are->rssi >= (are->ext_rssi + 12)) ? 0 : are->ext_rssi;
+ break;
+ case (PRI_CH_RADAR_FOUND | EXT_CH_RADAR_FOUND):
+ /*
+ * Conducted testing, when pulse is on DC, both pri and ext
+ * durations are reported to be same
+ *
+ * Radiated testing, when pulse is on DC, different pri and
+ * ext durations are reported, so take the larger of the two
+ * */
+ if (are->pulse_length_ext >= are->pulse_length_pri)
+ dur = are->pulse_length_ext;
+ else
+ dur = are->pulse_length_pri;
+ DFS_STAT_INC(sc, dc_phy_errors);
+
+ /* when both are present use stronger one */
+ rssi = (are->rssi < are->ext_rssi) ? are->ext_rssi : are->rssi;
+ break;
+ default:
+ /* Bogus bandwidth info received in descriptor,
+ so ignore this PHY error */
+ DFS_STAT_INC(sc, bwinfo_discards);
+ return false;
+ }
+
+ if (rssi == 0) {
+ DFS_STAT_INC(sc, rssi_discards);
+ return false;
+ }
+
+ /*
+ * TODO: check chirping pulses
+ * checks for chirping are dependent on the DFS regulatory domain
+ * used, which is yet TBD
+ */
+
+ /* convert duration to usecs */
+ drp->width = dur_to_usecs(sc->sc_ah, dur);
+ drp->rssi = rssi;
+
+ DFS_STAT_INC(sc, pulses_detected);
+ return true;
+}
+#undef PRI_CH_RADAR_FOUND
+#undef EXT_CH_RADAR_FOUND
+
+
+/*
+ * DFS: check PHY-error for radar pulse and feed the detector
+ */
+void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
+ struct ath_rx_status *rs, u64 mactime)
+{
+ struct ath_radar_data ard;
+ u16 datalen;
+ char *vdata_end;
+ struct dfs_radar_pulse drp;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+
+ if ((!(rs->rs_phyerr != ATH9K_PHYERR_RADAR)) &&
+ (!(rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT))) {
+ ath_dbg(common, ATH_DBG_DFS,
+ "Error: rs_phyer=0x%x not a radar error\n",
+ rs->rs_phyerr);
+ return;
+ }
+
+ datalen = rs->rs_datalen;
+ if (datalen == 0) {
+ DFS_STAT_INC(sc, datalen_discards);
+ return;
+ }
+
+ ard.rssi = rs->rs_rssi_ctl0;
+ ard.ext_rssi = rs->rs_rssi_ext0;
+
+ /* hardware stores this as 8 bit signed value.
+ * we will cap it at 0 if it is a negative number
+ */
+ if (ard.rssi & 0x80)
+ ard.rssi = 0;
+ if (ard.ext_rssi & 0x80)
+ ard.ext_rssi = 0;
+
+ vdata_end = (char *)data + datalen;
+ ard.pulse_bw_info = vdata_end[-1];
+ ard.pulse_length_ext = vdata_end[-2];
+ ard.pulse_length_pri = vdata_end[-3];
+
+ ath_dbg(common, ATH_DBG_DFS,
+ "bw_info=%d, length_pri=%d, length_ext=%d, "
+ "rssi_pri=%d, rssi_ext=%d\n",
+ ard.pulse_bw_info, ard.pulse_length_pri, ard.pulse_length_ext,
+ ard.rssi, ard.ext_rssi);
+
+ drp.freq = ah->curchan->channel;
+ drp.ts = mactime;
+ if (ath9k_postprocess_radar_event(sc, &ard, &drp)) {
+ static u64 last_ts;
+ ath_dbg(common, ATH_DBG_DFS,
+ "ath9k_dfs_process_phyerr: channel=%d, ts=%llu, "
+ "width=%d, rssi=%d, delta_ts=%llu\n",
+ drp.freq, drp.ts, drp.width, drp.rssi, drp.ts-last_ts);
+ last_ts = drp.ts;
+ /*
+ * TODO: forward pulse to pattern detector
+ *
+ * ieee80211_add_radar_pulse(drp.freq, drp.ts,
+ * drp.width, drp.rssi);
+ */
+ }
+}
+EXPORT_SYMBOL(ath9k_dfs_process_phyerr);
diff --git a/drivers/net/wireless/ath/ath9k/dfs.h b/drivers/net/wireless/ath/ath9k/dfs.h
new file mode 100644
index 0000000..c73c175
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/dfs.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ * Copyright (c) 2011 Neratec Solutions AG
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ATH9K_DFS_H
+#define ATH9K_DFS_H
+
+/**
+ * ath9k_dfs_process_phyerr - process radar PHY error
+ * @sc: ath_softc
+ * @data: RX payload data
+ * @rs: RX status after processing descriptor
+ * @mactime: receive time
+ *
+ * This function is called whenever the HW DFS module detects a radar
+ * pulse and reports it as a PHY error.
+ *
+ * The radar information provided as raw payload data is validated and
+ * filtered for false pulses. Events passing all tests are forwarded to
+ * the upper layer for pattern detection.
+ */
+void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
+ struct ath_rx_status *rs, u64 mactime);
+
+#endif /* ATH9K_DFS_H */
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.c b/drivers/net/wireless/ath/ath9k/dfs_debug.c
new file mode 100644
index 0000000..3c03552
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.c
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ * Copyright (c) 2011 Neratec Solutions AG
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#include <linux/debugfs.h>
+
+#include "ath9k.h"
+#include "dfs_debug.h"
+
+
+#if defined(CONFIG_ATH9K_DEBUGFS)
+
+#define ATH9K_DFS_STAT(s, p) \
+ len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \
+ sc->debug.stats.dfs_stats.p);
+
+static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ struct ath9k_hw_version *hw_ver = &sc->sc_ah->hw_version;
+ char *buf;
+ unsigned int len = 0, size = 8000;
+ ssize_t retval = 0;
+
+ buf = kzalloc(size, GFP_KERNEL);
+ if (buf == NULL)
+ return -ENOMEM;
+
+ len += snprintf(buf + len, size - len, "DFS support for "
+ "macVersion = 0x%x, macRev = 0x%x: %s\n",
+ hw_ver->macVersion, hw_ver->macRev,
+ (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ?
+ "enabled" : "disabled");
+ ATH9K_DFS_STAT("DFS pulses detected ", pulses_detected);
+ ATH9K_DFS_STAT("Datalen discards ", datalen_discards);
+ ATH9K_DFS_STAT("RSSI discards ", rssi_discards);
+ ATH9K_DFS_STAT("BW info discards ", bwinfo_discards);
+ ATH9K_DFS_STAT("Primary channel pulses ", pri_phy_errors);
+ ATH9K_DFS_STAT("Secondary channel pulses", ext_phy_errors);
+ ATH9K_DFS_STAT("Dual channel pulses ", dc_phy_errors);
+
+ if (len > size)
+ len = size;
+
+ retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ kfree(buf);
+
+ return retval;
+}
+
+static int ath9k_dfs_debugfs_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->i_private;
+ return 0;
+}
+
+
+static const struct file_operations fops_dfs_stats = {
+ .read = read_file_dfs,
+ .open = ath9k_dfs_debugfs_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+
+void ath9k_dfs_init_debug(struct ath_softc *sc)
+{
+ debugfs_create_file("dfs_stats", S_IRUSR,
+ sc->debug.debugfs_phy, sc, &fops_dfs_stats);
+}
+EXPORT_SYMBOL(ath9k_dfs_init_debug);
+
+#endif /* CONFIG_ATH9K_DEBUGFS */
+
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.h b/drivers/net/wireless/ath/ath9k/dfs_debug.h
new file mode 100644
index 0000000..079cf53
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
+ * Copyright (c) 2011 Neratec Solutions AG
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+
+#ifndef DFS_DEBUG_H
+#define DFS_DEBUG_H
+
+#include "hw.h"
+
+/**
+ * struct ath_dfs_stats - DFS Statistics
+ *
+ * @pulses_detected: No. of pulses detected so far
+ * @datalen_discards: No. of pulses discarded due to invalid datalen
+ * @rssi_discards: No. of pulses discarded due to invalid RSSI
+ * @bwinfo_discards: No. of pulses discarded due to invalid BW info
+ * @pri_phy_errors: No. of pulses reported for primary channel
+ * @ext_phy_errors: No. of pulses reported for extension channel
+ * @dc_phy_errors: No. of pulses reported for primary + extension channel
+ */
+struct ath_dfs_stats {
+ u32 pulses_detected;
+ u32 datalen_discards;
+ u32 rssi_discards;
+ u32 bwinfo_discards;
+ u32 pri_phy_errors;
+ u32 ext_phy_errors;
+ u32 dc_phy_errors;
+};
+
+
+#if defined(CONFIG_ATH9K_DEBUGFS)
+
+#define DFS_STAT_INC(sc, c) (sc->debug.stats.dfs_stats.c++)
+void ath9k_dfs_init_debug(struct ath_softc *sc);
+
+#else
+
+#define DFS_STAT_INC(sc, c) do { } while (0)
+static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { }
+
+#endif
+
+
+#endif /* DFS_DEBUG_H */
--
1.7.4.1


2011-11-15 16:46:20

by Luis R. Rodriguez

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath9k: integrate initial DFS module

On Tue, Nov 8, 2011 at 8:34 AM, Zefir Kurtisi <[email protected]> wrote:
> This patch integrates the DFS module into ath9k, including
>  * build the module into ath9k_hw
>  * set up DFS debugfs
>  * define HW capability flag for DFS support
>   (so far: AR_SREV_9280_20_OR_LATER, TBC)
>  * define and set DFS opmode flag when on DFS channel
>   * configure radar params after reset
>   * provide radar RX filter flag in ath_calcrxfilter()
>  * forward radar PHY errors to DFS module
>
> This is WIP and at its current stage is limited to test ath9k
> pulse detection capabilities. The DFS pattern matching is
> TBD in the higher layers and not part of this patch.
>
> Signed-off-by: Zefir Kurtisi <[email protected]>
> ---
>  drivers/net/wireless/ath/ath9k/Makefile |    2 ++
>  drivers/net/wireless/ath/ath9k/ath9k.h  |    1 +
>  drivers/net/wireless/ath/ath9k/debug.c  |    3 +++
>  drivers/net/wireless/ath/ath9k/debug.h  |    2 ++
>  drivers/net/wireless/ath/ath9k/hw-ops.h |    9 +++++++++
>  drivers/net/wireless/ath/ath9k/hw.c     |    7 +++++++
>  drivers/net/wireless/ath/ath9k/hw.h     |    1 +
>  drivers/net/wireless/ath/ath9k/main.c   |   16 ++++++++++++++++
>  drivers/net/wireless/ath/ath9k/recv.c   |   19 ++++++++++++++-----
>  9 files changed, 55 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
> index 36ed3c4..1f260a5 100644
> --- a/drivers/net/wireless/ath/ath9k/Makefile
> +++ b/drivers/net/wireless/ath/ath9k/Makefile
> @@ -29,6 +29,8 @@ ath9k_hw-y:=  \
>                eeprom_9287.o \
>                ani.o \
>                btcoex.o \
> +               dfs.o \
> +               dfs_debug.o \
>                mac.o \
>                ar9002_mac.o \
>                ar9003_mac.o \
> diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
> index 7ab7a1e..de0309e 100644
> --- a/drivers/net/wireless/ath/ath9k/ath9k.h
> +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
> @@ -563,6 +563,7 @@ struct ath_ant_comb {
>  #define SC_OP_BT_SCAN               BIT(13)
>  #define SC_OP_ANI_RUN               BIT(14)
>  #define SC_OP_PRIM_STA_VIF          BIT(15)
> +#define SC_OP_DFS                   BIT(16)

The way you use this is to set the bit when a DFS channel is found on
the mac80211 config() callback so that upon ath_complete_reset() we
call ath9k_hw_set_radar_params() with the params captured in
ath_calcrxfilter(). This seems fair... but have you considered all the
other cases that will call ath_complete_reset() that do come through
the mac80211 config() callback? What got me thinking about this was
the actual declaration of this bit, is it really necessary? It seems
to reflect a state from a small state machine that you need to ensure
is respected. If this is true you just need then to guarantee that
that the ath9k_hw_set_radar_params() will get called properly for all
the cases that you do need. Its not clear from the current
implementation that this is the case right now, it seems a bit
fragile. Consider all the idle() and non-idle() calls that mac80211
could use to call on the driver. Granted, the idle stuff is mostly
observed on the client side, but its just one case I am thinking off
the top of my head based on a quick review of this patch.

>  /* Powersave flags */
>  #define PS_WAIT_FOR_BEACON        BIT(0)
> diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
> index 138ae09..6642108 100644
> --- a/drivers/net/wireless/ath/ath9k/debug.c
> +++ b/drivers/net/wireless/ath/ath9k/debug.c
> @@ -1633,6 +1633,9 @@ int ath9k_init_debug(struct ath_hw *ah)
>        debugfs_create_file("debug", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
>                            sc, &fops_debug);
>  #endif
> +
> +       ath9k_dfs_init_debug(sc);
> +
>        debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
>                            &fops_dma);
>        debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
> diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
> index 4f6c939..f70735a 100644
> --- a/drivers/net/wireless/ath/ath9k/debug.h
> +++ b/drivers/net/wireless/ath/ath9k/debug.h
> @@ -19,6 +19,7 @@
>
>  #include "hw.h"
>  #include "rc.h"
> +#include "dfs_debug.h"
>
>  struct ath_txq;
>  struct ath_buf;
> @@ -180,6 +181,7 @@ struct ath_stats {
>        struct ath_interrupt_stats istats;
>        struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
>        struct ath_rx_stats rxstats;
> +       struct ath_dfs_stats dfs_stats;
>        u32 reset[__RESET_TYPE_MAX];
>  };
>
> diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
> index e74c233..c4ad0b0 100644
> --- a/drivers/net/wireless/ath/ath9k/hw-ops.h
> +++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
> @@ -212,4 +212,13 @@ static inline int ath9k_hw_fast_chan_change(struct ath_hw *ah,
>        return ath9k_hw_private_ops(ah)->fast_chan_change(ah, chan,
>                                                          ini_reloaded);
>  }
> +
> +static inline void ath9k_hw_set_radar_params(struct ath_hw *ah)
> +{
> +       if (!ath9k_hw_private_ops(ah)->set_radar_params)
> +               return;
> +
> +       ath9k_hw_private_ops(ah)->set_radar_params(ah, &ah->radar_conf);
> +}
> +
>  #endif /* ATH9K_HW_OPS_H */
> diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
> index 76dbc85..c9ba80d 100644
> --- a/drivers/net/wireless/ath/ath9k/hw.c
> +++ b/drivers/net/wireless/ath/ath9k/hw.c
> @@ -2333,6 +2333,13 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
>                pCap->pcie_lcr_offset = 0x80;
>        }
>
> +       if (AR_SREV_9280_20_OR_LATER(ah)) {
> +               /*
> +                * TODO: check for which chip-sets we want to support DFS
> +                */
> +               pCap->hw_caps |= ATH9K_HW_CAP_DFS;
> +       }
> +

Please change to AR_SREV_9300_20_OR_LATER(), its the only family that
we can likely get resources to support, validate and test for. I'm
even having a hard time getting support, etc for AR9003 but I think
its fair to at least get this chugging for AR9003. If someone wants to
pick up support, validation and testing for AR9002 then great, but
this is not trivial to commit to. I rather deal only with what we can
get commitment to properly test and validate.

In fact I will need to verify our test plan for this. I'll start on
that while you review my comments.

>        tx_chainmask = pCap->tx_chainmask;
>        rx_chainmask = pCap->rx_chainmask;
>        while (tx_chainmask || rx_chainmask) {
> diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
> index 9dbc3cd..4f02f83 100644
> --- a/drivers/net/wireless/ath/ath9k/hw.h
> +++ b/drivers/net/wireless/ath/ath9k/hw.h
> @@ -204,6 +204,7 @@ enum ath9k_hw_caps {
>        ATH9K_HW_CAP_5GHZ                       = BIT(14),
>        ATH9K_HW_CAP_APM                        = BIT(15),
>        ATH9K_HW_CAP_RTT                        = BIT(16),
> +       ATH9K_HW_CAP_DFS                        = BIT(17),
>  };
>
>  struct ath9k_hw_capabilities {
> diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
> index d3b92ce..e86d820 100644
> --- a/drivers/net/wireless/ath/ath9k/main.c
> +++ b/drivers/net/wireless/ath/ath9k/main.c
> @@ -305,6 +305,10 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
>                ath9k_hw_antdiv_comb_conf_set(ah, &div_ant_conf);
>        }
>
> +       /* set radar parameters if in DFS mode */
> +       if (sc->sc_flags & SC_OP_DFS)
> +               ath9k_hw_set_radar_params(ah);
> +
>        ieee80211_wake_queues(sc->hw);
>
>        return true;
> @@ -1722,9 +1726,21 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
>                        memset(&sc->survey[pos], 0, sizeof(struct survey_info));
>                }
>
> +               if (curchan->flags & IEEE80211_CHAN_RADAR) {
> +                       if (!(ah->caps.hw_caps & ATH9K_HW_CAP_DFS)) {
> +                               ath_err(common, "HW does not support DFS\n");
> +                               mutex_unlock(&sc->mutex);
> +                               return -EINVAL;

Seems like a wrong place for this, shouldn't cfg80211 deal with this
check for us? That is, export a cfg80211 DFS capability and cfg80211
would deny using any DFS channel unless the wiphy declares itself
capable.

> +                       }
> +                       sc->sc_flags |= SC_OP_DFS;
> +               } else
> +                       sc->sc_flags &= ~SC_OP_DFS;
> +
>                if (ath_set_channel(sc, hw, &sc->sc_ah->channels[pos]) < 0) {
>                        ath_err(common, "Unable to set channel\n");
>                        mutex_unlock(&sc->mutex);
> +                       /* clear DFS operation flag on failure */
> +                       sc->sc_flags &= ~SC_OP_DFS;
>                        return -EINVAL;
>                }
>
> diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
> index 0d5f275..76d804c 100644
> --- a/drivers/net/wireless/ath/ath9k/recv.c
> +++ b/drivers/net/wireless/ath/ath9k/recv.c
> @@ -17,6 +17,7 @@
>  #include <linux/dma-mapping.h>
>  #include "ath9k.h"
>  #include "ar9003_mac.h"
> +#include "dfs.h"
>
>  #define SKB_CB_ATHBUF(__skb)   (*((struct ath_buf **)__skb->cb))
>
> @@ -473,6 +474,8 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
>                rfilt |= ATH9K_RX_FILTER_MCAST_BCAST_ALL;
>        }
>
> +       if (sc->sc_flags & SC_OP_DFS)
> +               rfilt |= ATH9K_RX_FILTER_PHYRADAR;
>        return rfilt;
>
>  #undef RX_FILTER_PRESERVE
> @@ -1855,11 +1858,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
>                if (sc->sc_flags & SC_OP_RXFLUSH)
>                        goto requeue_drop_frag;
>
> -               retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
> -                                                rxs, &decrypt_error);
> -               if (retval)
> -                       goto requeue_drop_frag;
> -
>                rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
>                if (rs.rs_tstamp > tsf_lower &&
>                    unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
> @@ -1869,6 +1867,17 @@ 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)) {
> +                       /* DFS: check for radar pulse */
> +                       ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
> +               }
> +
> +               retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
> +                                                rxs, &decrypt_error);
> +               if (retval)
> +                       goto requeue_drop_frag;
> +

As noted in the other e-mail please split the move of the check to
another patch, the new code can be kept here.

Luis

2011-11-15 15:52:36

by Zefir Kurtisi

[permalink] [raw]
Subject: Re: [PATCH 2/2] ath9k: integrate initial DFS module

On 11/15/2011 04:24 PM, Mohammed Shafi wrote:
> Hi Zefir,
>
> just few doubt, sorry for the late reply
>
> On Tue, Nov 8, 2011 at 10:04 PM, Zefir Kurtisi
> <[email protected]> wrote:
>> This patch integrates the DFS module into ath9k, including
>> * build the module into ath9k_hw
>> * set up DFS debugfs
>> @@ -1855,11 +1858,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
>> if (sc->sc_flags & SC_OP_RXFLUSH)
>> goto requeue_drop_frag;
>>
>> - retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
>> - rxs, &decrypt_error);
>> - if (retval)
>> - goto requeue_drop_frag;
>> -
>> rxs->mactime = (tsf & ~0xffffffffULL) | rs.rs_tstamp;
>> if (rs.rs_tstamp > tsf_lower &&
>> unlikely(rs.rs_tstamp - tsf_lower > 0x10000000))
>> @@ -1869,6 +1867,17 @@ 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)) {
>> + /* DFS: check for radar pulse */
>> + ath9k_dfs_process_phyerr(sc, hdr, &rs, rxs->mactime);
>> + }
>> +
>> + retval = ath9k_rx_skb_preprocess(common, hw, hdr, &rs,
>> + rxs, &decrypt_error);
>> + if (retval)
>> + goto requeue_drop_frag;
>
> does the above fixes any bug related to mactime displayed in sniffer
>
>

Hi Mohammed,

no, like all other modifications within this patch the above does not fix anything (at least not intentionally) ;)

What it does is moving the calculation of rxs->mactime before ath9k_rx_skb_preprocess(), since the mactime is needed to stamp the radar event. So, the five lines marked as removals are actually moved further down which shouldn't have any side effects.


Thanks
Zefir