Date: Sat, 29 Mar 2014 19:53:04 +0000 (UTC) From: Adrian Chadd <adrian@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r263920 - head/sys/dev/iwi Message-ID: <201403291953.s2TJr43L053568@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: adrian Date: Sat Mar 29 19:53:04 2014 New Revision: 263920 URL: http://svnweb.freebsd.org/changeset/base/263920 Log: Add support to export the contents of the notification updates from the firmware. Right now the NIC isn't actually exporting useful data. I'm not quite sure why this is. :( Added: head/sys/dev/iwi/if_iwi_ioctl.h (contents, props changed) Modified: head/sys/dev/iwi/if_iwi.c head/sys/dev/iwi/if_iwireg.h head/sys/dev/iwi/if_iwivar.h Modified: head/sys/dev/iwi/if_iwi.c ============================================================================== --- head/sys/dev/iwi/if_iwi.c Sat Mar 29 19:04:38 2014 (r263919) +++ head/sys/dev/iwi/if_iwi.c Sat Mar 29 19:53:04 2014 (r263920) @@ -84,6 +84,7 @@ __FBSDID("$FreeBSD$"); #include <dev/iwi/if_iwireg.h> #include <dev/iwi/if_iwivar.h> +#include <dev/iwi/if_iwi_ioctl.h> #define IWI_DEBUG #ifdef IWI_DEBUG @@ -1373,6 +1374,33 @@ iwi_checkforqos(struct ieee80211vap *vap #undef SUBTYPE } +static void +iwi_notif_link_quality(struct iwi_softc *sc, struct iwi_notif *notif) +{ + struct iwi_notif_link_quality *lq; + int len; + + len = le16toh(notif->len); + + DPRINTFN(5, ("Notification (%u) - len=%d, sizeof=%d\n", + notif->type, + len, + sizeof(struct iwi_notif_link_quality) + )); + + /* enforce length */ + if (len != sizeof(struct iwi_notif_link_quality)) { + DPRINTFN(5, ("Notification: (%u) too short (%d)\n", + notif->type, + len)); + return; + } + + lq = (struct iwi_notif_link_quality *)(notif + 1); + memcpy(&sc->sc_linkqual, lq, sizeof(sc->sc_linkqual)); + sc->sc_linkqual_valid = 1; +} + /* * Task queue callbacks for iwi_notification_intr used to avoid LOR's. */ @@ -1542,9 +1570,12 @@ iwi_notification_intr(struct iwi_softc * case IWI_NOTIF_TYPE_CALIBRATION: case IWI_NOTIF_TYPE_NOISE: - case IWI_NOTIF_TYPE_LINK_QUALITY: + /* XXX handle? */ DPRINTFN(5, ("Notification (%u)\n", notif->type)); break; + case IWI_NOTIF_TYPE_LINK_QUALITY: + iwi_notif_link_quality(sc, notif); + break; default: DPRINTF(("unknown notification type %u flags 0x%x len %u\n", @@ -2063,11 +2094,25 @@ iwi_ioctl(struct ifnet *ifp, u_long cmd, case SIOCGIFADDR: error = ether_ioctl(ifp, cmd, data); break; + case SIOCGIWISTATS: + IWI_LOCK(sc); + /* XXX validate permissions/memory/etc? */ + error = copyout(&sc->sc_linkqual, ifr->ifr_data, + sizeof(struct iwi_notif_link_quality)); + IWI_UNLOCK(sc); + break; + case SIOCZIWISTATS: + IWI_LOCK(sc); + memset(&sc->sc_linkqual, 0, + sizeof(struct iwi_notif_link_quality)); + IWI_UNLOCK(sc); + error = 0; + break; default: error = EINVAL; break; } - return error; + return error; } static void Added: head/sys/dev/iwi/if_iwi_ioctl.h ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/dev/iwi/if_iwi_ioctl.h Sat Mar 29 19:53:04 2014 (r263920) @@ -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_IWI_IOCTL_H__ +#define __IF_IWI_IOCTL_H__ + +/* XXX how should I pick appropriate ioctl numbers? */ +#define SIOCGIWISTATS _IOWR('i', 147, struct ifreq) +#define SIOCZIWISTATS _IOWR('i', 148, struct ifreq) + +#endif /* __IF_IWI_IOCTL_H__ */ Modified: head/sys/dev/iwi/if_iwireg.h ============================================================================== --- head/sys/dev/iwi/if_iwireg.h Sat Mar 29 19:04:38 2014 (r263919) +++ head/sys/dev/iwi/if_iwireg.h Sat Mar 29 19:53:04 2014 (r263920) @@ -221,6 +221,7 @@ struct iwi_notif_association { /* structure for notification IWI_NOTIF_TYPE_SCAN_CHANNEL */ struct iwi_notif_scan_channel { uint8_t nchan; + /* XXX this is iwi_cmd_stats, and a u8 reserved field */ uint8_t reserved[47]; } __packed; @@ -239,6 +240,68 @@ struct iwi_notif_beacon_state { uint32_t number; } __packed; +/* structure(s) for notification IWI_NOTIF_TYPE_LINK_QUALITY */ + +#define RX_FREE_BUFFERS 32 +#define RX_LOW_WATERMARK 8 + +#define SUP_RATE_11A_MAX_NUM_CHANNELS 8 +#define SUP_RATE_11B_MAX_NUM_CHANNELS 4 +#define SUP_RATE_11G_MAX_NUM_CHANNELS 12 + +// Used for passing to driver number of successes and failures per rate +struct iwi_rate_histogram { + union { + uint32_t a[SUP_RATE_11A_MAX_NUM_CHANNELS]; + uint32_t b[SUP_RATE_11B_MAX_NUM_CHANNELS]; + uint32_t g[SUP_RATE_11G_MAX_NUM_CHANNELS]; + } success; + union { + uint32_t a[SUP_RATE_11A_MAX_NUM_CHANNELS]; + uint32_t b[SUP_RATE_11B_MAX_NUM_CHANNELS]; + uint32_t g[SUP_RATE_11G_MAX_NUM_CHANNELS]; + } failed; +} __packed; + +/* statistics command response */ +struct iwi_cmd_stats { + uint8_t cmd_id; + uint8_t seq_num; + uint16_t good_sfd; + uint16_t bad_plcp; + uint16_t wrong_bssid; + uint16_t valid_mpdu; + uint16_t bad_mac_header; + uint16_t reserved_frame_types; + uint16_t rx_ina; + uint16_t bad_crc32; + uint16_t invalid_cts; + uint16_t invalid_acks; + uint16_t long_distance_ina_fina; + uint16_t dsp_silence_unreachable; + uint16_t accumulated_rssi; + uint16_t rx_ovfl_frame_tossed; + uint16_t rssi_silence_threshold; + uint16_t rx_ovfl_frame_supplied; + uint16_t last_rx_frame_signal; + uint16_t last_rx_frame_noise; + uint16_t rx_autodetec_no_ofdm; + uint16_t rx_autodetec_no_barker; + uint16_t reserved; +} __packed; + +#define SILENCE_OVER_THRESH (1) +#define SILENCE_UNDER_THRESH (2) + +struct iwi_notif_link_quality { + struct iwi_cmd_stats stats; + uint8_t rate; + uint8_t modulation; + struct iwi_rate_histogram histogram; + uint8_t silence_notification_type; /* SILENCE_OVER/UNDER_THRESH */ + uint16_t silence_count; +} __packed; + /* received frame header */ struct iwi_frame { uint32_t reserved1[2]; Modified: head/sys/dev/iwi/if_iwivar.h ============================================================================== --- head/sys/dev/iwi/if_iwivar.h Sat Mar 29 19:04:38 2014 (r263919) +++ head/sys/dev/iwi/if_iwivar.h Sat Mar 29 19:53:04 2014 (r263920) @@ -215,6 +215,9 @@ struct iwi_softc { struct iwi_rx_radiotap_header sc_rxtap; struct iwi_tx_radiotap_header sc_txtap; + + struct iwi_notif_link_quality sc_linkqual; + int sc_linkqual_valid; }; #define IWI_STATE_BEGIN(_sc, _state) do { \
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201403291953.s2TJr43L053568>