staging: brcm80211: parsed ADDBA response ack window parameter
authorRoland Vossen <rvossen@broadcom.com>
Wed, 29 Jun 2011 23:46:45 +0000 (16:46 -0700)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 5 Jul 2011 16:57:12 +0000 (09:57 -0700)
IEEE80211_AMPDU_TX_OPERATIONAL provides a BA window size parameter. Code
is now using this parameter to restrict the amount of outstanding tx
AMPDUs.

Signed-off-by: Roland Vossen <rvossen@broadcom.com>
Reviewed-by: Arend van Spriel <arend@broadcom.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/brcm80211/brcmsmac/ampdu.c
drivers/staging/brcm80211/brcmsmac/mac80211_if.c
drivers/staging/brcm80211/brcmsmac/pub.h
drivers/staging/brcm80211/brcmsmac/scb.h

index 74c405555b0fae18e91d31222c1ac94b21f9b6ac..e9b78bf8e8cd3232bbc7088206d421ede14c1ef9 100644 (file)
@@ -114,9 +114,6 @@ static void brcms_c_ffpld_init(struct ampdu_info *ampdu);
 static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int f);
 static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f);
 
-static scb_ampdu_tid_ini_t *brcms_c_ampdu_init_tid_ini(struct ampdu_info *ampdu,
-                                                  scb_ampdu_t *scb_ampdu,
-                                                  u8 tid, bool override);
 static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu,
                                               u8 dur);
 static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
@@ -411,22 +408,26 @@ static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
        }
 }
 
-static void
-brcms_c_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p,
-             uint prec)
+void
+brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
+                 u8 ba_wsize)          /* negotiated ba window size (in pdu) */
 {
        scb_ampdu_t *scb_ampdu;
        scb_ampdu_tid_ini_t *ini;
-       u8 tid = (u8) (p->priority);
-
+       struct ampdu_info *ampdu = wlc->ampdu;
+       struct scb *scb = wlc->pub->global_scb;
        scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb);
 
-       /* initialize initiator on first packet; sends addba req */
-       ini = SCB_AMPDU_INI(scb_ampdu, tid);
-       if (ini->magic != INI_MAGIC) {
-               ini = brcms_c_ampdu_init_tid_ini(ampdu, scb_ampdu, tid, false);
+       if (!ampdu->ini_enable[tid]) {
+               wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
+                         __func__, tid);
+               return;
        }
-       return;
+
+       ini = SCB_AMPDU_INI(scb_ampdu, tid);
+       ini->tid = tid;
+       ini->scb = scb_ampdu->scb;
+       ini->ba_wsize = ba_wsize;
 }
 
 int
@@ -479,12 +480,13 @@ brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_c_txq_info *qi,
 
        /* Let pressure continue to build ... */
        qlen = pktq_plen(&qi->q, prec);
-       if (ini->tx_in_transit > 0 && qlen < scb_ampdu->max_pdu) {
+       if (ini->tx_in_transit > 0 &&
+           qlen < min(scb_ampdu->max_pdu, ini->ba_wsize)) {
+               /* Collect multiple MPDU's to be sent in the next AMPDU */
                return -EBUSY;
        }
 
-       brcms_c_ampdu_agg(ampdu, scb, p, tid);
-
+       /* at this point we intend to transmit an AMPDU */
        rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
        ampdu_len = 0;
        dma_len = 0;
@@ -1083,27 +1085,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
        brcms_c_txfifo_complete(wlc, queue, ampdu->txpkt_weight);
 }
 
-/* initialize the initiator code for tid */
-static scb_ampdu_tid_ini_t *brcms_c_ampdu_init_tid_ini(struct ampdu_info *ampdu,
-                                                  scb_ampdu_t *scb_ampdu,
-                                                  u8 tid, bool override)
-{
-       scb_ampdu_tid_ini_t *ini;
-
-       /* check for per-tid control of ampdu */
-       if (!ampdu->ini_enable[tid]) {
-               wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
-                         __func__, tid);
-               return NULL;
-       }
-
-       ini = SCB_AMPDU_INI(scb_ampdu, tid);
-       ini->tid = tid;
-       ini->scb = scb_ampdu->scb;
-       ini->magic = INI_MAGIC;
-       return ini;
-}
-
 static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
 {
        struct brcms_c_info *wlc = ampdu->wlc;
index 73e60dfdaca507a13bea31fac199fc310c3b97b3..547df7569a1b46b0a2c2617c3ec5e616c883bcfb 100644 (file)
@@ -656,7 +656,14 @@ brcms_ops_ampdu_action(struct ieee80211_hw *hw,
                ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
                break;
        case IEEE80211_AMPDU_TX_OPERATIONAL:
-               /* Not sure what to do here */
+               /*
+                * BA window size from ADDBA response ('buf_size') defines how
+                * many outstanding MPDUs are allowed for the BA stream by
+                * recipient and traffic class.
+                */
+               LOCK(wl);
+               brcms_c_ampdu_tx_operational(wl->wlc, tid, buf_size);
+               UNLOCK(wl);
                /* Power save wakeup */
                break;
        default:
index 2345a31b90e02ece9e68a22de172fe7a31ad80ef..14c0d20d43fb026084c5e0740ffc224c76caa266 100644 (file)
@@ -626,6 +626,8 @@ extern void brcms_default_rateset(struct brcms_c_info *wlc, wlc_rateset_t *rs);
 
 extern void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
                            struct ieee80211_sta *sta, u16 tid);
+extern void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
+                                        u8 ba_wsize);
 extern int brcms_c_set_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
                           int val);
 extern int brcms_c_get_par(struct brcms_c_info *wlc, enum wlc_par_id par_id,
index fa5c0b385c0fbd1688dac90678128bebe57b3644..c2080e9e7935a559c728db1ac9315207a35cb9b0 100644 (file)
 #define AMPDU_TX_BA_MAX_WSIZE  64      /* max Tx ba window size (in pdu) */
 /* structure to store per-tid state for the ampdu initiator */
 struct scb_ampdu_tid_ini {
-       u32 magic;
        u8 tx_in_transit;       /* number of pending mpdus in transit in driver */
        u8 tid;         /* initiator tid for easy lookup */
        u8 txretry[AMPDU_TX_BA_MAX_WSIZE];      /* tx retry count; indexed by seq modulo */
        struct scb *scb;        /* backptr for easy lookup */
+       u8 ba_wsize;            /* negotiated ba window size (in pdu) */
 };
 
 #define AMPDU_MAX_SCB_TID      NUMPRIO
@@ -51,7 +51,6 @@ struct scb_ampdu {
 };
 
 #define SCB_MAGIC      0xbeefcafe
-#define INI_MAGIC      0xabcd1234
 
 /* station control block - one per remote MAC address */
 struct scb {