]> CyberLeo.Net >> Repos - FreeBSD/releng/10.1.git/blob - sys/dev/sfxge/sfxge_tx.c
Copy stable/10@r272459 to releng/10.1 as part of
[FreeBSD/releng/10.1.git] / sys / dev / sfxge / sfxge_tx.c
1 /*-
2  * Copyright (c) 2010-2011 Solarflare Communications, Inc.
3  * All rights reserved.
4  *
5  * This software was developed in part by Philip Paeps under contract for
6  * Solarflare Communications, Inc.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29
30 /* Theory of operation:
31  *
32  * Tx queues allocation and mapping
33  *
34  * One Tx queue with enabled checksum offload is allocated per Rx channel
35  * (event queue).  Also 2 Tx queues (one without checksum offload and one
36  * with IP checksum offload only) are allocated and bound to event queue 0.
37  * sfxge_txq_type is used as Tx queue label.
38  *
39  * So, event queue plus label mapping to Tx queue index is:
40  *      if event queue index is 0, TxQ-index = TxQ-label * [0..SFXGE_TXQ_NTYPES)
41  *      else TxQ-index = SFXGE_TXQ_NTYPES + EvQ-index - 1
42  * See sfxge_get_txq_by_label() sfxge_ev.c
43  */
44
45 #include <sys/cdefs.h>
46 __FBSDID("$FreeBSD$");
47
48 #include <sys/types.h>
49 #include <sys/mbuf.h>
50 #include <sys/smp.h>
51 #include <sys/socket.h>
52 #include <sys/sysctl.h>
53
54 #include <net/bpf.h>
55 #include <net/ethernet.h>
56 #include <net/if.h>
57 #include <net/if_vlan_var.h>
58
59 #include <netinet/in.h>
60 #include <netinet/ip.h>
61 #include <netinet/ip6.h>
62 #include <netinet/tcp.h>
63
64 #include "common/efx.h"
65
66 #include "sfxge.h"
67 #include "sfxge_tx.h"
68
69 /* Set the block level to ensure there is space to generate a
70  * large number of descriptors for TSO.  With minimum MSS and
71  * maximum mbuf length we might need more than a ring-ful of
72  * descriptors, but this should not happen in practice except
73  * due to deliberate attack.  In that case we will truncate
74  * the output at a packet boundary.  Allow for a reasonable
75  * minimum MSS of 512.
76  */
77 #define SFXGE_TSO_MAX_DESC ((65535 / 512) * 2 + SFXGE_TX_MAPPING_MAX_SEG - 1)
78 #define SFXGE_TXQ_BLOCK_LEVEL (SFXGE_NDESCS - SFXGE_TSO_MAX_DESC)
79
80 /* Forward declarations. */
81 static inline void sfxge_tx_qdpl_service(struct sfxge_txq *txq);
82 static void sfxge_tx_qlist_post(struct sfxge_txq *txq);
83 static void sfxge_tx_qunblock(struct sfxge_txq *txq);
84 static int sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
85                               const bus_dma_segment_t *dma_seg, int n_dma_seg);
86
87 void
88 sfxge_tx_qcomplete(struct sfxge_txq *txq)
89 {
90         struct sfxge_softc *sc;
91         struct sfxge_evq *evq;
92         unsigned int completed;
93
94         sc = txq->sc;
95         evq = sc->evq[txq->evq_index];
96
97         mtx_assert(&evq->lock, MA_OWNED);
98
99         completed = txq->completed;
100         while (completed != txq->pending) {
101                 struct sfxge_tx_mapping *stmp;
102                 unsigned int id;
103
104                 id = completed++ & (SFXGE_NDESCS - 1);
105
106                 stmp = &txq->stmp[id];
107                 if (stmp->flags & TX_BUF_UNMAP) {
108                         bus_dmamap_unload(txq->packet_dma_tag, stmp->map);
109                         if (stmp->flags & TX_BUF_MBUF) {
110                                 struct mbuf *m = stmp->u.mbuf;
111                                 do
112                                         m = m_free(m);
113                                 while (m != NULL);
114                         } else {
115                                 free(stmp->u.heap_buf, M_SFXGE);
116                         }
117                         stmp->flags = 0;
118                 }
119         }
120         txq->completed = completed;
121
122         /* Check whether we need to unblock the queue. */
123         mb();
124         if (txq->blocked) {
125                 unsigned int level;
126
127                 level = txq->added - txq->completed;
128                 if (level <= SFXGE_TXQ_UNBLOCK_LEVEL)
129                         sfxge_tx_qunblock(txq);
130         }
131 }
132
133 #ifdef SFXGE_HAVE_MQ
134
135 /*
136  * Reorder the put list and append it to the get list.
137  */
138 static void
139 sfxge_tx_qdpl_swizzle(struct sfxge_txq *txq)
140 {
141         struct sfxge_tx_dpl *stdp;
142         struct mbuf *mbuf, *get_next, **get_tailp;
143         volatile uintptr_t *putp;
144         uintptr_t put;
145         unsigned int count;
146
147         mtx_assert(&txq->lock, MA_OWNED);
148
149         stdp = &txq->dpl;
150
151         /* Acquire the put list. */
152         putp = &stdp->std_put;
153         put = atomic_readandclear_ptr(putp);
154         mbuf = (void *)put;
155
156         if (mbuf == NULL)
157                 return;
158
159         /* Reverse the put list. */
160         get_tailp = &mbuf->m_nextpkt;
161         get_next = NULL;
162
163         count = 0;
164         do {
165                 struct mbuf *put_next;
166
167                 put_next = mbuf->m_nextpkt;
168                 mbuf->m_nextpkt = get_next;
169                 get_next = mbuf;
170                 mbuf = put_next;
171
172                 count++;
173         } while (mbuf != NULL);
174
175         /* Append the reversed put list to the get list. */
176         KASSERT(*get_tailp == NULL, ("*get_tailp != NULL"));
177         *stdp->std_getp = get_next;
178         stdp->std_getp = get_tailp;
179         stdp->std_count += count;
180 }
181
182 #endif /* SFXGE_HAVE_MQ */
183
184 static void
185 sfxge_tx_qreap(struct sfxge_txq *txq)
186 {
187         mtx_assert(SFXGE_TXQ_LOCK(txq), MA_OWNED);
188
189         txq->reaped = txq->completed;
190 }
191
192 static void
193 sfxge_tx_qlist_post(struct sfxge_txq *txq)
194 {
195         unsigned int old_added;
196         unsigned int level;
197         int rc;
198
199         mtx_assert(SFXGE_TXQ_LOCK(txq), MA_OWNED);
200
201         KASSERT(txq->n_pend_desc != 0, ("txq->n_pend_desc == 0"));
202         KASSERT(txq->n_pend_desc <= SFXGE_TSO_MAX_DESC,
203                 ("txq->n_pend_desc too large"));
204         KASSERT(!txq->blocked, ("txq->blocked"));
205
206         old_added = txq->added;
207
208         /* Post the fragment list. */
209         rc = efx_tx_qpost(txq->common, txq->pend_desc, txq->n_pend_desc,
210                           txq->reaped, &txq->added);
211         KASSERT(rc == 0, ("efx_tx_qpost() failed"));
212
213         /* If efx_tx_qpost() had to refragment, our information about
214          * buffers to free may be associated with the wrong
215          * descriptors.
216          */
217         KASSERT(txq->added - old_added == txq->n_pend_desc,
218                 ("efx_tx_qpost() refragmented descriptors"));
219
220         level = txq->added - txq->reaped;
221         KASSERT(level <= SFXGE_NDESCS, ("overfilled TX queue"));
222
223         /* Clear the fragment list. */
224         txq->n_pend_desc = 0;
225
226         /* Have we reached the block level? */
227         if (level < SFXGE_TXQ_BLOCK_LEVEL)
228                 return;
229
230         /* Reap, and check again */
231         sfxge_tx_qreap(txq);
232         level = txq->added - txq->reaped;
233         if (level < SFXGE_TXQ_BLOCK_LEVEL)
234                 return;
235
236         txq->blocked = 1;
237
238         /*
239          * Avoid a race with completion interrupt handling that could leave
240          * the queue blocked.
241          */
242         mb();
243         sfxge_tx_qreap(txq);
244         level = txq->added - txq->reaped;
245         if (level < SFXGE_TXQ_BLOCK_LEVEL) {
246                 mb();
247                 txq->blocked = 0;
248         }
249 }
250
251 static int sfxge_tx_queue_mbuf(struct sfxge_txq *txq, struct mbuf *mbuf)
252 {
253         bus_dmamap_t *used_map;
254         bus_dmamap_t map;
255         bus_dma_segment_t dma_seg[SFXGE_TX_MAPPING_MAX_SEG];
256         unsigned int id;
257         struct sfxge_tx_mapping *stmp;
258         efx_buffer_t *desc;
259         int n_dma_seg;
260         int rc;
261         int i;
262
263         KASSERT(!txq->blocked, ("txq->blocked"));
264
265         if (mbuf->m_pkthdr.csum_flags & CSUM_TSO)
266                 prefetch_read_many(mbuf->m_data);
267
268         if (txq->init_state != SFXGE_TXQ_STARTED) {
269                 rc = EINTR;
270                 goto reject;
271         }
272
273         /* Load the packet for DMA. */
274         id = txq->added & (SFXGE_NDESCS - 1);
275         stmp = &txq->stmp[id];
276         rc = bus_dmamap_load_mbuf_sg(txq->packet_dma_tag, stmp->map,
277                                      mbuf, dma_seg, &n_dma_seg, 0);
278         if (rc == EFBIG) {
279                 /* Try again. */
280                 struct mbuf *new_mbuf = m_collapse(mbuf, M_NOWAIT,
281                                                    SFXGE_TX_MAPPING_MAX_SEG);
282                 if (new_mbuf == NULL)
283                         goto reject;
284                 ++txq->collapses;
285                 mbuf = new_mbuf;
286                 rc = bus_dmamap_load_mbuf_sg(txq->packet_dma_tag,
287                                              stmp->map, mbuf,
288                                              dma_seg, &n_dma_seg, 0);
289         }
290         if (rc != 0)
291                 goto reject;
292
293         /* Make the packet visible to the hardware. */
294         bus_dmamap_sync(txq->packet_dma_tag, stmp->map, BUS_DMASYNC_PREWRITE);
295
296         used_map = &stmp->map;
297
298         if (mbuf->m_pkthdr.csum_flags & CSUM_TSO) {
299                 rc = sfxge_tx_queue_tso(txq, mbuf, dma_seg, n_dma_seg);
300                 if (rc < 0)
301                         goto reject_mapped;
302                 stmp = &txq->stmp[rc];
303         } else {
304                 /* Add the mapping to the fragment list, and set flags
305                  * for the buffer.
306                  */
307                 i = 0;
308                 for (;;) {
309                         desc = &txq->pend_desc[i];
310                         desc->eb_addr = dma_seg[i].ds_addr;
311                         desc->eb_size = dma_seg[i].ds_len;
312                         if (i == n_dma_seg - 1) {
313                                 desc->eb_eop = 1;
314                                 break;
315                         }
316                         desc->eb_eop = 0;
317                         i++;
318
319                         stmp->flags = 0;
320                         if (__predict_false(stmp ==
321                                             &txq->stmp[SFXGE_NDESCS - 1]))
322                                 stmp = &txq->stmp[0];
323                         else
324                                 stmp++;
325                 }
326                 txq->n_pend_desc = n_dma_seg;
327         }
328
329         /*
330          * If the mapping required more than one descriptor
331          * then we need to associate the DMA map with the last
332          * descriptor, not the first.
333          */
334         if (used_map != &stmp->map) {
335                 map = stmp->map;
336                 stmp->map = *used_map;
337                 *used_map = map;
338         }
339
340         stmp->u.mbuf = mbuf;
341         stmp->flags = TX_BUF_UNMAP | TX_BUF_MBUF;
342
343         /* Post the fragment list. */
344         sfxge_tx_qlist_post(txq);
345
346         return 0;
347
348 reject_mapped:
349         bus_dmamap_unload(txq->packet_dma_tag, *used_map);
350 reject:
351         /* Drop the packet on the floor. */
352         m_freem(mbuf);
353         ++txq->drops;
354
355         return rc;
356 }
357
358 #ifdef SFXGE_HAVE_MQ
359
360 /*
361  * Drain the deferred packet list into the transmit queue.
362  */
363 static void
364 sfxge_tx_qdpl_drain(struct sfxge_txq *txq)
365 {
366         struct sfxge_softc *sc;
367         struct sfxge_tx_dpl *stdp;
368         struct mbuf *mbuf, *next;
369         unsigned int count;
370         unsigned int pushed;
371         int rc;
372
373         mtx_assert(&txq->lock, MA_OWNED);
374
375         sc = txq->sc;
376         stdp = &txq->dpl;
377         pushed = txq->added;
378
379         prefetch_read_many(sc->enp);
380         prefetch_read_many(txq->common);
381
382         mbuf = stdp->std_get;
383         count = stdp->std_count;
384
385         while (count != 0) {
386                 KASSERT(mbuf != NULL, ("mbuf == NULL"));
387
388                 next = mbuf->m_nextpkt;
389                 mbuf->m_nextpkt = NULL;
390
391                 ETHER_BPF_MTAP(sc->ifnet, mbuf); /* packet capture */
392
393                 if (next != NULL)
394                         prefetch_read_many(next);
395
396                 rc = sfxge_tx_queue_mbuf(txq, mbuf);
397                 --count;
398                 mbuf = next;
399                 if (rc != 0)
400                         continue;
401
402                 if (txq->blocked)
403                         break;
404
405                 /* Push the fragments to the hardware in batches. */
406                 if (txq->added - pushed >= SFXGE_TX_BATCH) {
407                         efx_tx_qpush(txq->common, txq->added);
408                         pushed = txq->added;
409                 }
410         }
411
412         if (count == 0) {
413                 KASSERT(mbuf == NULL, ("mbuf != NULL"));
414                 stdp->std_get = NULL;
415                 stdp->std_count = 0;
416                 stdp->std_getp = &stdp->std_get;
417         } else {
418                 stdp->std_get = mbuf;
419                 stdp->std_count = count;
420         }
421
422         if (txq->added != pushed)
423                 efx_tx_qpush(txq->common, txq->added);
424
425         KASSERT(txq->blocked || stdp->std_count == 0,
426                 ("queue unblocked but count is non-zero"));
427 }
428
429 #define SFXGE_TX_QDPL_PENDING(_txq)                                     \
430     ((_txq)->dpl.std_put != 0)
431
432 /*
433  * Service the deferred packet list.
434  *
435  * NOTE: drops the txq mutex!
436  */
437 static inline void
438 sfxge_tx_qdpl_service(struct sfxge_txq *txq)
439 {
440         mtx_assert(&txq->lock, MA_OWNED);
441
442         do {
443                 if (SFXGE_TX_QDPL_PENDING(txq))
444                         sfxge_tx_qdpl_swizzle(txq);
445
446                 if (!txq->blocked)
447                         sfxge_tx_qdpl_drain(txq);
448
449                 mtx_unlock(&txq->lock);
450         } while (SFXGE_TX_QDPL_PENDING(txq) &&
451                  mtx_trylock(&txq->lock));
452 }
453
454 /*
455  * Put a packet on the deferred packet list.
456  *
457  * If we are called with the txq lock held, we put the packet on the "get
458  * list", otherwise we atomically push it on the "put list".  The swizzle
459  * function takes care of ordering.
460  *
461  * The length of the put list is bounded by SFXGE_TX_MAX_DEFFERED.  We
462  * overload the csum_data field in the mbuf to keep track of this length
463  * because there is no cheap alternative to avoid races.
464  */
465 static inline int
466 sfxge_tx_qdpl_put(struct sfxge_txq *txq, struct mbuf *mbuf, int locked)
467 {
468         struct sfxge_tx_dpl *stdp;
469
470         stdp = &txq->dpl;
471
472         KASSERT(mbuf->m_nextpkt == NULL, ("mbuf->m_nextpkt != NULL"));
473
474         if (locked) {
475                 mtx_assert(&txq->lock, MA_OWNED);
476
477                 sfxge_tx_qdpl_swizzle(txq);
478
479                 *(stdp->std_getp) = mbuf;
480                 stdp->std_getp = &mbuf->m_nextpkt;
481                 stdp->std_count++;
482         } else {
483                 volatile uintptr_t *putp;
484                 uintptr_t old;
485                 uintptr_t new;
486                 unsigned old_len;
487
488                 putp = &stdp->std_put;
489                 new = (uintptr_t)mbuf;
490
491                 do {
492                         old = *putp;
493                         if (old) {
494                                 struct mbuf *mp = (struct mbuf *)old;
495                                 old_len = mp->m_pkthdr.csum_data;
496                         } else
497                                 old_len = 0;
498                         if (old_len >= SFXGE_TX_MAX_DEFERRED)
499                                 return ENOBUFS;
500                         mbuf->m_pkthdr.csum_data = old_len + 1;
501                         mbuf->m_nextpkt = (void *)old;
502                 } while (atomic_cmpset_ptr(putp, old, new) == 0);
503         }
504
505         return (0);
506 }
507
508 /*
509  * Called from if_transmit - will try to grab the txq lock and enqueue to the
510  * put list if it succeeds, otherwise will push onto the defer list.
511  */
512 int
513 sfxge_tx_packet_add(struct sfxge_txq *txq, struct mbuf *m)
514 {
515         int locked;
516         int rc;
517
518         /*
519          * Try to grab the txq lock.  If we are able to get the lock,
520          * the packet will be appended to the "get list" of the deferred
521          * packet list.  Otherwise, it will be pushed on the "put list".
522          */
523         locked = mtx_trylock(&txq->lock);
524
525         /*
526          * Can only fail if we weren't able to get the lock.
527          */
528         if (sfxge_tx_qdpl_put(txq, m, locked) != 0) {
529                 KASSERT(!locked,
530                     ("sfxge_tx_qdpl_put() failed locked"));
531                 rc = ENOBUFS;
532                 goto fail;
533         }
534
535         /*
536          * Try to grab the lock again.
537          *
538          * If we are able to get the lock, we need to process the deferred
539          * packet list.  If we are not able to get the lock, another thread
540          * is processing the list.
541          */
542         if (!locked)
543                 locked = mtx_trylock(&txq->lock);
544
545         if (locked) {
546                 /* Try to service the list. */
547                 sfxge_tx_qdpl_service(txq);
548                 /* Lock has been dropped. */
549         }
550
551         return (0);
552
553 fail:
554         m_freem(m);
555         return (rc);
556         
557 }
558
559 static void
560 sfxge_tx_qdpl_flush(struct sfxge_txq *txq)
561 {
562         struct sfxge_tx_dpl *stdp = &txq->dpl;
563         struct mbuf *mbuf, *next;
564
565         mtx_lock(&txq->lock);
566
567         sfxge_tx_qdpl_swizzle(txq);
568         for (mbuf = stdp->std_get; mbuf != NULL; mbuf = next) {
569                 next = mbuf->m_nextpkt;
570                 m_freem(mbuf);
571         }
572         stdp->std_get = NULL;
573         stdp->std_count = 0;
574         stdp->std_getp = &stdp->std_get;        
575
576         mtx_unlock(&txq->lock);
577 }
578
579 void
580 sfxge_if_qflush(struct ifnet *ifp)
581 {
582         struct sfxge_softc *sc;
583         int i;
584
585         sc = ifp->if_softc;
586
587         for (i = 0; i < SFXGE_TX_SCALE(sc); i++)
588                 sfxge_tx_qdpl_flush(sc->txq[i]);
589 }
590
591 /*
592  * TX start -- called by the stack.
593  */
594 int
595 sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m)
596 {       
597         struct sfxge_softc *sc;
598         struct sfxge_txq *txq;
599         int rc;
600
601         sc = (struct sfxge_softc *)ifp->if_softc;
602
603         KASSERT(ifp->if_flags & IFF_UP, ("interface not up"));
604
605         if (!SFXGE_LINK_UP(sc)) {
606                 m_freem(m);
607                 return (0);
608         }
609
610         /* Pick the desired transmit queue. */
611         if (m->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_TSO)) {
612                 int index = 0;
613
614                 if (m->m_flags & M_FLOWID) {
615                         uint32_t hash = m->m_pkthdr.flowid;
616
617                         index = sc->rx_indir_table[hash % SFXGE_RX_SCALE_MAX];
618                 }
619                 txq = sc->txq[SFXGE_TXQ_IP_TCP_UDP_CKSUM + index];
620         } else if (m->m_pkthdr.csum_flags & CSUM_DELAY_IP) {
621                 txq = sc->txq[SFXGE_TXQ_IP_CKSUM];
622         } else {
623                 txq = sc->txq[SFXGE_TXQ_NON_CKSUM];
624         }
625
626         rc = sfxge_tx_packet_add(txq, m);
627
628         return (rc);
629 }
630
631 #else /* !SFXGE_HAVE_MQ */
632
633 static void sfxge_if_start_locked(struct ifnet *ifp)
634 {
635         struct sfxge_softc *sc = ifp->if_softc;
636         struct sfxge_txq *txq;
637         struct mbuf *mbuf;
638         unsigned int pushed[SFXGE_TXQ_NTYPES];
639         unsigned int q_index;
640
641         if ((ifp->if_drv_flags & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
642             IFF_DRV_RUNNING)
643                 return;
644
645         if (!sc->port.link_up)
646                 return;
647
648         for (q_index = 0; q_index < SFXGE_TXQ_NTYPES; q_index++) {
649                 txq = sc->txq[q_index];
650                 pushed[q_index] = txq->added;
651         }
652
653         while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
654                 IFQ_DRV_DEQUEUE(&ifp->if_snd, mbuf);
655                 if (mbuf == NULL)
656                         break;
657
658                 ETHER_BPF_MTAP(ifp, mbuf); /* packet capture */
659
660                 /* Pick the desired transmit queue. */
661                 if (mbuf->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_TSO))
662                         q_index = SFXGE_TXQ_IP_TCP_UDP_CKSUM;
663                 else if (mbuf->m_pkthdr.csum_flags & CSUM_DELAY_IP)
664                         q_index = SFXGE_TXQ_IP_CKSUM;
665                 else
666                         q_index = SFXGE_TXQ_NON_CKSUM;
667                 txq = sc->txq[q_index];
668
669                 if (sfxge_tx_queue_mbuf(txq, mbuf) != 0)
670                         continue;
671
672                 if (txq->blocked) {
673                         ifp->if_drv_flags |= IFF_DRV_OACTIVE;
674                         break;
675                 }
676
677                 /* Push the fragments to the hardware in batches. */
678                 if (txq->added - pushed[q_index] >= SFXGE_TX_BATCH) {
679                         efx_tx_qpush(txq->common, txq->added);
680                         pushed[q_index] = txq->added;
681                 }
682         }
683
684         for (q_index = 0; q_index < SFXGE_TXQ_NTYPES; q_index++) {
685                 txq = sc->txq[q_index];
686                 if (txq->added != pushed[q_index])
687                         efx_tx_qpush(txq->common, txq->added);
688         }
689 }
690
691 void sfxge_if_start(struct ifnet *ifp)
692 {
693         struct sfxge_softc *sc = ifp->if_softc;
694
695         mtx_lock(&sc->tx_lock);
696         sfxge_if_start_locked(ifp);
697         mtx_unlock(&sc->tx_lock);
698 }
699
700 static inline void
701 sfxge_tx_qdpl_service(struct sfxge_txq *txq)
702 {
703         struct sfxge_softc *sc = txq->sc;
704         struct ifnet *ifp = sc->ifnet;
705
706         mtx_assert(&sc->tx_lock, MA_OWNED);
707         ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
708         sfxge_if_start_locked(ifp);
709         mtx_unlock(&sc->tx_lock);
710 }
711
712 #endif /* SFXGE_HAVE_MQ */
713
714 /*
715  * Software "TSO".  Not quite as good as doing it in hardware, but
716  * still faster than segmenting in the stack.
717  */
718
719 struct sfxge_tso_state {
720         /* Output position */
721         unsigned out_len;       /* Remaining length in current segment */
722         unsigned seqnum;        /* Current sequence number */
723         unsigned packet_space;  /* Remaining space in current packet */
724
725         /* Input position */
726         unsigned dma_seg_i;     /* Current DMA segment number */
727         uint64_t dma_addr;      /* DMA address of current position */
728         unsigned in_len;        /* Remaining length in current mbuf */
729
730         const struct mbuf *mbuf; /* Input mbuf (head of chain) */
731         u_short protocol;       /* Network protocol (after VLAN decap) */
732         ssize_t nh_off;         /* Offset of network header */
733         ssize_t tcph_off;       /* Offset of TCP header */
734         unsigned header_len;    /* Number of bytes of header */
735         int full_packet_size;   /* Number of bytes to put in each outgoing
736                                  * segment */
737 };
738
739 static inline const struct ip *tso_iph(const struct sfxge_tso_state *tso)
740 {
741         KASSERT(tso->protocol == htons(ETHERTYPE_IP),
742                 ("tso_iph() in non-IPv4 state"));
743         return (const struct ip *)(tso->mbuf->m_data + tso->nh_off);
744 }
745 static inline const struct ip6_hdr *tso_ip6h(const struct sfxge_tso_state *tso)
746 {
747         KASSERT(tso->protocol == htons(ETHERTYPE_IPV6),
748                 ("tso_ip6h() in non-IPv6 state"));
749         return (const struct ip6_hdr *)(tso->mbuf->m_data + tso->nh_off);
750 }
751 static inline const struct tcphdr *tso_tcph(const struct sfxge_tso_state *tso)
752 {
753         return (const struct tcphdr *)(tso->mbuf->m_data + tso->tcph_off);
754 }
755
756 /* Size of preallocated TSO header buffers.  Larger blocks must be
757  * allocated from the heap.
758  */
759 #define TSOH_STD_SIZE   128
760
761 /* At most half the descriptors in the queue at any time will refer to
762  * a TSO header buffer, since they must always be followed by a
763  * payload descriptor referring to an mbuf.
764  */
765 #define TSOH_COUNT      (SFXGE_NDESCS / 2u)
766 #define TSOH_PER_PAGE   (PAGE_SIZE / TSOH_STD_SIZE)
767 #define TSOH_PAGE_COUNT ((TSOH_COUNT + TSOH_PER_PAGE - 1) / TSOH_PER_PAGE)
768
769 static int tso_init(struct sfxge_txq *txq)
770 {
771         struct sfxge_softc *sc = txq->sc;
772         int i, rc;
773
774         /* Allocate TSO header buffers */
775         txq->tsoh_buffer = malloc(TSOH_PAGE_COUNT * sizeof(txq->tsoh_buffer[0]),
776                                   M_SFXGE, M_WAITOK);
777
778         for (i = 0; i < TSOH_PAGE_COUNT; i++) {
779                 rc = sfxge_dma_alloc(sc, PAGE_SIZE, &txq->tsoh_buffer[i]);
780                 if (rc)
781                         goto fail;
782         }
783
784         return 0;
785
786 fail:
787         while (i-- > 0)
788                 sfxge_dma_free(&txq->tsoh_buffer[i]);
789         free(txq->tsoh_buffer, M_SFXGE);
790         txq->tsoh_buffer = NULL;
791         return rc;
792 }
793
794 static void tso_fini(struct sfxge_txq *txq)
795 {
796         int i;
797
798         if (txq->tsoh_buffer) {
799                 for (i = 0; i < TSOH_PAGE_COUNT; i++)
800                         sfxge_dma_free(&txq->tsoh_buffer[i]);
801                 free(txq->tsoh_buffer, M_SFXGE);
802         }
803 }
804
805 static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
806 {
807         struct ether_header *eh = mtod(mbuf, struct ether_header *);
808
809         tso->mbuf = mbuf;
810
811         /* Find network protocol and header */
812         tso->protocol = eh->ether_type;
813         if (tso->protocol == htons(ETHERTYPE_VLAN)) {
814                 struct ether_vlan_header *veh =
815                         mtod(mbuf, struct ether_vlan_header *);
816                 tso->protocol = veh->evl_proto;
817                 tso->nh_off = sizeof(*veh);
818         } else {
819                 tso->nh_off = sizeof(*eh);
820         }
821
822         /* Find TCP header */
823         if (tso->protocol == htons(ETHERTYPE_IP)) {
824                 KASSERT(tso_iph(tso)->ip_p == IPPROTO_TCP,
825                         ("TSO required on non-TCP packet"));
826                 tso->tcph_off = tso->nh_off + 4 * tso_iph(tso)->ip_hl;
827         } else {
828                 KASSERT(tso->protocol == htons(ETHERTYPE_IPV6),
829                         ("TSO required on non-IP packet"));
830                 KASSERT(tso_ip6h(tso)->ip6_nxt == IPPROTO_TCP,
831                         ("TSO required on non-TCP packet"));
832                 tso->tcph_off = tso->nh_off + sizeof(struct ip6_hdr);
833         }
834
835         /* We assume all headers are linear in the head mbuf */
836         tso->header_len = tso->tcph_off + 4 * tso_tcph(tso)->th_off;
837         KASSERT(tso->header_len <= mbuf->m_len, ("packet headers fragmented"));
838         tso->full_packet_size = tso->header_len + mbuf->m_pkthdr.tso_segsz;
839
840         tso->seqnum = ntohl(tso_tcph(tso)->th_seq);
841
842         /* These flags must not be duplicated */
843         KASSERT(!(tso_tcph(tso)->th_flags & (TH_URG | TH_SYN | TH_RST)),
844                 ("incompatible TCP flag on TSO packet"));
845
846         tso->out_len = mbuf->m_pkthdr.len - tso->header_len;
847 }
848
849 /*
850  * tso_fill_packet_with_fragment - form descriptors for the current fragment
851  *
852  * Form descriptors for the current fragment, until we reach the end
853  * of fragment or end-of-packet.  Return 0 on success, 1 if not enough
854  * space.
855  */
856 static void tso_fill_packet_with_fragment(struct sfxge_txq *txq,
857                                           struct sfxge_tso_state *tso)
858 {
859         efx_buffer_t *desc;
860         int n;
861
862         if (tso->in_len == 0 || tso->packet_space == 0)
863                 return;
864
865         KASSERT(tso->in_len > 0, ("TSO input length went negative"));
866         KASSERT(tso->packet_space > 0, ("TSO packet space went negative"));
867
868         n = min(tso->in_len, tso->packet_space);
869
870         tso->packet_space -= n;
871         tso->out_len -= n;
872         tso->in_len -= n;
873
874         desc = &txq->pend_desc[txq->n_pend_desc++];
875         desc->eb_addr = tso->dma_addr;
876         desc->eb_size = n;
877         desc->eb_eop = tso->out_len == 0 || tso->packet_space == 0;
878
879         tso->dma_addr += n;
880 }
881
882 /* Callback from bus_dmamap_load() for long TSO headers. */
883 static void tso_map_long_header(void *dma_addr_ret,
884                                 bus_dma_segment_t *segs, int nseg,
885                                 int error)
886 {
887         *(uint64_t *)dma_addr_ret = ((__predict_true(error == 0) &&
888                                       __predict_true(nseg == 1)) ?
889                                      segs->ds_addr : 0);
890 }
891
892 /*
893  * tso_start_new_packet - generate a new header and prepare for the new packet
894  *
895  * Generate a new header and prepare for the new packet.  Return 0 on
896  * success, or an error code if failed to alloc header.
897  */
898 static int tso_start_new_packet(struct sfxge_txq *txq,
899                                 struct sfxge_tso_state *tso,
900                                 unsigned int id)
901 {
902         struct sfxge_tx_mapping *stmp = &txq->stmp[id];
903         struct tcphdr *tsoh_th;
904         unsigned ip_length;
905         caddr_t header;
906         uint64_t dma_addr;
907         bus_dmamap_t map;
908         efx_buffer_t *desc;
909         int rc;
910
911         /* Allocate a DMA-mapped header buffer. */
912         if (__predict_true(tso->header_len <= TSOH_STD_SIZE)) {
913                 unsigned int page_index = (id / 2) / TSOH_PER_PAGE;
914                 unsigned int buf_index = (id / 2) % TSOH_PER_PAGE;
915
916                 header = (txq->tsoh_buffer[page_index].esm_base +
917                           buf_index * TSOH_STD_SIZE);
918                 dma_addr = (txq->tsoh_buffer[page_index].esm_addr +
919                             buf_index * TSOH_STD_SIZE);
920                 map = txq->tsoh_buffer[page_index].esm_map;
921
922                 stmp->flags = 0;
923         } else {
924                 /* We cannot use bus_dmamem_alloc() as that may sleep */
925                 header = malloc(tso->header_len, M_SFXGE, M_NOWAIT);
926                 if (__predict_false(!header))
927                         return ENOMEM;     
928                 rc = bus_dmamap_load(txq->packet_dma_tag, stmp->map,
929                                      header, tso->header_len,
930                                      tso_map_long_header, &dma_addr,
931                                      BUS_DMA_NOWAIT);
932                 if (__predict_false(dma_addr == 0)) {
933                         if (rc == 0) {
934                                 /* Succeeded but got >1 segment */
935                                 bus_dmamap_unload(txq->packet_dma_tag,
936                                                   stmp->map);
937                                 rc = EINVAL;
938                         }
939                         free(header, M_SFXGE);
940                         return rc;
941                 }
942                 map = stmp->map;
943
944                 txq->tso_long_headers++;
945                 stmp->u.heap_buf = header;
946                 stmp->flags = TX_BUF_UNMAP;
947         }
948
949         tsoh_th = (struct tcphdr *)(header + tso->tcph_off);
950
951         /* Copy and update the headers. */
952         memcpy(header, tso->mbuf->m_data, tso->header_len);
953
954         tsoh_th->th_seq = htonl(tso->seqnum);
955         tso->seqnum += tso->mbuf->m_pkthdr.tso_segsz;
956         if (tso->out_len > tso->mbuf->m_pkthdr.tso_segsz) {
957                 /* This packet will not finish the TSO burst. */
958                 ip_length = tso->full_packet_size - tso->nh_off;
959                 tsoh_th->th_flags &= ~(TH_FIN | TH_PUSH);
960         } else {
961                 /* This packet will be the last in the TSO burst. */
962                 ip_length = tso->header_len - tso->nh_off + tso->out_len;
963         }
964
965         if (tso->protocol == htons(ETHERTYPE_IP)) {
966                 struct ip *tsoh_iph = (struct ip *)(header + tso->nh_off);
967                 tsoh_iph->ip_len = htons(ip_length);
968                 /* XXX We should increment ip_id, but FreeBSD doesn't
969                  * currently allocate extra IDs for multiple segments.
970                  */
971         } else {
972                 struct ip6_hdr *tsoh_iph =
973                         (struct ip6_hdr *)(header + tso->nh_off);
974                 tsoh_iph->ip6_plen = htons(ip_length - sizeof(*tsoh_iph));
975         }
976
977         /* Make the header visible to the hardware. */
978         bus_dmamap_sync(txq->packet_dma_tag, map, BUS_DMASYNC_PREWRITE);
979
980         tso->packet_space = tso->mbuf->m_pkthdr.tso_segsz;
981         txq->tso_packets++;
982
983         /* Form a descriptor for this header. */
984         desc = &txq->pend_desc[txq->n_pend_desc++];
985         desc->eb_addr = dma_addr;
986         desc->eb_size = tso->header_len;
987         desc->eb_eop = 0;
988
989         return 0;
990 }
991
992 static int
993 sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
994                    const bus_dma_segment_t *dma_seg, int n_dma_seg)
995 {
996         struct sfxge_tso_state tso;
997         unsigned int id, next_id;
998
999         tso_start(&tso, mbuf);
1000
1001         /* Grab the first payload fragment. */
1002         if (dma_seg->ds_len == tso.header_len) {
1003                 --n_dma_seg;
1004                 KASSERT(n_dma_seg, ("no payload found in TSO packet"));
1005                 ++dma_seg;
1006                 tso.in_len = dma_seg->ds_len;
1007                 tso.dma_addr = dma_seg->ds_addr;
1008         } else {
1009                 tso.in_len = dma_seg->ds_len - tso.header_len;
1010                 tso.dma_addr = dma_seg->ds_addr + tso.header_len;
1011         }
1012
1013         id = txq->added & (SFXGE_NDESCS - 1);
1014         if (__predict_false(tso_start_new_packet(txq, &tso, id)))
1015                 return -1;
1016
1017         while (1) {
1018                 id = (id + 1) & (SFXGE_NDESCS - 1);
1019                 tso_fill_packet_with_fragment(txq, &tso);
1020
1021                 /* Move onto the next fragment? */
1022                 if (tso.in_len == 0) {
1023                         --n_dma_seg;
1024                         if (n_dma_seg == 0)
1025                                 break;
1026                         ++dma_seg;
1027                         tso.in_len = dma_seg->ds_len;
1028                         tso.dma_addr = dma_seg->ds_addr;
1029                 }
1030
1031                 /* End of packet? */
1032                 if (tso.packet_space == 0) {
1033                         /* If the queue is now full due to tiny MSS,
1034                          * or we can't create another header, discard
1035                          * the remainder of the input mbuf but do not
1036                          * roll back the work we have done.
1037                          */
1038                         if (txq->n_pend_desc >
1039                             SFXGE_TSO_MAX_DESC - (1 + SFXGE_TX_MAPPING_MAX_SEG))
1040                                 break;
1041                         next_id = (id + 1) & (SFXGE_NDESCS - 1);
1042                         if (__predict_false(tso_start_new_packet(txq, &tso,
1043                                                                  next_id)))
1044                                 break;
1045                         id = next_id;
1046                 }
1047         }
1048
1049         txq->tso_bursts++;
1050         return id;
1051 }
1052
1053 static void
1054 sfxge_tx_qunblock(struct sfxge_txq *txq)
1055 {
1056         struct sfxge_softc *sc;
1057         struct sfxge_evq *evq;
1058
1059         sc = txq->sc;
1060         evq = sc->evq[txq->evq_index];
1061
1062         mtx_assert(&evq->lock, MA_OWNED);
1063
1064         if (txq->init_state != SFXGE_TXQ_STARTED)
1065                 return;
1066
1067         mtx_lock(SFXGE_TXQ_LOCK(txq));
1068
1069         if (txq->blocked) {
1070                 unsigned int level;
1071
1072                 level = txq->added - txq->completed;
1073                 if (level <= SFXGE_TXQ_UNBLOCK_LEVEL)
1074                         txq->blocked = 0;
1075         }
1076
1077         sfxge_tx_qdpl_service(txq);
1078         /* note: lock has been dropped */
1079 }
1080
1081 void
1082 sfxge_tx_qflush_done(struct sfxge_txq *txq)
1083 {
1084
1085         txq->flush_state = SFXGE_FLUSH_DONE;
1086 }
1087
1088 static void
1089 sfxge_tx_qstop(struct sfxge_softc *sc, unsigned int index)
1090 {
1091         struct sfxge_txq *txq;
1092         struct sfxge_evq *evq;
1093         unsigned int count;
1094
1095         txq = sc->txq[index];
1096         evq = sc->evq[txq->evq_index];
1097
1098         mtx_lock(SFXGE_TXQ_LOCK(txq));
1099
1100         KASSERT(txq->init_state == SFXGE_TXQ_STARTED,
1101             ("txq->init_state != SFXGE_TXQ_STARTED"));
1102
1103         txq->init_state = SFXGE_TXQ_INITIALIZED;
1104         txq->flush_state = SFXGE_FLUSH_PENDING;
1105
1106         /* Flush the transmit queue. */
1107         efx_tx_qflush(txq->common);
1108
1109         mtx_unlock(SFXGE_TXQ_LOCK(txq));
1110
1111         count = 0;
1112         do {
1113                 /* Spin for 100ms. */
1114                 DELAY(100000);
1115
1116                 if (txq->flush_state != SFXGE_FLUSH_PENDING)
1117                         break;
1118         } while (++count < 20);
1119
1120         mtx_lock(&evq->lock);
1121         mtx_lock(SFXGE_TXQ_LOCK(txq));
1122
1123         KASSERT(txq->flush_state != SFXGE_FLUSH_FAILED,
1124             ("txq->flush_state == SFXGE_FLUSH_FAILED"));
1125
1126         txq->flush_state = SFXGE_FLUSH_DONE;
1127
1128         txq->blocked = 0;
1129         txq->pending = txq->added;
1130
1131         sfxge_tx_qcomplete(txq);
1132         KASSERT(txq->completed == txq->added,
1133             ("txq->completed != txq->added"));
1134
1135         sfxge_tx_qreap(txq);
1136         KASSERT(txq->reaped == txq->completed,
1137             ("txq->reaped != txq->completed"));
1138
1139         txq->added = 0;
1140         txq->pending = 0;
1141         txq->completed = 0;
1142         txq->reaped = 0;
1143
1144         /* Destroy the common code transmit queue. */
1145         efx_tx_qdestroy(txq->common);
1146         txq->common = NULL;
1147
1148         efx_sram_buf_tbl_clear(sc->enp, txq->buf_base_id,
1149             EFX_TXQ_NBUFS(SFXGE_NDESCS));
1150
1151         mtx_unlock(&evq->lock);
1152         mtx_unlock(SFXGE_TXQ_LOCK(txq));
1153 }
1154
1155 static int
1156 sfxge_tx_qstart(struct sfxge_softc *sc, unsigned int index)
1157 {
1158         struct sfxge_txq *txq;
1159         efsys_mem_t *esmp;
1160         uint16_t flags;
1161         struct sfxge_evq *evq;
1162         int rc;
1163
1164         txq = sc->txq[index];
1165         esmp = &txq->mem;
1166         evq = sc->evq[txq->evq_index];
1167
1168         KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED,
1169             ("txq->init_state != SFXGE_TXQ_INITIALIZED"));
1170         KASSERT(evq->init_state == SFXGE_EVQ_STARTED,
1171             ("evq->init_state != SFXGE_EVQ_STARTED"));
1172
1173         /* Program the buffer table. */
1174         if ((rc = efx_sram_buf_tbl_set(sc->enp, txq->buf_base_id, esmp,
1175             EFX_TXQ_NBUFS(SFXGE_NDESCS))) != 0)
1176                 return rc;
1177
1178         /* Determine the kind of queue we are creating. */
1179         switch (txq->type) {
1180         case SFXGE_TXQ_NON_CKSUM:
1181                 flags = 0;
1182                 break;
1183         case SFXGE_TXQ_IP_CKSUM:
1184                 flags = EFX_CKSUM_IPV4;
1185                 break;
1186         case SFXGE_TXQ_IP_TCP_UDP_CKSUM:
1187                 flags = EFX_CKSUM_IPV4 | EFX_CKSUM_TCPUDP;
1188                 break;
1189         default:
1190                 KASSERT(0, ("Impossible TX queue"));
1191                 flags = 0;
1192                 break;
1193         }
1194
1195         /* Create the common code transmit queue. */
1196         if ((rc = efx_tx_qcreate(sc->enp, index, txq->type, esmp,
1197             SFXGE_NDESCS, txq->buf_base_id, flags, evq->common,
1198             &txq->common)) != 0)
1199                 goto fail;
1200
1201         mtx_lock(SFXGE_TXQ_LOCK(txq));
1202         
1203         /* Enable the transmit queue. */
1204         efx_tx_qenable(txq->common);
1205
1206         txq->init_state = SFXGE_TXQ_STARTED;
1207
1208         mtx_unlock(SFXGE_TXQ_LOCK(txq));
1209
1210         return (0);
1211
1212 fail:
1213         efx_sram_buf_tbl_clear(sc->enp, txq->buf_base_id,
1214             EFX_TXQ_NBUFS(SFXGE_NDESCS));
1215         return rc;
1216 }
1217
1218 void
1219 sfxge_tx_stop(struct sfxge_softc *sc)
1220 {
1221         const efx_nic_cfg_t *encp;
1222         int index;
1223
1224         index = SFXGE_TX_SCALE(sc);
1225         while (--index >= 0)
1226                 sfxge_tx_qstop(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index);
1227
1228         sfxge_tx_qstop(sc, SFXGE_TXQ_IP_CKSUM);
1229
1230         encp = efx_nic_cfg_get(sc->enp);
1231         sfxge_tx_qstop(sc, SFXGE_TXQ_NON_CKSUM);
1232
1233         /* Tear down the transmit module */
1234         efx_tx_fini(sc->enp);
1235 }
1236
1237 int
1238 sfxge_tx_start(struct sfxge_softc *sc)
1239 {
1240         int index;
1241         int rc;
1242
1243         /* Initialize the common code transmit module. */
1244         if ((rc = efx_tx_init(sc->enp)) != 0)
1245                 return (rc);
1246
1247         if ((rc = sfxge_tx_qstart(sc, SFXGE_TXQ_NON_CKSUM)) != 0)
1248                 goto fail;
1249
1250         if ((rc = sfxge_tx_qstart(sc, SFXGE_TXQ_IP_CKSUM)) != 0)
1251                 goto fail2;
1252
1253         for (index = 0; index < SFXGE_TX_SCALE(sc); index++) {
1254                 if ((rc = sfxge_tx_qstart(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM +
1255                     index)) != 0)
1256                         goto fail3;
1257         }
1258
1259         return (0);
1260
1261 fail3:
1262         while (--index >= 0)
1263                 sfxge_tx_qstop(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index);
1264
1265         sfxge_tx_qstop(sc, SFXGE_TXQ_IP_CKSUM);
1266
1267 fail2:
1268         sfxge_tx_qstop(sc, SFXGE_TXQ_NON_CKSUM);
1269
1270 fail:
1271         efx_tx_fini(sc->enp);
1272
1273         return (rc);
1274 }
1275
1276 /**
1277  * Destroy a transmit queue.
1278  */
1279 static void
1280 sfxge_tx_qfini(struct sfxge_softc *sc, unsigned int index)
1281 {
1282         struct sfxge_txq *txq;
1283         unsigned int nmaps = SFXGE_NDESCS;
1284
1285         txq = sc->txq[index];
1286
1287         KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED,
1288             ("txq->init_state != SFXGE_TXQ_INITIALIZED"));
1289
1290         if (txq->type == SFXGE_TXQ_IP_TCP_UDP_CKSUM)
1291                 tso_fini(txq);
1292
1293         /* Free the context arrays. */
1294         free(txq->pend_desc, M_SFXGE);
1295         while (nmaps--)
1296                 bus_dmamap_destroy(txq->packet_dma_tag, txq->stmp[nmaps].map);
1297         free(txq->stmp, M_SFXGE);
1298
1299         /* Release DMA memory mapping. */
1300         sfxge_dma_free(&txq->mem);
1301
1302         sc->txq[index] = NULL;
1303
1304 #ifdef SFXGE_HAVE_MQ
1305         mtx_destroy(&txq->lock);
1306 #endif
1307
1308         free(txq, M_SFXGE);
1309 }
1310
1311 static int
1312 sfxge_tx_qinit(struct sfxge_softc *sc, unsigned int txq_index,
1313     enum sfxge_txq_type type, unsigned int evq_index)
1314 {
1315         struct sfxge_txq *txq;
1316         struct sfxge_evq *evq;
1317 #ifdef SFXGE_HAVE_MQ
1318         struct sfxge_tx_dpl *stdp;
1319 #endif
1320         efsys_mem_t *esmp;
1321         unsigned int nmaps;
1322         int rc;
1323
1324         txq = malloc(sizeof(struct sfxge_txq), M_SFXGE, M_ZERO | M_WAITOK);
1325         txq->sc = sc;
1326
1327         sc->txq[txq_index] = txq;
1328         esmp = &txq->mem;
1329
1330         evq = sc->evq[evq_index];
1331
1332         /* Allocate and zero DMA space for the descriptor ring. */
1333         if ((rc = sfxge_dma_alloc(sc, EFX_TXQ_SIZE(SFXGE_NDESCS), esmp)) != 0)
1334                 return (rc);
1335         (void)memset(esmp->esm_base, 0, EFX_TXQ_SIZE(SFXGE_NDESCS));
1336
1337         /* Allocate buffer table entries. */
1338         sfxge_sram_buf_tbl_alloc(sc, EFX_TXQ_NBUFS(SFXGE_NDESCS),
1339                                  &txq->buf_base_id);
1340
1341         /* Create a DMA tag for packet mappings. */
1342         if (bus_dma_tag_create(sc->parent_dma_tag, 1, 0x1000,
1343             MIN(0x3FFFFFFFFFFFUL, BUS_SPACE_MAXADDR), BUS_SPACE_MAXADDR, NULL,
1344             NULL, 0x11000, SFXGE_TX_MAPPING_MAX_SEG, 0x1000, 0, NULL, NULL,
1345             &txq->packet_dma_tag) != 0) {
1346                 device_printf(sc->dev, "Couldn't allocate txq DMA tag\n");
1347                 rc = ENOMEM;
1348                 goto fail;
1349         }
1350
1351         /* Allocate pending descriptor array for batching writes. */
1352         txq->pend_desc = malloc(sizeof(efx_buffer_t) * SFXGE_NDESCS,
1353                                 M_SFXGE, M_ZERO | M_WAITOK);
1354
1355         /* Allocate and initialise mbuf DMA mapping array. */
1356         txq->stmp = malloc(sizeof(struct sfxge_tx_mapping) * SFXGE_NDESCS,
1357             M_SFXGE, M_ZERO | M_WAITOK);
1358         for (nmaps = 0; nmaps < SFXGE_NDESCS; nmaps++) {
1359                 rc = bus_dmamap_create(txq->packet_dma_tag, 0,
1360                                        &txq->stmp[nmaps].map);
1361                 if (rc != 0)
1362                         goto fail2;
1363         }
1364
1365         if (type == SFXGE_TXQ_IP_TCP_UDP_CKSUM &&
1366             (rc = tso_init(txq)) != 0)
1367                 goto fail3;
1368
1369 #ifdef SFXGE_HAVE_MQ
1370         /* Initialize the deferred packet list. */
1371         stdp = &txq->dpl;
1372         stdp->std_getp = &stdp->std_get;
1373
1374         mtx_init(&txq->lock, "txq", NULL, MTX_DEF);
1375 #endif
1376
1377         txq->type = type;
1378         txq->evq_index = evq_index;
1379         txq->txq_index = txq_index;
1380         txq->init_state = SFXGE_TXQ_INITIALIZED;
1381
1382         return (0);
1383
1384 fail3:
1385         free(txq->pend_desc, M_SFXGE);
1386 fail2:
1387         while (nmaps--)
1388                 bus_dmamap_destroy(txq->packet_dma_tag, txq->stmp[nmaps].map);
1389         free(txq->stmp, M_SFXGE);
1390         bus_dma_tag_destroy(txq->packet_dma_tag);
1391
1392 fail:
1393         sfxge_dma_free(esmp);
1394
1395         return (rc);
1396 }
1397
1398 static const struct {
1399         const char *name;
1400         size_t offset;
1401 } sfxge_tx_stats[] = {
1402 #define SFXGE_TX_STAT(name, member) \
1403         { #name, offsetof(struct sfxge_txq, member) }
1404         SFXGE_TX_STAT(tso_bursts, tso_bursts),
1405         SFXGE_TX_STAT(tso_packets, tso_packets),
1406         SFXGE_TX_STAT(tso_long_headers, tso_long_headers),
1407         SFXGE_TX_STAT(tx_collapses, collapses),
1408         SFXGE_TX_STAT(tx_drops, drops),
1409 };
1410
1411 static int
1412 sfxge_tx_stat_handler(SYSCTL_HANDLER_ARGS)
1413 {
1414         struct sfxge_softc *sc = arg1;
1415         unsigned int id = arg2;
1416         unsigned long sum;
1417         unsigned int index;
1418
1419         /* Sum across all TX queues */
1420         sum = 0;
1421         for (index = 0;
1422              index < SFXGE_TXQ_IP_TCP_UDP_CKSUM + SFXGE_TX_SCALE(sc);
1423              index++)
1424                 sum += *(unsigned long *)((caddr_t)sc->txq[index] +
1425                                           sfxge_tx_stats[id].offset);
1426
1427         return SYSCTL_OUT(req, &sum, sizeof(sum));
1428 }
1429
1430 static void
1431 sfxge_tx_stat_init(struct sfxge_softc *sc)
1432 {
1433         struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
1434         struct sysctl_oid_list *stat_list;
1435         unsigned int id;
1436
1437         stat_list = SYSCTL_CHILDREN(sc->stats_node);
1438
1439         for (id = 0;
1440              id < sizeof(sfxge_tx_stats) / sizeof(sfxge_tx_stats[0]);
1441              id++) {
1442                 SYSCTL_ADD_PROC(
1443                         ctx, stat_list,
1444                         OID_AUTO, sfxge_tx_stats[id].name,
1445                         CTLTYPE_ULONG|CTLFLAG_RD,
1446                         sc, id, sfxge_tx_stat_handler, "LU",
1447                         "");
1448         }
1449 }
1450
1451 void
1452 sfxge_tx_fini(struct sfxge_softc *sc)
1453 {
1454         int index;
1455
1456         index = SFXGE_TX_SCALE(sc);
1457         while (--index >= 0)
1458                 sfxge_tx_qfini(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index);
1459
1460         sfxge_tx_qfini(sc, SFXGE_TXQ_IP_CKSUM);
1461         sfxge_tx_qfini(sc, SFXGE_TXQ_NON_CKSUM);
1462 }
1463
1464
1465 int
1466 sfxge_tx_init(struct sfxge_softc *sc)
1467 {
1468         struct sfxge_intr *intr;
1469         int index;
1470         int rc;
1471
1472         intr = &sc->intr;
1473
1474         KASSERT(intr->state == SFXGE_INTR_INITIALIZED,
1475             ("intr->state != SFXGE_INTR_INITIALIZED"));
1476
1477         /* Initialize the transmit queues */
1478         if ((rc = sfxge_tx_qinit(sc, SFXGE_TXQ_NON_CKSUM,
1479             SFXGE_TXQ_NON_CKSUM, 0)) != 0)
1480                 goto fail;
1481
1482         if ((rc = sfxge_tx_qinit(sc, SFXGE_TXQ_IP_CKSUM,
1483             SFXGE_TXQ_IP_CKSUM, 0)) != 0)
1484                 goto fail2;
1485
1486         for (index = 0; index < SFXGE_TX_SCALE(sc); index++) {
1487                 if ((rc = sfxge_tx_qinit(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index,
1488                     SFXGE_TXQ_IP_TCP_UDP_CKSUM, index)) != 0)
1489                         goto fail3;
1490         }
1491
1492         sfxge_tx_stat_init(sc);
1493
1494         return (0);
1495
1496 fail3:
1497         sfxge_tx_qfini(sc, SFXGE_TXQ_IP_CKSUM);
1498
1499         while (--index >= 0)
1500                 sfxge_tx_qfini(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index);
1501
1502 fail2:
1503         sfxge_tx_qfini(sc, SFXGE_TXQ_NON_CKSUM);
1504
1505 fail:
1506         return (rc);
1507 }