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 * $FreeBSD$ 30 */ 31 32 #ifndef _SFXGE_RX_H 33 #define _SFXGE_RX_H 34 35 #include "opt_inet.h" 36 #include "opt_inet6.h" 37 38 #if defined(INET) || defined(INET6) 39 #define SFXGE_LRO 1 40 #endif 41 42 #define SFXGE_MAGIC_RESERVED 0x8000 43 44 #define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6 45 #define SFXGE_MAGIC_DMAQ_LABEL_MASK \ 46 ((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1) 47 48 #define SFXGE_MAGIC_RX_QFLUSH_DONE \ 49 (SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 50 51 #define SFXGE_MAGIC_RX_QFLUSH_FAILED \ 52 (SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 53 54 #define SFXGE_MAGIC_RX_QREFILL \ 55 (SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 56 57 #define SFXGE_MAGIC_TX_QFLUSH_DONE \ 58 (SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 59 60 #define SFXGE_RX_SCALE_MAX EFX_MAXRSS 61 62 struct sfxge_rx_sw_desc { 63 struct mbuf *mbuf; 64 bus_dmamap_t map; 65 int flags; 66 int size; 67 }; 68 69 #ifdef SFXGE_LRO 70 71 /** 72 * struct sfxge_lro_conn - Connection state for software LRO 73 * @link: Link for hash table and free list. 74 * @active_link: Link for active_conns list 75 * @l2_id: Identifying information from layer 2 76 * @conn_hash: Hash of connection 4-tuple 77 * @nh: IP (v4 or v6) header of super-packet 78 * @source: Source TCP port number 79 * @dest: Destination TCP port number 80 * @n_in_order_pkts: Number of in-order packets with payload. 81 * @next_seq: Next in-order sequence number. 82 * @last_pkt_ticks: Time we last saw a packet on this connection. 83 * @mbuf: The mbuf we are currently holding. 84 * If %NULL, then all following fields are undefined. 85 * @mbuf_tail: The tail of the frag_list of mbufs we're holding. 86 * Only valid after at least one merge. 87 * @th_last: The TCP header of the last packet merged. 88 * @next_buf: The next RX buffer to process. 89 * @next_eh: Ethernet header of the next buffer. 90 * @next_nh: IP header of the next buffer. 91 * @delivered: True if we've delivered a payload packet up this interrupt. 92 */ 93 struct sfxge_lro_conn { 94 TAILQ_ENTRY(sfxge_lro_conn) link; 95 LIST_ENTRY(sfxge_lro_conn) active_link; 96 uint16_t l2_id; 97 uint32_t conn_hash; 98 void *nh; 99 uint16_t source, dest; 100 int n_in_order_pkts; 101 unsigned next_seq; 102 unsigned last_pkt_ticks; 103 struct mbuf *mbuf; 104 struct mbuf *mbuf_tail; 105 struct tcphdr *th_last; 106 struct sfxge_rx_sw_desc next_buf; 107 void *next_eh; 108 void *next_nh; 109 int delivered; 110 }; 111 112 /** 113 * struct sfxge_lro_state - Port state for software LRO 114 * @sc: The associated NIC. 115 * @conns_mask: Number of hash buckets - 1. 116 * @conns: Hash buckets for tracked connections. 117 * @conns_n: Length of linked list for each hash bucket. 118 * @active_conns: Connections that are holding a packet. 119 * Connections are self-linked when not in this list. 120 * @free_conns: Free sfxge_lro_conn instances. 121 * @last_purge_ticks: The value of ticks last time we purged idle 122 * connections. 123 * @n_merges: Number of packets absorbed by LRO. 124 * @n_bursts: Number of bursts spotted by LRO. 125 * @n_slow_start: Number of packets not merged because connection may be in 126 * slow-start. 127 * @n_misorder: Number of out-of-order packets seen in tracked streams. 128 * @n_too_many: Incremented when we're trying to track too many streams. 129 * @n_new_stream: Number of distinct streams we've tracked. 130 * @n_drop_idle: Number of streams discarded because they went idle. 131 * @n_drop_closed: Number of streams that have seen a FIN or RST. 132 */ 133 struct sfxge_lro_state { 134 struct sfxge_softc *sc; 135 unsigned conns_mask; 136 TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns; 137 unsigned *conns_n; 138 LIST_HEAD(, sfxge_lro_conn) active_conns; 139 TAILQ_HEAD(, sfxge_lro_conn) free_conns; 140 unsigned last_purge_ticks; 141 unsigned n_merges; 142 unsigned n_bursts; 143 unsigned n_slow_start; 144 unsigned n_misorder; 145 unsigned n_too_many; 146 unsigned n_new_stream; 147 unsigned n_drop_idle; 148 unsigned n_drop_closed; 149 }; 150 151 #endif /* SFXGE_LRO */ 152 153 enum sfxge_flush_state { 154 SFXGE_FLUSH_DONE = 0, 155 SFXGE_FLUSH_PENDING, 156 SFXGE_FLUSH_FAILED 157 }; 158 159 enum sfxge_rxq_state { 160 SFXGE_RXQ_UNINITIALIZED = 0, 161 SFXGE_RXQ_INITIALIZED, 162 SFXGE_RXQ_STARTED 163 }; 164 165 #define SFXGE_RX_BATCH 128 166 167 struct sfxge_rxq { 168 struct sfxge_softc *sc __aligned(CACHE_LINE_SIZE); 169 unsigned int index; 170 efsys_mem_t mem; 171 unsigned int buf_base_id; 172 enum sfxge_rxq_state init_state; 173 unsigned int entries; 174 unsigned int ptr_mask; 175 176 struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE); 177 unsigned int added; 178 unsigned int pending; 179 unsigned int completed; 180 unsigned int loopback; 181 #ifdef SFXGE_LRO 182 struct sfxge_lro_state lro; 183 #endif 184 unsigned int refill_threshold; 185 struct callout refill_callout; 186 unsigned int refill_delay; 187 188 efx_rxq_t *common __aligned(CACHE_LINE_SIZE); 189 volatile enum sfxge_flush_state flush_state; 190 }; 191 192 /* 193 * From sfxge_rx.c. 194 */ 195 extern int sfxge_rx_init(struct sfxge_softc *sc); 196 extern void sfxge_rx_fini(struct sfxge_softc *sc); 197 extern int sfxge_rx_start(struct sfxge_softc *sc); 198 extern void sfxge_rx_stop(struct sfxge_softc *sc); 199 extern void sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop); 200 extern void sfxge_rx_qrefill(struct sfxge_rxq *rxq); 201 extern void sfxge_rx_qflush_done(struct sfxge_rxq *rxq); 202 extern void sfxge_rx_qflush_failed(struct sfxge_rxq *rxq); 203 extern void sfxge_rx_scale_update(void *arg, int npending); 204 205 #endif 206