From owner-p4-projects@FreeBSD.ORG Wed Nov 23 22:51:09 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 36E0016A422; Wed, 23 Nov 2005 22:51:09 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EB9F616A420 for ; Wed, 23 Nov 2005 22:51:08 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 6A6D643D5E for ; Wed, 23 Nov 2005 22:51:08 +0000 (GMT) (envelope-from sam@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id jANMp8qF004413 for ; Wed, 23 Nov 2005 22:51:08 GMT (envelope-from sam@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id jANMp8Q0004410 for perforce@freebsd.org; Wed, 23 Nov 2005 22:51:08 GMT (envelope-from sam@freebsd.org) Date: Wed, 23 Nov 2005 22:51:08 GMT Message-Id: <200511232251.jANMp8Q0004410@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to sam@freebsd.org using -f From: Sam Leffler To: Perforce Change Reviews Cc: Subject: PERFORCE change 87159 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 23 Nov 2005 22:51:10 -0000 http://perforce.freebsd.org/chv.cgi?CH=87159 Change 87159 by sam@sam_ebb on 2005/11/23 22:50:06 IFC Affected files ... .. //depot/projects/wifi/sys/dev/ath/if_ath.c#112 edit .. //depot/projects/wifi/sys/dev/ral/if_ral.c#7 edit .. //depot/projects/wifi/sys/dev/usb/if_ural.c#7 edit .. //depot/projects/wifi/sys/dev/wi/if_wi.c#20 edit Differences ... ==== //depot/projects/wifi/sys/dev/ath/if_ath.c#112 (text+ko) ==== @@ -2151,7 +2151,7 @@ * * XXX should get from lladdr instead of arpcom but that's more work */ - IEEE80211_ADDR_COPY(ic->ic_myaddr, IFP2ENADDR(ifp)); + IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); ath_hal_setmac(ah, ic->ic_myaddr); /* calculate and install multicast filter */ ==== //depot/projects/wifi/sys/dev/ral/if_ral.c#7 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/ral/if_ral.c,v 1.17 2005/09/19 03:10:19 imp Exp $ */ +/* $FreeBSD: src/sys/dev/ral/if_ral.c,v 1.19 2005/11/15 17:17:15 damien Exp $ */ /*- * Copyright (c) 2005 @@ -18,7 +18,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.17 2005/09/19 03:10:19 imp Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral.c,v 1.19 2005/11/15 17:17:15 damien Exp $"); /*- * Ralink Technology RT2500 chipset driver @@ -1280,7 +1280,7 @@ struct ieee80211_frame *wh; struct ieee80211_node *ni; struct ral_node *rn; - struct mbuf *m; + struct mbuf *mnew, *m; int hw, error; /* retrieve last decriptor index processed by cipher engine */ @@ -1308,12 +1308,51 @@ goto skip; } + /* + * Try to allocate a new mbuf for this ring element and load it + * before processing the current mbuf. If the ring element + * cannot be loaded, drop the received packet and reuse the old + * mbuf. In the unlikely case that the old mbuf can't be + * reloaded either, explicitly panic. + */ + mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (mnew == NULL) { + ifp->if_ierrors++; + goto skip; + } + bus_dmamap_sync(sc->rxq.data_dmat, data->map, BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->rxq.data_dmat, data->map); + error = bus_dmamap_load(sc->rxq.data_dmat, data->map, + mtod(mnew, void *), MCLBYTES, ral_dma_map_addr, &physaddr, + 0); + if (error != 0) { + m_freem(mnew); + + /* try to reload the old mbuf */ + error = bus_dmamap_load(sc->rxq.data_dmat, data->map, + mtod(data->m, void *), MCLBYTES, ral_dma_map_addr, + &physaddr, 0); + if (error != 0) { + /* very unlikely that it will fail... */ + panic("%s: could not load old rx mbuf", + device_get_name(sc->sc_dev)); + } + ifp->if_ierrors++; + goto skip; + } + + /* + * New mbuf successfully loaded, update Rx ring and continue + * processing. + */ + m = data->m; + data->m = mnew; + desc->physaddr = htole32(physaddr); + /* finalize mbuf */ - m = data->m; m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; @@ -1343,7 +1382,7 @@ (struct ieee80211_frame_min *)wh); /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, desc->rssi, 0); + ieee80211_input(ic, m, ni, desc->rssi, -95/*XXX*/, 0); /* give rssi to the rate adatation algorithm */ rn = (struct ral_node *)ni; @@ -1352,25 +1391,6 @@ /* node is no longer needed */ ieee80211_free_node(ni); - data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (data->m == NULL) { - device_printf(sc->sc_dev, - "could not allocate rx mbuf\n"); - break; - } - - error = bus_dmamap_load(sc->rxq.data_dmat, data->map, - mtod(data->m, void *), MCLBYTES, ral_dma_map_addr, - &physaddr, 0); - if (error != 0) { - device_printf(sc->sc_dev, - "could not load rx buf DMA map\n"); - m_freem(data->m); - data->m = NULL; - break; - } - - desc->physaddr = htole32(physaddr); skip: desc->flags = htole32(RAL_RX_BUSY); DPRINTFN(15, ("decryption done idx=%u\n", sc->rxq.cur_decrypt)); @@ -1567,33 +1587,18 @@ ral_txtime(int len, int rate, uint32_t flags) { uint16_t txtime; - int ceil, dbps; if (RAL_RATE_IS_OFDM(rate)) { - /* - * OFDM TXTIME calculation. - * From IEEE Std 802.11a-1999, pp. 37. - */ - dbps = rate * 2; /* data bits per OFDM symbol */ - - ceil = (16 + 8 * len + 6) / dbps; - if ((16 + 8 * len + 6) % dbps != 0) - ceil++; - - txtime = 16 + 4 + 4 * ceil + 6; + /* IEEE Std 802.11a-1999, pp. 37 */ + txtime = (8 + 4 * len + 3 + rate - 1) / rate; + txtime = 16 + 4 + 4 * txtime + 6; } else { - /* - * High Rate TXTIME calculation. - * From IEEE Std 802.11b-1999, pp. 28. - */ - ceil = (8 * len * 2) / rate; - if ((8 * len * 2) % rate != 0) - ceil++; - + /* IEEE Std 802.11b-1999, pp. 28 */ + txtime = (16 * len + rate - 1) / rate; if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) - txtime = 72 + 24 + ceil; + txtime += 72 + 24; else - txtime = 144 + 48 + ceil; + txtime += 144 + 48; } return txtime; ==== //depot/projects/wifi/sys/dev/usb/if_ural.c#7 (text+ko) ==== @@ -1,4 +1,4 @@ -/* $FreeBSD: src/sys/dev/usb/if_ural.c,v 1.16 2005/09/19 18:19:22 damien Exp $ */ +/* $FreeBSD: src/sys/dev/usb/if_ural.c,v 1.21 2005/11/19 15:08:05 damien Exp $ */ /*- * Copyright (c) 2005 @@ -18,7 +18,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/usb/if_ural.c,v 1.16 2005/09/19 18:19:22 damien Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/usb/if_ural.c,v 1.21 2005/11/19 15:08:05 damien Exp $"); /*- * Ralink Technology RT2500USB chipset driver @@ -70,7 +70,7 @@ #ifdef USB_DEBUG #define DPRINTF(x) do { if (uraldebug > 0) logprintf x; } while (0) #define DPRINTFN(n, x) do { if (uraldebug >= (n)) logprintf x; } while (0) -int uraldebug = 2; +int uraldebug = 0; SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural"); SYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RW, &uraldebug, 0, "ural debug level"); @@ -158,6 +158,13 @@ Static void ural_set_rxantenna(struct ural_softc *, int); Static void ural_init(void *); Static void ural_stop(void *); +Static void ural_amrr_start(struct ural_softc *, + struct ieee80211_node *); +Static void ural_amrr_timeout(void *); +Static void ural_amrr_update(usbd_xfer_handle, usbd_private_handle, + usbd_status status); +Static void ural_ratectl(struct ural_amrr *, + struct ieee80211_node *); /* * Supported rates for 802.11a/b/g modes (in 500Kbps unit). @@ -410,6 +417,7 @@ MTX_DEF | MTX_RECURSE); usb_init_task(&sc->sc_task, ural_task, sc); + callout_init(&sc->amrr_ch, 0); /* retrieve RT2570 rev. no */ sc->asic_rev = ural_read(sc, RAL_MAC_CSR0); @@ -520,6 +528,7 @@ struct ifnet *ifp = ic->ic_ifp; usb_rem_task(sc->sc_udev, &sc->sc_task); + callout_stop(&sc->amrr_ch); if (sc->sc_rx_pipeh != NULL) { usbd_abort_pipe(sc->sc_rx_pipeh); @@ -734,6 +743,12 @@ if (ic->ic_opmode != IEEE80211_M_MONITOR) ural_enable_tsf_sync(sc); + + /* enable automatic rate adaptation in STA mode */ + if (ic->ic_opmode == IEEE80211_M_STA && + ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) + ural_amrr_start(sc, ic->ic_bss); + break; default: @@ -749,6 +764,7 @@ struct ural_softc *sc = ic->ic_ifp->if_softc; usb_rem_task(sc->sc_udev, &sc->sc_task); + callout_stop(&sc->amrr_ch); /* do it in a process context */ sc->sc_state = nstate; @@ -810,7 +826,7 @@ struct ural_rx_desc *desc; struct ieee80211_frame *wh; struct ieee80211_node *ni; - struct mbuf *m; + struct mbuf *mnew, *m; int len; if (status != USBD_NORMAL_COMPLETION) { @@ -844,8 +860,17 @@ goto skip; } + mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (mnew == NULL) { + ifp->if_ierrors++; + goto skip; + } + + m = data->m; + data->m = mnew; + data->buf = mtod(data->m, uint8_t *); + /* finalize mbuf */ - m = data->m; m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; m->m_flags |= M_HASFCS; /* hardware appends FCS */ @@ -854,20 +879,11 @@ ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, desc->rssi, 0); + ieee80211_input(ic, m, ni, desc->rssi, -95/*XXX*/, 0); /* node is no longer needed */ ieee80211_free_node(ni); - data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (data->m == NULL) { - printf("%s: could not allocate rx mbuf\n", - USBDEVNAME(sc->sc_dev)); - return; - } - - data->buf = mtod(data->m, uint8_t *); - DPRINTFN(15, ("rx done\n")); skip: /* setup a new transfer */ @@ -919,33 +935,18 @@ ural_txtime(int len, int rate, uint32_t flags) { uint16_t txtime; - int ceil, dbps; if (RAL_RATE_IS_OFDM(rate)) { - /* - * OFDM TXTIME calculation. - * From IEEE Std 802.11a-1999, pp. 37. - */ - dbps = rate * 2; /* data bits per OFDM symbol */ - - ceil = (16 + 8 * len + 6) / dbps; - if ((16 + 8 * len + 6) % dbps != 0) - ceil++; - - txtime = 16 + 4 + 4 * ceil + 6; + /* IEEE Std 802.11a-1999, pp. 37 */ + txtime = (8 + 4 * len + 3 + rate - 1) / rate; + txtime = 16 + 4 + 4 * txtime + 6; } else { - /* - * High Rate TXTIME calculation. - * From IEEE Std 802.11b-1999, pp. 28. - */ - ceil = (8 * len * 2) / rate; - if ((8 * len * 2) % rate != 0) - ceil++; - + /* IEEE Std 802.11b-1999, pp. 28 */ + txtime = (16 * len + rate - 1) / rate; if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) - txtime = 72 + 24 + ceil; + txtime += 72 + 24; else - txtime = 144 + 48 + ceil; + txtime += 144 + 48; } return txtime; @@ -1170,7 +1171,6 @@ wh = mtod(m0, struct ieee80211_frame *); - /* XXX should do automatic rate adaptation */ if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) rate = ic->ic_fixed_rate; else @@ -1906,7 +1906,7 @@ struct ifnet *ifp = ic->ic_ifp; struct ieee80211_key *wk; struct ural_rx_data *data; - uint16_t sta[11], tmp; + uint16_t tmp; usbd_status error; int i, ntries; @@ -1942,7 +1942,7 @@ ural_set_chan(sc, ic->ic_curchan); /* clear statistic registers (STA_CSR0 to STA_CSR10) */ - ural_read_multi(sc, RAL_STA_CSR0, sta, sizeof sta); + ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); ural_set_txantenna(sc, sc->tx_ant); ural_set_rxantenna(sc, sc->rx_ant); @@ -1960,6 +1960,16 @@ } /* + * Allocate xfer for AMRR statistics requests. + */ + sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev); + if (sc->amrr_xfer == NULL) { + printf("%s: could not allocate AMRR xfer\n", + USBDEVNAME(sc->sc_dev)); + goto fail; + } + + /* * Open Tx and Rx USB bulk pipes. */ error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE, @@ -2052,6 +2062,11 @@ ural_write(sc, RAL_MAC_CSR1, RAL_RESET_ASIC | RAL_RESET_BBP); ural_write(sc, RAL_MAC_CSR1, 0); + if (sc->amrr_xfer != NULL) { + usbd_free_xfer(sc->amrr_xfer); + sc->amrr_xfer = NULL; + } + if (sc->sc_rx_pipeh != NULL) { usbd_abort_pipe(sc->sc_rx_pipeh); usbd_close_pipe(sc->sc_rx_pipeh); @@ -2068,4 +2083,149 @@ ural_free_tx_list(sc); } +Static void +ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni) +{ + struct ural_amrr *amrr = &sc->amrr; + int i; + + /* clear statistic registers (STA_CSR0 to STA_CSR10) */ + ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); + + amrr->success = 0; + amrr->recovery = 0; + amrr->success_threshold = 0; + amrr->txcnt = amrr->retrycnt = 0; + + /* set rate to some reasonable initial value */ + for (i = ni->ni_rates.rs_nrates - 1; + i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; + i--); + + ni->ni_txrate = i; + + callout_reset(&sc->amrr_ch, hz, ural_amrr_timeout, sc); +} + +Static void +ural_amrr_timeout(void *arg) +{ + struct ural_softc *sc = (struct ural_softc *)arg; + usb_device_request_t req; + int s; + + s = splusb(); + + /* + * Asynchronously read statistic registers (cleared by read). + */ + req.bmRequestType = UT_READ_VENDOR_DEVICE; + req.bRequest = RAL_READ_MULTI_MAC; + USETW(req.wValue, 0); + USETW(req.wIndex, RAL_STA_CSR0); + USETW(req.wLength, sizeof sc->sta); + + usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc, + USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0, + ural_amrr_update); + (void)usbd_transfer(sc->amrr_xfer); + + splx(s); +} + +Static void +ural_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, + usbd_status status) +{ + struct ural_softc *sc = (struct ural_softc *)priv; + struct ural_amrr *amrr = &sc->amrr; + + if (status != USBD_NORMAL_COMPLETION) + return; + + amrr->retrycnt = + sc->sta[7] + /* TX one-retry ok count */ + sc->sta[8] + /* TX more-retry ok count */ + sc->sta[8]; /* TX retry-fail count */ + + amrr->txcnt = + amrr->retrycnt + + sc->sta[6]; /* TX no-retry ok count */ + + ural_ratectl(amrr, sc->sc_ic.ic_bss); + + callout_reset(&sc->amrr_ch, hz, ural_amrr_timeout, sc); +} + +/*- + * Naive implementation of the Adaptive Multi Rate Retry algorithm: + * "IEEE 802.11 Rate Adaptation: A Practical Approach" + * Mathieu Lacage, Hossein Manshaei, Thierry Turletti + * INRIA Sophia - Projet Planete + * http://www-sop.inria.fr/rapports/sophia/RR-5208.html + * + * This algorithm is particularly well suited for ural since it does not + * require per-frame retry statistics. Note however that since h/w does + * not provide per-frame stats, we can't do per-node rate adaptation and + * thus automatic rate adaptation is only enabled in STA operating mode. + */ + +#define URAL_AMRR_MIN_SUCCESS_THRESHOLD 1 +#define URAL_AMRR_MAX_SUCCESS_THRESHOLD 10 + +#define is_success(amrr) \ + ((amrr)->retrycnt < (amrr)->txcnt / 10) +#define is_failure(amrr) \ + ((amrr)->retrycnt > (amrr)->txcnt / 3) +#define is_enough(amrr) \ + ((amrr)->txcnt > 10) +#define is_min_rate(ni) \ + ((ni)->ni_txrate == 0) +#define is_max_rate(ni) \ + ((ni)->ni_txrate == (ni)->ni_rates.rs_nrates - 1) +#define increase_rate(ni) \ + ((ni)->ni_txrate++) +#define decrease_rate(ni) \ + ((ni)->ni_txrate--) +#define reset_cnt(amrr) \ + do { (amrr)->txcnt = (amrr)->retrycnt = 0; } while (0) +Static void +ural_ratectl(struct ural_amrr *amrr, struct ieee80211_node *ni) +{ + int need_change = 0; + + if (is_success(amrr) && is_enough(amrr)) { + amrr->success++; + if (amrr->success >= amrr->success_threshold && + !is_max_rate(ni)) { + amrr->recovery = 1; + amrr->success = 0; + increase_rate(ni); + need_change = 1; + } else { + amrr->recovery = 0; + } + } else if (is_failure(amrr)) { + amrr->success = 0; + if (!is_min_rate(ni)) { + if (amrr->recovery) { + amrr->success_threshold *= 2; + if (amrr->success_threshold > + URAL_AMRR_MAX_SUCCESS_THRESHOLD) + amrr->success_threshold = + URAL_AMRR_MAX_SUCCESS_THRESHOLD; + } else { + amrr->success_threshold = + URAL_AMRR_MIN_SUCCESS_THRESHOLD; + } + decrease_rate(ni); + need_change = 1; + } + amrr->recovery = 0; /* original paper was incorrect */ + } + + if (is_enough(amrr) || need_change) + reset_cnt(amrr); +} + DRIVER_MODULE(ural, uhub, ural_driver, ural_devclass, usbd_driver_load, 0); ==== //depot/projects/wifi/sys/dev/wi/if_wi.c#20 (text+ko) ==== @@ -62,7 +62,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/wi/if_wi.c,v 1.193 2005/10/02 04:29:08 avatar Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/wi/if_wi.c,v 1.194 2005/11/11 16:04:56 ru Exp $"); #define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ #define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ @@ -659,8 +659,6 @@ struct wi_joinreq join; int i; int error = 0, wasenabled; - struct ifaddr *ifa; - struct sockaddr_dl *sdl; WI_LOCK_DECL(); WI_LOCK(sc); @@ -724,9 +722,7 @@ wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_ssid[0].ssid, ic->ic_des_ssid[0].len); - ifa = ifaddr_byindex(ifp->if_index); - sdl = (struct sockaddr_dl *) ifa->ifa_addr; - IEEE80211_ADDR_COPY(ic->ic_myaddr, LLADDR(sdl)); + IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN); if (ic->ic_caps & IEEE80211_C_PMGT) @@ -1578,7 +1574,7 @@ /* * Send frame up for processing. */ - ieee80211_input(ic, m, ni, rssi, rstamp); + ieee80211_input(ic, m, ni, rssi, -95/*XXXXwi_rx_silence?*/, rstamp); /* * The frame may have caused the node to be marked for * reclamation (e.g. in response to a DEAUTH message)