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