From ccbc8367e90f5621c631bbe8a8f9a873fd29af13 Mon Sep 17 00:00:00 2001 From: Alexander Egorenkov Date: Thu, 18 Mar 2010 22:35:00 +0100 Subject: [PATCH] Added A-MPDU Rx session counter; Added hooks for ic_ampdu_rx_start and ic_ampdu_rx_stop; Catch negative A-MPDU Tx/Rx session values --- rt2860.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- rt2860_softc.h | 11 +++++-- 2 files changed, 104 insertions(+), 5 deletions(-) diff --git a/rt2860.c b/rt2860.c index 0aed60a..8dddb74 100644 --- a/rt2860.c +++ b/rt2860.c @@ -179,6 +179,13 @@ static int rt2860_addba_response(struct ieee80211_node *ni, static void rt2860_addba_stop(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap); +static int rt2860_ampdu_rx_start(struct ieee80211_node *ni, + struct ieee80211_rx_ampdu *rap, + int baparamset, int batimeout, int baseqctl); + +static void rt2860_ampdu_rx_stop(struct ieee80211_node *ni, + struct ieee80211_rx_ampdu *rap); + static int rt2860_send_bar(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap, ieee80211_seq seqno); @@ -689,6 +696,12 @@ static int rt2860_attach(device_t dev) sc->addba_stop = ic->ic_addba_stop; ic->ic_addba_stop = rt2860_addba_stop; + sc->ampdu_rx_start = ic->ic_ampdu_rx_start; + ic->ic_ampdu_rx_start = rt2860_ampdu_rx_start; + + sc->ampdu_rx_stop = ic->ic_ampdu_rx_stop; + ic->ic_ampdu_rx_stop = rt2860_ampdu_rx_stop; + /* hardware requires padding between 802.11 frame header and body */ ic->ic_flags |= IEEE80211_F_DATAPAD | IEEE80211_F_DOTH; @@ -2995,7 +3008,8 @@ static int rt2860_addba_response(struct ieee80211_node *ni, { sc->tx_ampdu_sessions++; - rt2860_asic_updateprot(sc); + if (sc->tx_ampdu_sessions == 1) + rt2860_asic_updateprot(sc); } } @@ -3040,14 +3054,88 @@ static void rt2860_addba_stop(struct ieee80211_node *ni, "%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--; + if (tap->txa_flags & IEEE80211_AGGR_RUNNING) + { + if (sc->tx_ampdu_sessions > 0) + { + sc->tx_ampdu_sessions--; - rt2860_asic_updateprot(sc); + if (sc->tx_ampdu_sessions == 0) + rt2860_asic_updateprot(sc); + } + else + { + printf("%s: number of A-MPDU Tx sessions cannot be negative\n", + device_get_nameunit(sc->dev)); + } + } sc->addba_stop(ni, tap); } /* + * rt2860_ampdu_rx_start + */ +static int rt2860_ampdu_rx_start(struct ieee80211_node *ni, + struct ieee80211_rx_ampdu *rap, + int baparamset, int batimeout, int baseqctl) +{ + struct rt2860_softc *sc; + struct ieee80211com *ic; + struct ifnet *ifp; + struct rt2860_softc_node *rni; + int tid; + + ic = ni->ni_ic; + ifp = ic->ic_ifp; + sc = ifp->if_softc; + rni = (struct rt2860_softc_node *) ni; + + tid = RT2860_MS(baparamset, IEEE80211_BAPS_TID); + + RT2860_DPRINTF(sc, RT2860_DEBUG_BA, + "%s: starting A-MPDU Rx: associd=0x%04x, staid=0x%02x, tid=%d\n", + device_get_nameunit(sc->dev), ni->ni_associd, rni->staid, tid); + + if (!(rap->rxa_flags & IEEE80211_AGGR_RUNNING)) + sc->rx_ampdu_sessions++; + + return sc->ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl); +} + +/* + * rt2860_ampdu_rx_stop + */ +static void rt2860_ampdu_rx_stop(struct ieee80211_node *ni, + struct ieee80211_rx_ampdu *rap) +{ + struct rt2860_softc *sc; + struct ieee80211com *ic; + struct ifnet *ifp; + struct rt2860_softc_node *rni; + + ic = ni->ni_ic; + ifp = ic->ic_ifp; + sc = ifp->if_softc; + rni = (struct rt2860_softc_node *) ni; + + RT2860_DPRINTF(sc, RT2860_DEBUG_BA, + "%s: stopping A-MPDU Rx: associd=0x%04x, staid=0x%02x\n", + device_get_nameunit(sc->dev), ni->ni_associd, rni->staid); + + if (rap->rxa_flags & IEEE80211_AGGR_RUNNING) + { + if (sc->rx_ampdu_sessions > 0) + sc->rx_ampdu_sessions--; + else + printf("%s: number of A-MPDU Rx sessions cannot be negative\n", + device_get_nameunit(sc->dev)); + } + + sc->ampdu_rx_stop(ni, rap); +} + +/* * rt2860_send_bar */ static int rt2860_send_bar(struct ieee80211_node *ni, @@ -7027,6 +7115,10 @@ static void rt2860_sysctl_attach(struct rt2860_softc *sc) "Rx MPDU with zero density"); SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO, + "rx_ampdu_sessions", CTLFLAG_RD, &sc->rx_ampdu_sessions, 0, + "Rx A-MPDU sessions"); + + SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(stats), OID_AUTO, "rx_amsdu", CTLFLAG_RD, &sc->rx_amsdu, 0, "Rx A-MSDU"); diff --git a/rt2860_softc.h b/rt2860_softc.h index 3e22032..f671c1f 100644 --- a/rt2860_softc.h +++ b/rt2860_softc.h @@ -237,8 +237,6 @@ struct rt2860_softc void (*node_cleanup)(struct ieee80211_node *ni); - int tx_ampdu_sessions; - int (*recv_action)(struct ieee80211_node *ni, const struct ieee80211_frame *wh, const uint8_t *frm, const uint8_t *efrm); @@ -253,6 +251,13 @@ struct rt2860_softc void (*addba_stop)(struct ieee80211_node *ni, struct ieee80211_tx_ampdu *tap); + int (*ampdu_rx_start)(struct ieee80211_node *ni, + struct ieee80211_rx_ampdu *rap, + int baparamset, int batimeout, int baseqctl); + + void (*ampdu_rx_stop)(struct ieee80211_node *ni, + struct ieee80211_rx_ampdu *rap); + struct rt2860_amrr_node amrr_node[RT2860_SOFTC_STAID_COUNT]; uint32_t mac_rev; @@ -378,11 +383,13 @@ struct rt2860_softc unsigned long tx_agg; unsigned long tx_ampdu; unsigned long tx_mpdu_zero_density; + unsigned long tx_ampdu_sessions; unsigned long rx_packets; unsigned long rx_ampdu; unsigned long rx_ampdu_retries; unsigned long rx_mpdu_zero_density; + unsigned long rx_ampdu_sessions; unsigned long rx_amsdu; unsigned long rx_crc_errors; unsigned long rx_phy_errors; -- 2.11.4.GIT