diff options
| author | Andriy Voskoboinyk <avos@FreeBSD.org> | 2016-10-02 20:35:55 +0000 |
|---|---|---|
| committer | Andriy Voskoboinyk <avos@FreeBSD.org> | 2016-10-02 20:35:55 +0000 |
| commit | f6930bec3346bb31ba289844a0532e51b011ac8e (patch) | |
| tree | 7498c690145d9d293ef9ed00615987f9093c6777 /sys/dev/iwn | |
| parent | d2e877f0fab3ffdc4017a542929416e953297332 (diff) | |
Notes
Diffstat (limited to 'sys/dev/iwn')
| -rw-r--r-- | sys/dev/iwn/if_iwn.c | 81 | ||||
| -rw-r--r-- | sys/dev/iwn/if_iwnvar.h | 1 |
2 files changed, 50 insertions, 32 deletions
diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 7372e60f27d4..b2107ae9fc5f 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -210,9 +210,10 @@ static void iwn4965_tx_done(struct iwn_softc *, struct iwn_rx_desc *, struct iwn_rx_data *); static void iwn5000_tx_done(struct iwn_softc *, struct iwn_rx_desc *, struct iwn_rx_data *); -static void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int, +static void iwn_tx_done(struct iwn_softc *, struct iwn_rx_desc *, int, int, uint8_t); -static void iwn_ampdu_tx_done(struct iwn_softc *, int, int, int, int, void *); +static void iwn_ampdu_tx_done(struct iwn_softc *, int, int, int, int, int, + void *); static void iwn_cmd_done(struct iwn_softc *, struct iwn_rx_desc *); static void iwn_notif_intr(struct iwn_softc *); static void iwn_wakeup_intr(struct iwn_softc *); @@ -3147,6 +3148,7 @@ static void iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc, struct iwn_rx_data *data) { + struct ieee80211_ratectl_tx_status *txs = &sc->sc_txs; struct iwn_ops *ops = &sc->ops; struct iwn_node *wn; struct ieee80211_node *ni; @@ -3158,7 +3160,7 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc, uint64_t bitmap; uint16_t ssn; uint8_t tid; - int ackfailcnt = 0, i, lastidx, qid, *res, shift; + int i, lastidx, qid, *res, shift; int tx_ok = 0, tx_err = 0; DPRINTF(sc, IWN_DEBUG_TRACE | IWN_DEBUG_XMIT, "->%s begin\n", __func__); @@ -3227,15 +3229,15 @@ iwn_rx_compressed_ba(struct iwn_softc *sc, struct iwn_rx_desc *desc, ni = tap->txa_ni; bitmap = (le64toh(ba->bitmap) >> shift) & wn->agg[tid].bitmap; for (i = 0; bitmap; i++) { + txs->flags = 0; /* XXX TODO */ if ((bitmap & 1) == 0) { tx_err ++; - ieee80211_ratectl_tx_complete(ni->ni_vap, ni, - IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); + txs->status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED; } else { tx_ok ++; - ieee80211_ratectl_tx_complete(ni->ni_vap, ni, - IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); + txs->status = IEEE80211_RATECTL_TX_SUCCESS; } + ieee80211_ratectl_tx_complete(ni, txs); bitmap >>= 1; } @@ -3501,9 +3503,9 @@ iwn4965_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD); if (qid >= sc->firstaggqueue) { iwn_ampdu_tx_done(sc, qid, desc->idx, stat->nframes, - stat->ackfailcnt, &stat->status); + stat->rtsfailcnt, stat->ackfailcnt, &stat->status); } else { - iwn_tx_done(sc, desc, stat->ackfailcnt, + iwn_tx_done(sc, desc, stat->rtsfailcnt, stat->ackfailcnt, le32toh(stat->status) & 0xff); } } @@ -3536,9 +3538,9 @@ iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, bus_dmamap_sync(ring->data_dmat, data->map, BUS_DMASYNC_POSTREAD); if (qid >= sc->firstaggqueue) { iwn_ampdu_tx_done(sc, qid, desc->idx, stat->nframes, - stat->ackfailcnt, &stat->status); + stat->rtsfailcnt, stat->ackfailcnt, &stat->status); } else { - iwn_tx_done(sc, desc, stat->ackfailcnt, + iwn_tx_done(sc, desc, stat->rtsfailcnt, stat->ackfailcnt, le16toh(stat->status) & 0xff); } } @@ -3547,14 +3549,14 @@ iwn5000_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, * Adapter-independent backend for TX_DONE firmware notifications. */ static void -iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt, - uint8_t status) +iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int rtsfailcnt, + int ackfailcnt, uint8_t status) { + struct ieee80211_ratectl_tx_status *txs = &sc->sc_txs; struct iwn_tx_ring *ring = &sc->txq[desc->qid & 0xf]; struct iwn_tx_data *data = &ring->data[desc->idx]; struct mbuf *m; struct ieee80211_node *ni; - struct ieee80211vap *vap; KASSERT(data->ni != NULL, ("no node")); @@ -3565,17 +3567,33 @@ iwn_tx_done(struct iwn_softc *sc, struct iwn_rx_desc *desc, int ackfailcnt, bus_dmamap_unload(ring->data_dmat, data->map); m = data->m, data->m = NULL; ni = data->ni, data->ni = NULL; - vap = ni->ni_vap; /* * Update rate control statistics for the node. */ - if (status & IWN_TX_FAIL) - ieee80211_ratectl_tx_complete(vap, ni, - IEEE80211_RATECTL_TX_FAILURE, &ackfailcnt, NULL); - else - ieee80211_ratectl_tx_complete(vap, ni, - IEEE80211_RATECTL_TX_SUCCESS, &ackfailcnt, NULL); + txs->flags = IEEE80211_RATECTL_STATUS_SHORT_RETRY | + IEEE80211_RATECTL_STATUS_LONG_RETRY; + txs->short_retries = rtsfailcnt; + txs->long_retries = ackfailcnt; + if (!(status & IWN_TX_FAIL)) + txs->status = IEEE80211_RATECTL_TX_SUCCESS; + else { + switch (status) { + case IWN_TX_FAIL_SHORT_LIMIT: + txs->status = IEEE80211_RATECTL_TX_FAIL_SHORT; + break; + case IWN_TX_FAIL_LONG_LIMIT: + txs->status = IEEE80211_RATECTL_TX_FAIL_LONG; + break; + case IWN_TX_STATUS_FAIL_LIFE_EXPIRE: + txs->status = IEEE80211_RATECTL_TX_FAIL_EXPIRED; + break; + default: + txs->status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED; + break; + } + } + ieee80211_ratectl_tx_complete(ni, txs); /* * Channels marked for "radar" require traffic to be received @@ -3640,10 +3658,11 @@ iwn_cmd_done(struct iwn_softc *sc, struct iwn_rx_desc *desc) static void iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, - int ackfailcnt, void *stat) + int rtsfailcnt, int ackfailcnt, void *stat) { struct iwn_ops *ops = &sc->ops; struct iwn_tx_ring *ring = &sc->txq[qid]; + struct ieee80211_ratectl_tx_status *txs = &sc->sc_txs; struct iwn_tx_data *data; struct mbuf *m; struct iwn_node *wn; @@ -3682,6 +3701,10 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, * handled differently. */ if (nframes == 1) { + txs->flags = IEEE80211_RATECTL_STATUS_SHORT_RETRY | + IEEE80211_RATECTL_STATUS_LONG_RETRY; + txs->short_retries = rtsfailcnt; + txs->long_retries = ackfailcnt; if ((*status & 0xff) != 1 && (*status & 0xff) != 2) { #ifdef NOT_YET printf("ieee80211_send_bar()\n"); @@ -3691,11 +3714,8 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, * notification is pushed up to the rate control * layer. */ - ieee80211_ratectl_tx_complete(ni->ni_vap, - ni, - IEEE80211_RATECTL_TX_FAILURE, - &ackfailcnt, - NULL); + /* XXX */ + txs->status = IEEE80211_RATECTL_TX_FAIL_UNSPECIFIED; } else { /* * If nframes=1, then we won't be getting a BA for @@ -3703,12 +3723,9 @@ iwn_ampdu_tx_done(struct iwn_softc *sc, int qid, int idx, int nframes, * rate control code with how many retries were * needed to send it. */ - ieee80211_ratectl_tx_complete(ni->ni_vap, - ni, - IEEE80211_RATECTL_TX_SUCCESS, - &ackfailcnt, - NULL); + txs->status = IEEE80211_RATECTL_TX_SUCCESS; } + ieee80211_ratectl_tx_complete(ni, txs); } bitmap = 0; diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h index 290bd5a3a1ab..f8f860bc16d7 100644 --- a/sys/dev/iwn/if_iwnvar.h +++ b/sys/dev/iwn/if_iwnvar.h @@ -238,6 +238,7 @@ struct iwn_softc { struct cdev *sc_cdev; struct mtx sc_mtx; struct ieee80211com sc_ic; + struct ieee80211_ratectl_tx_status sc_txs; u_int sc_flags; #define IWN_FLAG_HAS_OTPROM (1 << 1) |
