sfxge_rx.c (272325) | sfxge_rx.c (272328) |
---|---|
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 --- 14 unchanged lines hidden (view full) --- 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#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 --- 14 unchanged lines hidden (view full) --- 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#include <sys/cdefs.h> |
31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge_rx.c 272325 2014-09-30 20:18:10Z gnn $"); | 31__FBSDID("$FreeBSD: head/sys/dev/sfxge/sfxge_rx.c 272328 2014-09-30 20:36:07Z gnn $"); |
32 33#include <sys/types.h> 34#include <sys/mbuf.h> 35#include <sys/smp.h> 36#include <sys/socket.h> 37#include <sys/sysctl.h> 38#include <sys/limits.h> 39 --- 9 unchanged lines hidden (view full) --- 49#include <machine/in_cksum.h> 50 51#include "common/efx.h" 52 53 54#include "sfxge.h" 55#include "sfxge_rx.h" 56 | 32 33#include <sys/types.h> 34#include <sys/mbuf.h> 35#include <sys/smp.h> 36#include <sys/socket.h> 37#include <sys/sysctl.h> 38#include <sys/limits.h> 39 --- 9 unchanged lines hidden (view full) --- 49#include <machine/in_cksum.h> 50 51#include "common/efx.h" 52 53 54#include "sfxge.h" 55#include "sfxge_rx.h" 56 |
57#define RX_REFILL_THRESHOLD (EFX_RXQ_LIMIT(SFXGE_NDESCS) * 9 / 10) 58#define RX_REFILL_THRESHOLD_2 (RX_REFILL_THRESHOLD / 2) | 57#define RX_REFILL_THRESHOLD(_entries) (EFX_RXQ_LIMIT(_entries) * 9 / 10) |
59 60/* Size of the LRO hash table. Must be a power of 2. A larger table 61 * means we can accelerate a larger number of streams. 62 */ 63static unsigned lro_table_size = 128; 64 65/* Maximum length of a hash chain. If chains get too long then the lookup 66 * time increases and may exceed the benefit of LRO. --- 142 unchanged lines hidden (view full) --- 209 prefetch_read_many(rxq->common); 210 211 mtx_assert(&evq->lock, MA_OWNED); 212 213 if (rxq->init_state != SFXGE_RXQ_STARTED) 214 return; 215 216 rxfill = rxq->added - rxq->completed; | 58 59/* Size of the LRO hash table. Must be a power of 2. A larger table 60 * means we can accelerate a larger number of streams. 61 */ 62static unsigned lro_table_size = 128; 63 64/* Maximum length of a hash chain. If chains get too long then the lookup 65 * time increases and may exceed the benefit of LRO. --- 142 unchanged lines hidden (view full) --- 208 prefetch_read_many(rxq->common); 209 210 mtx_assert(&evq->lock, MA_OWNED); 211 212 if (rxq->init_state != SFXGE_RXQ_STARTED) 213 return; 214 215 rxfill = rxq->added - rxq->completed; |
217 KASSERT(rxfill <= EFX_RXQ_LIMIT(SFXGE_NDESCS), 218 ("rxfill > EFX_RXQ_LIMIT(SFXGE_NDESCS)")); 219 ntodo = min(EFX_RXQ_LIMIT(SFXGE_NDESCS) - rxfill, target); 220 KASSERT(ntodo <= EFX_RXQ_LIMIT(SFXGE_NDESCS), 221 ("ntodo > EFX_RQX_LIMIT(SFXGE_NDESCS)")); | 216 KASSERT(rxfill <= EFX_RXQ_LIMIT(rxq->entries), 217 ("rxfill > EFX_RXQ_LIMIT(rxq->entries)")); 218 ntodo = min(EFX_RXQ_LIMIT(rxq->entries) - rxfill, target); 219 KASSERT(ntodo <= EFX_RXQ_LIMIT(rxq->entries), 220 ("ntodo > EFX_RQX_LIMIT(rxq->entries)")); |
222 223 if (ntodo == 0) 224 return; 225 226 batch = 0; 227 mblksize = sc->rx_buffer_size; 228 while (ntodo-- > 0) { 229 unsigned int id; 230 struct sfxge_rx_sw_desc *rx_desc; 231 bus_dma_segment_t seg; 232 struct mbuf *m; 233 | 221 222 if (ntodo == 0) 223 return; 224 225 batch = 0; 226 mblksize = sc->rx_buffer_size; 227 while (ntodo-- > 0) { 228 unsigned int id; 229 struct sfxge_rx_sw_desc *rx_desc; 230 bus_dma_segment_t seg; 231 struct mbuf *m; 232 |
234 id = (rxq->added + batch) & (SFXGE_NDESCS - 1); | 233 id = (rxq->added + batch) & rxq->ptr_mask; |
235 rx_desc = &rxq->queue[id]; 236 KASSERT(rx_desc->mbuf == NULL, ("rx_desc->mbuf != NULL")); 237 238 rx_desc->flags = EFX_DISCARD; 239 m = rx_desc->mbuf = sfxge_rx_alloc_mbuf(sc); 240 if (m == NULL) 241 break; 242 sfxge_map_mbuf_fast(rxq->mem.esm_tag, rxq->mem.esm_map, m, &seg); --- 26 unchanged lines hidden (view full) --- 269void 270sfxge_rx_qrefill(struct sfxge_rxq *rxq) 271{ 272 273 if (rxq->init_state != SFXGE_RXQ_STARTED) 274 return; 275 276 /* Make sure the queue is full */ | 234 rx_desc = &rxq->queue[id]; 235 KASSERT(rx_desc->mbuf == NULL, ("rx_desc->mbuf != NULL")); 236 237 rx_desc->flags = EFX_DISCARD; 238 m = rx_desc->mbuf = sfxge_rx_alloc_mbuf(sc); 239 if (m == NULL) 240 break; 241 sfxge_map_mbuf_fast(rxq->mem.esm_tag, rxq->mem.esm_map, m, &seg); --- 26 unchanged lines hidden (view full) --- 268void 269sfxge_rx_qrefill(struct sfxge_rxq *rxq) 270{ 271 272 if (rxq->init_state != SFXGE_RXQ_STARTED) 273 return; 274 275 /* Make sure the queue is full */ |
277 sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(SFXGE_NDESCS), B_TRUE); | 276 sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(rxq->entries), B_TRUE); |
278} 279 280static void __sfxge_rx_deliver(struct sfxge_softc *sc, struct mbuf *m) 281{ 282 struct ifnet *ifp = sc->ifnet; 283 284 m->m_pkthdr.rcvif = ifp; 285 m->m_pkthdr.csum_data = 0xffff; --- 466 unchanged lines hidden (view full) --- 752 753 mtx_assert(&evq->lock, MA_OWNED); 754 755 completed = rxq->completed; 756 while (completed != rxq->pending) { 757 unsigned int id; 758 struct sfxge_rx_sw_desc *rx_desc; 759 | 277} 278 279static void __sfxge_rx_deliver(struct sfxge_softc *sc, struct mbuf *m) 280{ 281 struct ifnet *ifp = sc->ifnet; 282 283 m->m_pkthdr.rcvif = ifp; 284 m->m_pkthdr.csum_data = 0xffff; --- 466 unchanged lines hidden (view full) --- 751 752 mtx_assert(&evq->lock, MA_OWNED); 753 754 completed = rxq->completed; 755 while (completed != rxq->pending) { 756 unsigned int id; 757 struct sfxge_rx_sw_desc *rx_desc; 758 |
760 id = completed++ & (SFXGE_NDESCS - 1); | 759 id = completed++ & rxq->ptr_mask; |
761 rx_desc = &rxq->queue[id]; 762 m = rx_desc->mbuf; 763 764 if (rxq->init_state != SFXGE_RXQ_STARTED) 765 goto discard; 766 767 if (rx_desc->flags & (EFX_ADDR_MISMATCH | EFX_DISCARD)) 768 goto discard; --- 47 unchanged lines hidden (view full) --- 816 /* 817 * If there are any pending flows and this is the end of the 818 * poll then they must be completed. 819 */ 820 if (eop) 821 sfxge_lro_end_of_burst(rxq); 822 823 /* Top up the queue if necessary */ | 760 rx_desc = &rxq->queue[id]; 761 m = rx_desc->mbuf; 762 763 if (rxq->init_state != SFXGE_RXQ_STARTED) 764 goto discard; 765 766 if (rx_desc->flags & (EFX_ADDR_MISMATCH | EFX_DISCARD)) 767 goto discard; --- 47 unchanged lines hidden (view full) --- 815 /* 816 * If there are any pending flows and this is the end of the 817 * poll then they must be completed. 818 */ 819 if (eop) 820 sfxge_lro_end_of_burst(rxq); 821 822 /* Top up the queue if necessary */ |
824 if (level < RX_REFILL_THRESHOLD) 825 sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(SFXGE_NDESCS), B_FALSE); | 823 if (level < rxq->refill_threshold) 824 sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(rxq->entries), B_FALSE); |
826} 827 828static void 829sfxge_rx_qstop(struct sfxge_softc *sc, unsigned int index) 830{ 831 struct sfxge_rxq *rxq; 832 struct sfxge_evq *evq; 833 unsigned int count; --- 45 unchanged lines hidden (view full) --- 879 rxq->pending = 0; 880 rxq->completed = 0; 881 rxq->loopback = 0; 882 883 /* Destroy the common code receive queue. */ 884 efx_rx_qdestroy(rxq->common); 885 886 efx_sram_buf_tbl_clear(sc->enp, rxq->buf_base_id, | 825} 826 827static void 828sfxge_rx_qstop(struct sfxge_softc *sc, unsigned int index) 829{ 830 struct sfxge_rxq *rxq; 831 struct sfxge_evq *evq; 832 unsigned int count; --- 45 unchanged lines hidden (view full) --- 878 rxq->pending = 0; 879 rxq->completed = 0; 880 rxq->loopback = 0; 881 882 /* Destroy the common code receive queue. */ 883 efx_rx_qdestroy(rxq->common); 884 885 efx_sram_buf_tbl_clear(sc->enp, rxq->buf_base_id, |
887 EFX_RXQ_NBUFS(SFXGE_NDESCS)); | 886 EFX_RXQ_NBUFS(sc->rxq_entries)); |
888 889 mtx_unlock(&evq->lock); 890} 891 892static int 893sfxge_rx_qstart(struct sfxge_softc *sc, unsigned int index) 894{ 895 struct sfxge_rxq *rxq; --- 7 unchanged lines hidden (view full) --- 903 904 KASSERT(rxq->init_state == SFXGE_RXQ_INITIALIZED, 905 ("rxq->init_state != SFXGE_RXQ_INITIALIZED")); 906 KASSERT(evq->init_state == SFXGE_EVQ_STARTED, 907 ("evq->init_state != SFXGE_EVQ_STARTED")); 908 909 /* Program the buffer table. */ 910 if ((rc = efx_sram_buf_tbl_set(sc->enp, rxq->buf_base_id, esmp, | 887 888 mtx_unlock(&evq->lock); 889} 890 891static int 892sfxge_rx_qstart(struct sfxge_softc *sc, unsigned int index) 893{ 894 struct sfxge_rxq *rxq; --- 7 unchanged lines hidden (view full) --- 902 903 KASSERT(rxq->init_state == SFXGE_RXQ_INITIALIZED, 904 ("rxq->init_state != SFXGE_RXQ_INITIALIZED")); 905 KASSERT(evq->init_state == SFXGE_EVQ_STARTED, 906 ("evq->init_state != SFXGE_EVQ_STARTED")); 907 908 /* Program the buffer table. */ 909 if ((rc = efx_sram_buf_tbl_set(sc->enp, rxq->buf_base_id, esmp, |
911 EFX_RXQ_NBUFS(SFXGE_NDESCS))) != 0) 912 return rc; | 910 EFX_RXQ_NBUFS(sc->rxq_entries))) != 0) 911 return (rc); |
913 914 /* Create the common code receive queue. */ 915 if ((rc = efx_rx_qcreate(sc->enp, index, index, EFX_RXQ_TYPE_DEFAULT, | 912 913 /* Create the common code receive queue. */ 914 if ((rc = efx_rx_qcreate(sc->enp, index, index, EFX_RXQ_TYPE_DEFAULT, |
916 esmp, SFXGE_NDESCS, rxq->buf_base_id, evq->common, | 915 esmp, sc->rxq_entries, rxq->buf_base_id, evq->common, |
917 &rxq->common)) != 0) 918 goto fail; 919 920 mtx_lock(&evq->lock); 921 922 /* Enable the receive queue. */ 923 efx_rx_qenable(rxq->common); 924 925 rxq->init_state = SFXGE_RXQ_STARTED; 926 927 /* Try to fill the queue from the pool. */ | 916 &rxq->common)) != 0) 917 goto fail; 918 919 mtx_lock(&evq->lock); 920 921 /* Enable the receive queue. */ 922 efx_rx_qenable(rxq->common); 923 924 rxq->init_state = SFXGE_RXQ_STARTED; 925 926 /* Try to fill the queue from the pool. */ |
928 sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(SFXGE_NDESCS), B_FALSE); | 927 sfxge_rx_qfill(rxq, EFX_RXQ_LIMIT(sc->rxq_entries), B_FALSE); |
929 930 mtx_unlock(&evq->lock); 931 932 return (0); 933 934fail: 935 efx_sram_buf_tbl_clear(sc->enp, rxq->buf_base_id, | 928 929 mtx_unlock(&evq->lock); 930 931 return (0); 932 933fail: 934 efx_sram_buf_tbl_clear(sc->enp, rxq->buf_base_id, |
936 EFX_RXQ_NBUFS(SFXGE_NDESCS)); 937 return rc; | 935 EFX_RXQ_NBUFS(sc->rxq_entries)); 936 return (rc); |
938} 939 940void 941sfxge_rx_stop(struct sfxge_softc *sc) 942{ 943 struct sfxge_intr *intr; 944 int index; 945 --- 154 unchanged lines hidden (view full) --- 1100 efsys_mem_t *esmp; 1101 int rc; 1102 1103 KASSERT(index < sc->intr.n_alloc, ("index >= %d", sc->intr.n_alloc)); 1104 1105 rxq = malloc(sizeof(struct sfxge_rxq), M_SFXGE, M_ZERO | M_WAITOK); 1106 rxq->sc = sc; 1107 rxq->index = index; | 937} 938 939void 940sfxge_rx_stop(struct sfxge_softc *sc) 941{ 942 struct sfxge_intr *intr; 943 int index; 944 --- 154 unchanged lines hidden (view full) --- 1099 efsys_mem_t *esmp; 1100 int rc; 1101 1102 KASSERT(index < sc->intr.n_alloc, ("index >= %d", sc->intr.n_alloc)); 1103 1104 rxq = malloc(sizeof(struct sfxge_rxq), M_SFXGE, M_ZERO | M_WAITOK); 1105 rxq->sc = sc; 1106 rxq->index = index; |
1107 rxq->entries = sc->rxq_entries; 1108 rxq->ptr_mask = rxq->entries - 1; 1109 rxq->refill_threshold = RX_REFILL_THRESHOLD(rxq->entries); |
|
1108 1109 sc->rxq[index] = rxq; 1110 esmp = &rxq->mem; 1111 1112 evq = sc->evq[index]; 1113 1114 /* Allocate and zero DMA space. */ | 1110 1111 sc->rxq[index] = rxq; 1112 esmp = &rxq->mem; 1113 1114 evq = sc->evq[index]; 1115 1116 /* Allocate and zero DMA space. */ |
1115 if ((rc = sfxge_dma_alloc(sc, EFX_RXQ_SIZE(SFXGE_NDESCS), esmp)) != 0) | 1117 if ((rc = sfxge_dma_alloc(sc, EFX_RXQ_SIZE(sc->rxq_entries), esmp)) != 0) |
1116 return (rc); | 1118 return (rc); |
1117 (void)memset(esmp->esm_base, 0, EFX_RXQ_SIZE(SFXGE_NDESCS)); | 1119 (void)memset(esmp->esm_base, 0, EFX_RXQ_SIZE(sc->rxq_entries)); |
1118 1119 /* Allocate buffer table entries. */ | 1120 1121 /* Allocate buffer table entries. */ |
1120 sfxge_sram_buf_tbl_alloc(sc, EFX_RXQ_NBUFS(SFXGE_NDESCS), | 1122 sfxge_sram_buf_tbl_alloc(sc, EFX_RXQ_NBUFS(sc->rxq_entries), |
1121 &rxq->buf_base_id); 1122 1123 /* Allocate the context array and the flow table. */ | 1123 &rxq->buf_base_id); 1124 1125 /* Allocate the context array and the flow table. */ |
1124 rxq->queue = malloc(sizeof(struct sfxge_rx_sw_desc) * SFXGE_NDESCS, | 1126 rxq->queue = malloc(sizeof(struct sfxge_rx_sw_desc) * sc->rxq_entries, |
1125 M_SFXGE, M_WAITOK | M_ZERO); 1126 sfxge_lro_init(rxq); 1127 1128 callout_init(&rxq->refill_callout, B_TRUE); 1129 1130 rxq->init_state = SFXGE_RXQ_INITIALIZED; 1131 1132 return (0); --- 100 unchanged lines hidden --- | 1127 M_SFXGE, M_WAITOK | M_ZERO); 1128 sfxge_lro_init(rxq); 1129 1130 callout_init(&rxq->refill_callout, B_TRUE); 1131 1132 rxq->init_state = SFXGE_RXQ_INITIALIZED; 1133 1134 return (0); --- 100 unchanged lines hidden --- |