if_ath_tx.c (240592) | if_ath_tx.c (240639) |
---|---|
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> | 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 $"); | 32__FBSDID("$FreeBSD: head/sys/dev/ath/if_ath_tx.c 240639 2012-09-18 10:14:17Z 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); | 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); |
117static struct ath_buf * 118ath_tx_retry_clone(struct ath_softc *sc, struct ath_node *an, 119 struct ath_tid *tid, struct ath_buf *bf); |
|
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 | 120 121/* 122 * Whether to use the 11n rate scenario functions or not 123 */ 124static inline int 125ath_tx_is_11n(struct ath_softc *sc) 126{ 127 return ((sc->sc_ah->ah_magic == 0x20065416) || --- 15 unchanged lines hidden (view full) --- 143 144 wh = mtod(m0, const struct ieee80211_frame *); 145 if (! IEEE80211_QOS_HAS_SEQ(wh)) 146 return IEEE80211_NONQOS_TID; 147 else 148 return WME_AC_TO_TID(pri); 149} 150 |
151static void 152ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf) 153{ 154 struct ieee80211_frame *wh; 155 156 wh = mtod(bf->bf_m, struct ieee80211_frame *); 157 /* Only update/resync if needed */ 158 if (bf->bf_state.bfs_isretried == 0) { 159 wh->i_fc[1] |= IEEE80211_FC1_RETRY; 160 bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, 161 BUS_DMASYNC_PREWRITE); 162 } 163 bf->bf_state.bfs_isretried = 1; 164 bf->bf_state.bfs_retries ++; 165} 166 |
|
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]; | 167/* 168 * Determine what the correct AC queue for the given frame 169 * should be. 170 * 171 * This code assumes that the TIDs map consistently to 172 * the underlying hardware (or software) ath_txq. 173 * Since the sender may try to set an AC which is 174 * arbitrary, non-QoS TIDs may end up being put on --- 2550 unchanged lines hidden (view full) --- 2725void 2726ath_tx_tid_init(struct ath_softc *sc, struct ath_node *an) 2727{ 2728 int i, j; 2729 struct ath_tid *atid; 2730 2731 for (i = 0; i < IEEE80211_TID_SIZE; i++) { 2732 atid = &an->an_tid[i]; |
2733 2734 /* XXX now with this bzer(), is the field 0'ing needed? */ 2735 bzero(atid, sizeof(*atid)); 2736 |
|
2714 TAILQ_INIT(&atid->axq_q); | 2737 TAILQ_INIT(&atid->axq_q); |
2738 TAILQ_INIT(&atid->filtq.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; | 2739 atid->tid = i; 2740 atid->an = an; 2741 for (j = 0; j < ATH_TID_MAX_BUFS; j++) 2742 atid->tx_buf[j] = NULL; 2743 atid->baw_head = atid->baw_tail = 0; 2744 atid->paused = 0; 2745 atid->sched = 0; 2746 atid->hwq_depth = 0; 2747 atid->cleanup_inprogress = 0; |
2748 atid->clrdmask = 1; /* Always start by setting this bit */ |
|
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 | 2749 if (i == IEEE80211_NONQOS_TID) 2750 atid->ac = WME_AC_BE; 2751 else 2752 atid->ac = TID_TO_WME_AC(i); 2753 } 2754} 2755 2756/* --- 25 unchanged lines hidden (view full) --- 2782 2783 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, "%s: unpaused = %d\n", 2784 __func__, tid->paused); 2785 2786 if (tid->paused || tid->axq_depth == 0) { 2787 return; 2788 } 2789 |
2790 /* XXX isfiltered shouldn't ever be 0 at this point */ 2791 if (tid->isfiltered == 1) { 2792 device_printf(sc->sc_dev, "%s: filtered?!\n", __func__); 2793 return; 2794 } 2795 |
|
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/* | 2796 ath_tx_tid_sched(sc, tid); 2797 /* Punt some frames to the hardware if needed */ 2798 //ath_txq_sched(sc, sc->sc_ac2q[tid->ac]); 2799 taskqueue_enqueue(sc->sc_tq, &sc->sc_txqtask); 2800} 2801 2802/* |
2803 * Add the given ath_buf to the TID filtered frame list. 2804 * This requires the TID be filtered. 2805 */ 2806static void 2807ath_tx_tid_filt_addbuf(struct ath_softc *sc, struct ath_tid *tid, 2808 struct ath_buf *bf) 2809{ 2810 2811 ATH_TID_LOCK_ASSERT(sc, tid); 2812 if (! tid->isfiltered) 2813 device_printf(sc->sc_dev, "%s: not filtered?!\n", __func__); 2814 2815 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: bf=%p\n", __func__, bf); 2816 2817 /* Set the retry bit and bump the retry counter */ 2818 ath_tx_set_retry(sc, bf); 2819 sc->sc_stats.ast_tx_swfiltered++; 2820 2821 ATH_TXQ_INSERT_TAIL(&tid->filtq, bf, bf_list); 2822} 2823 2824/* 2825 * Handle a completed filtered frame from the given TID. 2826 * This just enables/pauses the filtered frame state if required 2827 * and appends the filtered frame to the filtered queue. 2828 */ 2829static void 2830ath_tx_tid_filt_comp_buf(struct ath_softc *sc, struct ath_tid *tid, 2831 struct ath_buf *bf) 2832{ 2833 2834 ATH_TID_LOCK_ASSERT(sc, tid); 2835 2836 if (! tid->isfiltered) { 2837 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: filter transition\n", 2838 __func__); 2839 tid->isfiltered = 1; 2840 ath_tx_tid_pause(sc, tid); 2841 } 2842 2843 /* Add the frame to the filter queue */ 2844 ath_tx_tid_filt_addbuf(sc, tid, bf); 2845} 2846 2847/* 2848 * Complete the filtered frame TX completion. 2849 * 2850 * If there are no more frames in the hardware queue, unpause/unfilter 2851 * the TID if applicable. Otherwise we will wait for a node PS transition 2852 * to unfilter. 2853 */ 2854static void 2855ath_tx_tid_filt_comp_complete(struct ath_softc *sc, struct ath_tid *tid) 2856{ 2857 struct ath_buf *bf; 2858 2859 ATH_TID_LOCK_ASSERT(sc, tid); 2860 2861 if (tid->hwq_depth != 0) 2862 return; 2863 2864 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, "%s: hwq=0, transition back\n", 2865 __func__); 2866 tid->isfiltered = 0; 2867 tid->clrdmask = 1; 2868 2869 /* XXX this is really quite inefficient */ 2870 while ((bf = TAILQ_LAST(&tid->filtq.axq_q, ath_bufhead_s)) != NULL) { 2871 ATH_TXQ_REMOVE(&tid->filtq, bf, bf_list); 2872 ATH_TXQ_INSERT_HEAD(tid, bf, bf_list); 2873 } 2874 2875 ath_tx_tid_resume(sc, tid); 2876} 2877 2878/* 2879 * Called when a single (aggregate or otherwise) frame is completed. 2880 * 2881 * Returns 1 if the buffer could be added to the filtered list 2882 * (cloned or otherwise), 0 if the buffer couldn't be added to the 2883 * filtered list (failed clone; expired retry) and the caller should 2884 * free it and handle it like a failure (eg by sending a BAR.) 2885 */ 2886static int 2887ath_tx_tid_filt_comp_single(struct ath_softc *sc, struct ath_tid *tid, 2888 struct ath_buf *bf) 2889{ 2890 struct ath_buf *nbf; 2891 int retval; 2892 2893 ATH_TID_LOCK_ASSERT(sc, tid); 2894 2895 /* 2896 * Don't allow a filtered frame to live forever. 2897 */ 2898 if (bf->bf_state.bfs_retries > SWMAX_RETRIES) { 2899 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, 2900 "%s: bf=%p, seqno=%d, exceeded retries\n", 2901 __func__, 2902 bf, 2903 bf->bf_state.bfs_seqno); 2904 return (0); 2905 } 2906 2907 /* 2908 * A busy buffer can't be added to the retry list. 2909 * It needs to be cloned. 2910 */ 2911 if (bf->bf_flags & ATH_BUF_BUSY) { 2912 nbf = ath_tx_retry_clone(sc, tid->an, tid, bf); 2913 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, 2914 "%s: busy buffer clone: %p -> %p\n", 2915 __func__, bf, nbf); 2916 } else { 2917 nbf = bf; 2918 } 2919 2920 if (nbf == NULL) { 2921 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, 2922 "%s: busy buffer couldn't be cloned (%p)!\n", 2923 __func__, bf); 2924 retval = 1; 2925 } else { 2926 ath_tx_tid_filt_comp_buf(sc, tid, nbf); 2927 retval = 0; 2928 } 2929 ath_tx_tid_filt_comp_complete(sc, tid); 2930 2931 return (retval); 2932} 2933 2934static void 2935ath_tx_tid_filt_comp_aggr(struct ath_softc *sc, struct ath_tid *tid, 2936 struct ath_buf *bf_first, ath_bufhead *bf_q) 2937{ 2938 struct ath_buf *bf, *bf_next, *nbf; 2939 2940 ATH_TID_LOCK_ASSERT(sc, tid); 2941 2942 bf = bf_first; 2943 while (bf) { 2944 bf_next = bf->bf_next; 2945 bf->bf_next = NULL; /* Remove it from the aggr list */ 2946 2947 /* 2948 * Don't allow a filtered frame to live forever. 2949 */ 2950 if (bf->bf_state.bfs_retries > SWMAX_RETRIES) { 2951 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, 2952 "%s: bf=%p, seqno=%d, exceeded retries\n", 2953 __func__, 2954 bf, 2955 bf->bf_state.bfs_seqno); 2956 TAILQ_INSERT_TAIL(bf_q, bf, bf_list); 2957 goto next; 2958 } 2959 2960 if (bf->bf_flags & ATH_BUF_BUSY) { 2961 nbf = ath_tx_retry_clone(sc, tid->an, tid, bf); 2962 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, 2963 "%s: busy buffer cloned: %p -> %p", 2964 __func__, bf, nbf); 2965 } else { 2966 nbf = bf; 2967 } 2968 2969 /* 2970 * If the buffer couldn't be cloned, add it to bf_q; 2971 * the caller will free the buffer(s) as required. 2972 */ 2973 if (nbf == NULL) { 2974 DPRINTF(sc, ATH_DEBUG_SW_TX_FILT, 2975 "%s: buffer couldn't be cloned! (%p)\n", 2976 __func__, bf); 2977 TAILQ_INSERT_TAIL(bf_q, bf, bf_list); 2978 } else { 2979 ath_tx_tid_filt_comp_buf(sc, tid, nbf); 2980 } 2981next: 2982 bf = bf_next; 2983 } 2984 2985 ath_tx_tid_filt_comp_complete(sc, tid); 2986} 2987 2988/* |
|
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 | 2989 * Suspend the queue because we need to TX a BAR. 2990 */ 2991static void 2992ath_tx_tid_bar_suspend(struct ath_softc *sc, struct ath_tid *tid) 2993{ 2994 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); 2995 2996 DPRINTF(sc, ATH_DEBUG_SW_TX_BAR, --- 139 unchanged lines hidden (view full) --- 3136 3137 /* Failure? For now, warn loudly and continue */ 3138 ATH_TXQ_LOCK(sc->sc_ac2q[tid->ac]); 3139 device_printf(sc->sc_dev, "%s: tid=%p, failed to TX BAR, continue!\n", 3140 __func__, tid); 3141 ath_tx_tid_bar_unsuspend(sc, tid); 3142} 3143 |
3144static void 3145ath_tx_tid_drain_pkt(struct ath_softc *sc, struct ath_node *an, 3146 struct ath_tid *tid, ath_bufhead *bf_cq, struct ath_buf *bf) 3147{ |
|
2927 | 3148 |
3149 ATH_TID_LOCK_ASSERT(sc, tid); 3150 3151 /* 3152 * If the current TID is running AMPDU, update 3153 * the BAW. 3154 */ 3155 if (ath_tx_ampdu_running(sc, an, tid->tid) && 3156 bf->bf_state.bfs_dobaw) { 3157 /* 3158 * Only remove the frame from the BAW if it's 3159 * been transmitted at least once; this means 3160 * the frame was in the BAW to begin with. 3161 */ 3162 if (bf->bf_state.bfs_retries > 0) { 3163 ath_tx_update_baw(sc, an, tid, bf); 3164 bf->bf_state.bfs_dobaw = 0; 3165 } 3166 /* 3167 * This has become a non-fatal error now 3168 */ 3169 if (! bf->bf_state.bfs_addedbaw) 3170 device_printf(sc->sc_dev, 3171 "%s: wasn't added: seqno %d\n", 3172 __func__, SEQNO(bf->bf_state.bfs_seqno)); 3173 } 3174 TAILQ_INSERT_TAIL(bf_cq, bf, bf_list); 3175} 3176 3177static void 3178ath_tx_tid_drain_print(struct ath_softc *sc, struct ath_node *an, 3179 struct ath_tid *tid, struct ath_buf *bf) 3180{ 3181 struct ieee80211_node *ni = &an->an_node; 3182 struct ath_txq *txq = sc->sc_ac2q[tid->ac]; 3183 struct ieee80211_tx_ampdu *tap; 3184 3185 tap = ath_tx_get_tx_tid(an, tid->tid); 3186 3187 device_printf(sc->sc_dev, 3188 "%s: node %p: bf=%p: addbaw=%d, dobaw=%d, " 3189 "seqno=%d, retry=%d\n", 3190 __func__, ni, bf, 3191 bf->bf_state.bfs_addedbaw, 3192 bf->bf_state.bfs_dobaw, 3193 SEQNO(bf->bf_state.bfs_seqno), 3194 bf->bf_state.bfs_retries); 3195 device_printf(sc->sc_dev, 3196 "%s: node %p: bf=%p: tid txq_depth=%d hwq_depth=%d, bar_wait=%d, isfiltered=%d\n", 3197 __func__, ni, bf, 3198 tid->axq_depth, 3199 tid->hwq_depth, 3200 tid->bar_wait, 3201 tid->isfiltered); 3202 device_printf(sc->sc_dev, 3203 "%s: node %p: tid %d: txq_depth=%d, " 3204 "txq_aggr_depth=%d, sched=%d, paused=%d, " 3205 "hwq_depth=%d, incomp=%d, baw_head=%d, " 3206 "baw_tail=%d txa_start=%d, ni_txseqs=%d\n", 3207 __func__, ni, tid->tid, txq->axq_depth, 3208 txq->axq_aggr_depth, tid->sched, tid->paused, 3209 tid->hwq_depth, tid->incomp, tid->baw_head, 3210 tid->baw_tail, tap == NULL ? -1 : tap->txa_start, 3211 ni->ni_txseqs[tid->tid]); 3212 3213 /* XXX Dump the frame, see what it is? */ 3214 ieee80211_dump_pkt(ni->ni_ic, 3215 mtod(bf->bf_m, const uint8_t *), 3216 bf->bf_m->m_len, 0, -1); 3217} 3218 |
|
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; | 3219/* 3220 * Free any packets currently pending in the software TX queue. 3221 * 3222 * This will be called when a node is being deleted. 3223 * 3224 * It can also be called on an active node during an interface 3225 * reset or state transition. 3226 * --- 6 unchanged lines hidden (view full) --- 3233 */ 3234static void 3235ath_tx_tid_drain(struct ath_softc *sc, struct ath_node *an, 3236 struct ath_tid *tid, ath_bufhead *bf_cq) 3237{ 3238 struct ath_buf *bf; 3239 struct ieee80211_tx_ampdu *tap; 3240 struct ieee80211_node *ni = &an->an_node; |
2950 int t = 0; 2951 struct ath_txq *txq = sc->sc_ac2q[tid->ac]; | 3241 int t; |
2952 2953 tap = ath_tx_get_tx_tid(an, tid->tid); 2954 | 3242 3243 tap = ath_tx_get_tx_tid(an, tid->tid); 3244 |
2955 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[tid->ac]); | 3245 ATH_TID_LOCK_ASSERT(sc, tid); |
2956 2957 /* Walk the queue, free frames */ | 3246 3247 /* Walk the queue, free frames */ |
3248 t = 0; |
|
2958 for (;;) { 2959 bf = TAILQ_FIRST(&tid->axq_q); 2960 if (bf == NULL) { 2961 break; 2962 } 2963 2964 if (t == 0) { | 3249 for (;;) { 3250 bf = TAILQ_FIRST(&tid->axq_q); 3251 if (bf == NULL) { 3252 break; 3253 } 3254 3255 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 | 3256 ath_tx_tid_drain_print(sc, an, tid, bf); |
2995 t = 1; 2996 } 2997 | 3257 t = 1; 3258 } 3259 |
3260 ATH_TXQ_REMOVE(tid, bf, bf_list); 3261 ath_tx_tid_drain_pkt(sc, an, tid, bf_cq, bf); 3262 } |
|
2998 | 3263 |
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)); | 3264 /* And now, drain the filtered frame queue */ 3265 t = 0; 3266 for (;;) { 3267 bf = TAILQ_FIRST(&tid->filtq.axq_q); 3268 if (bf == NULL) 3269 break; 3270 3271 if (t == 0) { 3272 ath_tx_tid_drain_print(sc, an, tid, bf); 3273 t = 1; |
3021 } | 3274 } |
3022 ATH_TXQ_REMOVE(tid, bf, bf_list); 3023 TAILQ_INSERT_TAIL(bf_cq, bf, bf_list); | 3275 3276 ATH_TXQ_REMOVE(&tid->filtq, bf, bf_list); 3277 ath_tx_tid_drain_pkt(sc, an, tid, bf_cq, bf); |
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--; | 3278 } 3279 3280 /* 3281 * Now that it's completed, grab the TID lock and update 3282 * the sequence number and BAW window. 3283 * Because sequence numbers have been assigned to frames 3284 * that haven't been sent yet, it's entirely possible 3285 * we'll be called with some pending frames that have not --- 97 unchanged lines hidden (view full) --- 3383 3384 /* The TID state is protected behind the TXQ lock */ 3385 ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); 3386 3387 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: bf=%p: fail=%d, hwq_depth now %d\n", 3388 __func__, bf, fail, atid->hwq_depth - 1); 3389 3390 atid->hwq_depth--; |
3391 3392 if (atid->isfiltered) 3393 device_printf(sc->sc_dev, "%s: isfiltered=1, normal_comp?\n", 3394 __func__); 3395 |
|
3137 if (atid->hwq_depth < 0) 3138 device_printf(sc->sc_dev, "%s: hwq_depth < 0: %d\n", 3139 __func__, atid->hwq_depth); | 3396 if (atid->hwq_depth < 0) 3397 device_printf(sc->sc_dev, "%s: hwq_depth < 0: %d\n", 3398 __func__, atid->hwq_depth); |
3399 3400 /* 3401 * If the queue is filtered, potentially mark it as complete 3402 * and reschedule it as needed. 3403 * 3404 * This is required as there may be a subsequent TX descriptor 3405 * for this end-node that has CLRDMASK set, so it's quite possible 3406 * that a filtered frame will be followed by a non-filtered 3407 * (complete or otherwise) frame. 3408 * 3409 * XXX should we do this before we complete the frame? 3410 */ 3411 if (atid->isfiltered) 3412 ath_tx_tid_filt_comp_complete(sc, atid); 3413 |
|
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 /* | 3414 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 3415 3416 /* 3417 * punt to rate control if we're not being cleaned up 3418 * during a hw queue drain and the frame wanted an ACK. 3419 */ 3420 if (fail == 0 && ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0)) 3421 ath_tx_update_ratectrl(sc, ni, bf->bf_state.bfs_rc, --- 56 unchanged lines hidden (view full) --- 3478 3479 DPRINTF(sc, ATH_DEBUG_SW_TX_BAW, 3480 "%s: TID %d: called\n", __func__, tid); 3481 3482 TAILQ_INIT(&bf_cq); 3483 ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); 3484 3485 /* |
3486 * Move the filtered frames to the TX queue, before 3487 * we run off and discard/process things. 3488 */ 3489 /* XXX this is really quite inefficient */ 3490 while ((bf = TAILQ_LAST(&atid->filtq.axq_q, ath_bufhead_s)) != NULL) { 3491 ATH_TXQ_REMOVE(&atid->filtq, bf, bf_list); 3492 ATH_TXQ_INSERT_HEAD(atid, bf, bf_list); 3493 } 3494 3495 /* |
|
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 | 3496 * Update the frames in the software TX queue: 3497 * 3498 * + Discard retry frames in the queue 3499 * + Fix the completion function to be non-aggregate 3500 */ 3501 bf = TAILQ_FIRST(&atid->axq_q); 3502 while (bf) { 3503 if (bf->bf_state.bfs_isretried) { --- 62 unchanged lines hidden (view full) --- 3566 3567 /* Handle completing frames and fail them */ 3568 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) { 3569 TAILQ_REMOVE(&bf_cq, bf, bf_list); 3570 ath_tx_default_comp(sc, bf, 1); 3571 } 3572} 3573 |
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); | 3574static struct ath_buf * 3575ath_tx_retry_clone(struct ath_softc *sc, struct ath_node *an, 3576 struct ath_tid *tid, struct ath_buf *bf) 3577{ 3578 struct ath_buf *nbf; 3579 int error; 3580 3581 nbf = ath_buf_clone(sc, bf); --- 32 unchanged lines hidden (view full) --- 3614 /* Update BAW if required, before we free the original buf */ 3615 if (bf->bf_state.bfs_dobaw) 3616 ath_tx_switch_baw_buf(sc, an, tid, bf, nbf); 3617 3618 /* Free current buffer; return the older buffer */ 3619 bf->bf_m = NULL; 3620 bf->bf_node = NULL; 3621 ath_freebuf(sc, bf); |
3622 |
|
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); | 3623 return nbf; 3624} 3625 3626/* 3627 * Handle retrying an unaggregate frame in an aggregate 3628 * session. 3629 * 3630 * If too many retries occur, pause the TID, wait for --- 65 unchanged lines hidden (view full) --- 3696 } 3697 3698 /* 3699 * This increments the retry counter as well as 3700 * sets the retry flag in the ath_buf and packet 3701 * body. 3702 */ 3703 ath_tx_set_retry(sc, bf); |
3704 sc->sc_stats.ast_tx_swretries++; |
|
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); | 3705 3706 /* 3707 * Insert this at the head of the queue, so it's 3708 * retried before any current/subsequent frames. 3709 */ 3710 ATH_TXQ_INSERT_HEAD(atid, bf, bf_list); 3711 ath_tx_tid_sched(sc, atid); 3712 /* Send the BAR if there are no other frames waiting */ --- 19 unchanged lines hidden (view full) --- 3732 int tid = bf->bf_state.bfs_tid; 3733 struct ath_tid *atid = &an->an_tid[tid]; 3734 3735 ATH_TXQ_LOCK_ASSERT(sc->sc_ac2q[atid->ac]); 3736 3737 /* XXX clr11naggr should be done for all subframes */ 3738 ath_hal_clr11n_aggr(sc->sc_ah, bf->bf_desc); 3739 ath_hal_set11nburstduration(sc->sc_ah, bf->bf_desc, 0); |
3740 |
|
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); | 3741 /* ath_hal_set11n_virtualmorefrag(sc->sc_ah, bf->bf_desc, 0); */ 3742 3743 /* 3744 * If the buffer is marked as busy, we can't directly 3745 * reuse it. Instead, try to clone the buffer. 3746 * If the clone is successful, recycle the old buffer. 3747 * If the clone is unsuccessful, set bfs_retries to max 3748 * to force the next bit of code to free the buffer --- 20 unchanged lines hidden (view full) --- 3769 device_printf(sc->sc_dev, 3770 "%s: wasn't added: seqno %d\n", 3771 __func__, SEQNO(bf->bf_state.bfs_seqno)); 3772 bf->bf_state.bfs_dobaw = 0; 3773 return 1; 3774 } 3775 3776 ath_tx_set_retry(sc, bf); |
3777 sc->sc_stats.ast_tx_swretries++; |
|
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); | 3778 bf->bf_next = NULL; /* Just to make sure */ 3779 3780 /* Clear the aggregate state */ 3781 bf->bf_state.bfs_aggr = 0; 3782 bf->bf_state.bfs_ndelim = 0; /* ??? needed? */ 3783 bf->bf_state.bfs_nframes = 1; 3784 3785 TAILQ_INSERT_TAIL(bf_q, bf, bf_list); --- 70 unchanged lines hidden (view full) --- 3856 ath_tx_tid_bar_suspend(sc, tid); 3857 } 3858 3859 /* 3860 * Send BAR if required 3861 */ 3862 if (ath_tx_tid_bar_tx_ready(sc, tid)) 3863 ath_tx_tid_bar_tx(sc, tid); |
3864 |
|
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 */ | 3865 ATH_TXQ_UNLOCK(sc->sc_ac2q[tid->ac]); 3866 3867 /* Complete frames which errored out */ 3868 while ((bf = TAILQ_FIRST(&bf_cq)) != NULL) { 3869 TAILQ_REMOVE(&bf_cq, bf, bf_list); 3870 ath_tx_default_comp(sc, bf, 0); 3871 } 3872} --- 27 unchanged lines hidden (view full) --- 3900 DPRINTF(sc, ATH_DEBUG_SW_TX_CTRL, 3901 "%s: TID %d: cleaned up! resume!\n", 3902 __func__, tid); 3903 atid->cleanup_inprogress = 0; 3904 ath_tx_tid_resume(sc, atid); 3905 } 3906 3907 /* Send BAR if required */ |
3908 /* XXX why would we send a BAR when transitioning to non-aggregation? */ |
|
3636 if (ath_tx_tid_bar_tx_ready(sc, atid)) 3637 ath_tx_tid_bar_tx(sc, atid); | 3909 if (ath_tx_tid_bar_tx_ready(sc, atid)) 3910 ath_tx_tid_bar_tx(sc, atid); |
3911 |
|
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 | 3912 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 3913 3914 /* Handle frame completion */ 3915 while (bf) { 3916 bf_next = bf->bf_next; 3917 ath_tx_default_comp(sc, bf, 1); 3918 bf = bf_next; 3919 } --- 30 unchanged lines hidden (view full) --- 3950 int pktlen; 3951 /* XXX there's too much on the stack? */ 3952 struct ath_rc_series rc[ATH_RC_NUM]; 3953 int txseq; 3954 3955 DPRINTF(sc, ATH_DEBUG_SW_TX_AGGR, "%s: called; hwq_depth=%d\n", 3956 __func__, atid->hwq_depth); 3957 |
3958 TAILQ_INIT(&bf_q); 3959 TAILQ_INIT(&bf_cq); 3960 |
|
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 /* | 3961 /* The TID state is kept behind the TXQ lock */ 3962 ATH_TXQ_LOCK(sc->sc_ac2q[atid->ac]); 3963 3964 atid->hwq_depth--; 3965 if (atid->hwq_depth < 0) 3966 device_printf(sc->sc_dev, "%s: hwq_depth < 0: %d\n", 3967 __func__, atid->hwq_depth); 3968 3969 /* |
3970 * If the TID is filtered, handle completing the filter 3971 * transition before potentially kicking it to the cleanup 3972 * function. 3973 */ 3974 if (atid->isfiltered) 3975 ath_tx_tid_filt_comp_complete(sc, atid); 3976 3977 /* |
|
3693 * Punt cleanup to the relevant function, not our problem now 3694 */ 3695 if (atid->cleanup_inprogress) { | 3978 * Punt cleanup to the relevant function, not our problem now 3979 */ 3980 if (atid->cleanup_inprogress) { |
3981 if (atid->isfiltered) 3982 device_printf(sc->sc_dev, 3983 "%s: isfiltered=1, normal_comp?\n", 3984 __func__); |
|
3696 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 3697 ath_tx_comp_cleanup_aggr(sc, bf_first); 3698 return; 3699 } 3700 3701 /* | 3985 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 3986 ath_tx_comp_cleanup_aggr(sc, bf_first); 3987 return; 3988 } 3989 3990 /* |
3991 * If the frame is filtered, transition to filtered frame 3992 * mode and add this to the filtered frame list. 3993 * 3994 * XXX TODO: figure out how this interoperates with 3995 * BAR, pause and cleanup states. 3996 */ 3997 if ((ts.ts_status & HAL_TXERR_FILT) || 3998 (ts.ts_status != 0 && atid->isfiltered)) { 3999 if (fail != 0) 4000 device_printf(sc->sc_dev, 4001 "%s: isfiltered=1, fail=%d\n", __func__, fail); 4002 ath_tx_tid_filt_comp_aggr(sc, atid, bf_first, &bf_cq); 4003 4004 /* Remove from BAW */ 4005 TAILQ_FOREACH_SAFE(bf, &bf_cq, bf_list, bf_next) { 4006 if (bf->bf_state.bfs_addedbaw) 4007 drops++; 4008 if (bf->bf_state.bfs_dobaw) { 4009 ath_tx_update_baw(sc, an, atid, bf); 4010 if (! bf->bf_state.bfs_addedbaw) 4011 device_printf(sc->sc_dev, 4012 "%s: wasn't added: seqno %d\n", 4013 __func__, 4014 SEQNO(bf->bf_state.bfs_seqno)); 4015 } 4016 bf->bf_state.bfs_dobaw = 0; 4017 } 4018 /* 4019 * If any intermediate frames in the BAW were dropped when 4020 * handling filtering things, send a BAR. 4021 */ 4022 if (drops) 4023 ath_tx_tid_bar_suspend(sc, atid); 4024 4025 /* 4026 * Finish up by sending a BAR if required and freeing 4027 * the frames outside of the TX lock. 4028 */ 4029 goto finish_send_bar; 4030 } 4031 4032 /* |
|
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 | 4033 * Take a copy; this may be needed -after- bf_first 4034 * has been completed and freed. 4035 */ 4036 ts = bf_first->bf_status.ds_txstat; 4037 /* 4038 * XXX for now, use the first frame in the aggregate for 4039 * XXX rate control completion; it's at least consistent. 4040 */ --- 10 unchanged lines hidden (view full) --- 4051 if (ts.ts_status & HAL_TXERR_XRETRY) { 4052#endif 4053 if (ts.ts_status != 0) { 4054 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 4055 ath_tx_comp_aggr_error(sc, bf_first, atid); 4056 return; 4057 } 4058 |
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 /* | 4059 tap = ath_tx_get_tx_tid(an, tid); 4060 4061 /* 4062 * extract starting sequence and block-ack bitmap 4063 */ 4064 /* XXX endian-ness of seq_st, ba? */ 4065 seq_st = ts.ts_seqnum; 4066 hasba = !! (ts.ts_flags & HAL_TX_BA); --- 140 unchanged lines hidden (view full) --- 4207 } 4208 4209 /* 4210 * Reschedule to grab some further frames. 4211 */ 4212 ath_tx_tid_sched(sc, atid); 4213 4214 /* |
4215 * If the queue is filtered, re-schedule as required. 4216 * 4217 * This is required as there may be a subsequent TX descriptor 4218 * for this end-node that has CLRDMASK set, so it's quite possible 4219 * that a filtered frame will be followed by a non-filtered 4220 * (complete or otherwise) frame. 4221 * 4222 * XXX should we do this before we complete the frame? 4223 */ 4224 if (atid->isfiltered) 4225 ath_tx_tid_filt_comp_complete(sc, atid); 4226 4227finish_send_bar: 4228 4229 /* |
|
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; | 4230 * Send BAR if required 4231 */ 4232 if (ath_tx_tid_bar_tx_ready(sc, atid)) 4233 ath_tx_tid_bar_tx(sc, atid); 4234 4235 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 4236 4237 /* Do deferred completion */ --- 13 unchanged lines hidden (view full) --- 4251static void 4252ath_tx_aggr_comp_unaggr(struct ath_softc *sc, struct ath_buf *bf, int fail) 4253{ 4254 struct ieee80211_node *ni = bf->bf_node; 4255 struct ath_node *an = ATH_NODE(ni); 4256 int tid = bf->bf_state.bfs_tid; 4257 struct ath_tid *atid = &an->an_tid[tid]; 4258 struct ath_tx_status *ts = &bf->bf_status.ds_txstat; |
4259 int drops = 0; |
|
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 /* | 4260 4261 /* 4262 * Update rate control status here, before we possibly 4263 * punt to retry or cleanup. 4264 * 4265 * Do it outside of the TXQ lock. 4266 */ 4267 if (fail == 0 && ((bf->bf_state.bfs_txflags & HAL_TXDESC_NOACK) == 0)) --- 18 unchanged lines hidden (view full) --- 4286 SEQNO(bf->bf_state.bfs_seqno)); 4287 4288 atid->hwq_depth--; 4289 if (atid->hwq_depth < 0) 4290 device_printf(sc->sc_dev, "%s: hwq_depth < 0: %d\n", 4291 __func__, atid->hwq_depth); 4292 4293 /* |
4294 * If the TID is filtered, handle completing the filter 4295 * transition before potentially kicking it to the cleanup 4296 * function. 4297 */ 4298 if (atid->isfiltered) 4299 ath_tx_tid_filt_comp_complete(sc, atid); 4300 4301 /* |
|
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) { | 4302 * If a cleanup is in progress, punt to comp_cleanup; 4303 * rather than handling it here. It's thus their 4304 * responsibility to clean up, call the completion 4305 * function in net80211, etc. 4306 */ 4307 if (atid->cleanup_inprogress) { |
4308 if (atid->isfiltered) 4309 device_printf(sc->sc_dev, 4310 "%s: isfiltered=1, normal_comp?\n", 4311 __func__); |
|
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 /* | 4312 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 4313 DPRINTF(sc, ATH_DEBUG_SW_TX, "%s: cleanup_unaggr\n", 4314 __func__); 4315 ath_tx_comp_cleanup_unaggr(sc, bf); 4316 return; 4317 } 4318 4319 /* |
4320 * XXX TODO: how does cleanup, BAR and filtered frame handling 4321 * overlap? 4322 * 4323 * If the frame is filtered OR if it's any failure but 4324 * the TID is filtered, the frame must be added to the 4325 * filtered frame list. 4326 * 4327 * However - a busy buffer can't be added to the filtered 4328 * list as it will end up being recycled without having 4329 * been made available for the hardware. 4330 */ 4331 if ((ts->ts_status & HAL_TXERR_FILT) || 4332 (ts->ts_status != 0 && atid->isfiltered)) { 4333 int freeframe; 4334 4335 if (fail != 0) 4336 device_printf(sc->sc_dev, 4337 "%s: isfiltered=1, fail=%d\n", 4338 __func__, 4339 fail); 4340 freeframe = ath_tx_tid_filt_comp_single(sc, atid, bf); 4341 if (freeframe) { 4342 /* Remove from BAW */ 4343 if (bf->bf_state.bfs_addedbaw) 4344 drops++; 4345 if (bf->bf_state.bfs_dobaw) { 4346 ath_tx_update_baw(sc, an, atid, bf); 4347 if (! bf->bf_state.bfs_addedbaw) 4348 device_printf(sc->sc_dev, 4349 "%s: wasn't added: seqno %d\n", 4350 __func__, SEQNO(bf->bf_state.bfs_seqno)); 4351 } 4352 bf->bf_state.bfs_dobaw = 0; 4353 } 4354 4355 /* 4356 * If the frame couldn't be filtered, treat it as a drop and 4357 * prepare to send a BAR. 4358 */ 4359 if (freeframe && drops) 4360 ath_tx_tid_bar_suspend(sc, atid); 4361 4362 /* 4363 * Send BAR if required 4364 */ 4365 if (ath_tx_tid_bar_tx_ready(sc, atid)) 4366 ath_tx_tid_bar_tx(sc, atid); 4367 4368 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 4369 /* 4370 * If freeframe is set, then the frame couldn't be 4371 * cloned and bf is still valid. Just complete/free it. 4372 */ 4373 if (freeframe) 4374 ath_tx_default_comp(sc, bf, fail); 4375 4376 4377 return; 4378 } 4379 /* |
|
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 /* | 4380 * Don't bother with the retry check if all frames 4381 * are being failed (eg during queue deletion.) 4382 */ 4383#if 0 4384 if (fail == 0 && ts->ts_status & HAL_TXERR_XRETRY) { 4385#endif 4386 if (fail == 0 && ts->ts_status != 0) { 4387 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); --- 11 unchanged lines hidden (view full) --- 4399 bf->bf_state.bfs_dobaw = 0; 4400 if (! bf->bf_state.bfs_addedbaw) 4401 device_printf(sc->sc_dev, 4402 "%s: wasn't added: seqno %d\n", 4403 __func__, SEQNO(bf->bf_state.bfs_seqno)); 4404 } 4405 4406 /* |
4407 * If the queue is filtered, re-schedule as required. 4408 * 4409 * This is required as there may be a subsequent TX descriptor 4410 * for this end-node that has CLRDMASK set, so it's quite possible 4411 * that a filtered frame will be followed by a non-filtered 4412 * (complete or otherwise) frame. 4413 * 4414 * XXX should we do this before we complete the frame? 4415 */ 4416 if (atid->isfiltered) 4417 ath_tx_tid_filt_comp_complete(sc, atid); 4418 4419 /* |
|
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 --- | 4420 * Send BAR if required 4421 */ 4422 if (ath_tx_tid_bar_tx_ready(sc, atid)) 4423 ath_tx_tid_bar_tx(sc, atid); 4424 4425 ATH_TXQ_UNLOCK(sc->sc_ac2q[atid->ac]); 4426 4427 ath_tx_default_comp(sc, bf, fail); --- 682 unchanged lines hidden --- |