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_H
33227569Sphilip#define _SFXGE_H
34227569Sphilip
35227569Sphilip#include <sys/param.h>
36227569Sphilip#include <sys/kernel.h>
37227569Sphilip#include <sys/condvar.h>
38227569Sphilip#include <sys/socket.h>
39227569Sphilip#include <sys/sysctl.h>
40227569Sphilip#include <sys/sx.h>
41227569Sphilip#include <vm/uma.h>
42227569Sphilip
43227569Sphilip#include <net/ethernet.h>
44227569Sphilip#include <net/if.h>
45227569Sphilip#include <net/if_media.h>
46227569Sphilip#include <net/if_types.h>
47227569Sphilip
48227569Sphilip/*
49227569Sphilip * Backward-compatibility
50227569Sphilip */
51227569Sphilip#ifndef CACHE_LINE_SIZE
52227569Sphilip/* This should be right on most machines the driver will be used on, and
53227569Sphilip * we needn't care too much about wasting a few KB per interface.
54227569Sphilip */
55227569Sphilip#define CACHE_LINE_SIZE 128
56227569Sphilip#endif
57227569Sphilip#ifndef IFCAP_LINKSTATE
58227569Sphilip#define IFCAP_LINKSTATE 0
59227569Sphilip#endif
60227569Sphilip#ifndef IFCAP_VLAN_HWTSO
61227569Sphilip#define IFCAP_VLAN_HWTSO 0
62227569Sphilip#endif
63227569Sphilip#ifndef IFM_10G_T
64227569Sphilip#define IFM_10G_T IFM_UNKNOWN
65227569Sphilip#endif
66227569Sphilip#ifndef IFM_10G_KX4
67227569Sphilip#define IFM_10G_KX4 IFM_10G_CX4
68227569Sphilip#endif
69227569Sphilip#if __FreeBSD_version >= 800054
70227569Sphilip/* Networking core is multiqueue aware. We can manage our own TX
71227569Sphilip * queues and use m_pkthdr.flowid.
72227569Sphilip */
73227569Sphilip#define SFXGE_HAVE_MQ
74227569Sphilip#endif
75227569Sphilip#if (__FreeBSD_version >= 800501 && __FreeBSD_version < 900000) || \
76227569Sphilip	__FreeBSD_version >= 900003
77227569Sphilip#define SFXGE_HAVE_DESCRIBE_INTR
78227569Sphilip#endif
79227569Sphilip#ifdef IFM_ETH_RXPAUSE
80227569Sphilip#define SFXGE_HAVE_PAUSE_MEDIAOPTS
81227569Sphilip#endif
82227569Sphilip#ifndef CTLTYPE_U64
83227569Sphilip#define CTLTYPE_U64 CTLTYPE_QUAD
84227569Sphilip#endif
85227569Sphilip
86227569Sphilip#include "sfxge_rx.h"
87227569Sphilip#include "sfxge_tx.h"
88227569Sphilip
89227569Sphilip#define SFXGE_IP_ALIGN 2
90227569Sphilip
91227569Sphilip#define SFXGE_ETHERTYPE_LOOPBACK        0x9000  /* Xerox loopback */
92227569Sphilip
93227569Sphilipenum sfxge_evq_state {
94227569Sphilip	SFXGE_EVQ_UNINITIALIZED = 0,
95227569Sphilip	SFXGE_EVQ_INITIALIZED,
96227569Sphilip	SFXGE_EVQ_STARTING,
97227569Sphilip	SFXGE_EVQ_STARTED
98227569Sphilip};
99227569Sphilip
100227569Sphilip#define	SFXGE_EV_BATCH	16384
101227569Sphilip
102227569Sphilipstruct sfxge_evq {
103227569Sphilip	struct sfxge_softc	*sc  __aligned(CACHE_LINE_SIZE);
104227569Sphilip	struct mtx		lock __aligned(CACHE_LINE_SIZE);
105227569Sphilip
106227569Sphilip	enum sfxge_evq_state	init_state;
107227569Sphilip	unsigned int		index;
108227569Sphilip	efsys_mem_t		mem;
109227569Sphilip	unsigned int		buf_base_id;
110227569Sphilip
111227569Sphilip	boolean_t		exception;
112227569Sphilip
113227569Sphilip	efx_evq_t		*common;
114227569Sphilip	unsigned int		read_ptr;
115227569Sphilip	unsigned int		rx_done;
116227569Sphilip	unsigned int		tx_done;
117227569Sphilip
118227569Sphilip	/* Linked list of TX queues with completions to process */
119227569Sphilip	struct sfxge_txq	*txq;
120227569Sphilip	struct sfxge_txq	**txqs;
121227569Sphilip};
122227569Sphilip
123227569Sphilip#define	SFXGE_NEVS	4096
124227569Sphilip#define	SFXGE_NDESCS	1024
125227569Sphilip#define	SFXGE_MODERATION	30
126227569Sphilip
127227569Sphilipenum sfxge_intr_state {
128227569Sphilip	SFXGE_INTR_UNINITIALIZED = 0,
129227569Sphilip	SFXGE_INTR_INITIALIZED,
130227569Sphilip	SFXGE_INTR_TESTING,
131227569Sphilip	SFXGE_INTR_STARTED
132227569Sphilip};
133227569Sphilip
134227569Sphilipstruct sfxge_intr_hdl {
135227569Sphilip	int                eih_rid;
136227569Sphilip	void               *eih_tag;
137227569Sphilip	struct resource    *eih_res;
138227569Sphilip};
139227569Sphilip
140227569Sphilipstruct sfxge_intr {
141227569Sphilip	enum sfxge_intr_state	state;
142227569Sphilip	struct resource		*msix_res;
143227569Sphilip	struct sfxge_intr_hdl	*table;
144227569Sphilip	int			n_alloc;
145227569Sphilip	int			type;
146227569Sphilip	efsys_mem_t		status;
147227569Sphilip	uint32_t		zero_count;
148227569Sphilip};
149227569Sphilip
150227569Sphilipenum sfxge_mcdi_state {
151227569Sphilip	SFXGE_MCDI_UNINITIALIZED = 0,
152227569Sphilip	SFXGE_MCDI_INITIALIZED,
153227569Sphilip	SFXGE_MCDI_BUSY,
154227569Sphilip	SFXGE_MCDI_COMPLETED
155227569Sphilip};
156227569Sphilip
157227569Sphilipstruct sfxge_mcdi {
158227569Sphilip	struct mtx		lock;
159227569Sphilip	struct cv		cv;
160227569Sphilip	enum sfxge_mcdi_state	state;
161227569Sphilip	efx_mcdi_transport_t	transport;
162227569Sphilip};
163227569Sphilip
164227569Sphilipstruct sfxge_hw_stats {
165227569Sphilip	clock_t			update_time;
166227569Sphilip	efsys_mem_t		dma_buf;
167227569Sphilip	void			*decode_buf;
168227569Sphilip};
169227569Sphilip
170227569Sphilipenum sfxge_port_state {
171227569Sphilip	SFXGE_PORT_UNINITIALIZED = 0,
172227569Sphilip	SFXGE_PORT_INITIALIZED,
173227569Sphilip	SFXGE_PORT_STARTED
174227569Sphilip};
175227569Sphilip
176227569Sphilipstruct sfxge_port {
177227569Sphilip	struct sfxge_softc	*sc;
178227569Sphilip	struct mtx		lock;
179227569Sphilip	enum sfxge_port_state	init_state;
180227569Sphilip#ifndef SFXGE_HAVE_PAUSE_MEDIAOPTS
181227569Sphilip	unsigned int		wanted_fc;
182227569Sphilip#endif
183227569Sphilip	struct sfxge_hw_stats	phy_stats;
184227569Sphilip	struct sfxge_hw_stats	mac_stats;
185227569Sphilip	efx_link_mode_t		link_mode;
186227569Sphilip};
187227569Sphilip
188227569Sphilipenum sfxge_softc_state {
189227569Sphilip	SFXGE_UNINITIALIZED = 0,
190227569Sphilip	SFXGE_INITIALIZED,
191227569Sphilip	SFXGE_REGISTERED,
192227569Sphilip	SFXGE_STARTED
193227569Sphilip};
194227569Sphilip
195227569Sphilipstruct sfxge_softc {
196227569Sphilip	device_t			dev;
197227569Sphilip	struct sx			softc_lock;
198227569Sphilip	enum sfxge_softc_state		init_state;
199227569Sphilip	struct ifnet                    *ifnet;
200227569Sphilip	unsigned int			if_flags;
201227569Sphilip	struct sysctl_oid		*stats_node;
202227569Sphilip
203227569Sphilip	struct task			task_reset;
204227569Sphilip
205227569Sphilip	efx_family_t			family;
206227569Sphilip	caddr_t				vpd_data;
207227569Sphilip	size_t				vpd_size;
208227569Sphilip	efx_nic_t			*enp;
209227569Sphilip	struct mtx			enp_lock;
210227569Sphilip
211227569Sphilip	bus_dma_tag_t                   parent_dma_tag;
212227569Sphilip	efsys_bar_t			bar;
213227569Sphilip
214227569Sphilip	struct sfxge_intr		intr;
215227569Sphilip	struct sfxge_mcdi		mcdi;
216227569Sphilip	struct sfxge_port		port;
217227569Sphilip	uint32_t			buffer_table_next;
218227569Sphilip
219227569Sphilip	struct sfxge_evq		*evq[SFXGE_RX_SCALE_MAX];
220227569Sphilip	unsigned int			ev_moderation;
221227569Sphilip	clock_t				ev_stats_update_time;
222227569Sphilip	uint64_t			ev_stats[EV_NQSTATS];
223227569Sphilip
224227569Sphilip	uma_zone_t			rxq_cache;
225227569Sphilip	struct sfxge_rxq		*rxq[SFXGE_RX_SCALE_MAX];
226227569Sphilip	unsigned int			rx_indir_table[SFXGE_RX_SCALE_MAX];
227227569Sphilip
228227569Sphilip#ifdef SFXGE_HAVE_MQ
229227569Sphilip	struct sfxge_txq		*txq[SFXGE_TXQ_NTYPES + SFXGE_RX_SCALE_MAX];
230227569Sphilip#else
231227569Sphilip	struct sfxge_txq		*txq[SFXGE_TXQ_NTYPES];
232227569Sphilip#endif
233227569Sphilip
234227569Sphilip	struct ifmedia			media;
235227569Sphilip
236227569Sphilip	size_t				rx_prefix_size;
237227569Sphilip	size_t				rx_buffer_size;
238227569Sphilip	uma_zone_t			rx_buffer_zone;
239227569Sphilip
240227569Sphilip#ifndef SFXGE_HAVE_MQ
241227569Sphilip	struct mtx			tx_lock __aligned(CACHE_LINE_SIZE);
242227569Sphilip#endif
243227569Sphilip};
244227569Sphilip
245227569Sphilip#define SFXGE_LINK_UP(sc) ((sc)->port.link_mode != EFX_LINK_DOWN)
246227569Sphilip#define SFXGE_RUNNING(sc) ((sc)->ifnet->if_drv_flags & IFF_DRV_RUNNING)
247227569Sphilip
248227569Sphilip/*
249227569Sphilip * From sfxge.c.
250227569Sphilip */
251227569Sphilipextern void sfxge_schedule_reset(struct sfxge_softc *sc);
252227569Sphilipextern void sfxge_sram_buf_tbl_alloc(struct sfxge_softc *sc, size_t n,
253227569Sphilip				     uint32_t *idp);
254227569Sphilip
255227569Sphilip/*
256227569Sphilip * From sfxge_dma.c.
257227569Sphilip */
258227569Sphilipextern int sfxge_dma_init(struct sfxge_softc *sc);
259227569Sphilipextern void sfxge_dma_fini(struct sfxge_softc *sc);
260227569Sphilipextern int sfxge_dma_alloc(struct sfxge_softc *sc, bus_size_t len,
261227569Sphilip    efsys_mem_t *esmp);
262227569Sphilipextern void sfxge_dma_free(efsys_mem_t *esmp);
263227569Sphilipextern int sfxge_dma_map_sg_collapse(bus_dma_tag_t tag, bus_dmamap_t map,
264227569Sphilip    struct mbuf **mp, bus_dma_segment_t *segs, int *nsegs, int maxsegs);
265227569Sphilip
266227569Sphilip/*
267227569Sphilip * From sfxge_ev.c.
268227569Sphilip */
269227569Sphilipextern int sfxge_ev_init(struct sfxge_softc *sc);
270227569Sphilipextern void sfxge_ev_fini(struct sfxge_softc *sc);
271227569Sphilipextern int sfxge_ev_start(struct sfxge_softc *sc);
272227569Sphilipextern void sfxge_ev_stop(struct sfxge_softc *sc);
273227569Sphilipextern int sfxge_ev_qpoll(struct sfxge_softc *sc, unsigned int index);
274227569Sphilip
275227569Sphilip/*
276227569Sphilip * From sfxge_intr.c.
277227569Sphilip */
278227569Sphilipextern int sfxge_intr_init(struct sfxge_softc *sc);
279227569Sphilipextern void sfxge_intr_fini(struct sfxge_softc *sc);
280227569Sphilipextern int sfxge_intr_start(struct sfxge_softc *sc);
281227569Sphilipextern void sfxge_intr_stop(struct sfxge_softc *sc);
282227569Sphilip
283227569Sphilip/*
284227569Sphilip * From sfxge_mcdi.c.
285227569Sphilip */
286227569Sphilipextern int sfxge_mcdi_init(struct sfxge_softc *sc);
287227569Sphilipextern void sfxge_mcdi_fini(struct sfxge_softc *sc);
288227569Sphilip
289227569Sphilip/*
290227569Sphilip * From sfxge_port.c.
291227569Sphilip */
292227569Sphilipextern int sfxge_port_init(struct sfxge_softc *sc);
293227569Sphilipextern void sfxge_port_fini(struct sfxge_softc *sc);
294227569Sphilipextern int sfxge_port_start(struct sfxge_softc *sc);
295227569Sphilipextern void sfxge_port_stop(struct sfxge_softc *sc);
296227569Sphilipextern void sfxge_mac_link_update(struct sfxge_softc *sc,
297227569Sphilip    efx_link_mode_t mode);
298227569Sphilipextern int sfxge_mac_filter_set(struct sfxge_softc *sc);
299227569Sphilipextern int sfxge_port_ifmedia_init(struct sfxge_softc *sc);
300227569Sphilip
301227569Sphilip#define SFXGE_MAX_MTU (9 * 1024)
302227569Sphilip
303227569Sphilip#endif /* _SFXGE_H */
304