1227569Sphilip/*-
2227569Sphilip * Copyright (c) 2010-2011 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
9227569Sphilip * modification, are permitted provided that the following conditions
10227569Sphilip * are met:
11227569Sphilip * 1. Redistributions of source code must retain the above copyright
12227569Sphilip *    notice, this list of conditions and the following disclaimer.
13227569Sphilip * 2. Redistributions in binary form must reproduce the above copyright
14227569Sphilip *    notice, this list of conditions and the following disclaimer in the
15227569Sphilip *    documentation and/or other materials provided with the distribution.
16227569Sphilip *
17227569Sphilip * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18227569Sphilip * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19227569Sphilip * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20227569Sphilip * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21227569Sphilip * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22227569Sphilip * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23227569Sphilip * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24227569Sphilip * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25227569Sphilip * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26227569Sphilip * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27227569Sphilip * SUCH DAMAGE.
28227569Sphilip *
29227569Sphilip * $FreeBSD$
30227569Sphilip */
31227569Sphilip
32227569Sphilip#ifndef _SFXGE_RX_H
33227569Sphilip#define _SFXGE_RX_H
34227569Sphilip
35227569Sphilip#define SFXGE_MAGIC_RESERVED    0x8000
36227569Sphilip
37227569Sphilip#define SFXGE_MAGIC_DMAQ_LABEL_WIDTH  6
38227569Sphilip#define SFXGE_MAGIC_DMAQ_LABEL_MASK   \
39227569Sphilip        ((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1)
40227569Sphilip
41227569Sphilip#define SFXGE_MAGIC_RX_QFLUSH_DONE                                      \
42227569Sphilip        (SFXGE_MAGIC_RESERVED | (1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
43227569Sphilip
44227569Sphilip#define SFXGE_MAGIC_RX_QFLUSH_FAILED                                    \
45227569Sphilip        (SFXGE_MAGIC_RESERVED | (2 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
46227569Sphilip
47227569Sphilip#define SFXGE_MAGIC_RX_QREFILL                                          \
48227569Sphilip        (SFXGE_MAGIC_RESERVED | (3 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
49227569Sphilip
50227569Sphilip#define SFXGE_MAGIC_TX_QFLUSH_DONE                                      \
51227569Sphilip        (SFXGE_MAGIC_RESERVED | (4 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
52227569Sphilip
53227569Sphilip#define	SFXGE_RX_SCALE_MAX	EFX_MAXRSS
54227569Sphilip
55227569Sphilipstruct sfxge_rx_sw_desc {
56227569Sphilip	struct mbuf	*mbuf;
57227569Sphilip	bus_dmamap_t	map;
58227569Sphilip	int		flags;
59227569Sphilip	int		size;
60227569Sphilip};
61227569Sphilip
62227569Sphilip/**
63227569Sphilip * struct sfxge_lro_conn - Connection state for software LRO
64227569Sphilip * @link: Link for hash table and free list.
65227569Sphilip * @active_link: Link for active_conns list
66227569Sphilip * @l2_id: Identifying information from layer 2
67227569Sphilip * @conn_hash: Hash of connection 4-tuple
68227569Sphilip * @nh: IP (v4 or v6) header of super-packet
69227569Sphilip * @source: Source TCP port number
70227569Sphilip * @dest: Destination TCP port number
71227569Sphilip * @n_in_order_pkts: Number of in-order packets with payload.
72227569Sphilip * @next_seq: Next in-order sequence number.
73227569Sphilip * @last_pkt_ticks: Time we last saw a packet on this connection.
74227569Sphilip * @mbuf: The mbuf we are currently holding.
75227569Sphilip *	If %NULL, then all following fields are undefined.
76227569Sphilip * @mbuf_tail: The tail of the frag_list of mbufs we're holding.
77227569Sphilip *	Only valid after at least one merge.
78227569Sphilip * @th_last: The TCP header of the last packet merged.
79227569Sphilip * @next_buf: The next RX buffer to process.
80227569Sphilip * @next_eh: Ethernet header of the next buffer.
81227569Sphilip * @next_nh: IP header of the next buffer.
82227569Sphilip * @delivered: True if we've delivered a payload packet up this interrupt.
83227569Sphilip */
84227569Sphilipstruct sfxge_lro_conn {
85227569Sphilip	TAILQ_ENTRY(sfxge_lro_conn) link;
86227569Sphilip	LIST_ENTRY(sfxge_lro_conn) active_link;
87227569Sphilip	uint16_t l2_id;
88227569Sphilip	uint32_t conn_hash;
89227569Sphilip	void *nh;
90227569Sphilip	uint16_t source, dest;
91227569Sphilip	int n_in_order_pkts;
92227569Sphilip	unsigned next_seq;
93227569Sphilip	unsigned last_pkt_ticks;
94227569Sphilip	struct mbuf *mbuf;
95227569Sphilip	struct mbuf *mbuf_tail;
96227569Sphilip	struct tcphdr *th_last;
97227569Sphilip	struct sfxge_rx_sw_desc next_buf;
98227569Sphilip	void *next_eh;
99227569Sphilip	void *next_nh;
100227569Sphilip	int delivered;
101227569Sphilip};
102227569Sphilip
103227569Sphilip/**
104227569Sphilip * struct sfxge_lro_state - Port state for software LRO
105227569Sphilip * @sc: The associated NIC.
106227569Sphilip * @conns_mask: Number of hash buckets - 1.
107227569Sphilip * @conns: Hash buckets for tracked connections.
108227569Sphilip * @conns_n: Length of linked list for each hash bucket.
109227569Sphilip * @active_conns: Connections that are holding a packet.
110227569Sphilip *	Connections are self-linked when not in this list.
111227569Sphilip * @free_conns: Free sfxge_lro_conn instances.
112227569Sphilip * @last_purge_ticks: The value of ticks last time we purged idle
113227569Sphilip *	connections.
114227569Sphilip * @n_merges: Number of packets absorbed by LRO.
115227569Sphilip * @n_bursts: Number of bursts spotted by LRO.
116227569Sphilip * @n_slow_start: Number of packets not merged because connection may be in
117227569Sphilip *	slow-start.
118227569Sphilip * @n_misorder: Number of out-of-order packets seen in tracked streams.
119227569Sphilip * @n_too_many: Incremented when we're trying to track too many streams.
120227569Sphilip * @n_new_stream: Number of distinct streams we've tracked.
121227569Sphilip * @n_drop_idle: Number of streams discarded because they went idle.
122227569Sphilip * @n_drop_closed: Number of streams that have seen a FIN or RST.
123227569Sphilip */
124227569Sphilipstruct sfxge_lro_state {
125227569Sphilip	struct sfxge_softc *sc;
126227569Sphilip	unsigned conns_mask;
127227569Sphilip	TAILQ_HEAD(sfxge_lro_tailq, sfxge_lro_conn) *conns;
128227569Sphilip	unsigned *conns_n;
129227569Sphilip	LIST_HEAD(, sfxge_lro_conn) active_conns;
130227569Sphilip	TAILQ_HEAD(, sfxge_lro_conn) free_conns;
131227569Sphilip	unsigned last_purge_ticks;
132227569Sphilip	unsigned n_merges;
133227569Sphilip	unsigned n_bursts;
134227569Sphilip	unsigned n_slow_start;
135227569Sphilip	unsigned n_misorder;
136227569Sphilip	unsigned n_too_many;
137227569Sphilip	unsigned n_new_stream;
138227569Sphilip	unsigned n_drop_idle;
139227569Sphilip	unsigned n_drop_closed;
140227569Sphilip};
141227569Sphilip
142227569Sphilipenum sfxge_flush_state {
143227569Sphilip	SFXGE_FLUSH_DONE = 0,
144227569Sphilip	SFXGE_FLUSH_PENDING,
145227569Sphilip	SFXGE_FLUSH_FAILED
146227569Sphilip};
147227569Sphilip
148227569Sphilipenum sfxge_rxq_state {
149227569Sphilip	SFXGE_RXQ_UNINITIALIZED = 0,
150227569Sphilip	SFXGE_RXQ_INITIALIZED,
151227569Sphilip	SFXGE_RXQ_STARTED
152227569Sphilip};
153227569Sphilip
154227569Sphilip#define	SFXGE_RX_BATCH	128
155227569Sphilip
156227569Sphilipstruct sfxge_rxq {
157227569Sphilip	struct sfxge_softc		*sc __aligned(CACHE_LINE_SIZE);
158227569Sphilip	unsigned int			index;
159227569Sphilip	efsys_mem_t			mem;
160227569Sphilip	unsigned int			buf_base_id;
161227569Sphilip	enum sfxge_rxq_state		init_state;
162227569Sphilip
163227569Sphilip	struct sfxge_rx_sw_desc		*queue __aligned(CACHE_LINE_SIZE);
164227569Sphilip	unsigned int			added;
165227569Sphilip	unsigned int			pending;
166227569Sphilip	unsigned int			completed;
167227569Sphilip	unsigned int			loopback;
168227569Sphilip	struct sfxge_lro_state		lro;
169227569Sphilip	struct callout			refill_callout;
170227569Sphilip	unsigned int			refill_delay;
171227569Sphilip
172227569Sphilip	efx_rxq_t			*common __aligned(CACHE_LINE_SIZE);
173227569Sphilip	volatile enum sfxge_flush_state	flush_state;
174227569Sphilip};
175227569Sphilip
176227569Sphilip/*
177227569Sphilip * From sfxge_rx.c.
178227569Sphilip */
179227569Sphilipextern int sfxge_rx_init(struct sfxge_softc *sc);
180227569Sphilipextern void sfxge_rx_fini(struct sfxge_softc *sc);
181227569Sphilipextern int sfxge_rx_start(struct sfxge_softc *sc);
182227569Sphilipextern void sfxge_rx_stop(struct sfxge_softc *sc);
183227569Sphilipextern void sfxge_rx_qcomplete(struct sfxge_rxq *rxq, boolean_t eop);
184227569Sphilipextern void sfxge_rx_qrefill(struct sfxge_rxq *rxq);
185227569Sphilipextern void sfxge_rx_qflush_done(struct sfxge_rxq *rxq);
186227569Sphilipextern void sfxge_rx_qflush_failed(struct sfxge_rxq *rxq);
187227569Sphilipextern void sfxge_rx_scale_update(void *arg, int npending);
188227569Sphilip
189227569Sphilip#endif
190