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