mirror of https://gitee.com/openkylin/linux.git
ath9k: extend DFS detector stats in dfs_debugfs
Extend debugfs entry for dfs_stats with DFS detection events and shared pool statistics. Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
parent
2a5783b817
commit
b96f20b3af
|
@ -148,11 +148,13 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
|
|||
struct ath_hw *ah = sc->sc_ah;
|
||||
struct ath_common *common = ath9k_hw_common(ah);
|
||||
|
||||
DFS_STAT_INC(sc, pulses_total);
|
||||
if ((rs->rs_phyerr != ATH9K_PHYERR_RADAR) &&
|
||||
(rs->rs_phyerr != ATH9K_PHYERR_FALSE_RADAR_EXT)) {
|
||||
ath_dbg(common, DFS,
|
||||
"Error: rs_phyer=0x%x not a radar error\n",
|
||||
rs->rs_phyerr);
|
||||
DFS_STAT_INC(sc, pulses_no_dfs);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -188,7 +190,9 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
|
|||
"width=%d, rssi=%d, delta_ts=%llu\n",
|
||||
pe.freq, pe.ts, pe.width, pe.rssi, pe.ts-last_ts);
|
||||
last_ts = pe.ts;
|
||||
DFS_STAT_INC(sc, pulses_processed);
|
||||
if (pd != NULL && pd->add_pulse(pd, &pe)) {
|
||||
DFS_STAT_INC(sc, radar_detected);
|
||||
/*
|
||||
* TODO: forward radar event to DFS management layer
|
||||
*/
|
||||
|
|
|
@ -21,9 +21,15 @@
|
|||
#include "ath9k.h"
|
||||
#include "dfs_debug.h"
|
||||
|
||||
|
||||
struct ath_dfs_pool_stats global_dfs_pool_stats = { 0 };
|
||||
|
||||
#define ATH9K_DFS_STAT(s, p) \
|
||||
len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \
|
||||
sc->debug.stats.dfs_stats.p);
|
||||
#define ATH9K_DFS_POOL_STAT(s, p) \
|
||||
len += snprintf(buf + len, size - len, "%28s : %10u\n", s, \
|
||||
global_dfs_pool_stats.p);
|
||||
|
||||
static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
|
@ -43,6 +49,9 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
|
|||
hw_ver->macVersion, hw_ver->macRev,
|
||||
(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_DFS) ?
|
||||
"enabled" : "disabled");
|
||||
len += snprintf(buf + len, size - len, "Pulse detector statistics:\n");
|
||||
ATH9K_DFS_STAT("pulse events reported ", pulses_total);
|
||||
ATH9K_DFS_STAT("invalid pulse events ", pulses_no_dfs);
|
||||
ATH9K_DFS_STAT("DFS pulses detected ", pulses_detected);
|
||||
ATH9K_DFS_STAT("Datalen discards ", datalen_discards);
|
||||
ATH9K_DFS_STAT("RSSI discards ", rssi_discards);
|
||||
|
@ -50,6 +59,18 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
|
|||
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);
|
||||
len += snprintf(buf + len, size - len, "Radar detector statistics "
|
||||
"(current DFS region: %d)\n", sc->dfs_detector->region);
|
||||
ATH9K_DFS_STAT("Pulse events processed ", pulses_processed);
|
||||
ATH9K_DFS_STAT("Radars detected ", radar_detected);
|
||||
len += snprintf(buf + len, size - len, "Global Pool statistics:\n");
|
||||
ATH9K_DFS_POOL_STAT("Pool references ", pool_reference);
|
||||
ATH9K_DFS_POOL_STAT("Pulses allocated ", pulse_allocated);
|
||||
ATH9K_DFS_POOL_STAT("Pulses alloc error ", pulse_alloc_error);
|
||||
ATH9K_DFS_POOL_STAT("Pulses in use ", pulse_used);
|
||||
ATH9K_DFS_POOL_STAT("Seqs. allocated ", pseq_allocated);
|
||||
ATH9K_DFS_POOL_STAT("Seqs. alloc error ", pseq_alloc_error);
|
||||
ATH9K_DFS_POOL_STAT("Seqs. in use ", pseq_used);
|
||||
|
||||
if (len > size)
|
||||
len = size;
|
||||
|
@ -60,8 +81,33 @@ static ssize_t read_file_dfs(struct file *file, char __user *user_buf,
|
|||
return retval;
|
||||
}
|
||||
|
||||
/* magic number to prevent accidental reset of DFS statistics */
|
||||
#define DFS_STATS_RESET_MAGIC 0x80000000
|
||||
static ssize_t write_file_dfs(struct file *file, const char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct ath_softc *sc = file->private_data;
|
||||
unsigned long val;
|
||||
char buf[32];
|
||||
ssize_t len;
|
||||
|
||||
len = min(count, sizeof(buf) - 1);
|
||||
if (copy_from_user(buf, user_buf, len))
|
||||
return -EFAULT;
|
||||
|
||||
buf[len] = '\0';
|
||||
if (strict_strtoul(buf, 0, &val))
|
||||
return -EINVAL;
|
||||
|
||||
if (val == DFS_STATS_RESET_MAGIC)
|
||||
memset(&sc->debug.stats.dfs_stats, 0,
|
||||
sizeof(sc->debug.stats.dfs_stats));
|
||||
return count;
|
||||
}
|
||||
|
||||
static const struct file_operations fops_dfs_stats = {
|
||||
.read = read_file_dfs,
|
||||
.write = write_file_dfs,
|
||||
.open = simple_open,
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = default_llseek,
|
||||
|
|
|
@ -22,17 +22,23 @@
|
|||
#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 - DFS Statistics per wiphy
|
||||
* @pulses_total: pulses reported by HW
|
||||
* @pulses_no_dfs: pulses wrongly reported as DFS
|
||||
* @pulses_detected: pulses detected so far
|
||||
* @datalen_discards: pulses discarded due to invalid datalen
|
||||
* @rssi_discards: pulses discarded due to invalid RSSI
|
||||
* @bwinfo_discards: pulses discarded due to invalid BW info
|
||||
* @pri_phy_errors: pulses reported for primary channel
|
||||
* @ext_phy_errors: pulses reported for extension channel
|
||||
* @dc_phy_errors: pulses reported for primary + extension channel
|
||||
* @pulses_processed: pulses forwarded to detector
|
||||
* @radar_detected: radars detected
|
||||
*/
|
||||
struct ath_dfs_stats {
|
||||
/* pulse stats */
|
||||
u32 pulses_total;
|
||||
u32 pulses_no_dfs;
|
||||
u32 pulses_detected;
|
||||
u32 datalen_discards;
|
||||
u32 rssi_discards;
|
||||
|
@ -40,18 +46,39 @@ struct ath_dfs_stats {
|
|||
u32 pri_phy_errors;
|
||||
u32 ext_phy_errors;
|
||||
u32 dc_phy_errors;
|
||||
/* pattern detection stats */
|
||||
u32 pulses_processed;
|
||||
u32 radar_detected;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ath_dfs_pool_stats - DFS Statistics for global pools
|
||||
*/
|
||||
struct ath_dfs_pool_stats {
|
||||
u32 pool_reference;
|
||||
u32 pulse_allocated;
|
||||
u32 pulse_alloc_error;
|
||||
u32 pulse_used;
|
||||
u32 pseq_allocated;
|
||||
u32 pseq_alloc_error;
|
||||
u32 pseq_used;
|
||||
};
|
||||
#if defined(CONFIG_ATH9K_DFS_DEBUGFS)
|
||||
|
||||
#define DFS_STAT_INC(sc, c) (sc->debug.stats.dfs_stats.c++)
|
||||
void ath9k_dfs_init_debug(struct ath_softc *sc);
|
||||
|
||||
#define DFS_POOL_STAT_INC(c) (global_dfs_pool_stats.c++)
|
||||
#define DFS_POOL_STAT_DEC(c) (global_dfs_pool_stats.c--)
|
||||
extern struct ath_dfs_pool_stats global_dfs_pool_stats;
|
||||
|
||||
#else
|
||||
|
||||
#define DFS_STAT_INC(sc, c) do { } while (0)
|
||||
static inline void ath9k_dfs_init_debug(struct ath_softc *sc) { }
|
||||
|
||||
#define DFS_POOL_STAT_INC(c) do { } while (0)
|
||||
#define DFS_POOL_STAT_DEC(c) do { } while (0)
|
||||
#endif /* CONFIG_ATH9K_DFS_DEBUGFS */
|
||||
|
||||
#endif /* ATH9K_DFS_DEBUG_H */
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "ath9k.h"
|
||||
#include "dfs_pattern_detector.h"
|
||||
#include "dfs_pri_detector.h"
|
||||
#include "dfs_debug.h"
|
||||
|
||||
/**
|
||||
* struct pri_sequence - sequence of pulses matching one PRI
|
||||
|
@ -101,6 +103,7 @@ static void pool_register_ref(void)
|
|||
{
|
||||
spin_lock_bh(&pool_lock);
|
||||
singleton_pool_references++;
|
||||
DFS_POOL_STAT_INC(pool_reference);
|
||||
spin_unlock_bh(&pool_lock);
|
||||
}
|
||||
|
||||
|
@ -108,6 +111,7 @@ static void pool_deregister_ref(void)
|
|||
{
|
||||
spin_lock_bh(&pool_lock);
|
||||
singleton_pool_references--;
|
||||
DFS_POOL_STAT_DEC(pool_reference);
|
||||
if (singleton_pool_references == 0) {
|
||||
/* free singleton pools with no references left */
|
||||
struct pri_sequence *ps, *ps0;
|
||||
|
@ -115,10 +119,12 @@ static void pool_deregister_ref(void)
|
|||
|
||||
list_for_each_entry_safe(p, p0, &pulse_pool, head) {
|
||||
list_del(&p->head);
|
||||
DFS_POOL_STAT_DEC(pulse_allocated);
|
||||
kfree(p);
|
||||
}
|
||||
list_for_each_entry_safe(ps, ps0, &pseq_pool, head) {
|
||||
list_del(&ps->head);
|
||||
DFS_POOL_STAT_DEC(pseq_allocated);
|
||||
kfree(ps);
|
||||
}
|
||||
}
|
||||
|
@ -129,6 +135,7 @@ static void pool_put_pulse_elem(struct pulse_elem *pe)
|
|||
{
|
||||
spin_lock_bh(&pool_lock);
|
||||
list_add(&pe->head, &pulse_pool);
|
||||
DFS_POOL_STAT_DEC(pulse_used);
|
||||
spin_unlock_bh(&pool_lock);
|
||||
}
|
||||
|
||||
|
@ -136,6 +143,7 @@ static void pool_put_pseq_elem(struct pri_sequence *pse)
|
|||
{
|
||||
spin_lock_bh(&pool_lock);
|
||||
list_add(&pse->head, &pseq_pool);
|
||||
DFS_POOL_STAT_DEC(pseq_used);
|
||||
spin_unlock_bh(&pool_lock);
|
||||
}
|
||||
|
||||
|
@ -146,6 +154,7 @@ static struct pri_sequence *pool_get_pseq_elem(void)
|
|||
if (!list_empty(&pseq_pool)) {
|
||||
pse = list_first_entry(&pseq_pool, struct pri_sequence, head);
|
||||
list_del(&pse->head);
|
||||
DFS_POOL_STAT_INC(pseq_used);
|
||||
}
|
||||
spin_unlock_bh(&pool_lock);
|
||||
return pse;
|
||||
|
@ -158,6 +167,7 @@ static struct pulse_elem *pool_get_pulse_elem(void)
|
|||
if (!list_empty(&pulse_pool)) {
|
||||
pe = list_first_entry(&pulse_pool, struct pulse_elem, head);
|
||||
list_del(&pe->head);
|
||||
DFS_POOL_STAT_INC(pulse_used);
|
||||
}
|
||||
spin_unlock_bh(&pool_lock);
|
||||
return pe;
|
||||
|
@ -210,9 +220,11 @@ static bool pulse_queue_enqueue(struct pri_detector *pde, u64 ts)
|
|||
if (p == NULL) {
|
||||
p = kmalloc(sizeof(*p), GFP_KERNEL);
|
||||
if (p == NULL) {
|
||||
pr_err("failed to allocate pulse_elem\n");
|
||||
DFS_POOL_STAT_INC(pulse_alloc_error);
|
||||
return false;
|
||||
}
|
||||
DFS_POOL_STAT_INC(pulse_allocated);
|
||||
DFS_POOL_STAT_INC(pulse_used);
|
||||
}
|
||||
INIT_LIST_HEAD(&p->head);
|
||||
p->ts = ts;
|
||||
|
@ -288,8 +300,12 @@ static bool pseq_handler_create_sequences(struct pri_detector *pde,
|
|||
new_ps = pool_get_pseq_elem();
|
||||
if (new_ps == NULL) {
|
||||
new_ps = kmalloc(sizeof(*new_ps), GFP_KERNEL);
|
||||
if (new_ps == NULL)
|
||||
if (new_ps == NULL) {
|
||||
DFS_POOL_STAT_INC(pseq_alloc_error);
|
||||
return false;
|
||||
}
|
||||
DFS_POOL_STAT_INC(pseq_allocated);
|
||||
DFS_POOL_STAT_INC(pseq_used);
|
||||
}
|
||||
memcpy(new_ps, &ps, sizeof(ps));
|
||||
INIT_LIST_HEAD(&new_ps->head);
|
||||
|
|
Loading…
Reference in New Issue