sync ural with HEAD.
Brings automatic rate control in BSS mode and other goodies.
This commit is contained in:
parent
f4e3675df0
commit
384ea2a095
@ -1,7 +1,7 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005
|
||||
* Copyright (c) 2005, 2006
|
||||
* Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -70,7 +70,7 @@ __FBSDID("$FreeBSD$");
|
||||
#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");
|
||||
@ -90,9 +90,11 @@ static const struct usb_devno ural_devs[] = {
|
||||
{ USB_VENDOR_GUILLEMOT, USB_PRODUCT_GUILLEMOT_HWGUSB254 },
|
||||
{ USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54G },
|
||||
{ USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_WUSB54GP },
|
||||
{ USB_VENDOR_LINKSYS4, USB_PRODUCT_LINKSYS4_HU200TS },
|
||||
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54 },
|
||||
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54AI },
|
||||
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_KG54YB },
|
||||
{ USB_VENDOR_MELCO, USB_PRODUCT_MELCO_NINWIFI },
|
||||
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570 },
|
||||
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_2 },
|
||||
{ USB_VENDOR_MSI, USB_PRODUCT_MSI_RT2570_3 },
|
||||
@ -113,6 +115,7 @@ Static void ural_next_scan(void *);
|
||||
Static void ural_task(void *);
|
||||
Static int ural_newstate(struct ieee80211com *,
|
||||
enum ieee80211_state, int);
|
||||
Static int ural_rxrate(struct ural_rx_desc *);
|
||||
Static void ural_txeof(usbd_xfer_handle, usbd_private_handle,
|
||||
usbd_status);
|
||||
Static void ural_rxeof(usbd_xfer_handle, usbd_private_handle,
|
||||
@ -132,6 +135,7 @@ Static void ural_start(struct ifnet *);
|
||||
Static void ural_watchdog(struct ifnet *);
|
||||
Static int ural_reset(struct ifnet *);
|
||||
Static int ural_ioctl(struct ifnet *, u_long, caddr_t);
|
||||
Static void ural_set_testmode(struct ural_softc *);
|
||||
Static void ural_eeprom_read(struct ural_softc *, uint16_t, void *,
|
||||
int);
|
||||
Static uint16_t ural_read(struct ural_softc *, uint16_t);
|
||||
@ -145,10 +149,11 @@ Static uint8_t ural_bbp_read(struct ural_softc *, uint8_t);
|
||||
Static void ural_rf_write(struct ural_softc *, uint8_t, uint32_t);
|
||||
Static void ural_set_chan(struct ural_softc *,
|
||||
struct ieee80211_channel *);
|
||||
#if 0
|
||||
Static void ural_disable_rf_tune(struct ural_softc *);
|
||||
#endif
|
||||
Static void ural_enable_tsf_sync(struct ural_softc *);
|
||||
Static void ural_update_slot(struct ifnet *);
|
||||
Static void ural_set_txpreamble(struct ural_softc *);
|
||||
Static void ural_set_basicrates(struct ural_softc *);
|
||||
Static void ural_set_bssid(struct ural_softc *, uint8_t *);
|
||||
Static void ural_set_macaddr(struct ural_softc *, uint8_t *);
|
||||
Static void ural_update_promisc(struct ural_softc *);
|
||||
@ -159,6 +164,13 @@ Static void ural_set_txantenna(struct ural_softc *, int);
|
||||
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).
|
||||
@ -292,7 +304,6 @@ static const struct {
|
||||
uint32_t r2;
|
||||
uint32_t r4;
|
||||
} ural_rf5222[] = {
|
||||
/* channels in the 2.4GHz band */
|
||||
{ 1, 0x08808, 0x0044d, 0x00282 },
|
||||
{ 2, 0x08808, 0x0044e, 0x00282 },
|
||||
{ 3, 0x08808, 0x0044f, 0x00282 },
|
||||
@ -308,7 +319,6 @@ static const struct {
|
||||
{ 13, 0x08808, 0x00469, 0x00282 },
|
||||
{ 14, 0x08808, 0x0046b, 0x00286 },
|
||||
|
||||
/* channels in the 5.2GHz band */
|
||||
{ 36, 0x08804, 0x06225, 0x00287 },
|
||||
{ 40, 0x08804, 0x06226, 0x00287 },
|
||||
{ 44, 0x08804, 0x06227, 0x00287 },
|
||||
@ -411,6 +421,7 @@ USB_ATTACH(ural)
|
||||
|
||||
usb_init_task(&sc->sc_task, ural_task, sc);
|
||||
callout_init(&sc->scan_ch, debug_mpsafenet ? CALLOUT_MPSAFE : 0);
|
||||
callout_init(&sc->amrr_ch, 0);
|
||||
|
||||
/* retrieve RT2570 rev. no */
|
||||
sc->asic_rev = ural_read(sc, RAL_MAC_CSR0);
|
||||
@ -445,9 +456,14 @@ USB_ATTACH(ural)
|
||||
ic->ic_state = IEEE80211_S_INIT;
|
||||
|
||||
/* set device capabilities */
|
||||
ic->ic_caps = IEEE80211_C_MONITOR | IEEE80211_C_IBSS |
|
||||
IEEE80211_C_HOSTAP | IEEE80211_C_SHPREAMBLE | IEEE80211_C_SHSLOT |
|
||||
IEEE80211_C_PMGT | IEEE80211_C_TXPMGT | IEEE80211_C_WPA;
|
||||
ic->ic_caps =
|
||||
IEEE80211_C_IBSS | /* IBSS mode supported */
|
||||
IEEE80211_C_MONITOR | /* monitor mode supported */
|
||||
IEEE80211_C_HOSTAP | /* HostAp mode supported */
|
||||
IEEE80211_C_TXPMGT | /* tx power management */
|
||||
IEEE80211_C_SHPREAMBLE | /* short preamble supported */
|
||||
IEEE80211_C_SHSLOT | /* short slot time supported */
|
||||
IEEE80211_C_WPA; /* 802.11i */
|
||||
|
||||
if (sc->rf_rev == RAL_RF_5222) {
|
||||
/* set supported .11a rates */
|
||||
@ -517,6 +533,12 @@ USB_DETACH(ural)
|
||||
|
||||
usb_rem_task(sc->sc_udev, &sc->sc_task);
|
||||
callout_stop(&sc->scan_ch);
|
||||
callout_stop(&sc->amrr_ch);
|
||||
|
||||
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);
|
||||
@ -676,7 +698,7 @@ ural_media_change(struct ifnet *ifp)
|
||||
return error;
|
||||
}
|
||||
|
||||
if ((ifp->if_flags & IFF_UP) &&
|
||||
if ((ifp->if_flags & IFF_UP) &&
|
||||
(ifp->if_drv_flags & IFF_DRV_RUNNING))
|
||||
ural_init(sc);
|
||||
|
||||
@ -705,6 +727,7 @@ ural_task(void *arg)
|
||||
struct ural_softc *sc = arg;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
enum ieee80211_state ostate;
|
||||
struct ieee80211_node *ni;
|
||||
struct mbuf *m;
|
||||
|
||||
ostate = ic->ic_state;
|
||||
@ -736,31 +759,25 @@ ural_task(void *arg)
|
||||
case IEEE80211_S_RUN:
|
||||
ural_set_chan(sc, ic->ic_curchan);
|
||||
|
||||
/* update basic rate set */
|
||||
if (ic->ic_curmode == IEEE80211_MODE_11B) {
|
||||
/* 11b basic rates: 1, 2Mbps */
|
||||
ural_write(sc, RAL_TXRX_CSR11, 0x3);
|
||||
} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) {
|
||||
/* 11a basic rates: 6, 12, 24Mbps */
|
||||
ural_write(sc, RAL_TXRX_CSR11, 0x150);
|
||||
} else {
|
||||
/* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
|
||||
ural_write(sc, RAL_TXRX_CSR11, 0x15f);
|
||||
}
|
||||
ni = ic->ic_bss;
|
||||
|
||||
if (ic->ic_opmode != IEEE80211_M_MONITOR)
|
||||
ural_set_bssid(sc, ic->ic_bss->ni_bssid);
|
||||
if (ic->ic_opmode != IEEE80211_M_MONITOR) {
|
||||
ural_update_slot(ic->ic_ifp);
|
||||
ural_set_txpreamble(sc);
|
||||
ural_set_basicrates(sc);
|
||||
ural_set_bssid(sc, ni->ni_bssid);
|
||||
}
|
||||
|
||||
if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
|
||||
ic->ic_opmode == IEEE80211_M_IBSS) {
|
||||
m = ieee80211_beacon_alloc(ic, ic->ic_bss, &sc->sc_bo);
|
||||
m = ieee80211_beacon_alloc(ic, ni, &sc->sc_bo);
|
||||
if (m == NULL) {
|
||||
printf("%s: could not allocate beacon\n",
|
||||
USBDEVNAME(sc->sc_dev));
|
||||
return;
|
||||
}
|
||||
|
||||
if (ural_tx_bcn(sc, m, ic->ic_bss) != 0) {
|
||||
if (ural_tx_bcn(sc, m, ni) != 0) {
|
||||
printf("%s: could not send beacon\n",
|
||||
USBDEVNAME(sc->sc_dev));
|
||||
return;
|
||||
@ -772,6 +789,12 @@ ural_task(void *arg)
|
||||
|
||||
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, ni);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -785,6 +808,7 @@ ural_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
|
||||
usb_rem_task(sc->sc_udev, &sc->sc_task);
|
||||
callout_stop(&sc->scan_ch);
|
||||
callout_stop(&sc->amrr_ch);
|
||||
|
||||
/* do it in a process context */
|
||||
sc->sc_state = nstate;
|
||||
@ -798,7 +822,41 @@ ural_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
||||
|
||||
#define RAL_ACK_SIZE 14 /* 10 + 4(FCS) */
|
||||
#define RAL_CTS_SIZE 14 /* 10 + 4(FCS) */
|
||||
#define RAL_SIFS 10
|
||||
|
||||
#define RAL_SIFS 10 /* us */
|
||||
|
||||
#define RAL_RXTX_TURNAROUND 5 /* us */
|
||||
|
||||
/*
|
||||
* This function is only used by the Rx radiotap code.
|
||||
*/
|
||||
Static int
|
||||
ural_rxrate(struct ural_rx_desc *desc)
|
||||
{
|
||||
if (le32toh(desc->flags) & RAL_RX_OFDM) {
|
||||
/* reverse function of ural_plcp_signal */
|
||||
switch (desc->rate) {
|
||||
case 0xb: return 12;
|
||||
case 0xf: return 18;
|
||||
case 0xa: return 24;
|
||||
case 0xe: return 36;
|
||||
case 0x9: return 48;
|
||||
case 0xd: return 72;
|
||||
case 0x8: return 96;
|
||||
case 0xc: return 108;
|
||||
}
|
||||
} else {
|
||||
if (desc->rate == 10)
|
||||
return 2;
|
||||
if (desc->rate == 20)
|
||||
return 4;
|
||||
if (desc->rate == 55)
|
||||
return 11;
|
||||
if (desc->rate == 110)
|
||||
return 22;
|
||||
}
|
||||
return 2; /* should not get there */
|
||||
}
|
||||
|
||||
Static void
|
||||
ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
@ -815,7 +873,7 @@ ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
USBDEVNAME(sc->sc_dev), usbd_errstr(status));
|
||||
|
||||
if (status == USBD_STALLED)
|
||||
usbd_clear_endpoint_stall(sc->sc_rx_pipeh);
|
||||
usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
|
||||
|
||||
ifp->if_oerrors++;
|
||||
return;
|
||||
@ -846,7 +904,7 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
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) {
|
||||
@ -854,14 +912,15 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
return;
|
||||
|
||||
if (status == USBD_STALLED)
|
||||
usbd_clear_endpoint_stall(sc->sc_rx_pipeh);
|
||||
usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh);
|
||||
goto skip;
|
||||
}
|
||||
|
||||
usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL);
|
||||
|
||||
if (len < RAL_RX_DESC_SIZE) {
|
||||
printf("%s: xfer too short %d\n", USBDEVNAME(sc->sc_dev), len);
|
||||
if (len < RAL_RX_DESC_SIZE + IEEE80211_MIN_LEN) {
|
||||
DPRINTF(("%s: xfer too short %d\n", USBDEVNAME(sc->sc_dev),
|
||||
len));
|
||||
ifp->if_ierrors++;
|
||||
goto skip;
|
||||
}
|
||||
@ -880,11 +939,33 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
goto skip;
|
||||
}
|
||||
|
||||
/* finalize mbuf */
|
||||
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->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff;
|
||||
m->m_flags |= M_HASFCS; /* hardware appends FCS */
|
||||
m->m_flags |= M_HASFCS; /* h/w leaves FCS */
|
||||
|
||||
if (sc->sc_drvbpf != NULL) {
|
||||
struct ural_rx_radiotap_header *tap = &sc->sc_rxtap;
|
||||
|
||||
tap->wr_flags = IEEE80211_RADIOTAP_F_FCS;
|
||||
tap->wr_rate = ural_rxrate(desc);
|
||||
tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
||||
tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
||||
tap->wr_antenna = sc->rx_ant;
|
||||
tap->wr_antsignal = desc->rssi;
|
||||
|
||||
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
|
||||
}
|
||||
|
||||
wh = mtod(m, struct ieee80211_frame *);
|
||||
ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh);
|
||||
@ -895,15 +976,6 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status)
|
||||
/* 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 */
|
||||
@ -955,35 +1027,19 @@ Static uint16_t
|
||||
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;
|
||||
}
|
||||
|
||||
@ -1024,44 +1080,33 @@ ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc,
|
||||
desc->flags |= htole32(RAL_TX_NEWSEQ);
|
||||
desc->flags |= htole32(len << 16);
|
||||
|
||||
if (RAL_RATE_IS_OFDM(rate))
|
||||
desc->flags |= htole32(RAL_TX_OFDM);
|
||||
|
||||
desc->wme = htole16(RAL_AIFSN(3) | RAL_LOGCWMIN(4) | RAL_LOGCWMAX(6));
|
||||
desc->wme = htole16(RAL_AIFSN(2) | RAL_LOGCWMIN(3) | RAL_LOGCWMAX(5));
|
||||
desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame)));
|
||||
|
||||
/*
|
||||
* Fill PLCP fields.
|
||||
*/
|
||||
/* setup PLCP fields */
|
||||
desc->plcp_signal = ural_plcp_signal(rate);
|
||||
desc->plcp_service = 4;
|
||||
|
||||
len += 4; /* account for FCS */
|
||||
len += IEEE80211_CRC_LEN;
|
||||
if (RAL_RATE_IS_OFDM(rate)) {
|
||||
/*
|
||||
* PLCP length field (LENGTH).
|
||||
* From IEEE Std 802.11a-1999, pp. 14.
|
||||
*/
|
||||
plcp_length = len & 0xfff;
|
||||
desc->plcp_length = htole16((plcp_length >> 6) << 8 |
|
||||
(plcp_length & 0x3f));
|
||||
} else {
|
||||
/*
|
||||
* Long PLCP LENGTH field.
|
||||
* From IEEE Std 802.11b-1999, pp. 16.
|
||||
*/
|
||||
plcp_length = (8 * len * 2) / rate;
|
||||
remainder = (8 * len * 2) % rate;
|
||||
if (remainder != 0) {
|
||||
if (rate == 22 && (rate - remainder) / 16 != 0)
|
||||
desc->plcp_service |= RAL_PLCP_LENGEXT;
|
||||
plcp_length++;
|
||||
}
|
||||
desc->plcp_length = htole16(plcp_length);
|
||||
}
|
||||
desc->flags |= htole32(RAL_TX_OFDM);
|
||||
|
||||
desc->plcp_signal = ural_plcp_signal(rate);
|
||||
if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
|
||||
desc->plcp_signal |= 0x08;
|
||||
plcp_length = len & 0xfff;
|
||||
desc->plcp_length_hi = plcp_length >> 6;
|
||||
desc->plcp_length_lo = plcp_length & 0x3f;
|
||||
} else {
|
||||
plcp_length = (16 * len + rate - 1) / rate;
|
||||
if (rate == 22) {
|
||||
remainder = (16 * len) % 22;
|
||||
if (remainder != 0 && remainder < 7)
|
||||
desc->plcp_service |= RAL_PLCP_LENGEXT;
|
||||
}
|
||||
desc->plcp_length_hi = plcp_length >> 8;
|
||||
desc->plcp_length_lo = plcp_length & 0xff;
|
||||
|
||||
if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
|
||||
desc->plcp_signal |= 0x08;
|
||||
}
|
||||
|
||||
desc->iv = 0;
|
||||
desc->eiv = 0;
|
||||
@ -1079,7 +1124,7 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
uint8_t *buf;
|
||||
int xferlen, rate;
|
||||
|
||||
rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 4;
|
||||
rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
|
||||
|
||||
xfer = usbd_alloc_xfer(sc->sc_udev);
|
||||
if (xfer == NULL)
|
||||
@ -1136,19 +1181,7 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
data = &sc->tx_data[0];
|
||||
desc = (struct ural_tx_desc *)data->buf;
|
||||
|
||||
rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 4;
|
||||
|
||||
if (sc->sc_drvbpf != NULL) {
|
||||
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||
|
||||
tap->wt_flags = 0;
|
||||
tap->wt_rate = rate;
|
||||
tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
|
||||
tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
|
||||
tap->wt_antenna = sc->tx_ant;
|
||||
|
||||
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
|
||||
}
|
||||
rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
|
||||
|
||||
data->m = m0;
|
||||
data->ni = ni;
|
||||
@ -1169,12 +1202,31 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
flags |= RAL_TX_TIMESTAMP;
|
||||
}
|
||||
|
||||
if (sc->sc_drvbpf != NULL) {
|
||||
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||
|
||||
tap->wt_flags = 0;
|
||||
tap->wt_rate = rate;
|
||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
||||
tap->wt_antenna = sc->tx_ant;
|
||||
|
||||
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
|
||||
}
|
||||
|
||||
m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE);
|
||||
ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate);
|
||||
|
||||
/* xfer length needs to be a multiple of two! */
|
||||
/* align end on a 2-bytes boundary */
|
||||
xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1;
|
||||
|
||||
/*
|
||||
* No space left in the last URB to store the extra 2 bytes, force
|
||||
* sending of another URB.
|
||||
*/
|
||||
if ((xferlen % 64) == 0)
|
||||
xferlen += 2;
|
||||
|
||||
DPRINTFN(10, ("sending mgt frame len=%u rate=%u xfer len=%u\n",
|
||||
m0->m_pkthdr.len, rate, xferlen));
|
||||
|
||||
@ -1206,7 +1258,6 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
|
||||
wh = mtod(m0, struct ieee80211_frame *);
|
||||
|
||||
/* XXX should do automatic rate adaptation */
|
||||
if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE)
|
||||
rate = ic->ic_bss->ni_rates.rs_rates[ic->ic_fixed_rate];
|
||||
else
|
||||
@ -1225,18 +1276,6 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
wh = mtod(m0, struct ieee80211_frame *);
|
||||
}
|
||||
|
||||
if (sc->sc_drvbpf != NULL) {
|
||||
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||
|
||||
tap->wt_flags = 0;
|
||||
tap->wt_rate = rate;
|
||||
tap->wt_chan_freq = htole16(ic->ic_ibss_chan->ic_freq);
|
||||
tap->wt_chan_flags = htole16(ic->ic_ibss_chan->ic_flags);
|
||||
tap->wt_antenna = sc->tx_ant;
|
||||
|
||||
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
|
||||
}
|
||||
|
||||
data = &sc->tx_data[0];
|
||||
desc = (struct ural_tx_desc *)data->buf;
|
||||
|
||||
@ -1252,12 +1291,31 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni)
|
||||
*(uint16_t *)wh->i_dur = htole16(dur);
|
||||
}
|
||||
|
||||
if (sc->sc_drvbpf != NULL) {
|
||||
struct ural_tx_radiotap_header *tap = &sc->sc_txtap;
|
||||
|
||||
tap->wt_flags = 0;
|
||||
tap->wt_rate = rate;
|
||||
tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
||||
tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
||||
tap->wt_antenna = sc->tx_ant;
|
||||
|
||||
bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
|
||||
}
|
||||
|
||||
m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE);
|
||||
ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate);
|
||||
|
||||
/* xfer length needs to be a multiple of two! */
|
||||
/* align end on a 2-bytes boundary */
|
||||
xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1;
|
||||
|
||||
/*
|
||||
* No space left in the last URB to store the extra 2 bytes, force
|
||||
* sending of another URB.
|
||||
*/
|
||||
if ((xferlen % 64) == 0)
|
||||
xferlen += 2;
|
||||
|
||||
DPRINTFN(10, ("sending data frame len=%u rate=%u xfer len=%u\n",
|
||||
m0->m_pkthdr.len, rate, xferlen));
|
||||
|
||||
@ -1386,7 +1444,7 @@ ural_reset(struct ifnet *ifp)
|
||||
if (ic->ic_opmode != IEEE80211_M_MONITOR)
|
||||
return ENETRESET;
|
||||
|
||||
ural_set_chan(sc, ic->ic_ibss_chan);
|
||||
ural_set_chan(sc, ic->ic_curchan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1430,6 +1488,25 @@ ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
||||
return error;
|
||||
}
|
||||
|
||||
Static void
|
||||
ural_set_testmode(struct ural_softc *sc)
|
||||
{
|
||||
usb_device_request_t req;
|
||||
usbd_status error;
|
||||
|
||||
req.bmRequestType = UT_WRITE_VENDOR_DEVICE;
|
||||
req.bRequest = RAL_VENDOR_REQUEST;
|
||||
USETW(req.wValue, 4);
|
||||
USETW(req.wIndex, 1);
|
||||
USETW(req.wLength, 0);
|
||||
|
||||
error = usbd_do_request(sc->sc_udev, &req, NULL);
|
||||
if (error != 0) {
|
||||
printf("%s: could not set test mode: %s\n",
|
||||
USBDEVNAME(sc->sc_dev), usbd_errstr(error));
|
||||
}
|
||||
}
|
||||
|
||||
Static void
|
||||
ural_eeprom_read(struct ural_softc *sc, uint16_t addr, void *buf, int len)
|
||||
{
|
||||
@ -1488,7 +1565,6 @@ ural_read_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len)
|
||||
if (error != 0) {
|
||||
printf("%s: could not read MAC register: %s\n",
|
||||
USBDEVNAME(sc->sc_dev), usbd_errstr(error));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1598,7 +1674,6 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val)
|
||||
Static void
|
||||
ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
|
||||
{
|
||||
#define N(a) (sizeof (a) / sizeof ((a)[0]))
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
uint8_t power, tmp;
|
||||
u_int i, chan;
|
||||
@ -1612,6 +1687,9 @@ ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
|
||||
else
|
||||
power = 31;
|
||||
|
||||
/* adjust txpower using ifconfig settings */
|
||||
power -= (100 - ic->ic_txpowlimit) / 8;
|
||||
|
||||
DPRINTFN(2, ("setting channel to %u, txpower to %u\n", chan, power));
|
||||
|
||||
switch (sc->rf_rev) {
|
||||
@ -1666,16 +1744,12 @@ ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
|
||||
|
||||
/* dual-band RF */
|
||||
case RAL_RF_5222:
|
||||
for (i = 0; i < N(ural_rf5222); i++)
|
||||
if (ural_rf5222[i].chan == chan)
|
||||
break;
|
||||
for (i = 0; i < ural_rf5222[i].chan != chan; i++);
|
||||
|
||||
if (i < N(ural_rf5222)) {
|
||||
ural_rf_write(sc, RAL_RF1, ural_rf5222[i].r1);
|
||||
ural_rf_write(sc, RAL_RF2, ural_rf5222[i].r2);
|
||||
ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
|
||||
ural_rf_write(sc, RAL_RF4, ural_rf5222[i].r4);
|
||||
}
|
||||
ural_rf_write(sc, RAL_RF1, ural_rf5222[i].r1);
|
||||
ural_rf_write(sc, RAL_RF2, ural_rf5222[i].r2);
|
||||
ural_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
|
||||
ural_rf_write(sc, RAL_RF4, ural_rf5222[i].r4);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1692,11 +1766,12 @@ ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c)
|
||||
|
||||
/* clear CRC errors */
|
||||
ural_read(sc, RAL_STA_CSR0);
|
||||
|
||||
DELAY(10000);
|
||||
ural_disable_rf_tune(sc);
|
||||
}
|
||||
#undef N
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Disable RF auto-tuning.
|
||||
*/
|
||||
@ -1715,7 +1790,6 @@ ural_disable_rf_tune(struct ural_softc *sc)
|
||||
|
||||
DPRINTFN(2, ("disabling RF autotune\n"));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
|
||||
@ -1749,6 +1823,64 @@ ural_enable_tsf_sync(struct ural_softc *sc)
|
||||
DPRINTF(("enabling TSF synchronization\n"));
|
||||
}
|
||||
|
||||
Static void
|
||||
ural_update_slot(struct ifnet *ifp)
|
||||
{
|
||||
struct ural_softc *sc = ifp->if_softc;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
uint16_t slottime, sifs, eifs;
|
||||
|
||||
slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
|
||||
|
||||
/*
|
||||
* These settings may sound a bit inconsistent but this is what the
|
||||
* reference driver does.
|
||||
*/
|
||||
if (ic->ic_curmode == IEEE80211_MODE_11B) {
|
||||
sifs = 16 - RAL_RXTX_TURNAROUND;
|
||||
eifs = 364;
|
||||
} else {
|
||||
sifs = 10 - RAL_RXTX_TURNAROUND;
|
||||
eifs = 64;
|
||||
}
|
||||
|
||||
ural_write(sc, RAL_MAC_CSR10, slottime);
|
||||
ural_write(sc, RAL_MAC_CSR11, sifs);
|
||||
ural_write(sc, RAL_MAC_CSR12, eifs);
|
||||
}
|
||||
|
||||
Static void
|
||||
ural_set_txpreamble(struct ural_softc *sc)
|
||||
{
|
||||
uint16_t tmp;
|
||||
|
||||
tmp = ural_read(sc, RAL_TXRX_CSR10);
|
||||
|
||||
tmp &= ~RAL_SHORT_PREAMBLE;
|
||||
if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
|
||||
tmp |= RAL_SHORT_PREAMBLE;
|
||||
|
||||
ural_write(sc, RAL_TXRX_CSR10, tmp);
|
||||
}
|
||||
|
||||
Static void
|
||||
ural_set_basicrates(struct ural_softc *sc)
|
||||
{
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
|
||||
/* update basic rate set */
|
||||
if (ic->ic_curmode == IEEE80211_MODE_11B) {
|
||||
/* 11b basic rates: 1, 2Mbps */
|
||||
ural_write(sc, RAL_TXRX_CSR11, 0x3);
|
||||
} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) {
|
||||
/* 11a basic rates: 6, 12, 24Mbps */
|
||||
ural_write(sc, RAL_TXRX_CSR11, 0x150);
|
||||
} else {
|
||||
/* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
|
||||
ural_write(sc, RAL_TXRX_CSR11, 0x15f);
|
||||
}
|
||||
}
|
||||
|
||||
Static void
|
||||
ural_set_bssid(struct ural_softc *sc, uint8_t *bssid)
|
||||
{
|
||||
@ -1933,10 +2065,13 @@ ural_init(void *priv)
|
||||
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;
|
||||
|
||||
ural_set_testmode(sc);
|
||||
ural_write(sc, 0x308, 0x00f0); /* XXX magic */
|
||||
|
||||
ural_stop(sc);
|
||||
|
||||
/* initialize MAC registers to default values */
|
||||
@ -1961,18 +2096,16 @@ ural_init(void *priv)
|
||||
ural_write(sc, RAL_MAC_CSR1, RAL_HOST_READY);
|
||||
|
||||
/* set basic rate set (will be updated later) */
|
||||
ural_write(sc, RAL_TXRX_CSR11, 0x153);
|
||||
ural_write(sc, RAL_TXRX_CSR11, 0x15f);
|
||||
|
||||
if (ural_bbp_init(sc) != 0)
|
||||
goto fail;
|
||||
|
||||
/* set default BSS channel */
|
||||
ic->ic_bss->ni_chan = ic->ic_ibss_chan;
|
||||
ic->ic_curchan = ic->ic_ibss_chan;
|
||||
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);
|
||||
@ -1989,6 +2122,16 @@ ural_init(void *priv)
|
||||
RAL_SEC_CSR0, wk->wk_key, IEEE80211_KEYBUF_SIZE);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
@ -2082,6 +2225,11 @@ ural_stop(void *priv)
|
||||
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);
|
||||
@ -2098,4 +2246,155 @@ ural_stop(void *priv)
|
||||
ural_free_tx_list(sc);
|
||||
}
|
||||
|
||||
#define URAL_AMRR_MIN_SUCCESS_THRESHOLD 1
|
||||
#define URAL_AMRR_MAX_SUCCESS_THRESHOLD 10
|
||||
|
||||
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->txcnt = amrr->retrycnt = 0;
|
||||
amrr->success_threshold = URAL_AMRR_MIN_SUCCESS_THRESHOLD;
|
||||
|
||||
/* 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;
|
||||
struct ifnet *ifp = sc->sc_ic.ic_ifp;
|
||||
|
||||
if (status != USBD_NORMAL_COMPLETION) {
|
||||
device_printf(sc->sc_dev, "could not retrieve Tx statistics - "
|
||||
"cancelling automatic rate control\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* count TX retry-fail as Tx errors */
|
||||
ifp->if_oerrors += sc->sta[9];
|
||||
|
||||
amrr->retrycnt =
|
||||
sc->sta[7] + /* TX one-retry ok count */
|
||||
sc->sta[8] + /* TX more-retry ok count */
|
||||
sc->sta[9]; /* 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 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);
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005
|
||||
* Copyright (c) 2005, 2006
|
||||
* Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -23,6 +23,7 @@
|
||||
#define RAL_CONFIG_NO 1
|
||||
#define RAL_IFACE_INDEX 0
|
||||
|
||||
#define RAL_VENDOR_REQUEST 0x01
|
||||
#define RAL_WRITE_MAC 0x02
|
||||
#define RAL_READ_MAC 0x03
|
||||
#define RAL_WRITE_MULTI_MAC 0x06
|
||||
@ -42,6 +43,7 @@
|
||||
#define RAL_MAC_CSR7 0x040e /* BSSID2 */
|
||||
#define RAL_MAC_CSR8 0x0410 /* Max frame length */
|
||||
#define RAL_MAC_CSR9 0x0412 /* Timer control */
|
||||
#define RAL_MAC_CSR10 0x0414 /* Slot time */
|
||||
#define RAL_MAC_CSR11 0x0416 /* IFS */
|
||||
#define RAL_MAC_CSR12 0x0418 /* EIFS */
|
||||
#define RAL_MAC_CSR13 0x041a /* Power mode0 */
|
||||
@ -63,6 +65,7 @@
|
||||
#define RAL_TXRX_CSR6 0x044c /* CCK Tx BBP ID1 */
|
||||
#define RAL_TXRX_CSR7 0x044e /* OFDM Tx BBP ID0 */
|
||||
#define RAL_TXRX_CSR8 0x0450 /* OFDM Tx BBP ID1 */
|
||||
#define RAL_TXRX_CSR10 0x0454 /* Auto responder control */
|
||||
#define RAL_TXRX_CSR11 0x0456 /* Auto responder basic rate */
|
||||
#define RAL_TXRX_CSR18 0x0464 /* Beacon interval */
|
||||
#define RAL_TXRX_CSR19 0x0466 /* Beacon/sync control */
|
||||
@ -102,6 +105,8 @@
|
||||
#define RAL_DROP_MULTICAST (1 << 9)
|
||||
#define RAL_DROP_BROADCAST (1 << 10)
|
||||
|
||||
#define RAL_SHORT_PREAMBLE (1 << 2)
|
||||
|
||||
#define RAL_RESET_ASIC (1 << 0)
|
||||
#define RAL_RESET_BBP (1 << 1)
|
||||
#define RAL_HOST_READY (1 << 2)
|
||||
@ -167,7 +172,8 @@ struct ural_tx_desc {
|
||||
uint8_t plcp_service;
|
||||
#define RAL_PLCP_LENGEXT 0x80
|
||||
|
||||
uint16_t plcp_length;
|
||||
uint8_t plcp_length_lo;
|
||||
uint8_t plcp_length_hi;
|
||||
uint32_t iv;
|
||||
uint32_t eiv;
|
||||
} __packed;
|
||||
@ -175,10 +181,11 @@ struct ural_tx_desc {
|
||||
struct ural_rx_desc {
|
||||
uint32_t flags;
|
||||
#define RAL_RX_CRC_ERROR (1 << 5)
|
||||
#define RAL_RX_OFDM (1 << 6)
|
||||
#define RAL_RX_PHY_ERROR (1 << 7)
|
||||
|
||||
uint8_t rate;
|
||||
uint8_t rssi;
|
||||
uint8_t rate;
|
||||
uint16_t reserved;
|
||||
|
||||
uint32_t iv;
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* $FreeBSD$ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2005
|
||||
* Copyright (c) 2005, 2006
|
||||
* Damien Bergamini <damien.bergamini@free.fr>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
@ -23,6 +23,7 @@
|
||||
struct ural_rx_radiotap_header {
|
||||
struct ieee80211_radiotap_header wr_ihdr;
|
||||
uint8_t wr_flags;
|
||||
uint8_t wr_rate;
|
||||
uint16_t wr_chan_freq;
|
||||
uint16_t wr_chan_flags;
|
||||
uint8_t wr_antenna;
|
||||
@ -31,6 +32,7 @@ struct ural_rx_radiotap_header {
|
||||
|
||||
#define RAL_RX_RADIOTAP_PRESENT \
|
||||
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
||||
(1 << IEEE80211_RADIOTAP_RATE) | \
|
||||
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
||||
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
|
||||
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
|
||||
@ -67,6 +69,14 @@ struct ural_rx_data {
|
||||
struct mbuf *m;
|
||||
};
|
||||
|
||||
struct ural_amrr {
|
||||
int txcnt;
|
||||
int retrycnt;
|
||||
int success;
|
||||
int success_threshold;
|
||||
int recovery;
|
||||
};
|
||||
|
||||
struct ural_softc {
|
||||
struct ifnet *sc_ifp;
|
||||
struct ieee80211com sc_ic;
|
||||
@ -82,12 +92,16 @@ struct ural_softc {
|
||||
uint32_t asic_rev;
|
||||
uint8_t rf_rev;
|
||||
|
||||
usbd_xfer_handle amrr_xfer;
|
||||
|
||||
usbd_pipe_handle sc_rx_pipeh;
|
||||
usbd_pipe_handle sc_tx_pipeh;
|
||||
|
||||
enum ieee80211_state sc_state;
|
||||
struct usb_task sc_task;
|
||||
|
||||
struct ural_amrr amrr;
|
||||
|
||||
struct ural_rx_data rx_data[RAL_RX_LIST_COUNT];
|
||||
struct ural_tx_data tx_data[RAL_TX_LIST_COUNT];
|
||||
int tx_queued;
|
||||
@ -97,9 +111,11 @@ struct ural_softc {
|
||||
struct mtx sc_mtx;
|
||||
|
||||
struct callout scan_ch;
|
||||
struct callout amrr_ch;
|
||||
|
||||
int sc_tx_timer;
|
||||
|
||||
uint16_t sta[11];
|
||||
uint32_t rf_regs[4];
|
||||
uint8_t txpow[14];
|
||||
|
||||
|
@ -1095,6 +1095,7 @@ product LINKSYS2 USB200M 0x2226 USB 2.0 10/100 ethernet
|
||||
product LINKSYS3 WUSB11v28 0x2233 WUSB11 v2.8 wireless adapter
|
||||
product LINKSYS4 WUSB54G 0x000d WUSB54G wireless adapter
|
||||
product LINKSYS4 WUSB54GP 0x0011 WUSB54GP wireless adapter
|
||||
product LINKSYS4 HU200TS 0x001a HU200TS wireless adapter
|
||||
|
||||
/* Logitech products */
|
||||
product LOGITECH M2452 0x0203 M2452 keyboard
|
||||
@ -1155,6 +1156,7 @@ product MELCO LUAU2KTX 0x003d LUA-U2-KTX Ethernet
|
||||
product MELCO KG54YB 0x005e WLI-U2-KG54-YB WLAN
|
||||
product MELCO KG54 0x0066 WLI-U2-KG54 WLAN
|
||||
product MELCO KG54AI 0x0067 WLI-U2-KG54-AI WLAN
|
||||
product MELCO NINWIFI 0x008b Nintendo Wi-Fi
|
||||
|
||||
/* Metricom products */
|
||||
product METRICOM RICOCHET_GS 0x0001 Ricochet GS
|
||||
|
Loading…
x
Reference in New Issue
Block a user