Enable DFS radar pulse detection in ath9k PHY and feed radar detector with potential pulse events filtered from RX PHY errors. Signed-off-by: Zefir Kurtisi <zefir.kurtisi@xxxxxxxxxxx> --- .../drivers/net/wireless/ath/ath9k/mac.c | 51 ++++++++++++++++++++ .../drivers/net/wireless/ath/ath9k/main.c | 9 ++++ 2 files changed, 60 insertions(+), 0 deletions(-) diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index e3d2ebf..a303010 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c @@ -624,6 +624,53 @@ bool ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q) } EXPORT_SYMBOL(ath9k_hw_resettxqueue); +/* + * DFS: check PHY-error for radar pulse and feed the detector + */ +void ath9k_dfs_process_phyerr(struct ath_hw *ah, struct ath_desc *ds, + struct ath_rx_status *rs, u_int64_t fulltsf) +{ + static u64 last_ts; + static u32 ts_hi; + + struct ath9k_channel *chan = ah->curchan; + u8 rssi; + u32 dur = 0; + u32 ts; + + if ((!(rs->rs_phyerr != ATH9K_PHYERR_RADAR)) + && (!(rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT))) { + printk(KERN_INFO "Error: rs_phyer=0x%x not a radar error\n", + rs->rs_phyerr); + return; + } + + /* update internal 64-bit time stamp with that of rs */ + ts = rs->rs_tstamp; + if (ts <= (last_ts & 0xffffffff)) + ts_hi++; + last_ts = ((u64)ts_hi << 32) | ts; + + rssi = (u8) rs->rs_rssi_ctl0; + + if (rssi == 0) + return; + + if (rs->rs_datalen != 0) { + char *vdata = (char *)ds->ds_vdata + rs->rs_datalen - 3; + dur = (u32) vdata[0]; +#if 0 + printk(KERN_INFO "dur=%d, datalen=%d: [%.2x, %.2x, %.2x]\n", + dur, rs->rs_datalen, vdata[0], vdata[1], vdata[2]); +#endif + } + + /* ZKU: reverse measured scaling factor of 2/3 for duration */ + dur = (dur * 66 + 50) / 100; + ieee80211_add_radar_pulse(chan->channel, last_ts - dur, rssi, dur); +} +EXPORT_SYMBOL(ath9k_dfs_process_phyerr); + int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, struct ath_rx_status *rs, u64 tsf) { @@ -696,6 +743,10 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds, rs->rs_status |= ATH9K_RXERR_PHY; phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode); rs->rs_phyerr = phyerr; + + /* DFS: feed assumed radar pulse */ + ath9k_dfs_process_phyerr(ah, ds, rs, tsf); + } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr) rs->rs_status |= ATH9K_RXERR_DECRYPT; else if (ads.ds_rxstatus8 & AR_MichaelErr) diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 29a6d35..a799c36 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c @@ -290,6 +290,15 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw, ath_start_ani(common); } + /** + * enable radar pulse detection + * + * TODO: do this only for DFS channels + */ + ah->private_ops.set_radar_params(ah, &ah->radar_conf); + ath9k_hw_setrxfilter(ah, + ath9k_hw_getrxfilter(ah) | ATH9K_RX_FILTER_PHYRADAR); + ps_restore: spin_unlock_bh(&sc->sc_pcu_lock); -- 1.5.4.3 -- To unsubscribe from this list: send the line "unsubscribe linux-wireless" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html