PERFORCE change 87159 for review
Sam Leffler
sam at FreeBSD.org
Wed Nov 23 14:51:10 PST 2005
http://perforce.freebsd.org/chv.cgi?CH=87159
Change 87159 by sam at 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 <sys/cdefs.h>
-__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 <sys/cdefs.h>
-__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 <sys/cdefs.h>
-__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)
More information about the p4-projects
mailing list