Deleted Added
sdiff udiff text old ( 240592 ) new ( 240639 )
full compact
1/*-
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * Copyright (c) 2010-2012 Adrian Chadd, Xenion Pty Ltd
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 15 unchanged lines hidden (view full) ---

24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
26 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28 * THE POSSIBILITY OF SUCH DAMAGES.
29 */
30
31#include <sys/cdefs.h>
32__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx.c 240592 2012-09-17 03:17:42Z adrian $");
33
34/*
35 * Driver for the Atheros Wireless LAN controller.
36 *
37 * This software is derived from work of Atsushi Onoe; his contribution
38 * is greatly appreciated.
39 */
40

--- 68 unchanged lines hidden (view full) ---

109static int ath_tx_ampdu_pending(struct ath_softc *sc, struct ath_node *an,
110 int tid);
111static int ath_tx_ampdu_running(struct ath_softc *sc, struct ath_node *an,
112 int tid);
113static ieee80211_seq ath_tx_tid_seqno_assign(struct ath_softc *sc,
114 struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0);
115static int ath_tx_action_frame_override_queue(struct ath_softc *sc,
116 struct ieee80211_node *ni, struct mbuf *m0, int *tid);
117
118/*
119 * Whether to use the 11n rate scenario functions or not
120 */
121static inline int
122ath_tx_is_11n(struct ath_softc *sc)
123{
124 return ((sc->sc_ah->ah_magic == 0x20065416) ||

--- 15 unchanged lines hidden (view full) ---

140
141 wh = mtod(m0, const struct ieee80211_frame *);
142 if (! IEEE80211_QOS_HAS_SEQ(wh))
143 return IEEE80211_NONQOS_TID;
144 else
145 return WME_AC_TO_TID(pri);
146}
147
148/*
149 * Determine what the correct AC queue for the given frame
150 * should be.
151 *
152 * This code assumes that the TIDs map consistently to
153 * the underlying hardware (or software) ath_txq.
154 * Since the sender may try to set an AC which is
155 * arbitrary, non-QoS TIDs may end up being put on

--- 2550 unchanged lines hidden (view full) ---

2706void
2707ath_tx_tid_init(struct ath_softc *sc, struct ath_node *an)
2708{
2709 int i, j;
2710 struct ath_tid *atid;
2711
2712 for (i = 0; i < IEEE80211_TID_SIZE; i++) {
2713 atid = &an->an_tid[i];
2714 TAILQ_INIT(&atid->axq_q);
2715 atid->tid = i;
2716 atid->an = an;
2717 for (j = 0; j < ATH_TID_MAX_BUFS; j++)
2718 atid->tx_buf[j] = NULL;
2719 atid->baw_head = atid->baw_tail = 0;
2720 atid->paused = 0;
2721 atid->sched = 0;
2722 atid->hwq_depth = 0;
2723 atid->cleanup_inprogress = 0;
2724 if (i == IEEE80211_NONQOS_TID)
2725 atid->ac = WME_AC_BE;
2726 else
2727 atid->ac = TID_TO_WME_AC(i);
2728 }
2729}
2730
2731/*

--- 25 unchanged lines hidden (view full) ---

2757
2758 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: unpaused = %d\n",
2759 __func__, tid->paused);
2760
2761 if (tid->paused || tid->axq_depth == 0) {
2762 return;
2763 }
2764
2765 ath_tx_tid_sched(sc, tid);
2766 /* Punt some frames to the hardware if needed */
2767 //ath_txq_sched(sc, sc->sc_ac2q[tid->ac]);
2768 taskqueue_enqueue(sc->sc_tq, &sc->sc_txqtask);
2769}
2770
2771/*
2772 * Suspend the queue because we need to TX a BAR.
2773 */
2774static void
2775ath_tx_tid_bar_suspend(struct ath_softc *sc, struct ath_tid *tid)
2776{
2777 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]);
2778
2779 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR,

--- 139 unchanged lines hidden (view full) ---

2919
2920 /* Failure? For now, warn loudly and continue */
2921 ATH_TXQ_LOCK(sc->sc_ac2q[tid->ac]);
2922 device_printf(sc->sc_dev, "%s: tid=%p, failed to TX BAR, continue!\n",
2923 __func__, tid);
2924 ath_tx_tid_bar_unsuspend(sc, tid);
2925}
2926
2927
2928/*
2929 * Free any packets currently pending in the software TX queue.
2930 *
2931 * This will be called when a node is being deleted.
2932 *
2933 * It can also be called on an active node during an interface
2934 * reset or state transition.
2935 *

--- 6 unchanged lines hidden (view full) ---

2942 */
2943static void
2944ath_tx_tid_drain(struct ath_softc *sc, struct ath_node *an,
2945 struct ath_tid *tid, ath_bufhead *bf_cq)
2946{
2947 struct ath_buf *bf;
2948 struct ieee80211_tx_ampdu *tap;
2949 struct ieee80211_node *ni = &an->an_node;
2950 int t = 0;
2951 struct ath_txq *txq = sc->sc_ac2q[tid->ac];
2952
2953 tap = ath_tx_get_tx_tid(an, tid->tid);
2954
2955 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]);
2956
2957 /* Walk the queue, free frames */
2958 for (;;) {
2959 bf = TAILQ_FIRST(&tid->axq_q);
2960 if (bf == NULL) {
2961 break;
2962 }
2963
2964 if (t == 0) {
2965 device_printf(sc->sc_dev,
2966 "%s: node %p: bf=%p: addbaw=%d, dobaw=%d, "
2967 "seqno=%d, retry=%d\n",
2968 __func__, ni, bf,
2969 bf->bf_state.bfs_addedbaw,
2970 bf->bf_state.bfs_dobaw,
2971 SEQNO(bf->bf_state.bfs_seqno),
2972 bf->bf_state.bfs_retries);
2973 device_printf(sc->sc_dev,
2974 "%s: node %p: bf=%p: tid txq_depth=%d hwq_depth=%d, bar_wait=%d\n",
2975 __func__, ni, bf,
2976 tid->axq_depth,
2977 tid->hwq_depth,
2978 tid->bar_wait);
2979 device_printf(sc->sc_dev,
2980 "%s: node %p: tid %d: txq_depth=%d, "
2981 "txq_aggr_depth=%d, sched=%d, paused=%d, "
2982 "hwq_depth=%d, incomp=%d, baw_head=%d, "
2983 "baw_tail=%d txa_start=%d, ni_txseqs=%d\n",
2984 __func__, ni, tid->tid, txq->axq_depth,
2985 txq->axq_aggr_depth, tid->sched, tid->paused,
2986 tid->hwq_depth, tid->incomp, tid->baw_head,
2987 tid->baw_tail, tap == NULL ? -1 : tap->txa_start,
2988 ni->ni_txseqs[tid->tid]);
2989
2990 /* XXX Dump the frame, see what it is? */
2991 ieee80211_dump_pkt(ni->ni_ic,
2992 mtod(bf->bf_m, const uint8_t *),
2993 bf->bf_m->m_len, 0, -1);
2994
2995 t = 1;
2996 }
2997
2998
2999 /*
3000 * If the current TID is running AMPDU, update
3001 * the BAW.
3002 */
3003 if (ath_tx_ampdu_running(sc, an, tid->tid) &&
3004 bf->bf_state.bfs_dobaw) {
3005 /*
3006 * Only remove the frame from the BAW if it's
3007 * been transmitted at least once; this means
3008 * the frame was in the BAW to begin with.
3009 */
3010 if (bf->bf_state.bfs_retries > 0) {
3011 ath_tx_update_baw(sc, an, tid, bf);
3012 bf->bf_state.bfs_dobaw = 0;
3013 }
3014 /*
3015 * This has become a non-fatal error now
3016 */
3017 if (! bf->bf_state.bfs_addedbaw)
3018 device_printf(sc->sc_dev,
3019 "%s: wasn't added: seqno %d\n",
3020 __func__, SEQNO(bf->bf_state.bfs_seqno));
3021 }
3022 ATH_TXQ_REMOVE(tid, bf, bf_list);
3023 TAILQ_INSERT_TAIL(bf_cq, bf, bf_list);
3024 }
3025
3026 /*
3027 * Now that it's completed, grab the TID lock and update
3028 * the sequence number and BAW window.
3029 * Because sequence numbers have been assigned to frames
3030 * that haven't been sent yet, it's entirely possible
3031 * we'll be called with some pending frames that have not

--- 97 unchanged lines hidden (view full) ---

3129
3130 /* The TID state is protected behind the TXQ lock */
3131 ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]);
3132
3133 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: fail=%d, hwq_depth now %d\n",
3134 __func__, bf, fail, atid->hwq_depth - 1);
3135
3136 atid->hwq_depth--;
3137 if (atid->hwq_depth < 0)
3138 device_printf(sc->sc_dev, "%s: hwq_depth < 0: %d\n",
3139 __func__, atid->hwq_depth);
3140 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
3141
3142 /*
3143 * punt to rate control if we're not being cleaned up
3144 * during a hw queue drain and the frame wanted an ACK.
3145 */
3146 if (fail == 0 && ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0))
3147 ath_tx_update_ratectrl(sc, ni, bf->bf_state.bfs_rc,

--- 56 unchanged lines hidden (view full) ---

3204
3205 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW,
3206 "%s: TID %d: called\n", __func__, tid);
3207
3208 TAILQ_INIT(&bf_cq);
3209 ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]);
3210
3211 /*
3212 * Update the frames in the software TX queue:
3213 *
3214 * + Discard retry frames in the queue
3215 * + Fix the completion function to be non-aggregate
3216 */
3217 bf = TAILQ_FIRST(&atid->axq_q);
3218 while (bf) {
3219 if (bf->bf_state.bfs_isretried) {

--- 62 unchanged lines hidden (view full) ---

3282
3283 /* Handle completing frames and fail them */
3284 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) {
3285 TAILQ_REMOVE(&bf_cq, bf, bf_list);
3286 ath_tx_default_comp(sc, bf, 1);
3287 }
3288}
3289
3290static void
3291ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
3292{
3293 struct ieee80211_frame *wh;
3294
3295 wh = mtod(bf->bf_m, struct ieee80211_frame *);
3296 /* Only update/resync if needed */
3297 if (bf->bf_state.bfs_isretried == 0) {
3298 wh->i_fc[1] |= IEEE80211_FC1_RETRY;
3299 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap,
3300 BUS_DMASYNC_PREWRITE);
3301 }
3302 sc->sc_stats.ast_tx_swretries++;
3303 bf->bf_state.bfs_isretried = 1;
3304 bf->bf_state.bfs_retries ++;
3305}
3306
3307static struct ath_buf *
3308ath_tx_retry_clone(struct ath_softc *sc, struct ath_node *an,
3309 struct ath_tid *tid, struct ath_buf *bf)
3310{
3311 struct ath_buf *nbf;
3312 int error;
3313
3314 nbf = ath_buf_clone(sc, bf);

--- 32 unchanged lines hidden (view full) ---

3347 /* Update BAW if required, before we free the original buf */
3348 if (bf->bf_state.bfs_dobaw)
3349 ath_tx_switch_baw_buf(sc, an, tid, bf, nbf);
3350
3351 /* Free current buffer; return the older buffer */
3352 bf->bf_m = NULL;
3353 bf->bf_node = NULL;
3354 ath_freebuf(sc, bf);
3355 return nbf;
3356}
3357
3358/*
3359 * Handle retrying an unaggregate frame in an aggregate
3360 * session.
3361 *
3362 * If too many retries occur, pause the TID, wait for

--- 65 unchanged lines hidden (view full) ---

3428 }
3429
3430 /*
3431 * This increments the retry counter as well as
3432 * sets the retry flag in the ath_buf and packet
3433 * body.
3434 */
3435 ath_tx_set_retry(sc, bf);
3436
3437 /*
3438 * Insert this at the head of the queue, so it's
3439 * retried before any current/subsequent frames.
3440 */
3441 ATH_TXQ_INSERT_HEAD(atid, bf, bf_list);
3442 ath_tx_tid_sched(sc, atid);
3443 /* Send the BAR if there are no other frames waiting */

--- 19 unchanged lines hidden (view full) ---

3463 int tid = bf->bf_state.bfs_tid;
3464 struct ath_tid *atid = &an->an_tid[tid];
3465
3466 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[atid->ac]);
3467
3468 /* XXX clr11naggr should be done for all subframes */
3469 ath_hal_clr11n_aggr(sc->sc_ah, bf->bf_desc);
3470 ath_hal_set11nburstduration(sc->sc_ah, bf->bf_desc, 0);
3471 /* ath_hal_set11n_virtualmorefrag(sc->sc_ah, bf->bf_desc, 0); */
3472
3473 /*
3474 * If the buffer is marked as busy, we can't directly
3475 * reuse it. Instead, try to clone the buffer.
3476 * If the clone is successful, recycle the old buffer.
3477 * If the clone is unsuccessful, set bfs_retries to max
3478 * to force the next bit of code to free the buffer

--- 20 unchanged lines hidden (view full) ---

3499 device_printf(sc->sc_dev,
3500 "%s: wasn't added: seqno %d\n",
3501 __func__, SEQNO(bf->bf_state.bfs_seqno));
3502 bf->bf_state.bfs_dobaw = 0;
3503 return 1;
3504 }
3505
3506 ath_tx_set_retry(sc, bf);
3507 bf->bf_next = NULL; /* Just to make sure */
3508
3509 /* Clear the aggregate state */
3510 bf->bf_state.bfs_aggr = 0;
3511 bf->bf_state.bfs_ndelim = 0; /* ??? needed? */
3512 bf->bf_state.bfs_nframes = 1;
3513
3514 TAILQ_INSERT_TAIL(bf_q, bf, bf_list);

--- 70 unchanged lines hidden (view full) ---

3585 ath_tx_tid_bar_suspend(sc, tid);
3586 }
3587
3588 /*
3589 * Send BAR if required
3590 */
3591 if (ath_tx_tid_bar_tx_ready(sc, tid))
3592 ath_tx_tid_bar_tx(sc, tid);
3593 ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]);
3594
3595 /* Complete frames which errored out */
3596 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) {
3597 TAILQ_REMOVE(&bf_cq, bf, bf_list);
3598 ath_tx_default_comp(sc, bf, 0);
3599 }
3600}

--- 27 unchanged lines hidden (view full) ---

3628 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL,
3629 "%s: TID %d: cleaned up! resume!\n",
3630 __func__, tid);
3631 atid->cleanup_inprogress = 0;
3632 ath_tx_tid_resume(sc, atid);
3633 }
3634
3635 /* Send BAR if required */
3636 if (ath_tx_tid_bar_tx_ready(sc, atid))
3637 ath_tx_tid_bar_tx(sc, atid);
3638 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
3639
3640 /* Handle frame completion */
3641 while (bf) {
3642 bf_next = bf->bf_next;
3643 ath_tx_default_comp(sc, bf, 1);
3644 bf = bf_next;
3645 }

--- 30 unchanged lines hidden (view full) ---

3676 int pktlen;
3677 /* XXX there's too much on the stack? */
3678 struct ath_rc_series rc[ATH_RC_NUM];
3679 int txseq;
3680
3681 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: called; hwq_depth=%d\n",
3682 __func__, atid->hwq_depth);
3683
3684 /* The TID state is kept behind the TXQ lock */
3685 ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]);
3686
3687 atid->hwq_depth--;
3688 if (atid->hwq_depth < 0)
3689 device_printf(sc->sc_dev, "%s: hwq_depth < 0: %d\n",
3690 __func__, atid->hwq_depth);
3691
3692 /*
3693 * Punt cleanup to the relevant function, not our problem now
3694 */
3695 if (atid->cleanup_inprogress) {
3696 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
3697 ath_tx_comp_cleanup_aggr(sc, bf_first);
3698 return;
3699 }
3700
3701 /*
3702 * Take a copy; this may be needed -after- bf_first
3703 * has been completed and freed.
3704 */
3705 ts = bf_first->bf_status.ds_txstat;
3706 /*
3707 * XXX for now, use the first frame in the aggregate for
3708 * XXX rate control completion; it's at least consistent.
3709 */

--- 10 unchanged lines hidden (view full) ---

3720 if (ts.ts_status & HAL_TXERR_XRETRY) {
3721#endif
3722 if (ts.ts_status != 0) {
3723 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
3724 ath_tx_comp_aggr_error(sc, bf_first, atid);
3725 return;
3726 }
3727
3728 TAILQ_INIT(&bf_q);
3729 TAILQ_INIT(&bf_cq);
3730 tap = ath_tx_get_tx_tid(an, tid);
3731
3732 /*
3733 * extract starting sequence and block-ack bitmap
3734 */
3735 /* XXX endian-ness of seq_st, ba? */
3736 seq_st = ts.ts_seqnum;
3737 hasba = !! (ts.ts_flags & HAL_TX_BA);

--- 140 unchanged lines hidden (view full) ---

3878 }
3879
3880 /*
3881 * Reschedule to grab some further frames.
3882 */
3883 ath_tx_tid_sched(sc, atid);
3884
3885 /*
3886 * Send BAR if required
3887 */
3888 if (ath_tx_tid_bar_tx_ready(sc, atid))
3889 ath_tx_tid_bar_tx(sc, atid);
3890
3891 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
3892
3893 /* Do deferred completion */

--- 13 unchanged lines hidden (view full) ---

3907static void
3908ath_tx_aggr_comp_unaggr(struct ath_softc *sc, struct ath_buf *bf, int fail)
3909{
3910 struct ieee80211_node *ni = bf->bf_node;
3911 struct ath_node *an = ATH_NODE(ni);
3912 int tid = bf->bf_state.bfs_tid;
3913 struct ath_tid *atid = &an->an_tid[tid];
3914 struct ath_tx_status *ts = &bf->bf_status.ds_txstat;
3915
3916 /*
3917 * Update rate control status here, before we possibly
3918 * punt to retry or cleanup.
3919 *
3920 * Do it outside of the TXQ lock.
3921 */
3922 if (fail == 0 && ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0))

--- 18 unchanged lines hidden (view full) ---

3941 SEQNO(bf->bf_state.bfs_seqno));
3942
3943 atid->hwq_depth--;
3944 if (atid->hwq_depth < 0)
3945 device_printf(sc->sc_dev, "%s: hwq_depth < 0: %d\n",
3946 __func__, atid->hwq_depth);
3947
3948 /*
3949 * If a cleanup is in progress, punt to comp_cleanup;
3950 * rather than handling it here. It's thus their
3951 * responsibility to clean up, call the completion
3952 * function in net80211, etc.
3953 */
3954 if (atid->cleanup_inprogress) {
3955 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
3956 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: cleanup_unaggr\n",
3957 __func__);
3958 ath_tx_comp_cleanup_unaggr(sc, bf);
3959 return;
3960 }
3961
3962 /*
3963 * Don't bother with the retry check if all frames
3964 * are being failed (eg during queue deletion.)
3965 */
3966#if 0
3967 if (fail == 0 && ts->ts_status & HAL_TXERR_XRETRY) {
3968#endif
3969 if (fail == 0 && ts->ts_status != 0) {
3970 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);

--- 11 unchanged lines hidden (view full) ---

3982 bf->bf_state.bfs_dobaw = 0;
3983 if (! bf->bf_state.bfs_addedbaw)
3984 device_printf(sc->sc_dev,
3985 "%s: wasn't added: seqno %d\n",
3986 __func__, SEQNO(bf->bf_state.bfs_seqno));
3987 }
3988
3989 /*
3990 * Send BAR if required
3991 */
3992 if (ath_tx_tid_bar_tx_ready(sc, atid))
3993 ath_tx_tid_bar_tx(sc, atid);
3994
3995 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]);
3996
3997 ath_tx_default_comp(sc, bf, fail);

--- 682 unchanged lines hidden ---