26 #define AMPDU_MAX_MPDU 32
28 #define AMPDU_NUM_MPDU_LEGACY 16
30 #define AMPDU_TX_BA_MAX_WSIZE 64
32 #define AMPDU_TX_BA_DEF_WSIZE 64
34 #define AMPDU_RX_BA_DEF_WSIZE 64
36 #define AMPDU_RX_BA_MAX_WSIZE 64
38 #define AMPDU_MAX_DUR 5
40 #define AMPDU_DEF_RETRY_LIMIT 5
42 #define AMPDU_DEF_RR_RETRY_LIMIT 2
44 #define AMPDU_DEF_TXPKT_WEIGHT 2
46 #define AMPDU_DEF_FFPLD_RSVD 2048
48 #define AMPDU_INI_FREE 10
50 #define AMPDU_SCB_MAX_RELEASE 20
52 #define NUM_FFPLD_FIFO 4
53 #define FFPLD_TX_MAX_UNFL 200
56 #define FFPLD_MPDU_SIZE 1800
57 #define FFPLD_MAX_MCS 23
58 #define FFPLD_PLD_INCR 1000
59 #define FFPLD_MAX_AMPDU_CNT 5000
63 #define AMPDU_DELIMITER_LEN 4
66 #define AMPDU_NUM_MPDU 16
68 #define TX_SEQ_TO_INDEX(seq) ((seq) % AMPDU_TX_BA_MAX_WSIZE)
71 #define AMPDU_MAX_MPDU_OVERHEAD (FCS_LEN + DOT11_ICV_AES_LEN +\
72 AMPDU_DELIMITER_LEN + 3\
73 + DOT11_A4_HDR_LEN + DOT11_QOS_LEN + DOT11_IV_MAX_LEN)
76 #define MODADD_POW2(x, y, bound) (((x) + (y)) & ((bound) - 1))
77 #define MODSUB_POW2(x, y, bound) (((x) - (y)) & ((bound) - 1))
154 static void brcms_c_scb_ampdu_update_max_txlen(
struct ampdu_info *ampdu,
u8 dur)
161 rate = mcs_2_rate(mcs,
false,
false);
164 rate = mcs_2_rate(mcs,
true,
false);
167 rate = mcs_2_rate(mcs,
false,
true);
170 rate = mcs_2_rate(mcs,
true,
true);
175 static bool brcms_c_ampdu_cap(
struct ampdu_info *ampdu)
183 static int brcms_c_ampdu_set(
struct ampdu_info *ampdu,
bool on)
187 wlc->
pub->_ampdu =
false;
192 "nmode enabled\n", wlc->
pub->unit);
195 if (!brcms_c_ampdu_cap(ampdu)) {
197 "ampdu capable\n", wlc->
pub->unit);
200 wlc->
pub->_ampdu = on;
206 static void brcms_c_ffpld_init(
struct ampdu_info *ampdu)
269 brcms_c_scb_ampdu_update_max_txlen(ampdu, ampdu->
dur);
272 brcms_c_ampdu_set(ampdu, wlc->
pub->_ampdu);
275 brcms_c_ffpld_init(ampdu);
285 static void brcms_c_scb_ampdu_update_config(
struct ampdu_info *ampdu,
315 static void brcms_c_scb_ampdu_update_config_all(
struct ampdu_info *ampdu)
317 brcms_c_scb_ampdu_update_config(ampdu, &du->
wlc->pri_scb);
320 static void brcms_c_ffpld_calc_mcs2ampdu_table(
struct ampdu_info *ampdu,
int f)
323 u32 phy_rate, dma_rate,
tmp;
339 dma_rate = dma_rate >> 7;
342 phy_rate = mcs_2_rate(i,
true,
false) >> 7;
343 if (phy_rate > dma_rate) {
358 static int brcms_c_ffpld_check_txfunfl(
struct brcms_c_info *wlc,
int fid)
361 u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS,
true,
false);
364 u32 current_ampdu_cnt = 0;
376 if (new_txunfl == 0) {
377 BCMMSG(wlc->
wiphy,
"TX status FRAG set but no tx underflows\n");
399 BCMMSG(wlc->
wiphy,
"ampdu_count %d tx_underflows %d\n",
439 brcms_c_scb_ampdu_update_config_all(ampdu);
451 / (max_mpdu * FFPLD_MPDU_SIZE)) * 100;
453 BCMMSG(wlc->
wiphy,
"DMA estimated transfer rate %d; "
454 "pre-load size %d\n",
467 brcms_c_ffpld_calc_mcs2ampdu_table(ampdu, fid);
470 brcms_c_scb_ampdu_update_config_all(ampdu);
480 uint max_rx_ampdu_bytes)
482 struct scb_ampdu *scb_ampdu;
485 struct scb *scb = &wlc->
pri_scb;
494 ini = &scb_ampdu->
ini[tid];
496 ini->
scb = scb_ampdu->
scb;
514 bool rr =
true, fbr =
false;
517 u32 ampdu_len, max_ampdu_bytes = 0;
522 struct scb_ampdu *scb_ampdu;
525 bool use_rts =
false, use_cts =
false;
526 u32 rspec = 0, rspec_fallback = 0;
527 u32 rts_rspec = 0, rts_rspec_fallback = 0;
547 ini = &scb_ampdu->
ini[tid];
550 qlen = pktq_plen(&qi->
q, prec);
563 tx_info = IEEE80211_SKB_CB(p);
564 txrate = tx_info->
status.rates;
569 wiphy_err(wiphy,
"%s: AMPDU flag is off!\n", __func__);
578 "prep_xdu retry; seq 0x%x\n",
579 wlc->
pub->unit, seq);
585 wiphy_err(wiphy,
"wl%d: sendampdu: prep_xdu "
586 "rejected; seq 0x%x\n", wlc->
pub->unit, seq);
593 plcp = (
u8 *) (txh + 1);
605 if (txrate[0].count <= rr_retry_limit) {
624 wlc->
pub->unit, count, len);
655 " seg_cnt %d null delim %d\n",
656 wlc->
pub->unit, ampdu_len, seg_cnt, ndelim);
665 u8 plcp0, plcp3, is40, sgi;
676 sgi = plcp3_issgi(plcp3) ? 1 : 0;
695 rspec_fallback = cck_rspec(cck_phy2mac_rate
707 if (use_rts || use_cts) {
710 rspec,
false, mimo_ctlchbw);
713 rspec_fallback,
false, mimo_ctlchbw);
719 if ((mcs_2_rate(mcs,
true,
false) >= f->
dmaxferrate) &&
722 " ampdu at %d for mcs %d\n",
723 wlc->
pub->unit, count, mcs);
727 if (count == scb_ampdu->
max_pdu)
734 p = pktq_ppeek(&qi->
q, prec);
736 tx_info = IEEE80211_SKB_CB(p);
742 if ((plen + ampdu_len) > max_ampdu_bytes) {
751 if (*wlc->
core->txavail[fifo] <= seg_cnt + 1) {
784 ampdu_len -=
roundup(len, 4) - len;
788 plcp = (
u8 *) (txh + 1);
810 if (mcs_2_rate(mcs,
true,
false) >= f->
dmaxferrate) {
819 if (use_rts || use_cts) {
832 rspec, rts_preamble_type,
833 preamble_type, ampdu_len,
839 rts_fbr_preamble_type,
857 BCMMSG(wlc->
wiphy,
"wl%d: count %d ampdu_len %d\n",
858 wlc->
pub->unit, count, ampdu_len);
863 wiphy_err(wiphy,
"%s: XXX what to do with "
864 "TXFID_RATE_PROBE_MASK!?\n", __func__);
866 for (i = 0; i <
count; i++)
891 brcms_c_ampdu_dotxstatus_complete(
struct ampdu_info *ampdu,
struct scb *scb,
895 struct scb_ampdu *scb_ampdu;
902 u16 seq, start_seq = 0, bindex,
index, mcl;
904 bool ba_recd =
false, ack_recd =
false;
905 u8 suc_mpdu = 0, tot_mpdu = 0;
907 bool update_rate =
true,
retry =
true, tx_error =
false;
910 u8 retry_limit, rr_retry_limit;
912 struct wiphy *wiphy = wlc->
wiphy;
916 memset(hole, 0,
sizeof(hole));
922 ini = &scb_ampdu->
ini[tid];
925 memset(bitmap, 0,
sizeof(bitmap));
944 bitmap[1] = (s1 >> 8) & 0xff;
945 bitmap[2] = (s1 >> 16) & 0xff;
946 bitmap[3] = (s1 >> 24) & 0xff;
948 bitmap[4] = s2 & 0xff;
949 bitmap[5] = (s2 >> 8) & 0xff;
950 bitmap[6] = (s2 >> 16) & 0xff;
951 bitmap[7] = (s2 >> 24) & 0xff;
959 "%s: Pkt tx suppressed, illegal channel possibly %d\n",
964 wiphy_err(wiphy,
"%s: supr_status 0x%x\n",
965 __func__, supr_status);
980 if (brcms_c_ffpld_check_txfunfl(wlc,
986 wiphy_err(wiphy,
"%s: ampdu tx phy error (0x%x)\n",
991 brcms_c_print_txdesc((
struct d11txh *) p->
data);
999 tx_info = IEEE80211_SKB_CB(p);
1002 plcp = (
u8 *) (txh + 1);
1006 if (tot_mpdu == 0) {
1016 "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n",
1017 tid, seq, start_seq, bindex,
1018 isset(bitmap, bindex), index);
1021 &&
isset(bitmap, bindex)) {
1030 brcms_c_ampdu_rate_status(wlc, tx_info, txs,
1034 tx_info->
status.ampdu_ack_len =
1035 tx_info->
status.ampdu_len = 1;
1048 if (
retry && (ini->
txretry[index] < (
int)retry_limit)) {
1060 ieee80211_tx_info_clear_status(tx_info);
1061 tx_info->
status.ampdu_ack_len = 0;
1062 tx_info->
status.ampdu_len = 1;
1068 "BA Timeout, seq %d, in_transit %d\n",
1095 struct scb_ampdu *scb_ampdu;
1101 tx_info = IEEE80211_SKB_CB(p);
1108 u8 status_delay = 0;
1111 s1 = bcma_read32(wlc->
hw->d11core,
D11REGOFFS(frmtxstatus));
1112 while ((s1 &
TXS_V) == 0) {
1115 if (status_delay > 10)
1117 s1 = bcma_read32(wlc->
hw->d11core,
1121 s2 = bcma_read32(wlc->
hw->d11core,
D11REGOFFS(frmtxstatus2));
1127 brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2);
1134 tx_info = IEEE80211_SKB_CB(p);
1154 memset(
template, 0,
sizeof(
template));
1163 return wlc->
ampdu->ini_enable[tid];
1187 static bool cb_del_ampdu_pkt(
struct sk_buff *mpdu,
void *arg_a)
1204 static void dma_cb_fn_ampdu(
void *txi,
void *arg_a)
1222 struct pktq *pq = &qi->
q;
1226 ampdu_pars.
sta = sta;
1227 ampdu_pars.
tid = tid;
1228 for (prec = 0; prec < pq->
num_prec; prec++)
1230 (
void *)&du_pars);