1/*-
2 * Copyright (c) 2010-2011 Aleksandr Rybalko <ray@ddteam.net>
3 * Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
4 * Copyright (c) 2009 Damien Bergamini <damien.bergamini@free.fr>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice unmodified, this list of conditions, and the following
11 *    disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 *
28 * $FreeBSD$
29 */
30
31#ifndef _IF_RTVAR_H_
32#define	_IF_RTVAR_H_
33
34#include <sys/param.h>
35#include <sys/sysctl.h>
36#include <sys/sockio.h>
37#include <sys/mbuf.h>
38#include <sys/kernel.h>
39#include <sys/socket.h>
40#include <sys/systm.h>
41#include <sys/malloc.h>
42#include <sys/taskqueue.h>
43#include <sys/module.h>
44#include <sys/bus.h>
45#include <sys/endian.h>
46
47#include <machine/bus.h>
48#include <machine/resource.h>
49#include <sys/rman.h>
50
51#include <net/bpf.h>
52#include <net/if.h>
53#include <net/if_arp.h>
54#include <net/ethernet.h>
55#include <net/if_dl.h>
56#include <net/if_media.h>
57#include <net/if_types.h>
58
59#include "opt_if_rt.h"
60
61#define	RT_SOFTC_LOCK(sc)		mtx_lock(&(sc)->lock)
62#define	RT_SOFTC_UNLOCK(sc)		mtx_unlock(&(sc)->lock)
63#define	RT_SOFTC_ASSERT_LOCKED(sc)	mtx_assert(&(sc)->lock, MA_OWNED)
64
65#define	RT_SOFTC_TX_RING_LOCK(ring)		mtx_lock(&(ring)->lock)
66#define	RT_SOFTC_TX_RING_UNLOCK(ring)		mtx_unlock(&(ring)->lock)
67#define	RT_SOFTC_TX_RING_ASSERT_LOCKED(ring)	\
68		    mtx_assert(&(ring)->lock, MA_OWNED)
69
70#define	RT_SOFTC_TX_RING_COUNT		4
71
72#ifndef IF_RT_RING_DATA_COUNT
73#define	IF_RT_RING_DATA_COUNT	128
74#endif
75
76#define	RT_SOFTC_RX_RING_DATA_COUNT	IF_RT_RING_DATA_COUNT
77
78#define	RT_SOFTC_MAX_SCATTER		10
79
80#define	RT_SOFTC_TX_RING_DATA_COUNT	(IF_RT_RING_DATA_COUNT/4)
81#define	RT_SOFTC_TX_RING_DESC_COUNT				\
82	(RT_SOFTC_TX_RING_DATA_COUNT * RT_SOFTC_MAX_SCATTER)
83
84#define	RT_TXDESC_SDL1_BURST		(1 << 15)
85#define	RT_TXDESC_SDL1_LASTSEG		(1 << 14)
86#define	RT_TXDESC_SDL0_DDONE		(1 << 15)
87#define	RT_TXDESC_SDL0_LASTSEG		(1 << 14)
88struct rt_txdesc
89{
90	uint32_t sdp0;
91	uint16_t sdl1;
92	uint16_t sdl0;
93	uint32_t sdp1;
94	uint8_t vid;
95#define	TXDSCR_INS_VLAN_TAG	0x80
96#define	TXDSCR_VLAN_PRIO_MASK	0x70
97#define	TXDSCR_VLAN_IDX_MASK	0x0f
98	uint8_t	pppoe;
99#define	TXDSCR_USR_DEF_FLD	0x80
100#define	TXDSCR_INS_PPPOE_HDR	0x10
101#define	TXDSCR_PPPOE_SID_MASK	0x0f
102	uint8_t qn;
103#define	TXDSCR_QUEUE_MASK	0x07
104	uint8_t	dst;
105#define	TXDSCR_IP_CSUM_GEN	0x80
106#define	TXDSCR_UDP_CSUM_GEN	0x40
107#define	TXDSCR_TCP_CSUM_GEN	0x20
108#define	TXDSCR_DST_PORT_MASK	0x07
109#define	TXDSCR_DST_PORT_CPU	0x00
110#define	TXDSCR_DST_PORT_GDMA1	0x01
111#define	TXDSCR_DST_PORT_GDMA2	0x02
112#define	TXDSCR_DST_PORT_PPE	0x06
113#define	TXDSCR_DST_PORT_DISC	0x07
114} __packed;
115
116#define	RT_RXDESC_SDL0_DDONE		(1 << 15)
117struct rt_rxdesc
118{
119	uint32_t sdp0;
120	uint16_t sdl1;
121	uint16_t sdl0;
122	uint32_t sdp1;
123	uint16_t foe;
124#define	RXDSXR_FOE_ENTRY_VALID		0x40
125#define	RXDSXR_FOE_ENTRY_MASK		0x3f
126	uint8_t ai;
127#define	RXDSXR_AI_COU_REASON		0xff
128#define	RXDSXR_AI_PARSER_RSLT_MASK	0xff
129	uint8_t src;
130#define	RXDSXR_SRC_IPFVLD		0x80
131#define	RXDSXR_SRC_L4FVLD		0x40
132#define	RXDSXR_SRC_IP_CSUM_FAIL	0x20
133#define	RXDSXR_SRC_L4_CSUM_FAIL	0x10
134#define	RXDSXR_SRC_AIS			0x08
135#define	RXDSXR_SRC_PORT_MASK		0x07
136} __packed;
137
138struct rt_softc_rx_data
139{
140	bus_dmamap_t dma_map;
141	struct mbuf *m;
142};
143
144struct rt_softc_rx_ring
145{
146	bus_dma_tag_t desc_dma_tag;
147	bus_dmamap_t desc_dma_map;
148	bus_addr_t desc_phys_addr;
149	struct rt_rxdesc *desc;
150	bus_dma_tag_t data_dma_tag;
151	bus_dmamap_t spare_dma_map;
152	struct rt_softc_rx_data data[RT_SOFTC_RX_RING_DATA_COUNT];
153	int cur;
154};
155
156struct rt_softc_tx_data
157{
158	bus_dmamap_t dma_map;
159	struct mbuf *m;
160};
161
162struct rt_softc_tx_ring
163{
164	struct mtx lock;
165	bus_dma_tag_t desc_dma_tag;
166	bus_dmamap_t desc_dma_map;
167	bus_addr_t desc_phys_addr;
168	struct rt_txdesc *desc;
169	int desc_queued;
170	int desc_cur;
171	int desc_next;
172	bus_dma_tag_t seg0_dma_tag;
173	bus_dmamap_t seg0_dma_map;
174	bus_addr_t seg0_phys_addr;
175	uint8_t *seg0;
176	bus_dma_tag_t data_dma_tag;
177	struct rt_softc_tx_data data[RT_SOFTC_TX_RING_DATA_COUNT];
178	int data_queued;
179	int data_cur;
180	int data_next;
181	int qid;
182};
183
184struct rt_softc
185{
186	device_t 	 dev;
187	struct mtx 	 lock;
188	uint32_t 	 flags;
189
190	int		 mem_rid;
191	struct resource	*mem;
192	int		 irq_rid;
193	struct resource *irq;
194	void		*irqh;
195
196	bus_space_tag_t	 bst;
197	bus_space_handle_t bsh;
198
199	struct ifnet	*ifp;
200	int 		 if_flags;
201	struct ifmedia	 rt_ifmedia;
202
203	uint32_t	 mac_rev;
204	uint8_t		 mac_addr[ETHER_ADDR_LEN];
205	device_t	 rt_miibus;
206
207	uint32_t	 intr_enable_mask;
208	uint32_t	 intr_disable_mask;
209	uint32_t	 intr_pending_mask;
210
211	struct task	 rx_done_task;
212	int		 rx_process_limit;
213	struct task	 tx_done_task;
214	struct task	 periodic_task;
215	struct callout	 periodic_ch;
216	unsigned long	 periodic_round;
217	struct taskqueue *taskqueue;
218
219	struct rt_softc_rx_ring rx_ring;
220	struct rt_softc_tx_ring tx_ring[RT_SOFTC_TX_RING_COUNT];
221	int		 tx_ring_mgtqid;
222
223	struct callout	 tx_watchdog_ch;
224	int		 tx_timer;
225
226	/* statistic counters */
227	unsigned long	 interrupts;
228	unsigned long	 tx_coherent_interrupts;
229	unsigned long	 rx_coherent_interrupts;
230	unsigned long	 rx_interrupts;
231	unsigned long	 rx_delay_interrupts;
232	unsigned long	 tx_interrupts[RT_SOFTC_TX_RING_COUNT];
233	unsigned long	 tx_delay_interrupts;
234	unsigned long	 tx_data_queue_full[RT_SOFTC_TX_RING_COUNT];
235	unsigned long	 tx_watchdog_timeouts;
236	unsigned long	 tx_defrag_packets;
237	unsigned long	 no_tx_desc_avail;
238	unsigned long	 rx_mbuf_alloc_errors;
239	unsigned long	 rx_mbuf_dmamap_errors;
240	unsigned long	 tx_queue_not_empty[2];
241
242	unsigned long	 rx_bytes;
243	unsigned long	 rx_packets;
244	unsigned long	 rx_crc_err;
245	unsigned long	 rx_phy_err;
246	unsigned long	 rx_dup_packets;
247	unsigned long	 rx_fifo_overflows;
248	unsigned long	 rx_short_err;
249	unsigned long	 rx_long_err;
250	unsigned long	 tx_bytes;
251	unsigned long	 tx_packets;
252	unsigned long	 tx_skip;
253	unsigned long	 tx_collision;
254
255	int		 phy_addr;
256
257#ifdef IF_RT_DEBUG
258	int		 debug;
259#endif
260};
261
262#ifdef IF_RT_DEBUG
263enum
264{
265	RT_DEBUG_RX = 0x00000001,
266	RT_DEBUG_TX = 0x00000002,
267	RT_DEBUG_INTR = 0x00000004,
268	RT_DEBUG_STATE = 0x00000008,
269	RT_DEBUG_STATS = 0x00000010,
270	RT_DEBUG_PERIODIC = 0x00000020,
271	RT_DEBUG_WATCHDOG = 0x00000040,
272	RT_DEBUG_ANY = 0xffffffff
273};
274
275#define	RT_DPRINTF(sc, m, fmt, ...)		\
276	do { if ((sc)->debug & (m)) 		\
277	    device_printf(sc->dev, fmt, __VA_ARGS__); } while (0)
278#else
279#define	RT_DPRINTF(sc, m, fmt, ...)
280#endif /* #ifdef IF_RT_DEBUG */
281
282#endif /* #ifndef _IF_RTVAR_H_ */
283