1/*-
2 * Copyright (c) 2010-2016 Solarflare Communications Inc.
3 * All rights reserved.
4 *
5 * This software was developed in part by Philip Paeps under contract for
6 * Solarflare Communications, Inc.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
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.
16 *
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.
28 *
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.
32 *
33 * $FreeBSD: stable/10/sys/dev/sfxge/sfxge.h 342529 2018-12-26 10:39:34Z arybchik $
34 */
35
36#ifndef _SFXGE_H
37#define	_SFXGE_H
38
39#include <sys/param.h>
40#include <sys/kernel.h>
41#include <sys/socket.h>
42#include <sys/sysctl.h>
43#include <sys/sx.h>
44#include <vm/uma.h>
45
46#include <net/ethernet.h>
47#include <net/if.h>
48#include <net/if_media.h>
49#include <net/if_types.h>
50
51#include "sfxge_ioc.h"
52
53/*
54 * Debugging
55 */
56#if 0
57#define	DBGPRINT(dev, fmt, args...) \
58	device_printf(dev, "%s: " fmt "\n", __func__, ## args)
59#else
60#define	DBGPRINT(dev, fmt, args...)
61#endif
62
63/*
64 * Backward-compatibility
65 */
66#ifndef CACHE_LINE_SIZE
67/* This should be right on most machines the driver will be used on, and
68 * we needn't care too much about wasting a few KB per interface.
69 */
70#define	CACHE_LINE_SIZE 128
71#endif
72
73#ifndef IFCAP_LINKSTATE
74#define	IFCAP_LINKSTATE 0
75#endif
76
77#ifndef IFCAP_VLAN_HWTSO
78#define	IFCAP_VLAN_HWTSO 0
79#endif
80
81#ifndef IFM_10G_T
82#define	IFM_10G_T IFM_UNKNOWN
83#endif
84
85#ifndef IFM_10G_KX4
86#define	IFM_10G_KX4 IFM_10G_CX4
87#endif
88
89#ifndef IFM_40G_CR4
90#define	IFM_40G_CR4 IFM_UNKNOWN
91#endif
92
93#if (__FreeBSD_version >= 800501 && __FreeBSD_version < 900000) || \
94	__FreeBSD_version >= 900003
95#define	SFXGE_HAVE_DESCRIBE_INTR
96#endif
97
98#ifdef IFM_ETH_RXPAUSE
99#define	SFXGE_HAVE_PAUSE_MEDIAOPTS
100#endif
101
102#ifndef CTLTYPE_U64
103#define	CTLTYPE_U64 CTLTYPE_QUAD
104#endif
105
106#include "sfxge_rx.h"
107#include "sfxge_tx.h"
108
109#define	ROUNDUP_POW_OF_TWO(_n)	(1ULL << flsl((_n) - 1))
110
111#define	SFXGE_IP_ALIGN	2
112
113#define	SFXGE_ETHERTYPE_LOOPBACK	0x9000	/* Xerox loopback */
114
115
116#define	SFXGE_MAGIC_RESERVED		0x8000
117
118#define	SFXGE_MAGIC_DMAQ_LABEL_WIDTH	6
119#define	SFXGE_MAGIC_DMAQ_LABEL_MASK \
120	((1 << SFXGE_MAGIC_DMAQ_LABEL_WIDTH) - 1)
121
122enum sfxge_sw_ev {
123	SFXGE_SW_EV_RX_QFLUSH_DONE = 1,
124	SFXGE_SW_EV_RX_QFLUSH_FAILED,
125	SFXGE_SW_EV_RX_QREFILL,
126	SFXGE_SW_EV_TX_QFLUSH_DONE,
127};
128
129#define	SFXGE_SW_EV_MAGIC(_sw_ev) \
130	(SFXGE_MAGIC_RESERVED | ((_sw_ev) << SFXGE_MAGIC_DMAQ_LABEL_WIDTH))
131
132static inline uint16_t
133sfxge_sw_ev_mk_magic(enum sfxge_sw_ev sw_ev, unsigned int label)
134{
135	KASSERT((label & SFXGE_MAGIC_DMAQ_LABEL_MASK) == label,
136	    ("(label & SFXGE_MAGIC_DMAQ_LABEL_MASK) != label"));
137	return SFXGE_SW_EV_MAGIC(sw_ev) | label;
138}
139
140static inline uint16_t
141sfxge_sw_ev_rxq_magic(enum sfxge_sw_ev sw_ev, struct sfxge_rxq *rxq)
142{
143	return sfxge_sw_ev_mk_magic(sw_ev, 0);
144}
145
146static inline uint16_t
147sfxge_sw_ev_txq_magic(enum sfxge_sw_ev sw_ev, struct sfxge_txq *txq)
148{
149	return sfxge_sw_ev_mk_magic(sw_ev, txq->type);
150}
151
152enum sfxge_evq_state {
153	SFXGE_EVQ_UNINITIALIZED = 0,
154	SFXGE_EVQ_INITIALIZED,
155	SFXGE_EVQ_STARTING,
156	SFXGE_EVQ_STARTED
157};
158
159#define	SFXGE_EV_BATCH	16384
160
161#define	SFXGE_STATS_UPDATE_PERIOD_MS	1000
162
163struct sfxge_evq {
164	/* Structure members below are sorted by usage order */
165	struct sfxge_softc	*sc;
166	struct mtx		lock;
167	unsigned int		index;
168	enum sfxge_evq_state	init_state;
169	efsys_mem_t		mem;
170	efx_evq_t		*common;
171	unsigned int		read_ptr;
172	boolean_t		exception;
173	unsigned int		rx_done;
174	unsigned int		tx_done;
175
176	/* Linked list of TX queues with completions to process */
177	struct sfxge_txq	*txq;
178	struct sfxge_txq	**txqs;
179
180	/* Structure members not used on event processing path */
181	unsigned int		buf_base_id;
182	unsigned int		entries;
183	char			lock_name[SFXGE_LOCK_NAME_MAX];
184#if EFSYS_OPT_QSTATS
185	clock_t			stats_update_time;
186	uint64_t		stats[EV_NQSTATS];
187#endif
188} __aligned(CACHE_LINE_SIZE);
189
190#define	SFXGE_NDESCS	1024
191#define	SFXGE_MODERATION	30
192
193enum sfxge_intr_state {
194	SFXGE_INTR_UNINITIALIZED = 0,
195	SFXGE_INTR_INITIALIZED,
196	SFXGE_INTR_TESTING,
197	SFXGE_INTR_STARTED
198};
199
200struct sfxge_intr_hdl {
201	int			eih_rid;
202	void			*eih_tag;
203	struct resource		*eih_res;
204};
205
206struct sfxge_intr {
207	enum sfxge_intr_state	state;
208	struct resource		*msix_res;
209	struct sfxge_intr_hdl	*table;
210	int			n_alloc;
211	int			type;
212	efsys_mem_t		status;
213	uint32_t		zero_count;
214};
215
216enum sfxge_mcdi_state {
217	SFXGE_MCDI_UNINITIALIZED = 0,
218	SFXGE_MCDI_INITIALIZED,
219	SFXGE_MCDI_BUSY,
220	SFXGE_MCDI_COMPLETED
221};
222
223struct sfxge_mcdi {
224	struct mtx		lock;
225	efsys_mem_t		mem;
226	enum sfxge_mcdi_state	state;
227	efx_mcdi_transport_t	transport;
228
229	/* Only used in debugging output */
230	char			lock_name[SFXGE_LOCK_NAME_MAX];
231};
232
233struct sfxge_hw_stats {
234	clock_t			update_time;
235	efsys_mem_t		dma_buf;
236	void			*decode_buf;
237};
238
239enum sfxge_port_state {
240	SFXGE_PORT_UNINITIALIZED = 0,
241	SFXGE_PORT_INITIALIZED,
242	SFXGE_PORT_STARTED
243};
244
245struct sfxge_port {
246	struct sfxge_softc	*sc;
247	struct mtx		lock;
248	enum sfxge_port_state	init_state;
249#ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS
250	unsigned int		wanted_fc;
251#endif
252	struct sfxge_hw_stats	phy_stats;
253	struct sfxge_hw_stats	mac_stats;
254	uint16_t		stats_update_period_ms;
255	efx_link_mode_t		link_mode;
256	uint8_t			mcast_addrs[EFX_MAC_MULTICAST_LIST_MAX *
257					    EFX_MAC_ADDR_LEN];
258	unsigned int		mcast_count;
259
260	/* Only used in debugging output */
261	char			lock_name[SFXGE_LOCK_NAME_MAX];
262};
263
264enum sfxge_softc_state {
265	SFXGE_UNINITIALIZED = 0,
266	SFXGE_INITIALIZED,
267	SFXGE_REGISTERED,
268	SFXGE_STARTED
269};
270
271struct sfxge_softc {
272	device_t			dev;
273	struct sx			softc_lock;
274	char				softc_lock_name[SFXGE_LOCK_NAME_MAX];
275	enum sfxge_softc_state		init_state;
276	struct ifnet			*ifnet;
277	unsigned int			if_flags;
278	struct sysctl_oid		*stats_node;
279#if EFSYS_OPT_QSTATS
280	struct sysctl_oid		*evqs_stats_node;
281#endif
282	struct sysctl_oid		*txqs_node;
283
284	struct task			task_reset;
285
286	efx_family_t			family;
287	caddr_t				vpd_data;
288	size_t				vpd_size;
289	efx_nic_t			*enp;
290	efsys_lock_t			enp_lock;
291
292	boolean_t			txq_dynamic_cksum_toggle_supported;
293
294	unsigned int			rxq_entries;
295	unsigned int			txq_entries;
296
297	bus_dma_tag_t			parent_dma_tag;
298	efsys_bar_t			bar;
299
300	struct sfxge_intr		intr;
301	struct sfxge_mcdi		mcdi;
302	struct sfxge_port		port;
303	uint32_t			buffer_table_next;
304
305	struct sfxge_evq		*evq[SFXGE_RX_SCALE_MAX];
306	unsigned int			ev_moderation;
307#if EFSYS_OPT_QSTATS
308	clock_t				ev_stats_update_time;
309	uint64_t			ev_stats[EV_NQSTATS];
310#endif
311
312	unsigned int			max_rss_channels;
313	struct sfxge_rxq		*rxq[SFXGE_RX_SCALE_MAX];
314	unsigned int			rx_indir_table[EFX_RSS_TBL_SIZE];
315
316	struct sfxge_txq		*txq[SFXGE_TXQ_NTYPES + SFXGE_RX_SCALE_MAX];
317
318	struct ifmedia			media;
319
320	size_t				rx_prefix_size;
321	size_t				rx_buffer_size;
322	size_t				rx_buffer_align;
323	uma_zone_t			rx_buffer_zone;
324
325	struct callout			tick_callout;
326
327	unsigned int			evq_max;
328	unsigned int			evq_count;
329	unsigned int			rxq_count;
330	unsigned int			txq_count;
331
332	unsigned int			tso_fw_assisted;
333#define	SFXGE_FATSOV1	(1 << 0)
334#define	SFXGE_FATSOV2	(1 << 1)
335
336#if EFSYS_OPT_MCDI_LOGGING
337	int				mcdi_logging;
338#endif
339};
340
341#define	SFXGE_LINK_UP(sc) \
342	((sc)->port.link_mode != EFX_LINK_DOWN && \
343	 (sc)->port.link_mode != EFX_LINK_UNKNOWN)
344#define	SFXGE_RUNNING(sc) ((sc)->ifnet->if_drv_flags & IFF_DRV_RUNNING)
345
346#define	SFXGE_PARAM(_name)	"hw.sfxge." #_name
347
348SYSCTL_DECL(_hw_sfxge);
349
350/*
351 * From sfxge.c.
352 */
353extern void sfxge_schedule_reset(struct sfxge_softc *sc);
354extern void sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n,
355				     uint32_t *idp);
356
357/*
358 * From sfxge_dma.c.
359 */
360extern int sfxge_dma_init(struct sfxge_softc *sc);
361extern void sfxge_dma_fini(struct sfxge_softc *sc);
362extern int sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len,
363			   efsys_mem_t *esmp);
364extern void sfxge_dma_free(efsys_mem_t *esmp);
365extern int sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map,
366				     struct mbuf **mp,
367				     bus_dma_segment_t *segs,
368				     int *nsegs, int maxsegs);
369
370/*
371 * From sfxge_ev.c.
372 */
373extern int sfxge_ev_init(struct sfxge_softc *sc);
374extern void sfxge_ev_fini(struct sfxge_softc *sc);
375extern int sfxge_ev_start(struct sfxge_softc *sc);
376extern void sfxge_ev_stop(struct sfxge_softc *sc);
377extern int sfxge_ev_qpoll(struct sfxge_evq *evq);
378
379/*
380 * From sfxge_intr.c.
381 */
382extern int sfxge_intr_init(struct sfxge_softc *sc);
383extern void sfxge_intr_fini(struct sfxge_softc *sc);
384extern int sfxge_intr_start(struct sfxge_softc *sc);
385extern void sfxge_intr_stop(struct sfxge_softc *sc);
386
387/*
388 * From sfxge_mcdi.c.
389 */
390extern int sfxge_mcdi_init(struct sfxge_softc *sc);
391extern void sfxge_mcdi_fini(struct sfxge_softc *sc);
392extern int sfxge_mcdi_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip);
393
394/*
395 * From sfxge_nvram.c.
396 */
397extern int sfxge_nvram_ioctl(struct sfxge_softc *sc, sfxge_ioc_t *ip);
398
399/*
400 * From sfxge_port.c.
401 */
402extern int sfxge_port_init(struct sfxge_softc *sc);
403extern void sfxge_port_fini(struct sfxge_softc *sc);
404extern int sfxge_port_start(struct sfxge_softc *sc);
405extern void sfxge_port_stop(struct sfxge_softc *sc);
406extern void sfxge_mac_link_update(struct sfxge_softc *sc,
407				  efx_link_mode_t mode);
408extern int sfxge_mac_filter_set(struct sfxge_softc *sc);
409extern int sfxge_port_ifmedia_init(struct sfxge_softc *sc);
410extern void sfxge_port_update_stats(struct sfxge_softc *sc);
411
412#define	SFXGE_MAX_MTU (9 * 1024)
413
414#define	SFXGE_ADAPTER_LOCK_INIT(_sc, _ifname)				\
415	do {								\
416		struct sfxge_softc *__sc = (_sc);			\
417									\
418		snprintf((__sc)->softc_lock_name,			\
419			 sizeof((__sc)->softc_lock_name),		\
420			 "%s:softc", (_ifname));			\
421		sx_init(&(__sc)->softc_lock, (__sc)->softc_lock_name);	\
422	} while (B_FALSE)
423#define	SFXGE_ADAPTER_LOCK_DESTROY(_sc)					\
424	sx_destroy(&(_sc)->softc_lock)
425#define	SFXGE_ADAPTER_LOCK(_sc)						\
426	sx_xlock(&(_sc)->softc_lock)
427#define	SFXGE_ADAPTER_UNLOCK(_sc)					\
428	sx_xunlock(&(_sc)->softc_lock)
429#define	SFXGE_ADAPTER_LOCK_ASSERT_OWNED(_sc)				\
430	sx_assert(&(_sc)->softc_lock, LA_XLOCKED)
431
432#define	SFXGE_PORT_LOCK_INIT(_port, _ifname)				\
433	do {								\
434		struct sfxge_port *__port = (_port);			\
435									\
436		snprintf((__port)->lock_name,				\
437			 sizeof((__port)->lock_name),			\
438			 "%s:port", (_ifname));				\
439		mtx_init(&(__port)->lock, (__port)->lock_name,		\
440			 NULL, MTX_DEF);				\
441	} while (B_FALSE)
442#define	SFXGE_PORT_LOCK_DESTROY(_port)					\
443	mtx_destroy(&(_port)->lock)
444#define	SFXGE_PORT_LOCK(_port)						\
445	mtx_lock(&(_port)->lock)
446#define	SFXGE_PORT_UNLOCK(_port)					\
447	mtx_unlock(&(_port)->lock)
448#define	SFXGE_PORT_LOCK_ASSERT_OWNED(_port)				\
449	mtx_assert(&(_port)->lock, MA_OWNED)
450
451#define	SFXGE_MCDI_LOCK_INIT(_mcdi, _ifname)				\
452	do {								\
453		struct sfxge_mcdi  *__mcdi = (_mcdi);			\
454									\
455		snprintf((__mcdi)->lock_name,				\
456			 sizeof((__mcdi)->lock_name),			\
457			 "%s:mcdi", (_ifname));				\
458		mtx_init(&(__mcdi)->lock, (__mcdi)->lock_name,		\
459			 NULL, MTX_DEF);				\
460	} while (B_FALSE)
461#define	SFXGE_MCDI_LOCK_DESTROY(_mcdi)					\
462	mtx_destroy(&(_mcdi)->lock)
463#define	SFXGE_MCDI_LOCK(_mcdi)						\
464	mtx_lock(&(_mcdi)->lock)
465#define	SFXGE_MCDI_UNLOCK(_mcdi)					\
466	mtx_unlock(&(_mcdi)->lock)
467#define	SFXGE_MCDI_LOCK_ASSERT_OWNED(_mcdi)				\
468	mtx_assert(&(_mcdi)->lock, MA_OWNED)
469
470#define	SFXGE_EVQ_LOCK_INIT(_evq, _ifname, _evq_index)			\
471	do {								\
472		struct sfxge_evq  *__evq = (_evq);			\
473									\
474		snprintf((__evq)->lock_name,				\
475			 sizeof((__evq)->lock_name),			\
476			 "%s:evq%u", (_ifname), (_evq_index));		\
477		mtx_init(&(__evq)->lock, (__evq)->lock_name,		\
478			 NULL, MTX_DEF);				\
479	} while (B_FALSE)
480#define	SFXGE_EVQ_LOCK_DESTROY(_evq)					\
481	mtx_destroy(&(_evq)->lock)
482#define	SFXGE_EVQ_LOCK(_evq)						\
483	mtx_lock(&(_evq)->lock)
484#define	SFXGE_EVQ_UNLOCK(_evq)						\
485	mtx_unlock(&(_evq)->lock)
486#define	SFXGE_EVQ_LOCK_ASSERT_OWNED(_evq)				\
487	mtx_assert(&(_evq)->lock, MA_OWNED)
488
489#endif /* _SFXGE_H */
490