Deleted Added
full compact
sfxge_tx.c (264461) sfxge_tx.c (272325)
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

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

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>
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

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

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: head/sys/dev/sfxge/sfxge_tx.c 264461 2014-04-14 16:31:56Z gnn $");
46__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge_tx.c 272325 2014-09-30 20:18:10Z gnn $");
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>

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

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 */
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>

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

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)
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. */
81static inline void sfxge_tx_qdpl_service(struct sfxge_txq *txq);
82static void sfxge_tx_qlist_post(struct sfxge_txq *txq);
83static void sfxge_tx_qunblock(struct sfxge_txq *txq);
84static 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

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

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
79
80/* Forward declarations. */
81static inline void sfxge_tx_qdpl_service(struct sfxge_txq *txq);
82static void sfxge_tx_qlist_post(struct sfxge_txq *txq);
83static void sfxge_tx_qunblock(struct sfxge_txq *txq);
84static 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

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

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;
346 return (0);
347
348reject_mapped:
349 bus_dmamap_unload(txq->packet_dma_tag, *used_map);
350reject:
351 /* Drop the packet on the floor. */
352 m_freem(mbuf);
353 ++txq->drops;
354
347
348reject_mapped:
349 bus_dmamap_unload(txq->packet_dma_tag, *used_map);
350reject:
351 /* Drop the packet on the floor. */
352 m_freem(mbuf);
353 ++txq->drops;
354
355 return rc;
355 return (rc);
356}
357
358#ifdef SFXGE_HAVE_MQ
359
360/*
361 * Drain the deferred packet list into the transmit queue.
362 */
363static void

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

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
356}
357
358#ifdef SFXGE_HAVE_MQ
359
360/*
361 * Drain the deferred packet list into the transmit queue.
362 */
363static void

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

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)
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 */
437static inline void
438sfxge_tx_qdpl_service(struct sfxge_txq *txq)

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

488 uintptr_t new;
489 unsigned old_len;
490
491 putp = &stdp->std_put;
492 new = (uintptr_t)mbuf;
493
494 do {
495 old = *putp;
431
432/*
433 * Service the deferred packet list.
434 *
435 * NOTE: drops the txq mutex!
436 */
437static inline void
438sfxge_tx_qdpl_service(struct sfxge_txq *txq)

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

488 uintptr_t new;
489 unsigned old_len;
490
491 putp = &stdp->std_put;
492 new = (uintptr_t)mbuf;
493
494 do {
495 old = *putp;
496 if (old) {
496 if (old != 0) {
497 struct mbuf *mp = (struct mbuf *)old;
498 old_len = mp->m_pkthdr.csum_data;
499 } else
500 old_len = 0;
501 if (old_len >= SFXGE_TX_DPL_PUT_PKT_LIMIT_DEFAULT)
502 return (ENOBUFS);
503 mbuf->m_pkthdr.csum_data = old_len + 1;
504 mbuf->m_nextpkt = (void *)old;

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

554 }
555
556 return (0);
557
558fail:
559 m_freem(m);
560 atomic_add_long(&txq->early_drops, 1);
561 return (rc);
497 struct mbuf *mp = (struct mbuf *)old;
498 old_len = mp->m_pkthdr.csum_data;
499 } else
500 old_len = 0;
501 if (old_len >= SFXGE_TX_DPL_PUT_PKT_LIMIT_DEFAULT)
502 return (ENOBUFS);
503 mbuf->m_pkthdr.csum_data = old_len + 1;
504 mbuf->m_nextpkt = (void *)old;

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

554 }
555
556 return (0);
557
558fail:
559 m_freem(m);
560 atomic_add_long(&txq->early_drops, 1);
561 return (rc);
562
563}
564
565static void
566sfxge_tx_qdpl_flush(struct sfxge_txq *txq)
567{
568 struct sfxge_tx_dpl *stdp = &txq->dpl;
569 struct mbuf *mbuf, *next;
570
571 mtx_lock(&txq->lock);
572
573 sfxge_tx_qdpl_swizzle(txq);
574 for (mbuf = stdp->std_get; mbuf != NULL; mbuf = next) {
575 next = mbuf->m_nextpkt;
576 m_freem(mbuf);
577 }
578 stdp->std_get = NULL;
579 stdp->std_count = 0;
562}
563
564static void
565sfxge_tx_qdpl_flush(struct sfxge_txq *txq)
566{
567 struct sfxge_tx_dpl *stdp = &txq->dpl;
568 struct mbuf *mbuf, *next;
569
570 mtx_lock(&txq->lock);
571
572 sfxge_tx_qdpl_swizzle(txq);
573 for (mbuf = stdp->std_get; mbuf != NULL; mbuf = next) {
574 next = mbuf->m_nextpkt;
575 m_freem(mbuf);
576 }
577 stdp->std_get = NULL;
578 stdp->std_count = 0;
580 stdp->std_getp = &stdp->std_get;
579 stdp->std_getp = &stdp->std_get;
581
582 mtx_unlock(&txq->lock);
583}
584
585void
586sfxge_if_qflush(struct ifnet *ifp)
587{
588 struct sfxge_softc *sc;

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

594 sfxge_tx_qdpl_flush(sc->txq[i]);
595}
596
597/*
598 * TX start -- called by the stack.
599 */
600int
601sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m)
580
581 mtx_unlock(&txq->lock);
582}
583
584void
585sfxge_if_qflush(struct ifnet *ifp)
586{
587 struct sfxge_softc *sc;

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

593 sfxge_tx_qdpl_flush(sc->txq[i]);
594}
595
596/*
597 * TX start -- called by the stack.
598 */
599int
600sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m)
602{
601{
603 struct sfxge_softc *sc;
604 struct sfxge_txq *txq;
605 int rc;
606
607 sc = (struct sfxge_softc *)ifp->if_softc;
608
609 KASSERT(ifp->if_flags & IFF_UP, ("interface not up"));
610

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

647 return;
648
649 for (q_index = 0; q_index < SFXGE_TXQ_NTYPES; q_index++) {
650 txq = sc->txq[q_index];
651 pushed[q_index] = txq->added;
652 }
653
654 while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
602 struct sfxge_softc *sc;
603 struct sfxge_txq *txq;
604 int rc;
605
606 sc = (struct sfxge_softc *)ifp->if_softc;
607
608 KASSERT(ifp->if_flags & IFF_UP, ("interface not up"));
609

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

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)) {
655 IFQ_DRV_DEQUEUE(&ifp->if_snd, mbuf);
654 IFQ_DRV_DEQUEUE(&ifp->if_snd, mbuf);
656 if (mbuf == NULL)
657 break;
658
659 ETHER_BPF_MTAP(ifp, mbuf); /* packet capture */
660
661 /* Pick the desired transmit queue. */
662 if (mbuf->m_pkthdr.csum_flags & (CSUM_DELAY_DATA | CSUM_TSO))
663 q_index = SFXGE_TXQ_IP_TCP_UDP_CKSUM;

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

752static inline const struct tcphdr *tso_tcph(const struct sfxge_tso_state *tso)
753{
754 return (const struct tcphdr *)(tso->mbuf->m_data + tso->tcph_off);
755}
756
757/* Size of preallocated TSO header buffers. Larger blocks must be
758 * allocated from the heap.
759 */
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;

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

751static 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 */
760#define TSOH_STD_SIZE 128
759#define TSOH_STD_SIZE 128
761
762/* At most half the descriptors in the queue at any time will refer to
763 * a TSO header buffer, since they must always be followed by a
764 * payload descriptor referring to an mbuf.
765 */
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 */
766#define TSOH_COUNT (SFXGE_NDESCS / 2u)
767#define TSOH_PER_PAGE (PAGE_SIZE / TSOH_STD_SIZE)
768#define TSOH_PAGE_COUNT ((TSOH_COUNT + TSOH_PER_PAGE - 1) / TSOH_PER_PAGE)
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)
769
770static int tso_init(struct sfxge_txq *txq)
771{
772 struct sfxge_softc *sc = txq->sc;
773 int i, rc;
774
775 /* Allocate TSO header buffers */
776 txq->tsoh_buffer = malloc(TSOH_PAGE_COUNT * sizeof(txq->tsoh_buffer[0]),
777 M_SFXGE, M_WAITOK);
778
779 for (i = 0; i < TSOH_PAGE_COUNT; i++) {
780 rc = sfxge_dma_alloc(sc, PAGE_SIZE, &txq->tsoh_buffer[i]);
768
769static 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]);
781 if (rc)
780 if (rc != 0)
782 goto fail;
783 }
784
781 goto fail;
782 }
783
785 return 0;
784 return (0);
786
787fail:
788 while (i-- > 0)
789 sfxge_dma_free(&txq->tsoh_buffer[i]);
790 free(txq->tsoh_buffer, M_SFXGE);
791 txq->tsoh_buffer = NULL;
785
786fail:
787 while (i-- > 0)
788 sfxge_dma_free(&txq->tsoh_buffer[i]);
789 free(txq->tsoh_buffer, M_SFXGE);
790 txq->tsoh_buffer = NULL;
792 return rc;
791 return (rc);
793}
794
795static void tso_fini(struct sfxge_txq *txq)
796{
797 int i;
798
792}
793
794static void tso_fini(struct sfxge_txq *txq)
795{
796 int i;
797
799 if (txq->tsoh_buffer) {
798 if (txq->tsoh_buffer != NULL) {
800 for (i = 0; i < TSOH_PAGE_COUNT; i++)
801 sfxge_dma_free(&txq->tsoh_buffer[i]);
802 free(txq->tsoh_buffer, M_SFXGE);
803 }
804}
805
806static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
807{

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

920 buf_index * TSOH_STD_SIZE);
921 map = txq->tsoh_buffer[page_index].esm_map;
922
923 stmp->flags = 0;
924 } else {
925 /* We cannot use bus_dmamem_alloc() as that may sleep */
926 header = malloc(tso->header_len, M_SFXGE, M_NOWAIT);
927 if (__predict_false(!header))
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
805static void tso_start(struct sfxge_tso_state *tso, struct mbuf *mbuf)
806{

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

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))
928 return ENOMEM;
927 return (ENOMEM);
929 rc = bus_dmamap_load(txq->packet_dma_tag, stmp->map,
930 header, tso->header_len,
931 tso_map_long_header, &dma_addr,
932 BUS_DMA_NOWAIT);
933 if (__predict_false(dma_addr == 0)) {
934 if (rc == 0) {
935 /* Succeeded but got >1 segment */
936 bus_dmamap_unload(txq->packet_dma_tag,
937 stmp->map);
938 rc = EINVAL;
939 }
940 free(header, M_SFXGE);
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);
941 return rc;
940 return (rc);
942 }
943 map = stmp->map;
944
945 txq->tso_long_headers++;
946 stmp->u.heap_buf = header;
947 stmp->flags = TX_BUF_UNMAP;
948 }
949

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

982 txq->tso_packets++;
983
984 /* Form a descriptor for this header. */
985 desc = &txq->pend_desc[txq->n_pend_desc++];
986 desc->eb_addr = dma_addr;
987 desc->eb_size = tso->header_len;
988 desc->eb_eop = 0;
989
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

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

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
990 return 0;
989 return (0);
991}
992
993static int
994sfxge_tx_queue_tso(struct sfxge_txq *txq, struct mbuf *mbuf,
995 const bus_dma_segment_t *dma_seg, int n_dma_seg)
996{
997 struct sfxge_tso_state tso;
998 unsigned int id, next_id;

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

1043 if (__predict_false(tso_start_new_packet(txq, &tso,
1044 next_id)))
1045 break;
1046 id = next_id;
1047 }
1048 }
1049
1050 txq->tso_bursts++;
990}
991
992static int
993sfxge_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;

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

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++;
1051 return id;
1050 return (id);
1052}
1053
1054static void
1055sfxge_tx_qunblock(struct sfxge_txq *txq)
1056{
1057 struct sfxge_softc *sc;
1058 struct sfxge_evq *evq;
1059

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

1195
1196 /* Create the common code transmit queue. */
1197 if ((rc = efx_tx_qcreate(sc->enp, index, txq->type, esmp,
1198 SFXGE_NDESCS, txq->buf_base_id, flags, evq->common,
1199 &txq->common)) != 0)
1200 goto fail;
1201
1202 mtx_lock(SFXGE_TXQ_LOCK(txq));
1051}
1052
1053static void
1054sfxge_tx_qunblock(struct sfxge_txq *txq)
1055{
1056 struct sfxge_softc *sc;
1057 struct sfxge_evq *evq;
1058

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

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));
1203
1202
1204 /* Enable the transmit queue. */
1205 efx_tx_qenable(txq->common);
1206
1207 txq->init_state = SFXGE_TXQ_STARTED;
1208
1209 mtx_unlock(SFXGE_TXQ_LOCK(txq));
1210
1211 return (0);

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

1224
1225 index = SFXGE_TX_SCALE(sc);
1226 while (--index >= 0)
1227 sfxge_tx_qstop(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index);
1228
1229 sfxge_tx_qstop(sc, SFXGE_TXQ_IP_CKSUM);
1230
1231 encp = efx_nic_cfg_get(sc->enp);
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);

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

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);
1232 sfxge_tx_qstop(sc, SFXGE_TXQ_NON_CKSUM);
1231 sfxge_tx_qstop(sc, SFXGE_TXQ_NON_CKSUM);
1233
1234 /* Tear down the transmit module */
1235 efx_tx_fini(sc->enp);
1236}
1237
1238int
1239sfxge_tx_start(struct sfxge_softc *sc)
1240{

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

1261
1262fail3:
1263 while (--index >= 0)
1264 sfxge_tx_qstop(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index);
1265
1266 sfxge_tx_qstop(sc, SFXGE_TXQ_IP_CKSUM);
1267
1268fail2:
1232
1233 /* Tear down the transmit module */
1234 efx_tx_fini(sc->enp);
1235}
1236
1237int
1238sfxge_tx_start(struct sfxge_softc *sc)
1239{

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

1260
1261fail3:
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
1267fail2:
1269 sfxge_tx_qstop(sc, SFXGE_TXQ_NON_CKSUM);
1268 sfxge_tx_qstop(sc, SFXGE_TXQ_NON_CKSUM);
1270
1271fail:
1272 efx_tx_fini(sc->enp);
1273
1274 return (rc);
1275}
1276
1277/**

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

1288 KASSERT(txq->init_state == SFXGE_TXQ_INITIALIZED,
1289 ("txq->init_state != SFXGE_TXQ_INITIALIZED"));
1290
1291 if (txq->type == SFXGE_TXQ_IP_TCP_UDP_CKSUM)
1292 tso_fini(txq);
1293
1294 /* Free the context arrays. */
1295 free(txq->pend_desc, M_SFXGE);
1269
1270fail:
1271 efx_tx_fini(sc->enp);
1272
1273 return (rc);
1274}
1275
1276/**

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

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);
1296 while (nmaps--)
1295 while (nmaps-- != 0)
1297 bus_dmamap_destroy(txq->packet_dma_tag, txq->stmp[nmaps].map);
1298 free(txq->stmp, M_SFXGE);
1299
1300 /* Release DMA memory mapping. */
1301 sfxge_dma_free(&txq->mem);
1302
1303 sc->txq[index] = NULL;
1304

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

1380 txq->txq_index = txq_index;
1381 txq->init_state = SFXGE_TXQ_INITIALIZED;
1382
1383 return (0);
1384
1385fail3:
1386 free(txq->pend_desc, M_SFXGE);
1387fail2:
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

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

1379 txq->txq_index = txq_index;
1380 txq->init_state = SFXGE_TXQ_INITIALIZED;
1381
1382 return (0);
1383
1384fail3:
1385 free(txq->pend_desc, M_SFXGE);
1386fail2:
1388 while (nmaps--)
1387 while (nmaps-- != 0)
1389 bus_dmamap_destroy(txq->packet_dma_tag, txq->stmp[nmaps].map);
1390 free(txq->stmp, M_SFXGE);
1391 bus_dma_tag_destroy(txq->packet_dma_tag);
1392
1393fail:
1394 sfxge_dma_free(esmp);
1395
1396 return (rc);
1397}
1398
1399static const struct {
1400 const char *name;
1401 size_t offset;
1402} sfxge_tx_stats[] = {
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
1392fail:
1393 sfxge_dma_free(esmp);
1394
1395 return (rc);
1396}
1397
1398static const struct {
1399 const char *name;
1400 size_t offset;
1401} sfxge_tx_stats[] = {
1403#define SFXGE_TX_STAT(name, member) \
1402#define SFXGE_TX_STAT(name, member) \
1404 { #name, offsetof(struct sfxge_txq, member) }
1405 SFXGE_TX_STAT(tso_bursts, tso_bursts),
1406 SFXGE_TX_STAT(tso_packets, tso_packets),
1407 SFXGE_TX_STAT(tso_long_headers, tso_long_headers),
1408 SFXGE_TX_STAT(tx_collapses, collapses),
1409 SFXGE_TX_STAT(tx_drops, drops),
1410 SFXGE_TX_STAT(tx_early_drops, early_drops),
1411};

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

1421 /* Sum across all TX queues */
1422 sum = 0;
1423 for (index = 0;
1424 index < SFXGE_TXQ_IP_TCP_UDP_CKSUM + SFXGE_TX_SCALE(sc);
1425 index++)
1426 sum += *(unsigned long *)((caddr_t)sc->txq[index] +
1427 sfxge_tx_stats[id].offset);
1428
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 SFXGE_TX_STAT(tx_early_drops, early_drops),
1410};

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

1420 /* Sum across all TX queues */
1421 sum = 0;
1422 for (index = 0;
1423 index < SFXGE_TXQ_IP_TCP_UDP_CKSUM + SFXGE_TX_SCALE(sc);
1424 index++)
1425 sum += *(unsigned long *)((caddr_t)sc->txq[index] +
1426 sfxge_tx_stats[id].offset);
1427
1429 return SYSCTL_OUT(req, &sum, sizeof(sum));
1428 return (SYSCTL_OUT(req, &sum, sizeof(sum)));
1430}
1431
1432static void
1433sfxge_tx_stat_init(struct sfxge_softc *sc)
1434{
1435 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
1436 struct sysctl_oid_list *stat_list;
1437 unsigned int id;

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

1455{
1456 int index;
1457
1458 index = SFXGE_TX_SCALE(sc);
1459 while (--index >= 0)
1460 sfxge_tx_qfini(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index);
1461
1462 sfxge_tx_qfini(sc, SFXGE_TXQ_IP_CKSUM);
1429}
1430
1431static void
1432sfxge_tx_stat_init(struct sfxge_softc *sc)
1433{
1434 struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->dev);
1435 struct sysctl_oid_list *stat_list;
1436 unsigned int id;

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

1454{
1455 int index;
1456
1457 index = SFXGE_TX_SCALE(sc);
1458 while (--index >= 0)
1459 sfxge_tx_qfini(sc, SFXGE_TXQ_IP_TCP_UDP_CKSUM + index);
1460
1461 sfxge_tx_qfini(sc, SFXGE_TXQ_IP_CKSUM);
1463 sfxge_tx_qfini(sc, SFXGE_TXQ_NON_CKSUM);
1462 sfxge_tx_qfini(sc, SFXGE_TXQ_NON_CKSUM);
1464}
1465
1466
1467int
1468sfxge_tx_init(struct sfxge_softc *sc)
1469{
1470 struct sfxge_intr *intr;
1471 int index;

--- 38 unchanged lines hidden ---
1463}
1464
1465
1466int
1467sfxge_tx_init(struct sfxge_softc *sc)
1468{
1469 struct sfxge_intr *intr;
1470 int index;

--- 38 unchanged lines hidden ---