Author: adrian
Date: Mon Feb 24 02:37:04 2014
New Revision: 262422
URL: http://svnweb.freebsd.org/changeset/base/262422

Log:
  Track and expose the latest statistics from the firmware.
  
  Tested:
  
  * Intel Centrino 6205

Added:
  head/sys/dev/iwn/if_iwn_ioctl.h   (contents, props changed)
Modified:
  head/sys/dev/iwn/if_iwn.c
  head/sys/dev/iwn/if_iwnvar.h

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c   Mon Feb 24 02:13:20 2014        (r262421)
+++ head/sys/dev/iwn/if_iwn.c   Mon Feb 24 02:37:04 2014        (r262422)
@@ -79,6 +79,7 @@ __FBSDID("$FreeBSD$");
 #include <dev/iwn/if_iwn_devid.h>
 #include <dev/iwn/if_iwn_chip_cfg.h>
 #include <dev/iwn/if_iwn_debug.h>
+#include <dev/iwn/if_iwn_ioctl.h>
 
 struct iwn_ident {
        uint16_t        vendor;
@@ -3140,6 +3141,16 @@ iwn5000_rx_calib_results(struct iwn_soft
        memcpy(sc->calibcmd[idx].buf, calib, len);
 }
 
+static void
+iwn_stats_update(struct iwn_softc *sc, struct iwn_calib_state *calib,
+    struct iwn_stats *stats)
+{
+
+       /* XXX lock assert */
+       memcpy(&sc->last_stat, stats, sizeof(struct iwn_stats));
+       sc->last_stat_valid = 1;
+}
+
 /*
  * Process an RX_STATISTICS or BEACON_STATISTICS firmware notification.
  * The latter is sent by the firmware after each received beacon.
@@ -3172,6 +3183,9 @@ iwn_rx_statistics(struct iwn_softc *sc, 
            __func__, desc->type);
        sc->calib_cnt = 0;      /* Reset TX power calibration timeout. */
 
+       /* Collect/track general statistics for reporting */
+       iwn_stats_update(sc, calib, stats);
+
        /* Test if temperature has changed. */
        if (stats->general.temp != sc->rawtemp) {
                /* Convert "raw" temperature to degC. */
@@ -4712,6 +4726,19 @@ iwn_ioctl(struct ifnet *ifp, u_long cmd,
        case SIOCGIFMEDIA:
                error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd);
                break;
+       case SIOCGIWNSTATS:
+               IWN_LOCK(sc);
+               /* XXX validate permissions/memory/etc? */
+               error = copyout(&sc->last_stat, ifr->ifr_data,
+                   sizeof(struct iwn_stats));
+               IWN_UNLOCK(sc);
+               break;
+       case SIOCZIWNSTATS:
+               IWN_LOCK(sc);
+               memset(&sc->last_stat, 0, sizeof(struct iwn_stats));
+               IWN_UNLOCK(sc);
+               error = 0;
+               break;
        default:
                error = EINVAL;
                break;

Added: head/sys/dev/iwn/if_iwn_ioctl.h
==============================================================================
--- /dev/null   00:00:00 1970   (empty, because file is newly added)
+++ head/sys/dev/iwn/if_iwn_ioctl.h     Mon Feb 24 02:37:04 2014        
(r262422)
@@ -0,0 +1,25 @@
+/*-
+ * Copyright (c) 2014 Adrian Chadd <adr...@freebsd.org>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * $FreeBSD$
+ */
+#ifndef        __IF_IWN_IOCTL_H__
+#define        __IF_IWN_IOCTL_H__
+
+/* XXX how should I pick appropriate ioctl numbers? */
+#define        SIOCGIWNSTATS           _IOWR('i', 145, struct ifreq)
+#define        SIOCZIWNSTATS           _IOWR('i', 146, struct ifreq)
+
+#endif /* __IF_IWN_IOCTL_H__ */

Modified: head/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- head/sys/dev/iwn/if_iwnvar.h        Mon Feb 24 02:13:20 2014        
(r262421)
+++ head/sys/dev/iwn/if_iwnvar.h        Mon Feb 24 02:37:04 2014        
(r262422)
@@ -328,6 +328,22 @@ struct iwn_softc {
        int                     ctx;
        struct ieee80211vap     *ivap[IWN_NUM_RXON_CTX];
 
+       /* General statistics */
+       /*
+        * The statistics are reset after each channel
+        * change.  So it may be zeroed after things like
+        * a background scan.
+        *
+        * So for now, this is just a cheap hack to
+        * expose the last received statistics dump
+        * via an ioctl().  Later versions of this
+        * could expose the last 'n' messages, or just
+        * provide a pipeline for the firmware responses
+        * via something like BPF.
+        */
+       struct iwn_stats        last_stat;
+       int                     last_stat_valid;
+
        uint8_t                 uc_scan_progress;
        uint32_t                rawtemp;
        int                     temp;
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to