Track and expose the latest statistics from the firmware.

Tested:

* Intel Centrino 6205
This commit is contained in:
adrian 2014-02-24 02:37:04 +00:00
parent 764774a005
commit 9033c92af5
3 changed files with 68 additions and 0 deletions

View File

@ -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_softc *sc, struct iwn_rx_desc *desc,
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, struct iwn_rx_desc *desc,
__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, caddr_t data)
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;

View File

@ -0,0 +1,25 @@
/*-
* Copyright (c) 2014 Adrian Chadd <adrian@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__ */

View File

@ -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;