2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 #include <net/mac80211.h>
20 #include "phy/phy_hal.h"
25 /* max number of mpdus in an ampdu */
26 #define AMPDU_MAX_MPDU 32
27 /* max number of mpdus in an ampdu to a legacy */
28 #define AMPDU_NUM_MPDU_LEGACY 16
29 /* max Tx ba window size (in pdu) */
30 #define AMPDU_TX_BA_MAX_WSIZE 64
31 /* default Tx ba window size (in pdu) */
32 #define AMPDU_TX_BA_DEF_WSIZE 64
33 /* default Rx ba window size (in pdu) */
34 #define AMPDU_RX_BA_DEF_WSIZE 64
35 /* max Rx ba window size (in pdu) */
36 #define AMPDU_RX_BA_MAX_WSIZE 64
37 /* max dur of tx ampdu (in msec) */
38 #define AMPDU_MAX_DUR 5
39 /* default tx retry limit */
40 #define AMPDU_DEF_RETRY_LIMIT 5
41 /* default tx retry limit at reg rate */
42 #define AMPDU_DEF_RR_RETRY_LIMIT 2
43 /* default ffpld reserved bytes */
44 #define AMPDU_DEF_FFPLD_RSVD 2048
45 /* # of inis to be freed on detach */
46 #define AMPDU_INI_FREE 10
47 /* max # of mpdus released at a time */
48 #define AMPDU_SCB_MAX_RELEASE 20
50 #define NUM_FFPLD_FIFO 4 /* number of fifo concerned by pre-loading */
51 #define FFPLD_TX_MAX_UNFL 200 /* default value of the average number of ampdu
54 #define FFPLD_MPDU_SIZE 1800 /* estimate of maximum mpdu size */
55 #define FFPLD_MAX_MCS 23 /* we don't deal with mcs 32 */
56 #define FFPLD_PLD_INCR 1000 /* increments in bytes */
57 #define FFPLD_MAX_AMPDU_CNT 5000 /* maximum number of ampdu we
58 * accumulate between resets.
61 #define AMPDU_DELIMITER_LEN 4
63 /* max allowed number of mpdus in an ampdu (2 streams) */
64 #define AMPDU_NUM_MPDU 16
66 #define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
68 /* max possible overhead per mpdu in the ampdu; 3 is for roundup if needed */
69 #define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
70 AMPDU_DELIMITER_LEN + 3\
71 + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
73 /* modulo add/sub, bound = 2^k */
74 #define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
75 #define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
77 /* structure to hold tx fifo information and pre-loading state
78 * counters specific to tx underflows of ampdus
79 * some counters might be redundant with the ones in wlc or ampdu structures.
80 * This allows to maintain a specific state independently of
81 * how often and/or when the wlc counters are updated.
83 * ampdu_pld_size: number of bytes to be pre-loaded
84 * mcs2ampdu_table: per-mcs max # of mpdus in an ampdu
85 * prev_txfunfl: num of underflows last read from the HW macstats counter
86 * accum_txfunfl: num of underflows since we modified pld params
87 * accum_txampdu: num of tx ampdu since we modified pld params
88 * prev_txampdu: previous reading of tx ampdu
89 * dmaxferrate: estimated dma avg xfer rate in kbits/sec
91 struct brcms_fifo_info {
93 u8 mcs2ampdu_table[FFPLD_MAX_MCS + 1];
101 /* AMPDU module specific state
103 * wlc: pointer to main wlc structure
104 * scb_handle: scb cubby handle to retrieve data from scb
105 * ini_enable: per-tid initiator enable/disable of ampdu
106 * ba_tx_wsize: Tx ba window size (in pdu)
107 * ba_rx_wsize: Rx ba window size (in pdu)
108 * retry_limit: mpdu transmit retry limit
109 * rr_retry_limit: mpdu transmit retry limit at regular rate
110 * retry_limit_tid: per-tid mpdu transmit retry limit
111 * rr_retry_limit_tid: per-tid mpdu transmit retry limit at regular rate
112 * mpdu_density: min mpdu spacing (0-7) ==> 2^(x-1)/8 usec
113 * max_pdu: max pdus allowed in ampdu
114 * dur: max duration of an ampdu (in msec)
115 * rx_factor: maximum rx ampdu factor (0-3) ==> 2^(13+x) bytes
116 * ffpld_rsvd: number of bytes to reserve for preload
117 * max_txlen: max size of ampdu per mcs, bw and sgi
118 * mfbr: enable multiple fallback rate
119 * tx_max_funl: underflows should be kept such that
120 * (tx_max_funfl*underflows) < tx frames
121 * fifo_tb: table of fifo infos
124 struct brcms_c_info *wlc;
126 u8 ini_enable[AMPDU_MAX_SCB_TID];
131 u8 retry_limit_tid[AMPDU_MAX_SCB_TID];
132 u8 rr_retry_limit_tid[AMPDU_MAX_SCB_TID];
138 u32 max_txlen[MCS_TABLE_SIZE][2][2];
141 struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO];
144 /* used for flushing ampdu packets */
145 struct cb_del_ampdu_pars {
146 struct ieee80211_sta *sta;
150 static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur)
154 for (mcs = 0; mcs < MCS_TABLE_SIZE; mcs++) {
155 /* rate is in Kbps; dur is in msec ==> len = (rate * dur) / 8 */
157 rate = mcs_2_rate(mcs, false, false);
158 ampdu->max_txlen[mcs][0][0] = (rate * dur) >> 3;
160 rate = mcs_2_rate(mcs, true, false);
161 ampdu->max_txlen[mcs][1][0] = (rate * dur) >> 3;
163 rate = mcs_2_rate(mcs, false, true);
164 ampdu->max_txlen[mcs][0][1] = (rate * dur) >> 3;
166 rate = mcs_2_rate(mcs, true, true);
167 ampdu->max_txlen[mcs][1][1] = (rate * dur) >> 3;
171 static bool brcms_c_ampdu_cap(struct ampdu_info *ampdu)
173 if (BRCMS_PHY_11N_CAP(ampdu->wlc->band))
179 static int brcms_c_ampdu_set(struct ampdu_info *ampdu, bool on)
181 struct brcms_c_info *wlc = ampdu->wlc;
183 wlc->pub->_ampdu = false;
186 if (!(wlc->pub->_n_enab & SUPPORT_11N)) {
187 wiphy_err(ampdu->wlc->wiphy, "wl%d: driver not "
188 "nmode enabled\n", wlc->pub->unit);
191 if (!brcms_c_ampdu_cap(ampdu)) {
192 wiphy_err(ampdu->wlc->wiphy, "wl%d: device not "
193 "ampdu capable\n", wlc->pub->unit);
196 wlc->pub->_ampdu = on;
202 static void brcms_c_ffpld_init(struct ampdu_info *ampdu)
205 struct brcms_fifo_info *fifo;
207 for (j = 0; j < NUM_FFPLD_FIFO; j++) {
208 fifo = (ampdu->fifo_tb + j);
209 fifo->ampdu_pld_size = 0;
210 for (i = 0; i <= FFPLD_MAX_MCS; i++)
211 fifo->mcs2ampdu_table[i] = 255;
212 fifo->dmaxferrate = 0;
213 fifo->accum_txampdu = 0;
214 fifo->prev_txfunfl = 0;
215 fifo->accum_txfunfl = 0;
220 struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc)
222 struct ampdu_info *ampdu;
225 ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC);
231 for (i = 0; i < AMPDU_MAX_SCB_TID; i++)
232 ampdu->ini_enable[i] = true;
233 /* Disable ampdu for VO by default */
234 ampdu->ini_enable[PRIO_8021D_VO] = false;
235 ampdu->ini_enable[PRIO_8021D_NC] = false;
237 /* Disable ampdu for BK by default since not enough fifo space */
238 ampdu->ini_enable[PRIO_8021D_NONE] = false;
239 ampdu->ini_enable[PRIO_8021D_BK] = false;
241 ampdu->ba_tx_wsize = AMPDU_TX_BA_DEF_WSIZE;
242 ampdu->ba_rx_wsize = AMPDU_RX_BA_DEF_WSIZE;
243 ampdu->mpdu_density = AMPDU_DEF_MPDU_DENSITY;
244 ampdu->max_pdu = AUTO;
245 ampdu->dur = AMPDU_MAX_DUR;
247 ampdu->ffpld_rsvd = AMPDU_DEF_FFPLD_RSVD;
249 * bump max ampdu rcv size to 64k for all 11n
250 * devices except 4321A0 and 4321A1
252 if (BRCMS_ISNPHY(wlc->band) && NREV_LT(wlc->band->phyrev, 2))
253 ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_32K;
255 ampdu->rx_factor = IEEE80211_HT_MAX_AMPDU_64K;
256 ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT;
257 ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT;
259 for (i = 0; i < AMPDU_MAX_SCB_TID; i++) {
260 ampdu->retry_limit_tid[i] = ampdu->retry_limit;
261 ampdu->rr_retry_limit_tid[i] = ampdu->rr_retry_limit;
264 brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->dur);
266 /* try to set ampdu to the default value */
267 brcms_c_ampdu_set(ampdu, wlc->pub->_ampdu);
269 ampdu->tx_max_funl = FFPLD_TX_MAX_UNFL;
270 brcms_c_ffpld_init(ampdu);
275 void brcms_c_ampdu_detach(struct ampdu_info *ampdu)
280 static void brcms_c_scb_ampdu_update_config(struct ampdu_info *ampdu,
283 struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
286 scb_ampdu->max_pdu = AMPDU_NUM_MPDU;
288 /* go back to legacy size if some preloading is occurring */
289 for (i = 0; i < NUM_FFPLD_FIFO; i++) {
290 if (ampdu->fifo_tb[i].ampdu_pld_size > FFPLD_PLD_INCR)
291 scb_ampdu->max_pdu = AMPDU_NUM_MPDU_LEGACY;
294 /* apply user override */
295 if (ampdu->max_pdu != AUTO)
296 scb_ampdu->max_pdu = (u8) ampdu->max_pdu;
298 scb_ampdu->release = min_t(u8, scb_ampdu->max_pdu,
299 AMPDU_SCB_MAX_RELEASE);
301 if (scb_ampdu->max_rx_ampdu_bytes)
302 scb_ampdu->release = min_t(u8, scb_ampdu->release,
303 scb_ampdu->max_rx_ampdu_bytes / 1600);
305 scb_ampdu->release = min(scb_ampdu->release,
306 ampdu->fifo_tb[TX_AC_BE_FIFO].
307 mcs2ampdu_table[FFPLD_MAX_MCS]);
310 static void brcms_c_scb_ampdu_update_config_all(struct ampdu_info *ampdu)
312 brcms_c_scb_ampdu_update_config(ampdu, &du->wlc->pri_scb);
315 static void brcms_c_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f)
318 u32 phy_rate, dma_rate, tmp;
320 struct brcms_fifo_info *fifo = (ampdu->fifo_tb + f);
322 /* recompute the dma rate */
323 /* note : we divide/multiply by 100 to avoid integer overflows */
324 max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
325 AMPDU_NUM_MPDU_LEGACY);
326 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
329 (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
330 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
331 fifo->dmaxferrate = dma_rate;
333 /* fill up the mcs2ampdu table; do not recalc the last mcs */
334 dma_rate = dma_rate >> 7;
335 for (i = 0; i < FFPLD_MAX_MCS; i++) {
336 /* shifting to keep it within integer range */
337 phy_rate = mcs_2_rate(i, true, false) >> 7;
338 if (phy_rate > dma_rate) {
339 tmp = ((fifo->ampdu_pld_size * phy_rate) /
340 ((phy_rate - dma_rate) * FFPLD_MPDU_SIZE)) + 1;
341 tmp = min_t(u32, tmp, 255);
342 fifo->mcs2ampdu_table[i] = (u8) tmp;
347 /* evaluate the dma transfer rate using the tx underflows as feedback.
348 * If necessary, increase tx fifo preloading. If not enough,
349 * decrease maximum ampdu size for each mcs till underflows stop
350 * Return 1 if pre-loading not active, -1 if not an underflow event,
351 * 0 if pre-loading module took care of the event.
353 static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid)
355 struct ampdu_info *ampdu = wlc->ampdu;
356 u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false);
359 u32 current_ampdu_cnt = 0;
362 struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid);
366 /* return if we got here for a different reason than underflows */
367 cur_txunfl = brcms_b_read_shm(wlc->hw,
369 offsetof(struct macstat, txfunfl[fid]));
370 new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl);
371 if (new_txunfl == 0) {
372 BCMMSG(wlc->wiphy, "TX status FRAG set but no tx underflows\n");
375 fifo->prev_txfunfl = cur_txunfl;
377 if (!ampdu->tx_max_funl)
380 /* check if fifo is big enough */
381 if (brcms_b_xmtfifo_sz_get(wlc->hw, fid, &xmtfifo_sz))
384 if ((TXFIFO_SIZE_UNIT * (u32) xmtfifo_sz) <= ampdu->ffpld_rsvd)
387 max_pld_size = TXFIFO_SIZE_UNIT * xmtfifo_sz - ampdu->ffpld_rsvd;
388 fifo->accum_txfunfl += new_txunfl;
390 /* we need to wait for at least 10 underflows */
391 if (fifo->accum_txfunfl < 10)
394 BCMMSG(wlc->wiphy, "ampdu_count %d tx_underflows %d\n",
395 current_ampdu_cnt, fifo->accum_txfunfl);
398 compute the current ratio of tx unfl per ampdu.
399 When the current ampdu count becomes too
400 big while the ratio remains small, we reset
401 the current count in order to not
402 introduce too big of a latency in detecting a
403 large amount of tx underflows later.
406 txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl;
408 if (txunfl_ratio > ampdu->tx_max_funl) {
409 if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT)
410 fifo->accum_txfunfl = 0;
414 max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS],
415 AMPDU_NUM_MPDU_LEGACY);
417 /* In case max value max_pdu is already lower than
418 the fifo depth, there is nothing more we can do.
421 if (fifo->ampdu_pld_size >= max_mpdu * FFPLD_MPDU_SIZE) {
422 fifo->accum_txfunfl = 0;
426 if (fifo->ampdu_pld_size < max_pld_size) {
428 /* increment by TX_FIFO_PLD_INC bytes */
429 fifo->ampdu_pld_size += FFPLD_PLD_INCR;
430 if (fifo->ampdu_pld_size > max_pld_size)
431 fifo->ampdu_pld_size = max_pld_size;
433 /* update scb release size */
434 brcms_c_scb_ampdu_update_config_all(ampdu);
437 * compute a new dma xfer rate for max_mpdu @ max mcs.
438 * This is the minimum dma rate that can achieve no
439 * underflow condition for the current mpdu size.
441 * note : we divide/multiply by 100 to avoid integer overflows
445 (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size))
446 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
448 BCMMSG(wlc->wiphy, "DMA estimated transfer rate %d; "
449 "pre-load size %d\n",
450 fifo->dmaxferrate, fifo->ampdu_pld_size);
453 /* decrease ampdu size */
454 if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] > 1) {
455 if (fifo->mcs2ampdu_table[FFPLD_MAX_MCS] == 255)
456 fifo->mcs2ampdu_table[FFPLD_MAX_MCS] =
457 AMPDU_NUM_MPDU_LEGACY - 1;
459 fifo->mcs2ampdu_table[FFPLD_MAX_MCS] -= 1;
461 /* recompute the table */
462 brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
464 /* update scb release size */
465 brcms_c_scb_ampdu_update_config_all(ampdu);
468 fifo->accum_txfunfl = 0;
473 brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid,
474 u8 ba_wsize, /* negotiated ba window size (in pdu) */
475 uint max_rx_ampdu_bytes) /* from ht_cap in beacon */
477 struct scb_ampdu *scb_ampdu;
478 struct scb_ampdu_tid_ini *ini;
479 struct ampdu_info *ampdu = wlc->ampdu;
480 struct scb *scb = &wlc->pri_scb;
481 scb_ampdu = &scb->scb_ampdu;
483 if (!ampdu->ini_enable[tid]) {
484 wiphy_err(ampdu->wlc->wiphy, "%s: Rejecting tid %d\n",
489 ini = &scb_ampdu->ini[tid];
491 ini->scb = scb_ampdu->scb;
492 ini->ba_wsize = ba_wsize;
493 scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes;
496 void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session,
497 struct brcms_c_info *wlc)
500 skb_queue_head_init(&session->skb_list);
501 session->max_ampdu_len = 0; /* determined from first MPDU */
502 session->max_ampdu_frames = 0; /* determined from first MPDU */
503 session->ampdu_len = 0;
504 session->dma_len = 0;
508 * Preps the given packet for AMPDU based on the session data. If the
509 * frame cannot be accomodated in the current session, -ENOSPC is
512 int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session,
515 struct brcms_c_info *wlc = session->wlc;
516 struct ampdu_info *ampdu = wlc->ampdu;
517 struct scb *scb = &wlc->pri_scb;
518 struct scb_ampdu *scb_ampdu = &scb->scb_ampdu;
519 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
520 struct ieee80211_tx_rate *txrate = tx_info->status.rates;
521 struct d11txh *txh = (struct d11txh *)p->data;
522 unsigned ampdu_frames;
530 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
531 plcp = (u8 *)(txh + 1);
532 fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03);
533 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) :
534 BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
535 len = roundup(len, 4) + (ndelim + 1) * AMPDU_DELIMITER_LEN;
537 ampdu_frames = skb_queue_len(&session->skb_list);
538 if (ampdu_frames != 0) {
539 struct sk_buff *first;
541 if (ampdu_frames + 1 > session->max_ampdu_frames ||
542 session->ampdu_len + len > session->max_ampdu_len)
546 * We aren't really out of space if the new frame is of
547 * a different priority, but we want the same behaviour
548 * so return -ENOSPC anyway.
550 * XXX: The old AMPDU code did this, but is it really
553 first = skb_peek(&session->skb_list);
554 if (p->priority != first->priority)
559 * Now that we're sure this frame can be accomodated, update the
560 * session information.
562 session->ampdu_len += len;
563 session->dma_len += p->len;
565 tid = (u8)p->priority;
567 /* Handle retry limits */
568 if (txrate[0].count <= ampdu->rr_retry_limit_tid[tid]) {
576 if (ampdu_frames == 0) {
577 u8 plcp0, plcp3, is40, sgi, mcs;
578 uint fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
579 struct brcms_fifo_info *f = &du->fifo_tb[fifo];
585 plcp0 = txh->FragPLCPFallback[0];
586 plcp3 = txh->FragPLCPFallback[3];
590 /* Limit AMPDU size based on MCS */
591 is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
592 sgi = plcp3_issgi(plcp3) ? 1 : 0;
593 mcs = plcp0 & ~MIMO_PLCP_40MHZ;
594 session->max_ampdu_len = min(scb_ampdu->max_rx_ampdu_bytes,
595 ampdu->max_txlen[mcs][is40][sgi]);
597 session->max_ampdu_frames = scb_ampdu->max_pdu;
598 if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
599 session->max_ampdu_frames =
600 min_t(u16, f->mcs2ampdu_table[mcs],
601 session->max_ampdu_frames);
606 * Treat all frames as "middle" frames of AMPDU here. First and
607 * last frames must be fixed up after all MPDUs have been prepped.
609 mcl = le16_to_cpu(txh->MacTxControlLow);
610 mcl &= ~TXC_AMPDU_MASK;
611 mcl |= (TXC_AMPDU_MIDDLE << TXC_AMPDU_SHIFT);
612 mcl &= ~(TXC_STARTMSDU | TXC_SENDRTS | TXC_SENDCTS);
613 txh->MacTxControlLow = cpu_to_le16(mcl);
614 txh->PreloadSize = 0; /* always default to 0 */
616 skb_queue_tail(&session->skb_list, p);
621 void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session)
623 struct brcms_c_info *wlc = session->wlc;
624 struct ampdu_info *ampdu = wlc->ampdu;
625 struct sk_buff *first, *last;
627 struct ieee80211_tx_info *tx_info;
628 struct ieee80211_tx_rate *txrate;
633 struct brcms_fifo_info *f;
637 struct ieee80211_rts *rts;
638 bool use_rts = false, use_cts = false;
639 u16 dma_len = session->dma_len;
640 u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
641 u32 rspec = 0, rspec_fallback = 0;
642 u32 rts_rspec = 0, rts_rspec_fallback = 0;
643 u8 plcp0, plcp3, is40, sgi, mcs;
645 u8 preamble_type = BRCMS_GF_PREAMBLE;
646 u8 fbr_preamble_type = BRCMS_GF_PREAMBLE;
647 u8 rts_preamble_type = BRCMS_LONG_PREAMBLE;
648 u8 rts_fbr_preamble_type = BRCMS_LONG_PREAMBLE;
650 if (skb_queue_empty(&session->skb_list))
653 first = skb_peek(&session->skb_list);
654 last = skb_peek_tail(&session->skb_list);
656 /* Need to fix up last MPDU first to adjust AMPDU length */
657 txh = (struct d11txh *)last->data;
658 fifo = le16_to_cpu(txh->TxFrameID) & TXFID_QUEUE_MASK;
659 f = &du->fifo_tb[fifo];
661 mcl = le16_to_cpu(txh->MacTxControlLow);
662 mcl &= ~TXC_AMPDU_MASK;
663 mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT);
664 txh->MacTxControlLow = cpu_to_le16(mcl);
666 /* remove the null delimiter after last mpdu */
667 ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM];
668 txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM] = 0;
669 session->ampdu_len -= ndelim * AMPDU_DELIMITER_LEN;
671 /* remove the pad len from last mpdu */
672 fbr_iscck = ((le16_to_cpu(txh->XtraFrameTypes) & 0x3) == 0);
673 len = fbr_iscck ? BRCMS_GET_CCK_PLCP_LEN(txh->FragPLCPFallback) :
674 BRCMS_GET_MIMO_PLCP_LEN(txh->FragPLCPFallback);
675 session->ampdu_len -= roundup(len, 4) - len;
677 /* Now fix up the first MPDU */
678 tx_info = IEEE80211_SKB_CB(first);
679 txrate = tx_info->status.rates;
680 txh = (struct d11txh *)first->data;
681 plcp = (u8 *)(txh + 1);
682 rts = (struct ieee80211_rts *)&txh->rts_frame;
684 mcl = le16_to_cpu(txh->MacTxControlLow);
685 /* If only one MPDU leave it marked as last */
687 mcl &= ~TXC_AMPDU_MASK;
688 mcl |= (TXC_AMPDU_FIRST << TXC_AMPDU_SHIFT);
690 mcl |= TXC_STARTMSDU;
691 if (ieee80211_is_rts(rts->frame_control)) {
695 if (ieee80211_is_cts(rts->frame_control)) {
699 txh->MacTxControlLow = cpu_to_le16(mcl);
701 fbr = txrate[1].count > 0;
706 plcp0 = txh->FragPLCPFallback[0];
707 plcp3 = txh->FragPLCPFallback[3];
709 is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0;
710 sgi = plcp3_issgi(plcp3) ? 1 : 0;
711 mcs = plcp0 & ~MIMO_PLCP_40MHZ;
714 if (CHSPEC_SB_UPPER(wlc_phy_chanspec_get(wlc->band->pi)))
715 mimo_ctlchbw = PHY_TXC1_BW_20MHZ_UP;
717 mimo_ctlchbw = PHY_TXC1_BW_20MHZ;
720 /* rebuild the rspec and rspec_fallback */
721 rspec = RSPEC_MIMORATE;
722 rspec |= plcp[0] & ~MIMO_PLCP_40MHZ;
723 if (plcp[0] & MIMO_PLCP_40MHZ)
724 rspec |= (PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT);
726 fbr_iscck = !(le16_to_cpu(txh->XtraFrameTypes) & 0x03);
729 cck_rspec(cck_phy2mac_rate(txh->FragPLCPFallback[0]));
731 rspec_fallback = RSPEC_MIMORATE;
732 rspec_fallback |= txh->FragPLCPFallback[0] & ~MIMO_PLCP_40MHZ;
733 if (txh->FragPLCPFallback[0] & MIMO_PLCP_40MHZ)
734 rspec_fallback |= PHY_TXC1_BW_40MHZ << RSPEC_BW_SHIFT;
737 if (use_rts || use_cts) {
739 brcms_c_rspec_to_rts_rspec(wlc, rspec,
740 false, mimo_ctlchbw);
742 brcms_c_rspec_to_rts_rspec(wlc, rspec_fallback,
743 false, mimo_ctlchbw);
746 BRCMS_SET_MIMO_PLCP_LEN(plcp, session->ampdu_len);
747 /* mark plcp to indicate ampdu */
748 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
750 /* reset the mixed mode header durations */
752 u16 mmodelen = brcms_c_calc_lsig_len(wlc, rspec,
754 txh->MModeLen = cpu_to_le16(mmodelen);
755 preamble_type = BRCMS_MM_PREAMBLE;
757 if (txh->MModeFbrLen) {
758 u16 mmfbrlen = brcms_c_calc_lsig_len(wlc, rspec_fallback,
760 txh->MModeFbrLen = cpu_to_le16(mmfbrlen);
761 fbr_preamble_type = BRCMS_MM_PREAMBLE;
764 /* set the preload length */
765 if (mcs_2_rate(mcs, true, false) >= f->dmaxferrate) {
766 dma_len = min(dma_len, f->ampdu_pld_size);
767 txh->PreloadSize = cpu_to_le16(dma_len);
769 txh->PreloadSize = 0;
772 mch = le16_to_cpu(txh->MacTxControlHigh);
774 /* update RTS dur fields */
775 if (use_rts || use_cts) {
777 if ((mch & TXC_PREAMBLE_RTS_MAIN_SHORT) ==
778 TXC_PREAMBLE_RTS_MAIN_SHORT)
779 rts_preamble_type = BRCMS_SHORT_PREAMBLE;
781 if ((mch & TXC_PREAMBLE_RTS_FB_SHORT) ==
782 TXC_PREAMBLE_RTS_FB_SHORT)
783 rts_fbr_preamble_type = BRCMS_SHORT_PREAMBLE;
785 durid = brcms_c_compute_rtscts_dur(wlc, use_cts, rts_rspec,
786 rspec, rts_preamble_type,
788 session->ampdu_len, true);
789 rts->duration = cpu_to_le16(durid);
790 durid = brcms_c_compute_rtscts_dur(wlc, use_cts,
793 rts_fbr_preamble_type,
795 session->ampdu_len, true);
796 txh->RTSDurFallback = cpu_to_le16(durid);
797 /* set TxFesTimeNormal */
798 txh->TxFesTimeNormal = rts->duration;
799 /* set fallback rate version of TxFesTimeNormal */
800 txh->TxFesTimeFallback = txh->RTSDurFallback;
803 /* set flag and plcp for fallback rate */
805 mch |= TXC_AMPDU_FBR;
806 txh->MacTxControlHigh = cpu_to_le16(mch);
807 BRCMS_SET_MIMO_PLCP_AMPDU(plcp);
808 BRCMS_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback);
811 BCMMSG(wlc->wiphy, "wl%d: count %d ampdu_len %d\n",
812 wlc->pub->unit, skb_queue_len(&session->skb_list),
817 brcms_c_sendampdu(struct ampdu_info *ampdu, struct brcms_txq_info *qi,
818 struct sk_buff **pdu, int prec)
820 struct brcms_c_info *wlc;
822 struct brcms_ampdu_session session;
826 uint count, fifo, seg_cnt = 0;
828 struct scb_ampdu *scb_ampdu;
829 struct scb_ampdu_tid_ini *ini;
830 struct ieee80211_tx_info *tx_info;
838 tid = (u8) (p->priority);
841 scb_ampdu = &scb->scb_ampdu;
842 ini = &scb_ampdu->ini[tid];
844 /* Let pressure continue to build ... */
845 qlen = pktq_plen(&qi->q, prec);
846 if (ini->tx_in_transit > 0 &&
847 qlen < min(scb_ampdu->max_pdu, ini->ba_wsize))
848 /* Collect multiple MPDU's to be sent in the next AMPDU */
851 /* at this point we intend to transmit an AMPDU */
852 brcms_c_ampdu_reset_session(&session, wlc);
855 struct ieee80211_tx_rate *txrate;
857 tx_info = IEEE80211_SKB_CB(p);
858 txrate = tx_info->status.rates;
860 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
861 err = brcms_c_prep_pdu(wlc, p, &fifo);
863 wiphy_err(wiphy, "%s: AMPDU flag is off!\n", __func__);
871 wiphy_err(wiphy, "wl%d: sendampdu: "
872 "prep_xdu retry\n", wlc->pub->unit);
877 /* error in the packet; reject it */
878 wiphy_err(wiphy, "wl%d: sendampdu: prep_xdu "
879 "rejected\n", wlc->pub->unit);
884 err = brcms_c_ampdu_add_frame(&session, p);
885 if (err == -ENOSPC) {
887 * No space for this packet in the AMPDU.
888 * Requeue packet and proceed;
893 /* Unexpected error; reject packet */
894 wiphy_err(wiphy, "wl%d: sendampdu: add_frame rejected",
903 * check to see if the next pkt is
904 * a candidate for aggregation
906 p = pktq_ppeek(&qi->q, prec);
908 tx_info = IEEE80211_SKB_CB(p);
909 if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) {
911 * check if there are enough
912 * descriptors available
914 if (*wlc->core->txavail[fifo] <= seg_cnt + 1) {
915 wiphy_err(wiphy, "%s: No fifo space "
920 /* next packet fit for aggregation so dequeue */
921 p = brcmu_pktq_pdeq(&qi->q, prec);
928 count = skb_queue_len(&session.skb_list);
929 ini->tx_in_transit += count;
932 /* patch up first and last txh's */
933 brcms_c_ampdu_finalize(&session);
935 while ((p = skb_dequeue(&session.skb_list)) != NULL)
936 brcms_c_txfifo(wlc, fifo, p,
937 skb_queue_empty(&session.skb_list));
944 brcms_c_ampdu_rate_status(struct brcms_c_info *wlc,
945 struct ieee80211_tx_info *tx_info,
946 struct tx_status *txs, u8 mcs)
948 struct ieee80211_tx_rate *txrate = tx_info->status.rates;
951 /* clear the rest of the rates */
952 for (i = 2; i < IEEE80211_TX_MAX_RATES; i++) {
959 brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb,
960 struct sk_buff *p, struct tx_status *txs,
963 struct scb_ampdu *scb_ampdu;
964 struct brcms_c_info *wlc = ampdu->wlc;
965 struct scb_ampdu_tid_ini *ini;
966 u8 bitmap[8], queue, tid;
969 struct ieee80211_hdr *h;
970 u16 seq, start_seq = 0, bindex, index, mcl;
972 bool ba_recd = false, ack_recd = false;
973 u8 suc_mpdu = 0, tot_mpdu = 0;
975 bool update_rate = true, retry = true, tx_error = false;
978 u8 retry_limit, rr_retry_limit;
979 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p);
980 struct wiphy *wiphy = wlc->wiphy;
983 u8 hole[AMPDU_MAX_MPDU];
984 memset(hole, 0, sizeof(hole));
987 scb_ampdu = &scb->scb_ampdu;
988 tid = (u8) (p->priority);
990 ini = &scb_ampdu->ini[tid];
991 retry_limit = ampdu->retry_limit_tid[tid];
992 rr_retry_limit = ampdu->rr_retry_limit_tid[tid];
993 memset(bitmap, 0, sizeof(bitmap));
994 queue = txs->frameid & TXFID_QUEUE_MASK;
995 supr_status = txs->status & TX_STATUS_SUPR_MASK;
997 if (txs->status & TX_STATUS_ACK_RCV) {
998 if (TX_STATUS_SUPR_UF == supr_status)
1001 WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE));
1002 start_seq = txs->sequence >> SEQNUM_SHIFT;
1003 bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >>
1004 TX_STATUS_BA_BMAP03_SHIFT;
1006 WARN_ON(s1 & TX_STATUS_INTERMEDIATE);
1007 WARN_ON(!(s1 & TX_STATUS_AMPDU));
1010 (s1 & TX_STATUS_BA_BMAP47_MASK) <<
1011 TX_STATUS_BA_BMAP47_SHIFT;
1012 bitmap[1] = (s1 >> 8) & 0xff;
1013 bitmap[2] = (s1 >> 16) & 0xff;
1014 bitmap[3] = (s1 >> 24) & 0xff;
1016 bitmap[4] = s2 & 0xff;
1017 bitmap[5] = (s2 >> 8) & 0xff;
1018 bitmap[6] = (s2 >> 16) & 0xff;
1019 bitmap[7] = (s2 >> 24) & 0xff;
1024 update_rate = false;
1025 if (supr_status == TX_STATUS_SUPR_BADCH) {
1027 "%s: Pkt tx suppressed, illegal channel possibly %d\n",
1028 __func__, CHSPEC_CHANNEL(
1029 wlc->default_bss->chanspec));
1031 if (supr_status != TX_STATUS_SUPR_FRAG)
1032 wiphy_err(wiphy, "%s: supr_status 0x%x\n",
1033 __func__, supr_status);
1035 /* no need to retry for badch; will fail again */
1036 if (supr_status == TX_STATUS_SUPR_BADCH ||
1037 supr_status == TX_STATUS_SUPR_EXPTIME) {
1039 } else if (supr_status == TX_STATUS_SUPR_EXPTIME) {
1041 * try tuning pre-loading or ampdu size
1043 } else if (supr_status == TX_STATUS_SUPR_FRAG) {
1045 * if there were underflows, but pre-loading
1046 * is not active, notify rate adaptation.
1048 if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0)
1051 } else if (txs->phyerr) {
1052 update_rate = false;
1053 wiphy_err(wiphy, "%s: ampdu tx phy error (0x%x)\n",
1054 __func__, txs->phyerr);
1056 if (brcm_msg_level & LOG_ERROR_VAL) {
1057 brcmu_prpkt("txpkt (AMPDU)", p);
1058 brcms_c_print_txdesc((struct d11txh *) p->data);
1060 brcms_c_print_txstatus(txs);
1064 /* loop through all pkts and retry if not acked */
1066 tx_info = IEEE80211_SKB_CB(p);
1067 txh = (struct d11txh *) p->data;
1068 mcl = le16_to_cpu(txh->MacTxControlLow);
1069 plcp = (u8 *) (txh + 1);
1070 h = (struct ieee80211_hdr *)(plcp + D11_PHY_HDR_LEN);
1071 seq = le16_to_cpu(h->seq_ctrl) >> SEQNUM_SHIFT;
1073 if (tot_mpdu == 0) {
1074 mcs = plcp[0] & MIMO_PLCP_MCS_MASK;
1075 mimoantsel = le16_to_cpu(txh->ABI_MimoAntSel);
1078 index = TX_SEQ_TO_INDEX(seq);
1081 bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX);
1083 "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
1084 tid, seq, start_seq, bindex,
1085 isset(bitmap, bindex), index);
1086 /* if acked then clear bit and free packet */
1087 if ((bindex < AMPDU_TX_BA_MAX_WSIZE)
1088 && isset(bitmap, bindex)) {
1089 ini->tx_in_transit--;
1090 ini->txretry[index] = 0;
1094 * number of acked aggregated frames
1096 /* ampdu_len: number of aggregated frames */
1097 brcms_c_ampdu_rate_status(wlc, tx_info, txs,
1099 tx_info->flags |= IEEE80211_TX_STAT_ACK;
1100 tx_info->flags |= IEEE80211_TX_STAT_AMPDU;
1101 tx_info->status.ampdu_ack_len =
1102 tx_info->status.ampdu_len = 1;
1104 skb_pull(p, D11_PHY_HDR_LEN);
1105 skb_pull(p, D11_TXH_LEN);
1107 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1113 /* either retransmit or send bar if ack not recd */
1115 if (retry && (ini->txretry[index] < (int)retry_limit)) {
1116 ini->txretry[index]++;
1117 ini->tx_in_transit--;
1118 brcms_c_txq_enq(wlc, scb, p);
1121 ini->tx_in_transit--;
1122 ieee80211_tx_info_clear_status(tx_info);
1123 tx_info->status.ampdu_ack_len = 0;
1124 tx_info->status.ampdu_len = 1;
1126 IEEE80211_TX_STAT_AMPDU_NO_BACK;
1127 skb_pull(p, D11_PHY_HDR_LEN);
1128 skb_pull(p, D11_TXH_LEN);
1130 "BA Timeout, seq %d, in_transit %d\n",
1131 seq, ini->tx_in_transit);
1132 ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw,
1138 /* break out if last packet of ampdu */
1139 if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1143 p = dma_getnexttxp(wlc->hw->di[queue], DMA_RANGE_TRANSMITTED);
1145 brcms_c_send_q(wlc);
1147 /* update rate state */
1148 antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel);
1150 brcms_c_txfifo_complete(wlc, queue);
1154 brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb,
1155 struct sk_buff *p, struct tx_status *txs)
1157 struct scb_ampdu *scb_ampdu;
1158 struct brcms_c_info *wlc = ampdu->wlc;
1159 struct scb_ampdu_tid_ini *ini;
1161 struct ieee80211_tx_info *tx_info;
1163 tx_info = IEEE80211_SKB_CB(p);
1165 /* BMAC_NOTE: For the split driver, second level txstatus comes later
1166 * So if the ACK was received then wait for the second level else just
1167 * call the first one
1169 if (txs->status & TX_STATUS_ACK_RCV) {
1170 u8 status_delay = 0;
1172 /* wait till the next 8 bytes of txstatus is available */
1173 s1 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus));
1174 while ((s1 & TXS_V) == 0) {
1177 if (status_delay > 10)
1178 return; /* error condition */
1179 s1 = bcma_read32(wlc->hw->d11core,
1180 D11REGOFFS(frmtxstatus));
1183 s2 = bcma_read32(wlc->hw->d11core, D11REGOFFS(frmtxstatus2));
1187 scb_ampdu = &scb->scb_ampdu;
1188 ini = &scb_ampdu->ini[p->priority];
1189 brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
1191 /* loop through all pkts and free */
1192 u8 queue = txs->frameid & TXFID_QUEUE_MASK;
1196 tx_info = IEEE80211_SKB_CB(p);
1197 txh = (struct d11txh *) p->data;
1198 mcl = le16_to_cpu(txh->MacTxControlLow);
1199 brcmu_pkt_buf_free_skb(p);
1200 /* break out if last packet of ampdu */
1201 if (((mcl & TXC_AMPDU_MASK) >> TXC_AMPDU_SHIFT) ==
1204 p = dma_getnexttxp(wlc->hw->di[queue],
1205 DMA_RANGE_TRANSMITTED);
1207 brcms_c_txfifo_complete(wlc, queue);
1211 void brcms_c_ampdu_macaddr_upd(struct brcms_c_info *wlc)
1213 char template[T_RAM_ACCESS_SZ * 2];
1215 /* driver needs to write the ta in the template; ta is at offset 16 */
1216 memset(template, 0, sizeof(template));
1217 memcpy(template, wlc->pub->cur_etheraddr, ETH_ALEN);
1218 brcms_b_write_template_ram(wlc->hw, (T_BA_TPL_BASE + 16),
1219 (T_RAM_ACCESS_SZ * 2),
1223 bool brcms_c_aggregatable(struct brcms_c_info *wlc, u8 tid)
1225 return wlc->ampdu->ini_enable[tid];
1228 void brcms_c_ampdu_shm_upd(struct ampdu_info *ampdu)
1230 struct brcms_c_info *wlc = ampdu->wlc;
1233 * Extend ucode internal watchdog timer to
1234 * match larger received frames
1236 if ((ampdu->rx_factor & IEEE80211_HT_AMPDU_PARM_FACTOR) ==
1237 IEEE80211_HT_MAX_AMPDU_64K) {
1238 brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_MAX);
1239 brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_MAX);
1241 brcms_b_write_shm(wlc->hw, M_MIMO_MAXSYM, MIMO_MAXSYM_DEF);
1242 brcms_b_write_shm(wlc->hw, M_WATCHDOG_8TU, WATCHDOG_8TU_DEF);
1247 * callback function that helps flushing ampdu packets from a priority queue
1249 static bool cb_del_ampdu_pkt(struct sk_buff *mpdu, void *arg_a)
1251 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(mpdu);
1252 struct cb_del_ampdu_pars *ampdu_pars =
1253 (struct cb_del_ampdu_pars *)arg_a;
1256 rc = tx_info->flags & IEEE80211_TX_CTL_AMPDU ? true : false;
1257 rc = rc && (tx_info->rate_driver_data[0] == NULL || ampdu_pars->sta == NULL ||
1258 tx_info->rate_driver_data[0] == ampdu_pars->sta);
1259 rc = rc && ((u8)(mpdu->priority) == ampdu_pars->tid);
1264 * callback function that helps invalidating ampdu packets in a DMA queue
1266 static void dma_cb_fn_ampdu(void *txi, void *arg_a)
1268 struct ieee80211_sta *sta = arg_a;
1269 struct ieee80211_tx_info *tx_info = (struct ieee80211_tx_info *)txi;
1271 if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) &&
1272 (tx_info->rate_driver_data[0] == sta || sta == NULL))
1273 tx_info->rate_driver_data[0] = NULL;
1277 * When a remote party is no longer available for ampdu communication, any
1278 * pending tx ampdu packets in the driver have to be flushed.
1280 void brcms_c_ampdu_flush(struct brcms_c_info *wlc,
1281 struct ieee80211_sta *sta, u16 tid)
1283 struct brcms_txq_info *qi = wlc->pkt_queue;
1284 struct pktq *pq = &qi->q;
1286 struct cb_del_ampdu_pars ampdu_pars;
1288 ampdu_pars.sta = sta;
1289 ampdu_pars.tid = tid;
1290 for (prec = 0; prec < pq->num_prec; prec++)
1291 brcmu_pktq_pflush(pq, prec, true, cb_del_ampdu_pkt,
1292 (void *)&du_pars);
1293 brcms_c_inval_dma_pkts(wlc->hw, sta, dma_cb_fn_ampdu);