1227569Sphilip/*-
2284555Sarybchik * Copyright (c) 2010-2015 Solarflare Communications Inc.
3227569Sphilip * All rights reserved.
4227569Sphilip *
5227569Sphilip * This software was developed in part by Philip Paeps under contract for
6227569Sphilip * Solarflare Communications, Inc.
7227569Sphilip *
8227569Sphilip * Redistribution and use in source and binary forms, with or without
9284555Sarybchik * modification, are permitted provided that the following conditions are met:
10227569Sphilip *
11284555Sarybchik * 1. Redistributions of source code must retain the above copyright notice,
12284555Sarybchik *    this list of conditions and the following disclaimer.
13284555Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice,
14284555Sarybchik *    this list of conditions and the following disclaimer in the documentation
15284555Sarybchik *    and/or other materials provided with the distribution.
16227569Sphilip *
17284555Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18284555Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19284555Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20284555Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21284555Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22284555Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23284555Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24284555Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25284555Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26284555Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27284555Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28284555Sarybchik *
29284555Sarybchik * The views and conclusions contained in the software and documentation are
30284555Sarybchik * those of the authors and should not be interpreted as representing official
31284555Sarybchik * policies, either expressed or implied, of the FreeBSD Project.
32284555Sarybchik *
33227569Sphilip * $FreeBSD: releng/10.2/sys/dev/sfxge/sfxge_rx.h 284555 2015-06-18 15:46:39Z arybchik $
34227569Sphilip */
35227569Sphilip
36227569Sphilip#ifndef _SFXGE_RX_H
37280501Sarybchik#define	_SFXGE_RX_H
38227569Sphilip
39280615Sarybchik#include "opt_inet.h"
40280615Sarybchik#include "opt_inet6.h"
41280615Sarybchik
42280615Sarybchik#if defined(INET) || defined(INET6)
43280615Sarybchik#define	SFXGE_LRO	1
44280615Sarybchik#endif
45280615Sarybchik
46284555Sarybchik#define	SFXGE_MAGIC_RESERVED		0x8000
47227569Sphilip
48280501Sarybchik#define	SFXGE_MAGIC_DMAQ_LABEL_WIDTH	6
49284555Sarybchik#define	SFXGE_MAGIC_DMAQ_LABEL_MASK \
50280501Sarybchik	((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1)
51227569Sphilip
52284555Sarybchik#define	SFXGE_MAGIC_RX_QFLUSH_DONE \
53280501Sarybchik	(SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
54227569Sphilip
55284555Sarybchik#define	SFXGE_MAGIC_RX_QFLUSH_FAILED \
56280501Sarybchik	(SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
57227569Sphilip
58284555Sarybchik#define	SFXGE_MAGIC_RX_QREFILL \
59280501Sarybchik	(SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
60227569Sphilip
61284555Sarybchik#define	SFXGE_MAGIC_TX_QFLUSH_DONE \
62280501Sarybchik	(SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
63227569Sphilip
64227569Sphilip#define	SFXGE_RX_SCALE_MAX	EFX_MAXRSS
65227569Sphilip
66227569Sphilipstruct sfxge_rx_sw_desc {
67227569Sphilip	struct mbuf	*mbuf;
68227569Sphilip	bus_dmamap_t	map;
69227569Sphilip	int		flags;
70227569Sphilip	int		size;
71227569Sphilip};
72227569Sphilip
73280615Sarybchik#ifdef SFXGE_LRO
74280615Sarybchik
75227569Sphilip/**
76227569Sphilip * struct sfxge_lro_conn - Connection state for software LRO
77227569Sphilip * @link: Link for hash table and free list.
78227569Sphilip * @active_link: Link for active_conns list
79227569Sphilip * @l2_id: Identifying information from layer 2
80227569Sphilip * @conn_hash: Hash of connection 4-tuple
81227569Sphilip * @nh: IP (v4 or v6) header of super-packet
82227569Sphilip * @source: Source TCP port number
83227569Sphilip * @dest: Destination TCP port number
84227569Sphilip * @n_in_order_pkts: Number of in-order packets with payload.
85227569Sphilip * @next_seq: Next in-order sequence number.
86227569Sphilip * @last_pkt_ticks: Time we last saw a packet on this connection.
87227569Sphilip * @mbuf: The mbuf we are currently holding.
88227569Sphilip *	If %NULL, then all following fields are undefined.
89227569Sphilip * @mbuf_tail: The tail of the frag_list of mbufs we're holding.
90227569Sphilip *	Only valid after at least one merge.
91227569Sphilip * @th_last: The TCP header of the last packet merged.
92227569Sphilip * @next_buf: The next RX buffer to process.
93227569Sphilip * @next_eh: Ethernet header of the next buffer.
94227569Sphilip * @next_nh: IP header of the next buffer.
95227569Sphilip * @delivered: True if we've delivered a payload packet up this interrupt.
96227569Sphilip */
97227569Sphilipstruct sfxge_lro_conn {
98227569Sphilip	TAILQ_ENTRY(sfxge_lro_conn) link;
99227569Sphilip	LIST_ENTRY(sfxge_lro_conn) active_link;
100227569Sphilip	uint16_t l2_id;
101227569Sphilip	uint32_t conn_hash;
102227569Sphilip	void *nh;
103227569Sphilip	uint16_t source, dest;
104227569Sphilip	int n_in_order_pkts;
105227569Sphilip	unsigned next_seq;
106227569Sphilip	unsigned last_pkt_ticks;
107227569Sphilip	struct mbuf *mbuf;
108227569Sphilip	struct mbuf *mbuf_tail;
109227569Sphilip	struct tcphdr *th_last;
110227569Sphilip	struct sfxge_rx_sw_desc next_buf;
111227569Sphilip	void *next_eh;
112227569Sphilip	void *next_nh;
113227569Sphilip	int delivered;
114227569Sphilip};
115227569Sphilip
116227569Sphilip/**
117227569Sphilip * struct sfxge_lro_state - Port state for software LRO
118227569Sphilip * @sc: The associated NIC.
119227569Sphilip * @conns_mask: Number of hash buckets - 1.
120227569Sphilip * @conns: Hash buckets for tracked connections.
121227569Sphilip * @conns_n: Length of linked list for each hash bucket.
122227569Sphilip * @active_conns: Connections that are holding a packet.
123227569Sphilip *	Connections are self-linked when not in this list.
124227569Sphilip * @free_conns: Free sfxge_lro_conn instances.
125227569Sphilip * @last_purge_ticks: The value of ticks last time we purged idle
126227569Sphilip *	connections.
127227569Sphilip * @n_merges: Number of packets absorbed by LRO.
128227569Sphilip * @n_bursts: Number of bursts spotted by LRO.
129227569Sphilip * @n_slow_start: Number of packets not merged because connection may be in
130227569Sphilip *	slow-start.
131227569Sphilip * @n_misorder: Number of out-of-order packets seen in tracked streams.
132227569Sphilip * @n_too_many: Incremented when we're trying to track too many streams.
133227569Sphilip * @n_new_stream: Number of distinct streams we've tracked.
134227569Sphilip * @n_drop_idle: Number of streams discarded because they went idle.
135227569Sphilip * @n_drop_closed: Number of streams that have seen a FIN or RST.
136227569Sphilip */
137227569Sphilipstruct sfxge_lro_state {
138227569Sphilip	struct sfxge_softc *sc;
139227569Sphilip	unsigned conns_mask;
140227569Sphilip	TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns;
141227569Sphilip	unsigned *conns_n;
142227569Sphilip	LIST_HEAD(, sfxge_lro_conn) active_conns;
143227569Sphilip	TAILQ_HEAD(, sfxge_lro_conn) free_conns;
144227569Sphilip	unsigned last_purge_ticks;
145227569Sphilip	unsigned n_merges;
146227569Sphilip	unsigned n_bursts;
147227569Sphilip	unsigned n_slow_start;
148227569Sphilip	unsigned n_misorder;
149227569Sphilip	unsigned n_too_many;
150227569Sphilip	unsigned n_new_stream;
151227569Sphilip	unsigned n_drop_idle;
152227569Sphilip	unsigned n_drop_closed;
153227569Sphilip};
154227569Sphilip
155280615Sarybchik#endif	/* SFXGE_LRO */
156280615Sarybchik
157227569Sphilipenum sfxge_flush_state {
158227569Sphilip	SFXGE_FLUSH_DONE = 0,
159284555Sarybchik	SFXGE_FLUSH_REQUIRED,
160227569Sphilip	SFXGE_FLUSH_PENDING,
161227569Sphilip	SFXGE_FLUSH_FAILED
162227569Sphilip};
163227569Sphilip
164227569Sphilipenum sfxge_rxq_state {
165227569Sphilip	SFXGE_RXQ_UNINITIALIZED = 0,
166227569Sphilip	SFXGE_RXQ_INITIALIZED,
167227569Sphilip	SFXGE_RXQ_STARTED
168227569Sphilip};
169227569Sphilip
170227569Sphilip#define	SFXGE_RX_BATCH	128
171227569Sphilip
172227569Sphilipstruct sfxge_rxq {
173227569Sphilip	struct sfxge_softc		*sc __aligned(CACHE_LINE_SIZE);
174227569Sphilip	unsigned int			index;
175227569Sphilip	efsys_mem_t			mem;
176227569Sphilip	unsigned int			buf_base_id;
177227569Sphilip	enum sfxge_rxq_state		init_state;
178280502Sarybchik	unsigned int			entries;
179280502Sarybchik	unsigned int			ptr_mask;
180227569Sphilip
181227569Sphilip	struct sfxge_rx_sw_desc		*queue __aligned(CACHE_LINE_SIZE);
182227569Sphilip	unsigned int			added;
183284555Sarybchik	unsigned int			pushed;
184227569Sphilip	unsigned int			pending;
185227569Sphilip	unsigned int			completed;
186227569Sphilip	unsigned int			loopback;
187280615Sarybchik#ifdef SFXGE_LRO
188227569Sphilip	struct sfxge_lro_state		lro;
189280615Sarybchik#endif
190280502Sarybchik	unsigned int			refill_threshold;
191227569Sphilip	struct callout			refill_callout;
192227569Sphilip	unsigned int			refill_delay;
193227569Sphilip
194227569Sphilip	efx_rxq_t			*common __aligned(CACHE_LINE_SIZE);
195227569Sphilip	volatile enum sfxge_flush_state	flush_state;
196227569Sphilip};
197227569Sphilip
198227569Sphilip/*
199227569Sphilip * From sfxge_rx.c.
200227569Sphilip */
201227569Sphilipextern int sfxge_rx_init(struct sfxge_softc *sc);
202227569Sphilipextern void sfxge_rx_fini(struct sfxge_softc *sc);
203227569Sphilipextern int sfxge_rx_start(struct sfxge_softc *sc);
204227569Sphilipextern void sfxge_rx_stop(struct sfxge_softc *sc);
205227569Sphilipextern void sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop);
206227569Sphilipextern void sfxge_rx_qrefill(struct sfxge_rxq *rxq);
207227569Sphilipextern void sfxge_rx_qflush_done(struct sfxge_rxq *rxq);
208227569Sphilipextern void sfxge_rx_qflush_failed(struct sfxge_rxq *rxq);
209227569Sphilipextern void sfxge_rx_scale_update(void *arg, int npending);
210227569Sphilip
211227569Sphilip#endif
212