[PATCH 1/3] ath10k: add phyerr/dfs handling
Kalle Valo
kvalo at qca.qualcomm.com
Wed Nov 6 04:47:11 EST 2013
Marek Puzyniak <marek.puzyniak at tieto.com> writes:
> From: Janusz Dziedzic <janusz.dziedzic at tieto.com>
>
> Handle phyerr, dfs event, radar_report and fft_report.
> Add also debugfs dfs_simulate_radar and dfs_stats files.
> Use ath dfs pattern detector.
>
> Signed-off-by: Janusz Dziedzic <janusz.dziedzic at tieto.com>
Are there any dependencies to mac80211 or cfg80211 patches? There has
been quite a lot of changes with DFS lately and it would be good to have
all those patches in ath-next branch before I apply these.
> --- a/drivers/net/wireless/ath/ath10k/debug.c
> +++ b/drivers/net/wireless/ath/ath10k/debug.c
> @@ -21,6 +21,14 @@
> #include "core.h"
> #include "debug.h"
>
> +#define ATH10K_DFS_STAT(s, p) (\
> + len += scnprintf(buf + len, size - len, "%28s : %10u\n", s, \
> + ar->debug.dfs_stats.p))
> +
> +#define ATH10K_DFS_POOL_STAT(s, p) (\
> + len += scnprintf(buf + len, size - len, "%28s : %10u\n", s, \
> + ar->debug.dfs_pool_stats.p))
As these are only used by ath10k_read_file_dfs() better to move those
just to top of that function.
> +static ssize_t ath10k_read_file_dfs(struct file *file, char __user *user_buf,
> + size_t count, loff_t *ppos)
> +{
ath10k_read_dfs_stats()?
> + int retval = 0, size = 8000, len = 0;
Like Joe said, size can be const.
> + struct ath10k *ar = file->private_data;
> + char *buf;
> +
> + buf = kzalloc(size, GFP_KERNEL);
> + if (buf == NULL)
> + return -ENOMEM;
> +
> + if (!ar->dfs_detector) {
> + len += scnprintf(buf + len, size - len, "DFS not enabled\n");
> + goto exit;
> + }
> +
> + ar->debug.dfs_pool_stats = ar->dfs_detector->get_stats(ar->dfs_detector);
I think we need to take conf_mutex to make sure ar->dfs_detector is not
destroyed while we use it.
> diff --git a/drivers/net/wireless/ath/ath10k/debug.h b/drivers/net/wireless/ath/ath10k/debug.h
> index 46e640a..cde53d6 100644
> --- a/drivers/net/wireless/ath/ath10k/debug.h
> +++ b/drivers/net/wireless/ath/ath10k/debug.h
> @@ -33,6 +33,7 @@ enum ath10k_debug_mask {
> ATH10K_DBG_MGMT = 0x00000100,
> ATH10K_DBG_DATA = 0x00000200,
> ATH10K_DBG_BMI = 0x00000400,
> + ATH10K_DBG_REGULATORY = 0x00000800,
> ATH10K_DBG_ANY = 0xffffffff,
> };
>
> @@ -53,6 +54,7 @@ void ath10k_debug_read_service_map(struct ath10k *ar,
> void ath10k_debug_read_target_stats(struct ath10k *ar,
> struct wmi_stats_event *ev);
>
> +#define ATH10K_DFS_STAT_INC(ar, c) (ar->debug.dfs_stats.c++)
> #else
Empty line after #define
> static inline int ath10k_debug_start(struct ath10k *ar)
> {
> @@ -82,6 +84,7 @@ static inline void ath10k_debug_read_target_stats(struct ath10k *ar,
> struct wmi_stats_event *ev)
> {
> }
> +#define ATH10K_DFS_STAT_INC(ar, c) do { } while (0)
> #endif /* CONFIG_ATH10K_DEBUGFS */
Empty line before and after #define.
>
> #ifdef CONFIG_ATH10K_DEBUG
> diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
> index bbb0efa..79f8bfd 100644
> --- a/drivers/net/wireless/ath/ath10k/mac.c
> +++ b/drivers/net/wireless/ath/ath10k/mac.c
> @@ -1438,9 +1438,20 @@ static void ath10k_reg_notifier(struct wiphy *wiphy,
> {
> struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
> struct ath10k *ar = hw->priv;
> + bool result;
>
> ath_reg_notifier_apply(wiphy, request, &ar->ath_common.regulatory);
>
> + if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED) && ar->dfs_detector) {
> + ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs region 0x%X\n",
> + request->dfs_region);
"0x%x" (also applies to elsewhere in the patch)
> --- a/drivers/net/wireless/ath/ath10k/wmi.c
> +++ b/drivers/net/wireless/ath/ath10k/wmi.c
> @@ -1383,9 +1383,251 @@ static void ath10k_wmi_event_tbttoffset_update(struct ath10k *ar,
> ath10k_dbg(ATH10K_DBG_WMI, "WMI_TBTTOFFSET_UPDATE_EVENTID\n");
> }
>
> +static void ath10k_dfs_radar_report(struct ath10k *ar,
> + struct wmi_single_phyerr_rx_event *event,
> + struct phyerr_radar_report *rr,
> + u64 tsf)
> +{
> + u32 reg0, reg1, tsf32l;
> + struct pulse_event pe;
> + u64 tsf64;
> + u8 rssi, width;
What about locking? Does this function assume that conf_mutex is held?
If yes, please document that with lockdep_assert_held(). If no, we have
a problem :)
(Reads wmi.c)
Ah, wmi events don't sleep anymore, forgot that. So we can't really use
conf_mutex here. I guess our options are bring back worker for wmi
events or use spinlock.
> +
> + reg0 = __le32_to_cpu(rr->reg0);
> + reg1 = __le32_to_cpu(rr->reg1);
> +
> + ath10k_dbg(ATH10K_DBG_REGULATORY,
> + "wmi phyerr radar report chirp %d max_width %d agc_total_gain %d pulse_delta_diff %d\n",
> + MS(reg0, RADAR_REPORT_REG0_PULSE_IS_CHIRP),
> + MS(reg0, RADAR_REPORT_REG0_PULSE_IS_MAX_WIDTH),
> + MS(reg0, RADAR_REPORT_REG0_AGC_TOTAL_GAIN),
> + MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_DIFF));
> + ath10k_dbg(ATH10K_DBG_REGULATORY,
> + "wmi phyerr radar report pulse_delta_pean %d pulse_sidx %d fft_valid %d agc_mb_gain %d subchan_mask %d\n",
> + MS(reg0, RADAR_REPORT_REG0_PULSE_DELTA_PEAK),
> + MS(reg0, RADAR_REPORT_REG0_PULSE_SIDX),
> + MS(reg1, RADAR_REPORT_REG1_PULSE_SRCH_FFT_VALID),
> + MS(reg1, RADAR_REPORT_REG1_PULSE_AGC_MB_GAIN),
> + MS(reg1, RADAR_REPORT_REG1_PULSE_SUBCHAN_MASK));
> + ath10k_dbg(ATH10K_DBG_REGULATORY,
> + "wmi phyerr radar report pulse_tsf_offset 0x%X pulse_dur: %d\n",
> + MS(reg1, RADAR_REPORT_REG1_PULSE_TSF_OFFSET),
> + MS(reg1, RADAR_REPORT_REG1_PULSE_DUR));
> +
> + if (!ar->dfs_detector)
> + return;
> +
> + /* report event to DFS pattern detector */
> + tsf32l = __le32_to_cpu(event->hdr.tsf_timestamp);
> + tsf64 = tsf & (~0xFFFFFFFFULL);
> + tsf64 |= tsf32l;
> +
> + width = MS(reg1, RADAR_REPORT_REG1_PULSE_DUR);
> + rssi = event->hdr.rssi_combined;
> +
> + /*
> + * hardware store this as 8 bit signed value,
> + * set to zero if negative number
> + */
to be consistent with rest of the comments in ath10k:
"/* hardware...."
> + if (rssi & 0x80)
> + rssi = 0;
> +
> + pe.ts = tsf64;
> + pe.freq = ar->hw->conf.chandef.chan->center_freq;
> + pe.width = width;
> + pe.rssi = rssi;
> +
> + ath10k_dbg(ATH10K_DBG_REGULATORY,
> + "dfs add pulse freq: %d, width: %d, rssi %d, tsf: %llX\n",
> + pe.freq, pe.width, pe.rssi, pe.ts);
> +
> + ATH10K_DFS_STAT_INC(ar, pulses_detected);
> +
> + if (!ar->dfs_detector->add_pulse(ar->dfs_detector, &pe)) {
> + ath10k_dbg(ATH10K_DBG_REGULATORY,
> + "dfs no pulse pattern detected, yet\n");
> + return;
> + }
> +
> + ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs radar detected\n");
> + ATH10K_DFS_STAT_INC(ar, radar_detected);
> + ieee80211_radar_detected(ar->hw);
> +}
> +
> +static int ath10k_dfs_fft_report(struct ath10k *ar,
> + struct wmi_single_phyerr_rx_event *event,
> + struct phyerr_fft_report *fftr,
> + u64 tsf)
> +{
> + u32 reg0, reg1;
> + u8 rssi, peak_mag;
> +
> + reg0 = __le32_to_cpu(fftr->reg0);
> + reg1 = __le32_to_cpu(fftr->reg1);
> + rssi = event->hdr.rssi_combined;
locking?
> + ath10k_dbg(ATH10K_DBG_REGULATORY,
> + "wmi phyerr fft report total_gain_db %d base_pwr_db %d fft_chn_idx %d peak_sidx %d\n",
> + MS(reg0, SEARCH_FFT_REPORT_REG0_TOTAL_GAIN_DB),
> + MS(reg0, SEARCH_FFT_REPORT_REG0_BASE_PWR_DB),
> + MS(reg0, SEARCH_FFT_REPORT_REG0_FFT_CHN_IDX),
> + MS(reg0, SEARCH_FFT_REPORT_REG0_PEAK_SIDX));
> + ath10k_dbg(ATH10K_DBG_REGULATORY,
> + "wmi phyerr fft report rel_pwr_db %d avgpwr_db %d peak_mag %d num_store_bin %d\n",
> + MS(reg1, SEARCH_FFT_REPORT_REG1_RELPWR_DB),
> + MS(reg1, SEARCH_FFT_REPORT_REG1_AVGPWR_DB),
> + MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG),
> + MS(reg1, SEARCH_FFT_REPORT_REG1_NUM_STR_BINS_IB));
> +
> + peak_mag = MS(reg1, SEARCH_FFT_REPORT_REG1_PEAK_MAG);
> +
> + /* false event detection */
> + if (rssi == DFS_RSSI_POSSIBLY_FALSE &&
> + peak_mag < 2 * DFS_PEAK_MAG_THOLD_POSSIBLY_FALSE) {
> + ath10k_dbg(ATH10K_DBG_REGULATORY, "dfs false pulse detected\n");
> + ATH10K_DFS_STAT_INC(ar, pulses_discarded);
> + return -EINVAL;
> + }
> +
> + return 0;
> +}
> +
> +static void ath10k_wmi_event_dfs(struct ath10k *ar,
> + struct wmi_single_phyerr_rx_event *event,
> + u64 tsf)
> +{
> + int buf_len, tlv_len, res, i = 0;
> + struct phyerr_tlv *tlv;
> + struct phyerr_radar_report *rr;
> + struct phyerr_fft_report *fftr;
> + u8 *tlv_buf;
locking?
--
Kalle Valo
More information about the ath10k
mailing list