1 /*- 2 * Copyright (c) 2010-2015 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 are met: 10 * 11 * 1. Redistributions of source code must retain the above copyright notice, 12 * this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright notice, 14 * this list of conditions and the following disclaimer in the documentation 15 * and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * 29 * The views and conclusions contained in the software and documentation are 30 * those of the authors and should not be interpreted as representing official 31 * policies, either expressed or implied, of the FreeBSD Project. 32 * 33 * $FreeBSD$ 34 */ 35 36 #ifndef _SFXGE_RX_H 37 #define _SFXGE_RX_H 38 39 #include "opt_inet.h" 40 #include "opt_inet6.h" 41 42 #if defined(INET) || defined(INET6) 43 #define SFXGE_LRO 1 44 #endif 45 46 #define SFXGE_MAGIC_RESERVED 0x8000 47 48 #define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6 49 #define SFXGE_MAGIC_DMAQ_LABEL_MASK \ 50 ((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1) 51 52 #define SFXGE_MAGIC_RX_QFLUSH_DONE \ 53 (SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 54 55 #define SFXGE_MAGIC_RX_QFLUSH_FAILED \ 56 (SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 57 58 #define SFXGE_MAGIC_RX_QREFILL \ 59 (SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 60 61 #define SFXGE_MAGIC_TX_QFLUSH_DONE \ 62 (SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH)) 63 64 #define SFXGE_RX_SCALE_MAX EFX_MAXRSS 65 66 struct sfxge_rx_sw_desc { 67 struct mbuf *mbuf; 68 bus_dmamap_t map; 69 int flags; 70 int size; 71 }; 72 73 #ifdef SFXGE_LRO 74 75 /** 76 * struct sfxge_lro_conn - Connection state for software LRO 77 * @link: Link for hash table and free list. 78 * @active_link: Link for active_conns list 79 * @l2_id: Identifying information from layer 2 80 * @conn_hash: Hash of connection 4-tuple 81 * @nh: IP (v4 or v6) header of super-packet 82 * @source: Source TCP port number 83 * @dest: Destination TCP port number 84 * @n_in_order_pkts: Number of in-order packets with payload. 85 * @next_seq: Next in-order sequence number. 86 * @last_pkt_ticks: Time we last saw a packet on this connection. 87 * @mbuf: The mbuf we are currently holding. 88 * If %NULL, then all following fields are undefined. 89 * @mbuf_tail: The tail of the frag_list of mbufs we're holding. 90 * Only valid after at least one merge. 91 * @th_last: The TCP header of the last packet merged. 92 * @next_buf: The next RX buffer to process. 93 * @next_eh: Ethernet header of the next buffer. 94 * @next_nh: IP header of the next buffer. 95 * @delivered: True if we've delivered a payload packet up this interrupt. 96 */ 97 struct sfxge_lro_conn { 98 TAILQ_ENTRY(sfxge_lro_conn) link; 99 LIST_ENTRY(sfxge_lro_conn) active_link; 100 uint16_t l2_id; 101 uint32_t conn_hash; 102 void *nh; 103 uint16_t source, dest; 104 int n_in_order_pkts; 105 unsigned next_seq; 106 unsigned last_pkt_ticks; 107 struct mbuf *mbuf; 108 struct mbuf *mbuf_tail; 109 struct tcphdr *th_last; 110 struct sfxge_rx_sw_desc next_buf; 111 void *next_eh; 112 void *next_nh; 113 int delivered; 114 }; 115 116 /** 117 * struct sfxge_lro_state - Port state for software LRO 118 * @sc: The associated NIC. 119 * @conns_mask: Number of hash buckets - 1. 120 * @conns: Hash buckets for tracked connections. 121 * @conns_n: Length of linked list for each hash bucket. 122 * @active_conns: Connections that are holding a packet. 123 * Connections are self-linked when not in this list. 124 * @free_conns: Free sfxge_lro_conn instances. 125 * @last_purge_ticks: The value of ticks last time we purged idle 126 * connections. 127 * @n_merges: Number of packets absorbed by LRO. 128 * @n_bursts: Number of bursts spotted by LRO. 129 * @n_slow_start: Number of packets not merged because connection may be in 130 * slow-start. 131 * @n_misorder: Number of out-of-order packets seen in tracked streams. 132 * @n_too_many: Incremented when we're trying to track too many streams. 133 * @n_new_stream: Number of distinct streams we've tracked. 134 * @n_drop_idle: Number of streams discarded because they went idle. 135 * @n_drop_closed: Number of streams that have seen a FIN or RST. 136 */ 137 struct sfxge_lro_state { 138 struct sfxge_softc *sc; 139 unsigned conns_mask; 140 TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns; 141 unsigned *conns_n; 142 LIST_HEAD(, sfxge_lro_conn) active_conns; 143 TAILQ_HEAD(, sfxge_lro_conn) free_conns; 144 unsigned last_purge_ticks; 145 unsigned n_merges; 146 unsigned n_bursts; 147 unsigned n_slow_start; 148 unsigned n_misorder; 149 unsigned n_too_many; 150 unsigned n_new_stream; 151 unsigned n_drop_idle; 152 unsigned n_drop_closed; 153 }; 154 155 #endif /* SFXGE_LRO */ 156 157 enum sfxge_flush_state { 158 SFXGE_FLUSH_DONE = 0, 159 SFXGE_FLUSH_REQUIRED, 160 SFXGE_FLUSH_PENDING, 161 SFXGE_FLUSH_FAILED 162 }; 163 164 enum sfxge_rxq_state { 165 SFXGE_RXQ_UNINITIALIZED = 0, 166 SFXGE_RXQ_INITIALIZED, 167 SFXGE_RXQ_STARTED 168 }; 169 170 #define SFXGE_RX_BATCH 128 171 172 struct sfxge_rxq { 173 struct sfxge_softc *sc __aligned(CACHE_LINE_SIZE); 174 unsigned int index; 175 efsys_mem_t mem; 176 unsigned int buf_base_id; 177 enum sfxge_rxq_state init_state; 178 unsigned int entries; 179 unsigned int ptr_mask; 180 181 struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE); 182 unsigned int added; 183 unsigned int pushed; 184 unsigned int pending; 185 unsigned int completed; 186 unsigned int loopback; 187 #ifdef SFXGE_LRO 188 struct sfxge_lro_state lro; 189 #endif 190 unsigned int refill_threshold; 191 struct callout refill_callout; 192 unsigned int refill_delay; 193 194 efx_rxq_t *common __aligned(CACHE_LINE_SIZE); 195 volatile enum sfxge_flush_state flush_state; 196 }; 197 198 /* 199 * From sfxge_rx.c. 200 */ 201 extern int sfxge_rx_init(struct sfxge_softc *sc); 202 extern void sfxge_rx_fini(struct sfxge_softc *sc); 203 extern int sfxge_rx_start(struct sfxge_softc *sc); 204 extern void sfxge_rx_stop(struct sfxge_softc *sc); 205 extern void sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop); 206 extern void sfxge_rx_qrefill(struct sfxge_rxq *rxq); 207 extern void sfxge_rx_qflush_done(struct sfxge_rxq *rxq); 208 extern void sfxge_rx_qflush_failed(struct sfxge_rxq *rxq); 209 extern void sfxge_rx_scale_update(void *arg, int npending); 210 211 #endif 212