1227569Sphilip/*-
2300607Sarybchik * Copyright (c) 2010-2016 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
9283514Sarybchik * modification, are permitted provided that the following conditions are met:
10227569Sphilip *
11283514Sarybchik * 1. Redistributions of source code must retain the above copyright notice,
12283514Sarybchik *    this list of conditions and the following disclaimer.
13283514Sarybchik * 2. Redistributions in binary form must reproduce the above copyright notice,
14283514Sarybchik *    this list of conditions and the following disclaimer in the documentation
15283514Sarybchik *    and/or other materials provided with the distribution.
16227569Sphilip *
17283514Sarybchik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18283514Sarybchik * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19283514Sarybchik * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20283514Sarybchik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21283514Sarybchik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22283514Sarybchik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23283514Sarybchik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24283514Sarybchik * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25283514Sarybchik * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26283514Sarybchik * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
27283514Sarybchik * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28283514Sarybchik *
29283514Sarybchik * The views and conclusions contained in the software and documentation are
30283514Sarybchik * those of the authors and should not be interpreted as representing official
31283514Sarybchik * policies, either expressed or implied, of the FreeBSD Project.
32283514Sarybchik *
33227569Sphilip * $FreeBSD: stable/11/sys/dev/sfxge/sfxge_tx.h 342455 2018-12-25 07:39:34Z arybchik $
34227569Sphilip */
35227569Sphilip
36227569Sphilip#ifndef _SFXGE_TX_H
37272325Sgnn#define	_SFXGE_TX_H
38227569Sphilip
39227569Sphilip#include <netinet/in.h>
40227569Sphilip#include <netinet/ip.h>
41227569Sphilip#include <netinet/tcp.h>
42227569Sphilip
43291584Sarybchik/* If defined, parse TX packets directly in if_transmit
44291584Sarybchik * for better cache locality and reduced time under TX lock
45291584Sarybchik */
46291584Sarybchik#define SFXGE_TX_PARSE_EARLY 1
47291584Sarybchik
48279094Sarybchik/* Maximum size of TSO packet */
49279094Sarybchik#define	SFXGE_TSO_MAX_SIZE		(65535)
50279094Sarybchik
51279094Sarybchik/*
52279094Sarybchik * Maximum number of segments to be created for a TSO packet.
53279094Sarybchik * Allow for a reasonable minimum MSS of 512.
54279094Sarybchik */
55279094Sarybchik#define	SFXGE_TSO_MAX_SEGS		howmany(SFXGE_TSO_MAX_SIZE, 512)
56279094Sarybchik
57227569Sphilip/* Maximum number of DMA segments needed to map an mbuf chain.  With
58227569Sphilip * TSO, the mbuf length may be just over 64K, divided into 2K mbuf
59291488Sarybchik * clusters taking into account that the first may be not 2K cluster
60291488Sarybchik * boundary aligned.
61291569Sarybchik * Packet header may be split into two segments because of, for example,
62291569Sarybchik * VLAN header insertion.
63291488Sarybchik * The chain could be longer than this initially, but can be shortened
64291488Sarybchik * with m_collapse().
65227569Sphilip */
66279094Sarybchik#define	SFXGE_TX_MAPPING_MAX_SEG					\
67291569Sarybchik	(2 + howmany(SFXGE_TSO_MAX_SIZE, MCLBYTES) + 1)
68227569Sphilip
69227569Sphilip/*
70227569Sphilip * Buffer mapping flags.
71227569Sphilip *
72227569Sphilip * Buffers and DMA mappings must be freed when the last descriptor
73227569Sphilip * referring to them is completed.  Set the TX_BUF_UNMAP and
74227569Sphilip * TX_BUF_MBUF flags on the last descriptor generated for an mbuf
75227569Sphilip * chain.  Set only the TX_BUF_UNMAP flag on a descriptor referring to
76227569Sphilip * a heap buffer.
77227569Sphilip */
78227569Sphilipenum sfxge_tx_buf_flags {
79227569Sphilip	TX_BUF_UNMAP = 1,
80227569Sphilip	TX_BUF_MBUF = 2,
81227569Sphilip};
82227569Sphilip
83227569Sphilip/*
84227569Sphilip * Buffer mapping information for descriptors in flight.
85227569Sphilip */
86227569Sphilipstruct sfxge_tx_mapping {
87227569Sphilip	union {
88227569Sphilip		struct mbuf	*mbuf;
89227569Sphilip		caddr_t		heap_buf;
90227569Sphilip	}			u;
91227569Sphilip	bus_dmamap_t		map;
92227569Sphilip	enum sfxge_tx_buf_flags	flags;
93227569Sphilip};
94227569Sphilip
95277895Sarybchik#define	SFXGE_TX_DPL_GET_PKT_LIMIT_DEFAULT		(64 * 1024)
96277895Sarybchik#define	SFXGE_TX_DPL_GET_NON_TCP_PKT_LIMIT_DEFAULT	1024
97280164Sarybchik#define	SFXGE_TX_DPL_PUT_PKT_LIMIT_DEFAULT		1024
98227569Sphilip
99227569Sphilip/*
100227569Sphilip * Deferred packet list.
101227569Sphilip */
102227569Sphilipstruct sfxge_tx_dpl {
103277895Sarybchik	unsigned int	std_get_max;		/* Maximum number  of packets
104272331Sgnn						 * in get list */
105277895Sarybchik	unsigned int	std_get_non_tcp_max;	/* Maximum number
106277895Sarybchik						 * of non-TCP packets
107277895Sarybchik						 * in get list */
108277895Sarybchik	unsigned int	std_put_max;		/* Maximum number of packets
109272331Sgnn						 * in put list */
110277895Sarybchik	uintptr_t	std_put;		/* Head of put list. */
111277895Sarybchik	struct mbuf	*std_get;		/* Head of get list. */
112277895Sarybchik	struct mbuf	**std_getp;		/* Tail of get list. */
113277895Sarybchik	unsigned int	std_get_count;		/* Packets in get list. */
114277895Sarybchik	unsigned int	std_get_non_tcp_count;	/* Non-TCP packets
115277895Sarybchik						 * in get list */
116277895Sarybchik	unsigned int	std_get_hiwat;		/* Packets in get list
117277895Sarybchik						 * high watermark */
118279231Sarybchik	unsigned int	std_put_hiwat;		/* Packets in put list
119279231Sarybchik						 * high watermark */
120227569Sphilip};
121227569Sphilip
122227569Sphilip
123227569Sphilip#define	SFXGE_TX_BUFFER_SIZE	0x400
124227569Sphilip#define	SFXGE_TX_HEADER_SIZE	0x100
125227569Sphilip#define	SFXGE_TX_COPY_THRESHOLD	0x200
126227569Sphilip
127227569Sphilipenum sfxge_txq_state {
128227569Sphilip	SFXGE_TXQ_UNINITIALIZED = 0,
129227569Sphilip	SFXGE_TXQ_INITIALIZED,
130227569Sphilip	SFXGE_TXQ_STARTED
131227569Sphilip};
132227569Sphilip
133227569Sphilipenum sfxge_txq_type {
134227569Sphilip	SFXGE_TXQ_NON_CKSUM = 0,
135227569Sphilip	SFXGE_TXQ_IP_CKSUM,
136227569Sphilip	SFXGE_TXQ_IP_TCP_UDP_CKSUM,
137227569Sphilip	SFXGE_TXQ_NTYPES
138227569Sphilip};
139227569Sphilip
140342455Sarybchik#define	SFXGE_EVQ0_N_TXQ(_sc)						\
141342455Sarybchik	((_sc)->txq_dynamic_cksum_toggle_supported ?			\
142342455Sarybchik	1 : SFXGE_TXQ_NTYPES)
143342454Sarybchik
144272328Sgnn#define	SFXGE_TXQ_UNBLOCK_LEVEL(_entries)	(EFX_TXQ_LIMIT(_entries) / 4)
145227569Sphilip
146227569Sphilip#define	SFXGE_TX_BATCH	64
147227569Sphilip
148278250Sarybchik#define	SFXGE_TXQ_LOCK_INIT(_txq, _ifname, _txq_index)			\
149278250Sarybchik	do {								\
150278250Sarybchik		struct sfxge_txq  *__txq = (_txq);			\
151278250Sarybchik									\
152278250Sarybchik		snprintf((__txq)->lock_name,				\
153278250Sarybchik			 sizeof((__txq)->lock_name),			\
154278250Sarybchik			 "%s:txq%u", (_ifname), (_txq_index));		\
155278250Sarybchik		mtx_init(&(__txq)->lock, (__txq)->lock_name,		\
156278250Sarybchik			 NULL, MTX_DEF);				\
157278250Sarybchik	} while (B_FALSE)
158278221Sarybchik#define	SFXGE_TXQ_LOCK_DESTROY(_txq)					\
159278221Sarybchik	mtx_destroy(&(_txq)->lock)
160278221Sarybchik#define	SFXGE_TXQ_LOCK(_txq)						\
161280376Sarybchik	mtx_lock(&(_txq)->lock)
162278221Sarybchik#define	SFXGE_TXQ_TRYLOCK(_txq)						\
163280376Sarybchik	mtx_trylock(&(_txq)->lock)
164278221Sarybchik#define	SFXGE_TXQ_UNLOCK(_txq)						\
165280376Sarybchik	mtx_unlock(&(_txq)->lock)
166278221Sarybchik#define	SFXGE_TXQ_LOCK_ASSERT_OWNED(_txq)				\
167280376Sarybchik	mtx_assert(&(_txq)->lock, MA_OWNED)
168282942Sarybchik#define	SFXGE_TXQ_LOCK_ASSERT_NOTOWNED(_txq)				\
169282942Sarybchik	mtx_assert(&(_txq)->lock, MA_NOTOWNED)
170278221Sarybchik
171278221Sarybchik
172227569Sphilipstruct sfxge_txq {
173227569Sphilip	/* The following fields should be written very rarely */
174227569Sphilip	struct sfxge_softc		*sc;
175227569Sphilip	enum sfxge_txq_state		init_state;
176227569Sphilip	enum sfxge_flush_state		flush_state;
177294077Sarybchik	unsigned int			tso_fw_assisted;
178227569Sphilip	enum sfxge_txq_type		type;
179227569Sphilip	unsigned int			evq_index;
180227569Sphilip	efsys_mem_t			mem;
181227569Sphilip	unsigned int			buf_base_id;
182272328Sgnn	unsigned int			entries;
183272328Sgnn	unsigned int			ptr_mask;
184283514Sarybchik	unsigned int			max_pkt_desc;
185227569Sphilip
186227569Sphilip	struct sfxge_tx_mapping		*stmp;	/* Packets in flight. */
187227569Sphilip	bus_dma_tag_t			packet_dma_tag;
188283514Sarybchik	efx_desc_t			*pend_desc;
189227569Sphilip	efx_txq_t			*common;
190227569Sphilip
191227569Sphilip	efsys_mem_t			*tsoh_buffer;
192227569Sphilip
193278250Sarybchik	char				lock_name[SFXGE_LOCK_NAME_MAX];
194278250Sarybchik
195227569Sphilip	/* This field changes more often and is read regularly on both
196227569Sphilip	 * the initiation and completion paths
197227569Sphilip	 */
198227569Sphilip	int				blocked __aligned(CACHE_LINE_SIZE);
199227569Sphilip
200227569Sphilip	/* The following fields change more often, and are used mostly
201227569Sphilip	 * on the initiation path
202227569Sphilip	 */
203227569Sphilip	struct mtx			lock __aligned(CACHE_LINE_SIZE);
204227569Sphilip	struct sfxge_tx_dpl		dpl;	/* Deferred packet list. */
205227569Sphilip	unsigned int			n_pend_desc;
206227569Sphilip	unsigned int			added;
207227569Sphilip	unsigned int			reaped;
208283514Sarybchik
209342455Sarybchik	/* The last (or constant) set of HW offloads requested on the queue */
210342455Sarybchik	uint16_t			hw_cksum_flags;
211342455Sarybchik
212283514Sarybchik	/* The last VLAN TCI seen on the queue if FW-assisted tagging is
213283514Sarybchik	   used */
214283514Sarybchik	uint16_t			hw_vlan_tci;
215283514Sarybchik
216227569Sphilip	/* Statistics */
217227569Sphilip	unsigned long			tso_bursts;
218227569Sphilip	unsigned long			tso_packets;
219227569Sphilip	unsigned long			tso_long_headers;
220227569Sphilip	unsigned long			collapses;
221227569Sphilip	unsigned long			drops;
222277895Sarybchik	unsigned long			get_overflow;
223277895Sarybchik	unsigned long			get_non_tcp_overflow;
224277895Sarybchik	unsigned long			put_overflow;
225277895Sarybchik	unsigned long			netdown_drops;
226278255Sarybchik	unsigned long			tso_pdrop_too_many;
227278255Sarybchik	unsigned long			tso_pdrop_no_rsrc;
228227569Sphilip
229227569Sphilip	/* The following fields change more often, and are used mostly
230227569Sphilip	 * on the completion path
231227569Sphilip	 */
232227569Sphilip	unsigned int			pending __aligned(CACHE_LINE_SIZE);
233227569Sphilip	unsigned int			completed;
234277885Sarybchik	struct sfxge_txq		*next;
235227569Sphilip};
236227569Sphilip
237277889Sarybchikstruct sfxge_evq;
238277889Sarybchik
239279184Sarybchikextern uint64_t sfxge_tx_get_drops(struct sfxge_softc *sc);
240227569Sphilip
241227569Sphilipextern int sfxge_tx_init(struct sfxge_softc *sc);
242227569Sphilipextern void sfxge_tx_fini(struct sfxge_softc *sc);
243227569Sphilipextern int sfxge_tx_start(struct sfxge_softc *sc);
244227569Sphilipextern void sfxge_tx_stop(struct sfxge_softc *sc);
245277889Sarybchikextern void sfxge_tx_qcomplete(struct sfxge_txq *txq, struct sfxge_evq *evq);
246227569Sphilipextern void sfxge_tx_qflush_done(struct sfxge_txq *txq);
247227569Sphilipextern void sfxge_if_qflush(struct ifnet *ifp);
248227569Sphilipextern int sfxge_if_transmit(struct ifnet *ifp, struct mbuf *m);
249227569Sphilip
250227569Sphilip#endif
251