Second part of the AMRR commit.
Enable automatic rate adaptation in BSS operating mode. Works great here. Will need a lot of testing though.
This commit is contained in:
parent
ef39adf007
commit
8403bb96a2
@ -159,6 +159,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).
|
||||
@ -411,6 +418,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);
|
||||
@ -517,6 +525,7 @@ USB_DETACH(ural)
|
||||
|
||||
usb_rem_task(sc->sc_udev, &sc->sc_task);
|
||||
callout_stop(&sc->scan_ch);
|
||||
callout_stop(&sc->amrr_ch);
|
||||
|
||||
if (sc->sc_rx_pipeh != NULL) {
|
||||
usbd_abort_pipe(sc->sc_rx_pipeh);
|
||||
@ -772,6 +781,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, ic->ic_bss);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -785,6 +800,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;
|
||||
@ -1918,7 +1934,7 @@ 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;
|
||||
|
||||
@ -1957,7 +1973,7 @@ ural_init(void *priv)
|
||||
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);
|
||||
@ -1974,6 +1990,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.
|
||||
*/
|
||||
@ -2081,6 +2107,81 @@ ural_stop(void *priv)
|
||||
|
||||
ural_free_rx_list(sc);
|
||||
ural_free_tx_list(sc);
|
||||
|
||||
if (sc->amrr_xfer != NULL)
|
||||
usbd_free_xfer(sc->amrr_xfer);
|
||||
}
|
||||
|
||||
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 STA 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, 22);
|
||||
|
||||
usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc,
|
||||
USBD_DEFAULT_TIMEOUT, &req, sc->sta, 22, 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);
|
||||
}
|
||||
|
||||
/*-
|
||||
@ -2091,8 +2192,9 @@ ural_stop(void *priv)
|
||||
* 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 we do not
|
||||
* have per-frame statistics, we cannot do per-node rate adaptation.
|
||||
* 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
|
||||
@ -2114,16 +2216,9 @@ ural_stop(void *priv)
|
||||
((ni)->ni_txrate--)
|
||||
#define reset_cnt(amrr) \
|
||||
do { (amrr)->txcnt = (amrr)->retrycnt = 0; } while (0)
|
||||
|
||||
Static void ural_ratectl(void *) __unused;
|
||||
|
||||
Static void
|
||||
ural_ratectl(void *priv)
|
||||
ural_ratectl(struct ural_amrr *amrr, struct ieee80211_node *ni)
|
||||
{
|
||||
struct ural_softc *sc = (struct ural_softc *)priv;
|
||||
struct ieee80211com *ic = &sc->sc_ic;
|
||||
struct ieee80211_node *ni = ic->ic_bss;
|
||||
struct ural_amrr *amrr = &sc->amrr;
|
||||
int need_change = 0;
|
||||
|
||||
if (is_success(amrr) && is_enough(amrr)) {
|
||||
@ -2137,7 +2232,7 @@ ural_ratectl(void *priv)
|
||||
} else {
|
||||
amrr->recovery = 0;
|
||||
}
|
||||
} else if (is_failure(amrr)) {
|
||||
} else if (is_failure(amrr)) {
|
||||
amrr->success = 0;
|
||||
if (!is_min_rate(ni)) {
|
||||
if (amrr->recovery) {
|
||||
|
@ -90,6 +90,8 @@ 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;
|
||||
|
||||
@ -107,9 +109,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];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user