Author: bschmidt
Date: Sun May  8 11:58:23 2011
New Revision: 221650
URL: http://svn.freebsd.org/changeset/base/221650

Log:
  Add support for RX packet aggregation.

Modified:
  head/sys/dev/iwn/if_iwn.c
  head/sys/dev/iwn/if_iwnvar.h

Modified: head/sys/dev/iwn/if_iwn.c
==============================================================================
--- head/sys/dev/iwn/if_iwn.c   Sun May  8 11:54:38 2011        (r221649)
+++ head/sys/dev/iwn/if_iwn.c   Sun May  8 11:58:23 2011        (r221650)
@@ -251,11 +251,11 @@ static uint8_t    *ieee80211_add_ssid(uint8
 static int     iwn_scan(struct iwn_softc *);
 static int     iwn_auth(struct iwn_softc *, struct ieee80211vap *vap);
 static int     iwn_run(struct iwn_softc *, struct ieee80211vap *vap);
+static int     iwn_ampdu_rx_start(struct ieee80211_node *,
+                   struct ieee80211_rx_ampdu *, int, int, int);
+static void    iwn_ampdu_rx_stop(struct ieee80211_node *,
+                   struct ieee80211_rx_ampdu *);
 #if 0  /* HT */
-static int     iwn_ampdu_rx_start(struct ieee80211com *,
-                   struct ieee80211_node *, uint8_t);
-static void    iwn_ampdu_rx_stop(struct ieee80211com *,
-                   struct ieee80211_node *, uint8_t);
 static int     iwn_ampdu_tx_start(struct ieee80211com *,
                    struct ieee80211_node *, uint8_t);
 static void    iwn_ampdu_tx_stop(struct ieee80211com *,
@@ -653,9 +653,11 @@ iwn_attach(device_t dev)
        ic->ic_vap_delete = iwn_vap_delete;
        ic->ic_raw_xmit = iwn_raw_xmit;
        ic->ic_node_alloc = iwn_node_alloc;
-#if 0  /* HT */
+       sc->sc_ampdu_rx_start = ic->ic_ampdu_rx_start;
        ic->ic_ampdu_rx_start = iwn_ampdu_rx_start;
+       sc->sc_ampdu_rx_stop = ic->ic_ampdu_rx_stop;
        ic->ic_ampdu_rx_stop = iwn_ampdu_rx_stop;
+#if 0  /* HT */
        ic->ic_ampdu_tx_start = iwn_ampdu_tx_start;
        ic->ic_ampdu_tx_stop = iwn_ampdu_tx_stop;
 #endif
@@ -2434,6 +2436,8 @@ iwn_rx_done(struct iwn_softc *sc, struct
 
        /* Send the frame to the 802.11 layer. */
        if (ni != NULL) {
+               if (ni->ni_flags & IEEE80211_NODE_HT)
+                       m->m_flags |= M_AMPDU;
                (void)ieee80211_input(ni, m, rssi - nf, nf);
                /* Node is no longer needed. */
                ieee80211_free_node(ni);
@@ -3765,7 +3769,8 @@ iwn_cmd(struct iwn_softc *sc, int code, 
        bus_addr_t paddr;
        int totlen, error;
 
-       IWN_LOCK_ASSERT(sc);
+       if (async == 0)
+               IWN_LOCK_ASSERT(sc);
 
        desc = &ring->desc[ring->cur];
        data = &ring->data[ring->cur];
@@ -5321,30 +5326,39 @@ iwn_run(struct iwn_softc *sc, struct iee
 #undef MS
 }
 
-#if 0  /* HT */
 /*
  * This function is called by upper layer when an ADDBA request is received
  * from another STA and before the ADDBA response is sent.
  */
 static int
-iwn_ampdu_rx_start(struct ieee80211com *ic, struct ieee80211_node *ni,
-    uint8_t tid)
+iwn_ampdu_rx_start(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap,
+    int baparamset, int batimeout, int baseqctl)
 {
-       struct ieee80211_rx_ba *ba = &ni->ni_rx_ba[tid];
-       struct iwn_softc *sc = ic->ic_softc;
+#define MS(_v, _f)     (((_v) & _f) >> _f##_S)
+       struct iwn_softc *sc = ni->ni_ic->ic_ifp->if_softc;
        struct iwn_ops *ops = &sc->ops;
        struct iwn_node *wn = (void *)ni;
        struct iwn_node_info node;
+       uint16_t ssn;
+       uint8_t tid;
+       int error;
+
+       tid = MS(le16toh(baparamset), IEEE80211_BAPS_TID);
+       ssn = MS(le16toh(baseqctl), IEEE80211_BASEQ_START);
 
        memset(&node, 0, sizeof node);
        node.id = wn->id;
        node.control = IWN_NODE_UPDATE;
        node.flags = IWN_FLAG_SET_ADDBA;
        node.addba_tid = tid;
-       node.addba_ssn = htole16(ba->ba_winstart);
+       node.addba_ssn = htole16(ssn);
        DPRINTF(sc, IWN_DEBUG_RECV, "ADDBA RA=%d TID=%d SSN=%d\n",
-           wn->id, tid, ba->ba_winstart);
-       return ops->add_node(sc, &node, 1);
+           wn->id, tid, ssn);
+       error = ops->add_node(sc, &node, 1);
+       if (error != 0)
+               return error;
+       return sc->sc_ampdu_rx_start(ni, rap, baparamset, batimeout, baseqctl);
+#undef MS
 }
 
 /*
@@ -5352,13 +5366,20 @@ iwn_ampdu_rx_start(struct ieee80211com *
  * Block Ack agreement (eg. uppon receipt of a DELBA frame).
  */
 static void
-iwn_ampdu_rx_stop(struct ieee80211com *ic, struct ieee80211_node *ni,
-    uint8_t tid)
+iwn_ampdu_rx_stop(struct ieee80211_node *ni, struct ieee80211_rx_ampdu *rap)
 {
-       struct iwn_softc *sc = ic->ic_softc;
+       struct ieee80211com *ic = ni->ni_ic;
+       struct iwn_softc *sc = ic->ic_ifp->if_softc;
        struct iwn_ops *ops = &sc->ops;
        struct iwn_node *wn = (void *)ni;
        struct iwn_node_info node;
+       uint8_t tid;
+
+       /* XXX: tid as an argument */
+       for (tid = 0; tid < WME_NUM_TID; tid++) {
+               if (&ni->ni_rx_ampdu[tid] == rap)
+                       break;
+       }
 
        memset(&node, 0, sizeof node);
        node.id = wn->id;
@@ -5367,8 +5388,10 @@ iwn_ampdu_rx_stop(struct ieee80211com *i
        node.delba_tid = tid;
        DPRINTF(sc, IWN_DEBUG_RECV, "DELBA RA=%d TID=%d\n", wn->id, tid);
        (void)ops->add_node(sc, &node, 1);
+       sc->sc_ampdu_rx_stop(ni, rap);
 }
 
+#if 0 /* HT */
 /*
  * This function is called by upper layer when an ADDBA response is received
  * from another STA.

Modified: head/sys/dev/iwn/if_iwnvar.h
==============================================================================
--- head/sys/dev/iwn/if_iwnvar.h        Sun May  8 11:54:38 2011        
(r221649)
+++ head/sys/dev/iwn/if_iwnvar.h        Sun May  8 11:58:23 2011        
(r221650)
@@ -306,6 +306,11 @@ struct iwn_softc {
 
        int                     sc_tx_timer;
 
+       int                     (*sc_ampdu_rx_start)(struct ieee80211_node *,
+                                   struct ieee80211_rx_ampdu *, int, int, int);
+       void                    (*sc_ampdu_rx_stop)(struct ieee80211_node *,
+                                   struct ieee80211_rx_ampdu *);
+
        struct iwn_rx_radiotap_header sc_rxtap;
        struct iwn_tx_radiotap_header sc_txtap;
 };
_______________________________________________
[email protected] mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to