From a4a2db9defa146aa84210e63ff6ec6384b146585 Mon Sep 17 00:00:00 2001 From: Alexander Egorenkov Date: Tue, 16 Mar 2010 08:24:51 +0100 Subject: [PATCH] Hook ic_addba_response and ic_addba_stop functions in order to be able to count active A-MPDU Tx sessions properly --- rt2870.c | 150 ++++++++++++++++++++++++++++++++++++++++----------------- rt2870_softc.h | 7 +++ 2 files changed, 112 insertions(+), 45 deletions(-) diff --git a/rt2870.c b/rt2870.c index 450c82c..1fe87f8 100644 --- a/rt2870.c +++ b/rt2870.c @@ -185,6 +185,13 @@ static int rt2870_recv_action(struct ieee80211_node *ni, static int rt2870_send_action(struct ieee80211_node *ni, int cat, int act, void *sa); +static int rt2870_addba_response(struct ieee80211_node *ni, + struct ieee80211_tx_ampdu *tap, + int status, int baparamset, int batimeout); + +static void rt2870_addba_stop(struct ieee80211_node *ni, + struct ieee80211_tx_ampdu *tap); + static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni); static void rt2870_periodic(void *arg); @@ -763,6 +770,12 @@ static int rt2870_attach(device_t dev) sc->send_action = ic->ic_send_action; ic->ic_send_action = rt2870_send_action; + sc->addba_response = ic->ic_addba_response; + ic->ic_addba_response = rt2870_addba_response; + + sc->addba_stop = ic->ic_addba_stop; + ic->ic_addba_stop = rt2870_addba_stop; + /* hardware requires padding between 802.11 frame header and body */ ic->ic_flags |= IEEE80211_F_DATAPAD | IEEE80211_F_DOTH; @@ -2563,10 +2576,9 @@ static int rt2870_recv_action(struct ieee80211_node *ni, struct ifnet *ifp; struct rt2870_softc_node *rni; const struct ieee80211_action *ia; - struct ieee80211_tx_ampdu *tx_ampdu; - uint16_t status, baparamset; + uint16_t baparamset; uint8_t wcid; - int ret, tid, bufsize, ac; + int ret, tid; uint32_t tmp; ic = ni->ni_ic; @@ -2583,42 +2595,6 @@ static int rt2870_recv_action(struct ieee80211_node *ni, switch (ia->ia_action) { - /* IEEE80211_ACTION_BA_ADDBA_RESPONSE */ - case IEEE80211_ACTION_BA_ADDBA_RESPONSE: - status = LE_READ_2(frm + 3); - baparamset = LE_READ_2(frm + 4); - tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID); - bufsize = RT2870_MS(baparamset, IEEE80211_BAPS_BUFSIZ); - ac = TID_TO_WME_AC(tid); - tx_ampdu = &ni->ni_tx_ampdu[ac]; - - RT2870_DPRINTF(sc, RT2870_DEBUG_BA, - "%s: received ADDBA response: associd=0x%04x, staid=0x%02x, status=%d, tid=%d, bufsize=%d\n", - device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, status, tid, bufsize); - - if (sc->mac_rev >= 0x28720200) - { - if (tx_ampdu->txa_wnd > 13) - tx_ampdu->txa_wnd = 13; - } - else - { - if (tx_ampdu->txa_wnd > 7) - tx_ampdu->txa_wnd = 7; - } - - if (status == IEEE80211_STATUS_SUCCESS) - { - sc->tx_ampdu_sessions++; - - RT2870_SOFTC_LOCK(sc); - - rt2870_asic_updateprot(sc); - - RT2870_SOFTC_UNLOCK(sc); - } - break; - /* IEEE80211_ACTION_BA_DELBA */ case IEEE80211_ACTION_BA_DELBA: baparamset = LE_READ_2(frm + 2); @@ -2718,12 +2694,6 @@ static int rt2870_send_action(struct ieee80211_node *ni, rt2870_io_mac_write(sc, RT2870_REG_WCID(wcid) + 4, tmp); } - else - { - sc->tx_ampdu_sessions--; - - rt2870_asic_updateprot(sc); - } RT2870_SOFTC_UNLOCK(sc); break; @@ -2733,6 +2703,96 @@ static int rt2870_send_action(struct ieee80211_node *ni, } /* + * rt2870_addba_response + */ +static int rt2870_addba_response(struct ieee80211_node *ni, + struct ieee80211_tx_ampdu *tap, + int status, int baparamset, int batimeout) +{ + struct rt2870_softc *sc; + struct ieee80211com *ic; + struct ifnet *ifp; + struct rt2870_softc_node *rni; + int tid, bufsize; + + ic = ni->ni_ic; + ifp = ic->ic_ifp; + sc = ifp->if_softc; + rni = (struct rt2870_softc_node *) ni; + + tid = RT2870_MS(baparamset, IEEE80211_BAPS_TID); + bufsize = RT2870_MS(baparamset, IEEE80211_BAPS_BUFSIZ); + + RT2870_DPRINTF(sc, RT2870_DEBUG_BA, + "%s: received ADDBA response: associd=0x%04x, staid=0x%02x, status=%d, tid=%d, bufsize=%d\n", + device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, status, tid, bufsize); + + if (status == IEEE80211_STATUS_SUCCESS) + { + if (sc->mac_rev >= 0x28720200) + { + if (bufsize > 13) + bufsize = 13; + } + else + { + if (bufsize > 7) + bufsize = 7; + } + + baparamset &= ~IEEE80211_BAPS_BUFSIZ; + baparamset = RT2870_SM(bufsize, IEEE80211_BAPS_BUFSIZ); + + if (!(tap->txa_flags & IEEE80211_AGGR_RUNNING)) + { + sc->tx_ampdu_sessions++; + + RT2870_SOFTC_LOCK(sc); + + rt2870_asic_updateprot(sc); + + RT2870_SOFTC_UNLOCK(sc); + } + } + + return sc->addba_response(ni, tap, status, baparamset, batimeout); +} + +/* + * rt2870_addba_stop + */ +static void rt2870_addba_stop(struct ieee80211_node *ni, + struct ieee80211_tx_ampdu *tap) +{ + struct rt2870_softc *sc; + struct ieee80211com *ic; + struct ifnet *ifp; + struct rt2870_softc_node *rni; + int tid; + + ic = ni->ni_ic; + ifp = ic->ic_ifp; + sc = ifp->if_softc; + rni = (struct rt2870_softc_node *) ni; + + tid = WME_AC_TO_TID(tap->txa_ac); + + RT2870_DPRINTF(sc, RT2870_DEBUG_BA, + "%s: stopping A-MPDU Tx: associd=0x%04x, staid=0x%02x, tid=%d\n", + device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid); + + sc->tx_ampdu_sessions--; + + RT2870_SOFTC_LOCK(sc); + + rt2870_asic_updateprot(sc); + + RT2870_SOFTC_UNLOCK(sc); + + sc->addba_stop(ni, tap); +} + +/* * rt2870_amrr_update_iter_func */ static void rt2870_amrr_update_iter_func(void *arg, struct ieee80211_node *ni) diff --git a/rt2870_softc.h b/rt2870_softc.h index 8577f04..020c005 100644 --- a/rt2870_softc.h +++ b/rt2870_softc.h @@ -249,6 +249,13 @@ struct rt2870_softc int (*send_action)(struct ieee80211_node *ni, int cat, int act, void *sa); + int (*addba_response)(struct ieee80211_node *ni, + struct ieee80211_tx_ampdu *tap, + int status, int baparamset, int batimeout); + + void (*addba_stop)(struct ieee80211_node *ni, + struct ieee80211_tx_ampdu *tap); + struct rt2870_amrr_node amrr_node[RT2870_SOFTC_STAID_COUNT]; uint32_t mac_rev; -- 2.11.4.GIT