diff options
Diffstat (limited to 'drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c')
| -rw-r--r-- | drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c | 89 |
1 files changed, 21 insertions, 68 deletions
diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c index fa391e4eb098..e1d707a7c964 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/ampdu.c @@ -143,12 +143,6 @@ struct ampdu_info { struct brcms_fifo_info fifo_tb[NUM_FFPLD_FIFO]; }; -/* used for flushing ampdu packets */ -struct cb_del_ampdu_pars { - struct ieee80211_sta *sta; - u16 tid; -}; - static void brcms_c_scb_ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) { u32 rate, mcs; @@ -225,7 +219,7 @@ struct ampdu_info *brcms_c_ampdu_attach(struct brcms_c_info *wlc) struct ampdu_info *ampdu; int i; - ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); + ampdu = kzalloc(sizeof(*ampdu), GFP_ATOMIC); if (!ampdu) return NULL; @@ -357,9 +351,7 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) { struct ampdu_info *ampdu = wlc->ampdu; u32 phy_rate = mcs_2_rate(FFPLD_MAX_MCS, true, false); - u32 txunfl_ratio; u8 max_mpdu; - u32 current_ampdu_cnt = 0; u16 max_pld_size; u32 new_txunfl; struct brcms_fifo_info *fifo = (ampdu->fifo_tb + fid); @@ -395,26 +387,8 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) if (fifo->accum_txfunfl < 10) return 0; - brcms_dbg_ht(wlc->hw->d11core, "ampdu_count %d tx_underflows %d\n", - current_ampdu_cnt, fifo->accum_txfunfl); - - /* - compute the current ratio of tx unfl per ampdu. - When the current ampdu count becomes too - big while the ratio remains small, we reset - the current count in order to not - introduce too big of a latency in detecting a - large amount of tx underflows later. - */ - - txunfl_ratio = current_ampdu_cnt / fifo->accum_txfunfl; + brcms_dbg_ht(wlc->hw->d11core, "tx_underflows %d\n", fifo->accum_txfunfl); - if (txunfl_ratio > ampdu->tx_max_funl) { - if (current_ampdu_cnt >= FFPLD_MAX_AMPDU_CNT) - fifo->accum_txfunfl = 0; - - return 0; - } max_mpdu = min_t(u8, fifo->mcs2ampdu_table[FFPLD_MAX_MCS], AMPDU_NUM_MPDU_LEGACY); @@ -476,11 +450,9 @@ static int brcms_c_ffpld_check_txfunfl(struct brcms_c_info *wlc, int fid) void brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, - u8 ba_wsize, /* negotiated ba window size (in pdu) */ uint max_rx_ampdu_bytes) /* from ht_cap in beacon */ { struct scb_ampdu *scb_ampdu; - struct scb_ampdu_tid_ini *ini; struct ampdu_info *ampdu = wlc->ampdu; struct scb *scb = &wlc->pri_scb; scb_ampdu = &scb->scb_ampdu; @@ -491,10 +463,6 @@ brcms_c_ampdu_tx_operational(struct brcms_c_info *wlc, u8 tid, return; } - ini = &scb_ampdu->ini[tid]; - ini->tid = tid; - ini->scb = scb_ampdu->scb; - ini->ba_wsize = ba_wsize; scb_ampdu->max_rx_ampdu_bytes = max_rx_ampdu_bytes; } @@ -511,7 +479,7 @@ void brcms_c_ampdu_reset_session(struct brcms_ampdu_session *session, /* * Preps the given packet for AMPDU based on the session data. If the - * frame cannot be accomodated in the current session, -ENOSPC is + * frame cannot be accommodated in the current session, -ENOSPC is * returned. */ int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, @@ -561,7 +529,7 @@ int brcms_c_ampdu_add_frame(struct brcms_ampdu_session *session, } /* - * Now that we're sure this frame can be accomodated, update the + * Now that we're sure this frame can be accommodated, update the * session information. */ session->ampdu_len += len; @@ -645,7 +613,7 @@ void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session) u16 mimo_ctlchbw = PHY_TXC1_BW_20MHZ; u32 rspec = 0, rspec_fallback = 0; u32 rts_rspec = 0, rts_rspec_fallback = 0; - u8 plcp0, plcp3, is40, sgi, mcs; + u8 plcp0, is40, mcs; u16 mch; u8 preamble_type = BRCMS_GF_PREAMBLE; u8 fbr_preamble_type = BRCMS_GF_PREAMBLE; @@ -704,15 +672,12 @@ void brcms_c_ampdu_finalize(struct brcms_ampdu_session *session) txh->MacTxControlLow = cpu_to_le16(mcl); fbr = txrate[1].count > 0; - if (!fbr) { + if (!fbr) plcp0 = plcp[0]; - plcp3 = plcp[3]; - } else { + else plcp0 = txh->FragPLCPFallback[0]; - plcp3 = txh->FragPLCPFallback[3]; - } + is40 = (plcp0 & MIMO_PLCP_40MHZ) ? 1 : 0; - sgi = plcp3_issgi(plcp3) ? 1 : 0; mcs = plcp0 & ~MIMO_PLCP_40MHZ; if (is40) { @@ -848,12 +813,11 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, u16 seq, start_seq = 0, bindex, index, mcl; u8 mcs = 0; bool ba_recd = false, ack_recd = false; - u8 suc_mpdu = 0, tot_mpdu = 0; + u8 tot_mpdu = 0; uint supr_status; - bool update_rate = true, retry = true, tx_error = false; + bool retry = true; u16 mimoantsel = 0; - u8 antselid = 0; - u8 retry_limit, rr_retry_limit; + u8 retry_limit; struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(p); #ifdef DEBUG @@ -866,15 +830,11 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ini = &scb_ampdu->ini[tid]; retry_limit = ampdu->retry_limit_tid[tid]; - rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; memset(bitmap, 0, sizeof(bitmap)); queue = txs->frameid & TXFID_QUEUE_MASK; supr_status = txs->status & TX_STATUS_SUPR_MASK; if (txs->status & TX_STATUS_ACK_RCV) { - if (TX_STATUS_SUPR_UF == supr_status) - update_rate = false; - WARN_ON(!(txs->status & TX_STATUS_INTERMEDIATE)); start_seq = txs->sequence >> SEQNUM_SHIFT; bitmap[0] = (txs->status & TX_STATUS_BA_BMAP03_MASK) >> @@ -898,7 +858,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ba_recd = true; } else { if (supr_status) { - update_rate = false; if (supr_status == TX_STATUS_SUPR_BADCH) { brcms_dbg_ht(wlc->hw->d11core, "%s: Pkt tx suppressed, illegal channel possibly %d\n", @@ -923,11 +882,9 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, * if there were underflows, but pre-loading * is not active, notify rate adaptation. */ - if (brcms_c_ffpld_check_txfunfl(wlc, queue) > 0) - tx_error = true; + brcms_c_ffpld_check_txfunfl(wlc, queue); } } else if (txs->phyerr) { - update_rate = false; brcms_dbg_ht(wlc->hw->d11core, "%s: ampdu tx phy error (0x%x)\n", __func__, txs->phyerr); @@ -953,14 +910,19 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, index = TX_SEQ_TO_INDEX(seq); ack_recd = false; if (ba_recd) { + int block_acked; + bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); + if (bindex < AMPDU_TX_BA_MAX_WSIZE) + block_acked = isset(bitmap, bindex); + else + block_acked = 0; brcms_dbg_ht(wlc->hw->d11core, "tid %d seq %d, start_seq %d, bindex %d set %d, index %d\n", tid, seq, start_seq, bindex, - isset(bitmap, bindex), index); + block_acked, index); /* if acked then clear bit and free packet */ - if ((bindex < AMPDU_TX_BA_MAX_WSIZE) - && isset(bitmap, bindex)) { + if (block_acked) { ini->txretry[index] = 0; /* @@ -981,7 +943,6 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); ack_recd = true; - suc_mpdu++; } } /* either retransmit or send bar if ack not recd */ @@ -1023,20 +984,15 @@ brcms_c_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, } /* update rate state */ - antselid = brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); + brcms_c_antsel_antsel2id(wlc->asi, mimoantsel); } void brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, struct tx_status *txs) { - struct scb_ampdu *scb_ampdu; struct brcms_c_info *wlc = ampdu->wlc; - struct scb_ampdu_tid_ini *ini; u32 s1 = 0, s2 = 0; - struct ieee80211_tx_info *tx_info; - - tx_info = IEEE80211_SKB_CB(p); /* BMAC_NOTE: For the split driver, second level txstatus comes later * So if the ACK was received then wait for the second level else just @@ -1060,8 +1016,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, } if (scb) { - scb_ampdu = &scb->scb_ampdu; - ini = &scb_ampdu->ini[p->priority]; brcms_c_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); } else { /* loop through all pkts and free */ @@ -1069,7 +1023,6 @@ brcms_c_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct d11txh *txh; u16 mcl; while (p) { - tx_info = IEEE80211_SKB_CB(p); txh = (struct d11txh *) p->data; trace_brcms_txdesc(&wlc->hw->d11core->dev, txh, sizeof(*txh)); |
