This patch adds error vector magnitude collection to AR9001 and
AR9002, as well as my best attempt at making sense of what the EVM
numbers actually mean.  There was an obvious problem with the
AR_RxEVMn macros (parts of status4 were being used for rssi, and all
of status4 was also being used for EVM0, so the EVM block probably
actually starts at 5, since 5, 6 and 7 aren't used in the code for any
other purpose).  The AR6002 driver has a bit for the PCU MISC register
related to EVM.  A lot of the other bits line up in that register
between AR9002 and AR6002, so this patch also sets that bit.  I'm
assuming that enables something related to EVM, but so far it seems
like the default behavior for the AR9220 reports EVM just fine (so
this change doesn't appear to be necessary).

The EVM readings themselves are a bit peculiar.  They seem broken up
by octet.  Legacy rates yield 0x80808080, and HT rates yield numbers
like 0x1a1e1f21.  MCS0-7 produce non-zero results in EVM0, and MCS8-15
produce non-zero results in EVM0 and EVM1.  At close range, the octets
are typically between 0x1a and 0x24.  At greater range, the octets go
down to between 0x04 and 0x13.  My best guess so far is that all
32-bits of each EVM reading is significant, and each octet of that is
the EVM of a pilot carrier in negative dB.  EVM0, then, is probably
the EVM for spatial stream 0, and so on.  Does that make sense to
anybody?

To aid in figuring this out, I track the last valid EVM reading for
each bitrate in the debug rx_stats struct, and these EVM stats can be
dumped by reading the recv file in debugfs.  There's also a lookup
table to handle conversion between EVM(dB) and EVM(%), since
percentage makes more sense to me in this context.

I'm just guessing on this stuff, based on experimentation.  Opinions
and insight are very welcome.  This is an RFC, and I haven't put much
thought into how this might actually be tracked and presented.  In the
short-term, I just want it for a better quality control metric.  It
does seem to shed some light on situations where RSSI is high, but
minstrel_ht settles on a mid-level bitrate.  In a few cases where I've
seen that now with EVM reporting, often I see what I assume is a pilot
carrier having an EVM 5 or 7 dB worse than the rest (perhaps due to
frequency-dependent multipath interference knocking down one block of
carriers).

Here is the chunk of recv when the ath9k station is near the AP, and
when it is about 30' away (through a few walls):

Short-range:
        Rate    Chain    Pilot 1     Pilot 2     Pilot 3     Pilot 4
        MCS00     0     27 (  4%)   24 (  6%)   24 (  6%)   24 (  6%)
        MCS01     0     24 (  6%)   24 (  6%)   26 (  5%)   24 (  6%)
        MCS02     0     26 (  5%)   27 (  4%)   26 (  5%)   25 (  5%)
        MCS03     0     33 (  2%)   30 (  3%)   29 (  3%)   32 (  2%)
        MCS04     0     28 (  3%)   26 (  5%)   28 (  3%)   31 (  2%)
        MCS05     0     32 (  2%)   25 (  5%)   30 (  3%)   23 (  7%)
        MCS06     0     28 (  3%)   26 (  5%)   31 (  2%)   29 (  3%)
        MCS07     0     28 (  3%)   26 (  5%)   30 (  3%)   28 (  3%)
        MCS08     0     26 (  5%)   25 (  5%)   27 (  4%)   26 (  5%)
        MCS08     1     25 (  5%)   26 (  5%)   27 (  4%)   23 (  7%)
        MCS09     0     24 (  6%)   28 (  3%)   29 (  3%)   28 (  3%)
        MCS09     1     24 (  6%)   26 (  5%)   26 (  5%)   26 (  5%)
        MCS10     0     21 (  8%)   24 (  6%)   26 (  5%)   26 (  5%)
        MCS10     1     22 (  7%)   27 (  4%)   28 (  3%)   25 (  5%)
        MCS11     0     26 (  5%)   24 (  6%)   26 (  5%)   28 (  3%)
        MCS11     1     23 (  7%)   29 (  3%)   31 (  2%)   25 (  5%)
        MCS12     0     29 (  3%)   25 (  5%)   32 (  2%)   29 (  3%)
        MCS12     1     27 (  4%)   26 (  5%)   34 (  1%)   23 (  7%)
        MCS13     0     25 (  5%)   22 (  7%)   28 (  3%)   26 (  5%)
        MCS13     1     23 (  7%)   26 (  5%)   30 (  3%)   26 (  5%)
        MCS14     0     21 (  8%)   23 (  7%)   21 (  8%)   24 (  6%)
        MCS14     1     20 ( 10%)   23 (  7%)   26 (  5%)   21 (  8%)
        MCS15     0     25 (  5%)   25 (  5%)   28 (  3%)   24 (  6%)
        MCS15     1     22 (  7%)   26 (  5%)   27 (  4%)   32 (  2%)

Mid-range:
        Rate    Chain    Pilot 1     Pilot 2     Pilot 3     Pilot 4
        MCS00     0     20 ( 10%)   15 ( 17%)   26 (  5%)   27 (  4%)
        MCS01     0     20 ( 10%)   18 ( 12%)   27 (  4%)   26 (  5%)
        MCS02     0     22 (  7%)   19 ( 11%)   25 (  5%)   22 (  7%)
        MCS03     0     19 ( 11%)   13 ( 22%)   31 (  2%)   25 (  5%)
        MCS04     0     21 (  8%)   20 ( 10%)   29 (  3%)   28 (  3%)
        MCS05     0     17 ( 14%)   15 ( 17%)   25 (  5%)   33 (  2%)
        MCS06     0     16 ( 15%)   17 ( 14%)   32 (  2%)   28 (  3%)
        MCS07     0     19 ( 11%)   13 ( 22%)   34 (  1%)   26 (  5%)
        MCS08     0     17 ( 14%)   18 ( 12%)   11 ( 28%)   12 ( 25%)
        MCS08     1      9 ( 35%)    7 ( 44%)   16 ( 15%)   15 ( 17%)
        MCS09     0     15 ( 17%)   19 ( 11%)    9 ( 35%)   10 ( 31%)
        MCS09     1     12 ( 25%)   11 ( 28%)   11 ( 28%)   13 ( 22%)
        MCS10     0     18 ( 12%)   20 ( 10%)    9 ( 35%)   10 ( 31%)
        MCS10     1      9 ( 35%)    9 ( 35%)   11 ( 28%)   11 ( 28%)
        MCS11     0     16 ( 15%)   22 (  7%)    5 ( 56%)    7 ( 44%)
        MCS11     1     14 ( 19%)   12 ( 25%)   11 ( 28%)   12 ( 25%)
        MCS12     0     19 ( 11%)   21 (  8%)   11 ( 28%)   14 ( 19%)
        MCS12     1     14 ( 19%)   15 ( 17%)   13 ( 22%)   19 ( 11%)
        MCS13     0     14 ( 19%)   20 ( 10%)    6 ( 50%)    8 ( 39%)
        MCS13     1     14 ( 19%)   12 ( 25%)   17 ( 14%)   13 ( 22%)
        MCS14     0     14 ( 19%)   17 ( 14%)   11 ( 28%)   13 ( 22%)
        MCS14     1     14 ( 19%)   15 ( 17%)   12 ( 25%)   14 ( 19%)
        MCS15     0     12 ( 25%)   11 ( 28%)    9 ( 35%)   10 ( 31%)
        MCS15     1     14 ( 19%)   12 ( 25%)   15 ( 17%)   16 ( 15%)

Keep in mind all those are just for the last received packet at that
bitrate, so there's a fair amount of flux over time (maybe +/- 2 at
each octet).


 drivers/net/wireless/ath/ath9k/debug.c |   54 +++++++++++++++++++++++++++++++-
 drivers/net/wireless/ath/ath9k/debug.h |    1 +
 drivers/net/wireless/ath/ath9k/hw.c    |    1 +
 drivers/net/wireless/ath/ath9k/mac.c   |   11 ++++++
 drivers/net/wireless/ath/ath9k/mac.h   |    6 ++--
 drivers/net/wireless/ath/ath9k/reg.h   |    1 +
 6 files changed, 70 insertions(+), 4 deletions(-)

---
Index: compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/mac.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/ath/ath9k/mac.c        
2011-01-09
01:52:28.544097198 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/mac.c     
2011-01-09
01:52:35.552097198 -0500
@@ -705,6 +705,17 @@
                        rs->rs_status |= ATH9K_RXERR_DECRYPT;
        }

+       rs->evm0 = ads.AR_RxEVM0;
+       rs->evm1 = ads.AR_RxEVM1;
+       rs->evm2 = ads.AR_RxEVM2;
+#if 0
+       if (0 != rs->evm0 && 0x80808080 != rs->evm0)
+       {
+               printk("ath9k: EVM0: 0x%.8x  EVM1: 0x%.8x  EVM2: 0x%.8x\n",
+                          rs->evm0, rs->evm1, rs->evm2);
+       }
+#endif
+
        return 0;
 }
 EXPORT_SYMBOL(ath9k_hw_rxprocdesc);
Index: compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/reg.h
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/ath/ath9k/reg.h        
2011-01-09
01:52:28.560097198 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/reg.h     
2011-01-09
01:52:35.552097198 -0500
@@ -1585,6 +1585,7 @@
 #define AR_PCU_TBTT_PROTECT        0x00200000
 #define AR_PCU_CLEAR_VMF           0x01000000
 #define AR_PCU_CLEAR_BA_VALID      0x04000000
+#define AR_PCU_SEL_EVM             0x08000000
 #define AR_PCU_ALWAYS_PERFORM_KEYSEARCH 0x10000000

 #define AR_PCU_BT_ANT_PREVENT_RX   0x00100000
Index: compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/debug.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/ath/ath9k/debug.c      
2011-01-09
01:52:28.608097198 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/debug.c   
2011-01-09
01:52:35.552097198 -0500
@@ -666,6 +666,16 @@
        .llseek = default_llseek,
 };

+#define ATH9K_EVM_LUT_MAX 44
+static u8 evm_dB_to_percent_lut[ATH9K_EVM_LUT_MAX] = {
+       100, 89, 79, 70, 63, 56, 50, 44, 39, 35, 31, 28,
+       25, 22, 19, 17, 15, 14, 12, 11, 10, 8, 7, 7,
+       6, 5, 5, 4, 3, 3, 3, 2, 2, 2, 1, 1,
+       1, 1, 1, 1, 1, 0, 0,
+};
+
+#define ATH9K_EVM_TO_PCT(x) (x >= ATH9K_EVM_LUT_MAX ? 0 :
evm_dB_to_percent_lut[x])
+
 static ssize_t read_file_recv(struct file *file, char __user *user_buf,
                              size_t count, loff_t *ppos)
 {
@@ -675,8 +685,9 @@

        struct ath_softc *sc = file->private_data;
        char *buf;
-       unsigned int len = 0, size = 1152;
+       unsigned int len = 0, size = 4096;
        ssize_t retval = 0;
+       int rateidx = 0;

        buf = kzalloc(size, GFP_KERNEL);
        if (buf == NULL)
@@ -738,6 +749,41 @@
                        "%18s : %10u\n", "RX-Bytes-All",
                        sc->debug.stats.rxstats.rx_bytes_all);

+       len += snprintf(buf + len, size - len, "\nEVM:\n");
+       len += snprintf(buf + len, size - len,
+                "\tRate    Chain    Pilot 1     Pilot 2     Pilot 3     Pilot 
4\n");
+       //        \tMCSnn     n     nn (nnn%)   nn (nnn%)   nn (nnn%)   nn 
(nnn%)
+       for (rateidx = 0; rateidx < 24; rateidx++)
+       {
+               if (sc->debug.stats.rxstats.evm_stats[rateidx][0] ||
+                   sc->debug.stats.rxstats.evm_stats[rateidx][1] ||
+                   sc->debug.stats.rxstats.evm_stats[rateidx][2])
+               {
+                       int chain;
+                       for (chain = 0; chain<2; chain++)
+                       {
+                               u32 evm = 
sc->debug.stats.rxstats.evm_stats[rateidx][chain];
+                               if (evm)
+                               {
+                                       u8 pilot1, pilot2, pilot3, pilot4;
+                                       pilot1 = (evm & 0xFF000000) >> 24;
+                                       pilot2 = (evm & 0x00FF0000) >> 16;
+                                       pilot3 = (evm & 0x0000FF00) >> 8;
+                                       pilot4 = (evm & 0x000000FF);
+                                       len += snprintf(buf + len, size - len,
+                                                "\tMCS%02u     %u     "
+                                                "%2u (%3u%%)   %2u (%3u%%)   "
+                                                "%2u (%3u%%)   %2u (%3u%%)\n",
+                                                        rateidx, chain,
+                                                pilot1, 
ATH9K_EVM_TO_PCT(pilot1),
+                                                pilot2, 
ATH9K_EVM_TO_PCT(pilot2),
+                                                pilot3, 
ATH9K_EVM_TO_PCT(pilot3),
+                                                pilot4, 
ATH9K_EVM_TO_PCT(pilot4));
+                               }
+                       }
+               }
+       }
+
        if (len > size)
                len = size;

@@ -778,6 +824,12 @@
                RX_PHY_ERR_INC(phyerr);
        }

+       if (rs->rs_rate & 0x80) { // HT rate
+               sc->debug.stats.rxstats.evm_stats[rs->rs_rate - 0x80][0] = 
rs->evm0;
+               sc->debug.stats.rxstats.evm_stats[rs->rs_rate - 0x80][1] = 
rs->evm1;
+               sc->debug.stats.rxstats.evm_stats[rs->rs_rate - 0x80][2] = 
rs->evm2;
+       }
+
 #undef RX_STAT_INC
 #undef RX_PHY_ERR_INC
 }
Index: compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/debug.h
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/ath/ath9k/debug.h      
2011-01-09
01:52:28.572097198 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/debug.h   
2011-01-09
01:52:35.552097198 -0500
@@ -149,6 +149,7 @@
        u32 post_delim_crc_err;
        u32 decrypt_busy_err;
        u32 phy_err_stats[ATH9K_PHYERR_MAX];
+       u32 evm_stats[24][3];
 };

 struct ath_stats {
Index: compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/mac.h
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/ath/ath9k/mac.h        
2011-01-09
01:52:28.584097198 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/mac.h     
2011-01-09
01:52:35.556097198 -0500
@@ -542,9 +542,9 @@
 #define AR_RxRSSICombined         0xff000000
 #define AR_RxRSSICombined_S       24

-#define AR_RxEVM0           ds_rxstatus4
-#define AR_RxEVM1           ds_rxstatus5
-#define AR_RxEVM2           ds_rxstatus6
+#define AR_RxEVM0           ds_rxstatus5
+#define AR_RxEVM1           ds_rxstatus6
+#define AR_RxEVM2           ds_rxstatus7

 #define AR_RxDone           0x00000001
 #define AR_RxFrameOK        0x00000002
Index: compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/hw.c
===================================================================
--- compat-wireless-2011-01-07.orig/drivers/net/wireless/ath/ath9k/hw.c 
2011-01-07
15:03:59.000000000 -0500
+++ compat-wireless-2011-01-07/drivers/net/wireless/ath/ath9k/hw.c      
2011-01-09
01:52:35.580097198 -0500
@@ -1815,6 +1815,7 @@
                pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);

        ah->misc_mode |= AR_PCU_MIC_NEW_LOC_ENA;
+       ah->misc_mode |= AR_PCU_SEL_EVM;

        /* enable key search for every frame in an aggregate */
        if (AR_SREV_9300_20_OR_LATER(ah))
_______________________________________________
ath9k-devel mailing list
ath9k-devel@lists.ath9k.org
https://lists.ath9k.org/mailman/listinfo/ath9k-devel

Reply via email to