wil6210: fix beamforming data reporting
authorVladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Wed, 6 Aug 2014 07:31:56 +0000 (10:31 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 25 Aug 2014 20:17:35 +0000 (16:17 -0400)
When reading 'bf' file on debugfs, query beam forming status from firmware.
Ignore CID's that return error or return all zeros.

Remove obsolete code that used to maintain statistics on per-device basis,
as now it is reported be per-CID and current.

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
drivers/net/wireless/ath/wil6210/debugfs.c
drivers/net/wireless/ath/wil6210/txrx.c
drivers/net/wireless/ath/wil6210/wil6210.h
drivers/net/wireless/ath/wil6210/wmi.c
drivers/net/wireless/ath/wil6210/wmi.h

index 95269d234ca9dd929d94b380cd5eac0f50204b83..b1c6a7293390a4364450c778b1ed24b156a2c77d 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/power_supply.h>
 
 #include "wil6210.h"
+#include "wmi.h"
 #include "txrx.h"
 
 /* Nasty hack. Better have per device instances */
@@ -728,16 +729,79 @@ static const struct file_operations fops_txdesc = {
 };
 
 /*---------beamforming------------*/
+static char *wil_bfstatus_str(u32 status)
+{
+       switch (status) {
+       case 0:
+               return "Failed";
+       case 1:
+               return "OK";
+       case 2:
+               return "Retrying";
+       default:
+               return "??";
+       }
+}
+
+static bool is_all_zeros(void * const x_, size_t sz)
+{
+       /* if reply is all-0, ignore this CID */
+       u32 *x = x_;
+       int n;
+
+       for (n = 0; n < sz / sizeof(*x); n++)
+               if (x[n])
+                       return false;
+
+       return true;
+}
+
 static int wil_bf_debugfs_show(struct seq_file *s, void *data)
 {
+       int rc;
+       int i;
        struct wil6210_priv *wil = s->private;
-       seq_printf(s,
-                  "TSF : 0x%016llx\n"
-                  "TxMCS : %d\n"
-                  "Sectors(rx:tx) my %2d:%2d peer %2d:%2d\n",
-                  wil->stats.tsf, wil->stats.bf_mcs,
-                  wil->stats.my_rx_sector, wil->stats.my_tx_sector,
-                  wil->stats.peer_rx_sector, wil->stats.peer_tx_sector);
+       struct wmi_notify_req_cmd cmd = {
+               .interval_usec = 0,
+       };
+       struct {
+               struct wil6210_mbox_hdr_wmi wmi;
+               struct wmi_notify_req_done_event evt;
+       } __packed reply;
+
+       for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
+               u32 status;
+
+               cmd.cid = i;
+               rc = wmi_call(wil, WMI_NOTIFY_REQ_CMDID, &cmd, sizeof(cmd),
+                             WMI_NOTIFY_REQ_DONE_EVENTID, &reply,
+                             sizeof(reply), 20);
+               /* if reply is all-0, ignore this CID */
+               if (rc || is_all_zeros(&reply.evt, sizeof(reply.evt)))
+                       continue;
+
+               status = le32_to_cpu(reply.evt.status);
+               seq_printf(s, "CID %d {\n"
+                          "  TSF = 0x%016llx\n"
+                          "  TxMCS = %2d TxTpt = %4d\n"
+                          "  SQI = %4d\n"
+                          "  Status = 0x%08x %s\n"
+                          "  Sectors(rx:tx) my %2d:%2d peer %2d:%2d\n"
+                          "  Goodput(rx:tx) %4d:%4d\n"
+                          "}\n",
+                          i,
+                          le64_to_cpu(reply.evt.tsf),
+                          le16_to_cpu(reply.evt.bf_mcs),
+                          le32_to_cpu(reply.evt.tx_tpt),
+                          reply.evt.sqi,
+                          status, wil_bfstatus_str(status),
+                          le16_to_cpu(reply.evt.my_rx_sector),
+                          le16_to_cpu(reply.evt.my_tx_sector),
+                          le16_to_cpu(reply.evt.other_rx_sector),
+                          le16_to_cpu(reply.evt.other_tx_sector),
+                          le32_to_cpu(reply.evt.rx_goodput),
+                          le32_to_cpu(reply.evt.tx_goodput));
+       }
        return 0;
 }
 
index 9fcc2e32180df2865f77a6bf5a7abb1a8d600b2d..9bd920d272bbf7c1d20edd165ddeac6aeb342041 100644 (file)
@@ -414,7 +414,6 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
        cid = wil_rxdesc_cid(d);
        stats = &wil->sta[cid].stats;
        stats->last_mcs_rx = wil_rxdesc_mcs(d);
-       wil->stats.last_mcs_rx = stats->last_mcs_rx;
 
        /* use radiotap header only if required */
        if (ndev->type == ARPHRD_IEEE80211_RADIOTAP)
index 0097300c863c184c902efba25b1064245fbb446d..f8718fe547c4aca257f1831b5a2cf5ba129a20b1 100644 (file)
@@ -330,17 +330,6 @@ struct wil_tid_ampdu_rx {
        bool first_time; /* is it 1-st time this buffer used? */
 };
 
-struct wil6210_stats {
-       u64 tsf;
-       u32 snr;
-       u16 last_mcs_rx;
-       u16 bf_mcs; /* last BF, used for Tx */
-       u16 my_rx_sector;
-       u16 my_tx_sector;
-       u16 peer_rx_sector;
-       u16 peer_tx_sector;
-};
-
 enum wil_sta_status {
        wil_sta_unused = 0,
        wil_sta_conn_pending = 1,
@@ -433,7 +422,6 @@ struct wil6210_priv {
 
        struct mutex mutex; /* for wil6210_priv access in wil_{up|down} */
        /* statistics */
-       struct wil6210_stats stats;
        atomic_t isr_count_rx, isr_count_tx;
        /* debugfs */
        struct dentry *debug;
index b25a62da8f2251f27399adcdf152a0fe4b7ed5f5..0beb129e985817dd6e9911f575ceb9bfc43128ad 100644 (file)
@@ -482,33 +482,6 @@ static void wmi_evt_disconnect(struct wil6210_priv *wil, int id,
        mutex_unlock(&wil->mutex);
 }
 
-static void wmi_evt_notify(struct wil6210_priv *wil, int id, void *d, int len)
-{
-       struct wmi_notify_req_done_event *evt = d;
-
-       if (len < sizeof(*evt)) {
-               wil_err(wil, "Short NOTIFY event\n");
-               return;
-       }
-
-       wil->stats.tsf = le64_to_cpu(evt->tsf);
-       wil->stats.snr = le32_to_cpu(evt->snr_val);
-       wil->stats.bf_mcs = le16_to_cpu(evt->bf_mcs);
-       wil->stats.my_rx_sector = le16_to_cpu(evt->my_rx_sector);
-       wil->stats.my_tx_sector = le16_to_cpu(evt->my_tx_sector);
-       wil->stats.peer_rx_sector = le16_to_cpu(evt->other_rx_sector);
-       wil->stats.peer_tx_sector = le16_to_cpu(evt->other_tx_sector);
-       wil_dbg_wmi(wil, "Link status, MCS %d TSF 0x%016llx\n"
-                   "BF status 0x%08x SNR 0x%08x SQI %d%%\n"
-                   "Tx Tpt %d goodput %d Rx goodput %d\n"
-                   "Sectors(rx:tx) my %d:%d peer %d:%d\n",
-                   wil->stats.bf_mcs, wil->stats.tsf, evt->status,
-                   wil->stats.snr, evt->sqi, le32_to_cpu(evt->tx_tpt),
-                   le32_to_cpu(evt->tx_goodput), le32_to_cpu(evt->rx_goodput),
-                   wil->stats.my_rx_sector, wil->stats.my_tx_sector,
-                   wil->stats.peer_rx_sector, wil->stats.peer_tx_sector);
-}
-
 /*
  * Firmware reports EAPOL frame using WME event.
  * Reconstruct Ethernet frame and deliver it via normal Rx
@@ -651,7 +624,6 @@ static const struct {
        {WMI_SCAN_COMPLETE_EVENTID,     wmi_evt_scan_complete},
        {WMI_CONNECT_EVENTID,           wmi_evt_connect},
        {WMI_DISCONNECT_EVENTID,        wmi_evt_disconnect},
-       {WMI_NOTIFY_REQ_DONE_EVENTID,   wmi_evt_notify},
        {WMI_EAPOL_RX_EVENTID,          wmi_evt_eapol_rx},
        {WMI_DATA_PORT_OPEN_EVENTID,    wmi_evt_linkup},
        {WMI_WBE_LINKDOWN_EVENTID,      wmi_evt_linkdown},
index 2f51b46f255b01bb46ef20c2844f1e5fdbc34ab0..061618cee9f6685c5645c8dec98f3651ffdcd64a 100644 (file)
@@ -980,7 +980,7 @@ struct wmi_ready_event {
  * WMI_NOTIFY_REQ_DONE_EVENTID
  */
 struct wmi_notify_req_done_event {
-       __le32 status;
+       __le32 status; /* beamforming status, 0: fail; 1: OK; 2: retrying */
        __le64 tsf;
        __le32 snr_val;
        __le32 tx_tpt;