From owner-svn-src-head@freebsd.org Wed Sep 30 05:19:17 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 49855A0B3F4; Wed, 30 Sep 2015 05:19:17 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 3996D1D09; Wed, 30 Sep 2015 05:19:17 +0000 (UTC) (envelope-from adrian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t8U5JH8m093089; Wed, 30 Sep 2015 05:19:17 GMT (envelope-from adrian@FreeBSD.org) Received: (from adrian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t8U5JG4Y093086; Wed, 30 Sep 2015 05:19:16 GMT (envelope-from adrian@FreeBSD.org) Message-Id: <201509300519.t8U5JG4Y093086@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: adrian set sender to adrian@FreeBSD.org using -f From: Adrian Chadd Date: Wed, 30 Sep 2015 05:19:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r288414 - head/sys/dev/usb/wlan X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 30 Sep 2015 05:19:17 -0000 Author: adrian Date: Wed Sep 30 05:19:16 2015 New Revision: 288414 URL: https://svnweb.freebsd.org/changeset/base/288414 Log: modify the rssi logic a bit to actually return a useful rssi. The fullmac firmware doesn't seem to populate a useful rssi indicator in the RX descriptor, so if one plotted said values, they'd basically look like garbage. The reference driver implements a "get current rssi" firmware command which I guess is really meant for station operation only (as hostap operation would need rssi per station, not a single firmware read.) So: * populate sc_currssi during each calibration run; * use this in the RX path instead of trying to reconstruct the RSSI value and passing it around as a pointer; * do up a quick hack to map the rssi hardware value to some useful signal level; * the survey results provide an RSSI value between 0..100, so just do another quick hack to map it into some usefulish signal level; * supply a faked noise floor - I haven't yet found how to pull it out of the firmware. The scan results and the station RSSI information is now more useful for indicating signal strength / distance. Modified: head/sys/dev/usb/wlan/if_rsu.c head/sys/dev/usb/wlan/if_rsureg.h Modified: head/sys/dev/usb/wlan/if_rsu.c ============================================================================== --- head/sys/dev/usb/wlan/if_rsu.c Wed Sep 30 04:48:56 2015 (r288413) +++ head/sys/dev/usb/wlan/if_rsu.c Wed Sep 30 05:19:16 2015 (r288414) @@ -203,17 +203,18 @@ static void rsu_delete_key(struct rsu_so static int rsu_site_survey(struct rsu_softc *, struct ieee80211vap *); static int rsu_join_bss(struct rsu_softc *, struct ieee80211_node *); static int rsu_disconnect(struct rsu_softc *); +static int rsu_hwrssi_to_rssi(struct rsu_softc *, int hw_rssi); static void rsu_event_survey(struct rsu_softc *, uint8_t *, int); static void rsu_event_join_bss(struct rsu_softc *, uint8_t *, int); static void rsu_rx_event(struct rsu_softc *, uint8_t, uint8_t *, int); static void rsu_rx_multi_event(struct rsu_softc *, uint8_t *, int); +#if 0 static int8_t rsu_get_rssi(struct rsu_softc *, int, void *); +#endif +static struct mbuf * rsu_rx_frame(struct rsu_softc *, uint8_t *, int); +static struct mbuf * rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int); static struct mbuf * - rsu_rx_frame(struct rsu_softc *, uint8_t *, int, int *); -static struct mbuf * - rsu_rx_multi_frame(struct rsu_softc *, uint8_t *, int, int *); -static struct mbuf * - rsu_rxeof(struct usb_xfer *, struct rsu_data *, int *); + rsu_rxeof(struct usb_xfer *, struct rsu_data *); static void rsu_txeof(struct usb_xfer *, struct rsu_data *); static int rsu_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); @@ -1082,7 +1083,9 @@ static void rsu_calib_task(void *arg, int pending __unused) { struct rsu_softc *sc = arg; +#ifdef notyet uint32_t reg; +#endif RSU_DPRINTF(sc, RSU_DEBUG_CALIB, "%s: running calibration task\n", __func__); @@ -1100,9 +1103,10 @@ rsu_calib_task(void *arg, int pending __ #endif /* Read current signal level. */ if (rsu_fw_iocmd(sc, 0xf4000001) == 0) { - reg = rsu_read_4(sc, R92S_IOCMD_DATA); - RSU_DPRINTF(sc, RSU_DEBUG_CALIB, "%s: RSSI=%d%%\n", - __func__, reg >> 4); + sc->sc_currssi = rsu_read_4(sc, R92S_IOCMD_DATA); + RSU_DPRINTF(sc, RSU_DEBUG_CALIB, "%s: RSSI=%d (%d)\n", + __func__, sc->sc_currssi, + rsu_hwrssi_to_rssi(sc, sc->sc_currssi)); } if (sc->sc_calibrating) taskqueue_enqueue_timeout(taskqueue_thread, &sc->calib_task, hz); @@ -1433,6 +1437,24 @@ rsu_disconnect(struct rsu_softc *sc) return (rsu_fw_cmd(sc, R92S_CMD_DISCONNECT, &zero, sizeof(zero))); } +/* + * Map the hardware provided RSSI value to a signal level. + * For the most part it's just something we divide by and cap + * so it doesn't overflow the representation by net80211. + */ +static int +rsu_hwrssi_to_rssi(struct rsu_softc *sc, int hw_rssi) +{ + int v; + + if (hw_rssi == 0) + return (0); + v = hw_rssi >> 4; + if (v > 80) + v = 80; + return (v); +} + static void rsu_event_survey(struct rsu_softc *sc, uint8_t *buf, int len) { @@ -1486,8 +1508,9 @@ rsu_event_survey(struct rsu_softc *sc, u rxs.r_flags |= IEEE80211_R_NF | IEEE80211_R_RSSI; rxs.c_ieee = le32toh(bss->config.dsconfig); rxs.c_freq = ieee80211_ieee2mhz(rxs.c_ieee, IEEE80211_CHAN_2GHZ); - rxs.rssi = le32toh(bss->rssi); - rxs.nf = 0; /* XXX */ + /* This is a number from 0..100; so let's just divide it down a bit */ + rxs.rssi = le32toh(bss->rssi) / 2; + rxs.nf = -96; /* XXX avoid a LOR */ RSU_UNLOCK(sc); @@ -1557,7 +1580,7 @@ rsu_event_addba_req_report(struct rsu_so if (vap == NULL) return; - device_printf(sc->sc_dev, "%s: mac=%s, tid=%d, ssn=%d\n", + RSU_DPRINTF(sc, RSU_DEBUG_AMPDU, "%s: mac=%s, tid=%d, ssn=%d\n", __func__, ether_sprintf(ba->mac_addr), (int) ba->tid, @@ -1670,6 +1693,7 @@ rsu_rx_multi_event(struct rsu_softc *sc, } } +#if 0 static int8_t rsu_get_rssi(struct rsu_softc *sc, int rate, void *physt) { @@ -1690,9 +1714,10 @@ rsu_get_rssi(struct rsu_softc *sc, int r } return (rssi); } +#endif static struct mbuf * -rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen, int *rssi) +rsu_rx_frame(struct rsu_softc *sc, uint8_t *buf, int pktlen) { struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_frame *wh; @@ -1718,16 +1743,17 @@ rsu_rx_frame(struct rsu_softc *sc, uint8 rate = MS(rxdw3, R92S_RXDW3_RATE); infosz = MS(rxdw0, R92S_RXDW0_INFOSZ) * 8; +#if 0 /* Get RSSI from PHY status descriptor if present. */ if (infosz != 0) *rssi = rsu_get_rssi(sc, rate, &stat[1]); else *rssi = 0; +#endif RSU_DPRINTF(sc, RSU_DEBUG_RX, - "%s: Rx frame len=%d rate=%d infosz=%d rssi=%d\n", - __func__, - pktlen, rate, infosz, *rssi); + "%s: Rx frame len=%d rate=%d infosz=%d\n", + __func__, pktlen, rate, infosz); m = m_get2(pktlen, M_NOWAIT, MT_DATA, M_PKTHDR); if (__predict_false(m == NULL)) { @@ -1769,7 +1795,11 @@ rsu_rx_frame(struct rsu_softc *sc, uint8 /* Bit 7 set means HT MCS instead of rate. */ tap->wr_rate = 0x80 | (rate - 12); } +#if 0 tap->wr_dbm_antsignal = *rssi; +#endif + /* XXX not nice */ + tap->wr_dbm_antsignal = rsu_hwrssi_to_rssi(sc, sc->sc_currssi); tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); } @@ -1778,7 +1808,7 @@ rsu_rx_frame(struct rsu_softc *sc, uint8 } static struct mbuf * -rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len, int *rssi) +rsu_rx_multi_frame(struct rsu_softc *sc, uint8_t *buf, int len) { struct r92s_rx_stat *stat; uint32_t rxdw0; @@ -1810,7 +1840,7 @@ rsu_rx_multi_frame(struct rsu_softc *sc, break; /* Process 802.11 frame. */ - m = rsu_rx_frame(sc, buf, pktlen, rssi); + m = rsu_rx_frame(sc, buf, pktlen); if (m0 == NULL) m0 = m; if (prevm == NULL) @@ -1829,7 +1859,7 @@ rsu_rx_multi_frame(struct rsu_softc *sc, } static struct mbuf * -rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data, int *rssi) +rsu_rxeof(struct usb_xfer *xfer, struct rsu_data *data) { struct rsu_softc *sc = data->sc; struct ieee80211com *ic = &sc->sc_ic; @@ -1850,7 +1880,7 @@ rsu_rxeof(struct usb_xfer *xfer, struct /* No packets to process. */ return (NULL); } else - return (rsu_rx_multi_frame(sc, data->buf, len, rssi)); + return (rsu_rx_multi_frame(sc, data->buf, len)); } static void @@ -1862,7 +1892,6 @@ rsu_bulk_rx_callback(struct usb_xfer *xf struct ieee80211_node *ni; struct mbuf *m = NULL, *next; struct rsu_data *data; - int rssi = 1; RSU_ASSERT_LOCKED(sc); @@ -1872,7 +1901,7 @@ rsu_bulk_rx_callback(struct usb_xfer *xf if (data == NULL) goto tr_setup; STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); - m = rsu_rxeof(xfer, data, &rssi); + m = rsu_rxeof(xfer, data); STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); /* FALLTHROUGH */ case USB_ST_SETUP: @@ -1898,6 +1927,11 @@ tr_setup: */ RSU_UNLOCK(sc); while (m != NULL) { + int rssi; + + /* Cheat and get the last calibrated RSSI */ + rssi = rsu_hwrssi_to_rssi(sc, sc->sc_currssi); + next = m->m_next; m->m_next = NULL; wh = mtod(m, struct ieee80211_frame *); @@ -1906,10 +1940,10 @@ tr_setup: if (ni != NULL) { if (ni->ni_flags & IEEE80211_NODE_HT) m->m_flags |= M_AMPDU; - (void)ieee80211_input(ni, m, rssi, 0); + (void)ieee80211_input(ni, m, rssi, -96); ieee80211_free_node(ni); } else - (void)ieee80211_input_all(ic, m, rssi, 0); + (void)ieee80211_input_all(ic, m, rssi, -96); m = next; } RSU_LOCK(sc); @@ -2003,6 +2037,12 @@ tr_setup: } break; } + + /* + * XXX TODO: if the queue is low, flush out FF TX frames. + * Remember to unlock the driver for now; net80211 doesn't + * defer it for us. + */ } static void Modified: head/sys/dev/usb/wlan/if_rsureg.h ============================================================================== --- head/sys/dev/usb/wlan/if_rsureg.h Wed Sep 30 04:48:56 2015 (r288413) +++ head/sys/dev/usb/wlan/if_rsureg.h Wed Sep 30 05:19:16 2015 (r288414) @@ -764,6 +764,7 @@ struct rsu_softc { int sc_ht; int sc_nendpoints; int sc_curpwrstate; + int sc_currssi; u_int sc_running:1, sc_calibrating:1,