2 * Copyright (c) 2010-2015 Solarflare Communications Inc.
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
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.
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.
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.
40 #include "opt_inet6.h"
42 #if defined(INET) || defined(INET6)
46 #define SFXGE_MAGIC_RESERVED 0x8000
48 #define SFXGE_MAGIC_DMAQ_LABEL_WIDTH 6
49 #define SFXGE_MAGIC_DMAQ_LABEL_MASK \
50 ((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1)
52 #define SFXGE_MAGIC_RX_QFLUSH_DONE \
53 (SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
55 #define SFXGE_MAGIC_RX_QFLUSH_FAILED \
56 (SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
58 #define SFXGE_MAGIC_RX_QREFILL \
59 (SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
61 #define SFXGE_MAGIC_TX_QFLUSH_DONE \
62 (SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
64 #define SFXGE_RX_SCALE_MAX EFX_MAXRSS
66 struct sfxge_rx_sw_desc {
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.
97 struct sfxge_lro_conn {
98 TAILQ_ENTRY(sfxge_lro_conn) link;
99 LIST_ENTRY(sfxge_lro_conn) active_link;
103 uint16_t source, dest;
106 unsigned last_pkt_ticks;
108 struct mbuf *mbuf_tail;
109 struct tcphdr *th_last;
110 struct sfxge_rx_sw_desc next_buf;
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
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
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.
137 struct sfxge_lro_state {
138 struct sfxge_softc *sc;
140 TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns;
142 LIST_HEAD(, sfxge_lro_conn) active_conns;
143 TAILQ_HEAD(, sfxge_lro_conn) free_conns;
144 unsigned last_purge_ticks;
147 unsigned n_slow_start;
150 unsigned n_new_stream;
151 unsigned n_drop_idle;
152 unsigned n_drop_closed;
155 #endif /* SFXGE_LRO */
157 enum sfxge_flush_state {
158 SFXGE_FLUSH_DONE = 0,
159 SFXGE_FLUSH_REQUIRED,
164 enum sfxge_rxq_state {
165 SFXGE_RXQ_UNINITIALIZED = 0,
166 SFXGE_RXQ_INITIALIZED,
170 #define SFXGE_RX_BATCH 128
173 struct sfxge_softc *sc __aligned(CACHE_LINE_SIZE);
176 unsigned int buf_base_id;
177 enum sfxge_rxq_state init_state;
178 unsigned int entries;
179 unsigned int ptr_mask;
181 struct sfxge_rx_sw_desc *queue __aligned(CACHE_LINE_SIZE);
184 unsigned int pending;
185 unsigned int completed;
186 unsigned int loopback;
188 struct sfxge_lro_state lro;
190 unsigned int refill_threshold;
191 struct callout refill_callout;
192 unsigned int refill_delay;
194 efx_rxq_t *common __aligned(CACHE_LINE_SIZE);
195 volatile enum sfxge_flush_state flush_state;
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);