1/*
2 * Solaris driver for ethernet cards based on the ADMtek Centaur
3 *
4 * Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following 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 * 3. Neither the name of the author nor the names of any co-contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31/*
32 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
33 * Use is subject to license terms.
34 */
35
36#ifndef	_AFEIMPL_H
37#define	_AFEIMPL_H
38
39#ifdef	_KERNEL
40
41#include	<sys/mac_provider.h>
42
43/*
44 * Compile time tunables.
45 */
46#define	AFE_RXRING	128	/* number of rcv buffers */
47#define	AFE_TXRING	128	/* number of xmt buffers */
48#define	AFE_TXRECLAIM	8	/* when to reclaim tx buffers (txavail) */
49#define	AFE_TXRESCHED	120	/* when to resched (txavail) */
50#define	AFE_WDOGTIMER	5000	/* how often we check for tx hang (in msec) */
51#define	AFE_HEADROOM	34	/* headroom in packet (should be 2 modulo 4) */
52
53/*
54 * Constants, do not change.
55 */
56#define	AFE_BUFSZ	(1664)	/* big enough for a vlan frame */
57#define	AFE_MCHASH	(64)
58
59typedef struct afe afe_t;
60typedef struct afe_card afe_card_t;
61typedef struct afe_rxbuf afe_rxbuf_t;
62typedef struct afe_txbuf afe_txbuf_t;
63typedef struct afe_desc afe_desc_t;
64
65/*
66 * Card models.
67 */
68typedef enum {
69	MODEL_CENTAUR = 1,
70	MODEL_COMET,
71} afe_model_t;
72
73struct afe_card {
74	uint16_t	card_venid;	/* PCI vendor id */
75	uint16_t	card_devid;	/* PCI device id */
76	char		*card_cardname;	/* Description of the card */
77	afe_model_t	card_model;	/* Card specific flags */
78};
79
80/*
81 * Device instance structure, one per PCI card.
82 */
83struct afe {
84	dev_info_t		*afe_dip;
85	mac_handle_t		afe_mh;
86	mii_handle_t		afe_mii;
87	afe_card_t		*afe_cardp;
88	uint16_t		afe_cachesize;
89	uint8_t			afe_sromwidth;
90	int			afe_flags;
91	kmutex_t		afe_xmtlock;
92	kmutex_t		afe_intrlock;
93	ddi_iblock_cookie_t	afe_icookie;
94
95	/*
96	 * Register and DMA access.
97	 */
98	uintptr_t		afe_regs;
99	ddi_acc_handle_t	afe_regshandle;
100
101	/*
102	 * Receive descriptors.
103	 */
104	int			afe_rxhead;
105	struct afe_desc		*afe_rxdescp;
106	ddi_dma_handle_t	afe_rxdesc_dmah;
107	ddi_acc_handle_t	afe_rxdesc_acch;
108	uint32_t		afe_rxdesc_paddr;
109	struct afe_rxbuf	**afe_rxbufs;
110
111	/*
112	 * Transmit descriptors.
113	 */
114	int			afe_txreclaim;
115	int			afe_txsend;
116	int			afe_txavail;
117	struct afe_desc		*afe_txdescp;
118	ddi_dma_handle_t	afe_txdesc_dmah;
119	ddi_acc_handle_t	afe_txdesc_acch;
120	uint32_t		afe_txdesc_paddr;
121	struct afe_txbuf	**afe_txbufs;
122	hrtime_t		afe_txstall_time;
123	boolean_t		afe_wantw;
124
125	/*
126	 * Transceiver stuff.
127	 */
128	int			afe_phyaddr;
129	int			afe_phyid;
130	int			afe_phyinuse;
131
132	int			afe_forcefiber;
133
134	/*
135	 * Address management.
136	 */
137	uchar_t			afe_curraddr[ETHERADDRL];
138	boolean_t		afe_promisc;
139	uint16_t		afe_mccount[AFE_MCHASH];
140	uint32_t		afe_mctab[AFE_MCHASH / 32];	/* Centaur */
141
142	/*
143	 * Kstats.
144	 */
145	kstat_t			*afe_intrstat;
146	uint64_t		afe_ipackets;
147	uint64_t		afe_opackets;
148	uint64_t		afe_rbytes;
149	uint64_t		afe_obytes;
150	uint64_t		afe_brdcstxmt;
151	uint64_t		afe_multixmt;
152	uint64_t		afe_brdcstrcv;
153	uint64_t		afe_multircv;
154	unsigned		afe_norcvbuf;
155	unsigned		afe_errrcv;
156	unsigned		afe_errxmt;
157	unsigned		afe_missed;
158	unsigned		afe_underflow;
159	unsigned		afe_overflow;
160	unsigned		afe_align_errors;
161	unsigned		afe_fcs_errors;
162	unsigned		afe_carrier_errors;
163	unsigned		afe_collisions;
164	unsigned		afe_ex_collisions;
165	unsigned		afe_tx_late_collisions;
166	unsigned		afe_defer_xmts;
167	unsigned		afe_first_collisions;
168	unsigned		afe_multi_collisions;
169	unsigned		afe_sqe_errors;
170	unsigned		afe_macxmt_errors;
171	unsigned		afe_macrcv_errors;
172	unsigned		afe_toolong_errors;
173	unsigned		afe_runt;
174	unsigned		afe_jabber;
175};
176
177struct afe_rxbuf {
178	caddr_t			rxb_buf;
179	ddi_dma_handle_t	rxb_dmah;
180	ddi_acc_handle_t	rxb_acch;
181	uint32_t		rxb_paddr;
182};
183
184struct afe_txbuf {
185	caddr_t			txb_buf;
186	uint32_t		txb_paddr;
187	ddi_dma_handle_t	txb_dmah;
188	ddi_acc_handle_t	txb_acch;
189};
190
191/*
192 * Descriptor.  We use rings rather than chains.
193 */
194struct afe_desc {
195	unsigned	desc_status;
196	unsigned	desc_control;
197	unsigned	desc_buffer1;
198	unsigned	desc_buffer2;
199};
200
201#define	PUTTXDESC(afep, member, val)	\
202	ddi_put32(afep->afe_txdesc_acch, &member, val)
203
204#define	PUTRXDESC(afep, member, val)	\
205	ddi_put32(afep->afe_rxdesc_acch, &member, val)
206
207#define	GETTXDESC(afep, member)	\
208	ddi_get32(afep->afe_txdesc_acch, &member)
209
210#define	GETRXDESC(afep, member)	\
211	ddi_get32(afep->afe_rxdesc_acch, &member)
212
213/*
214 * Receive descriptor fields.
215 */
216#define	RXSTAT_OWN		0x80000000U	/* ownership */
217#define	RXSTAT_RXLEN		0x3FFF0000U	/* frame length, incl. crc */
218#define	RXSTAT_RXERR		0x00008000U	/* error summary */
219#define	RXSTAT_DESCERR		0x00004000U	/* descriptor error */
220#define	RXSTAT_RXTYPE		0x00003000U	/* data type */
221#define	RXSTAT_RUNT		0x00000800U	/* runt frame */
222#define	RXSTAT_GROUP		0x00000400U	/* multicast/brdcast frame */
223#define	RXSTAT_FIRST		0x00000200U	/* first descriptor */
224#define	RXSTAT_LAST		0x00000100U	/* last descriptor */
225#define	RXSTAT_TOOLONG		0x00000080U	/* frame too long */
226#define	RXSTAT_COLLSEEN		0x00000040U	/* late collision seen */
227#define	RXSTAT_FRTYPE		0x00000020U	/* frame type */
228#define	RXSTAT_WATCHDOG		0x00000010U	/* receive watchdog */
229#define	RXSTAT_DRIBBLE		0x00000004U	/* dribbling bit */
230#define	RXSTAT_CRCERR		0x00000002U	/* crc error */
231#define	RXSTAT_OFLOW		0x00000001U	/* fifo overflow */
232#define	RXSTAT_ERRS		(RXSTAT_DESCERR | RXSTAT_RUNT | \
233				RXSTAT_COLLSEEN | RXSTAT_DRIBBLE | \
234				RXSTAT_CRCERR | RXSTAT_OFLOW)
235#define	RXLENGTH(x)		((x & RXSTAT_RXLEN) >> 16)
236
237#define	RXCTL_ENDRING		0x02000000U	/* end of ring */
238#define	RXCTL_CHAIN		0x01000000U	/* chained descriptors */
239#define	RXCTL_BUFLEN2		0x003FF800U	/* buffer 2 length */
240#define	RXCTL_BUFLEN1		0x000007FFU	/* buffer 1 length */
241
242/*
243 * Transmit descriptor fields.
244 */
245#define	TXSTAT_OWN		0x80000000U	/* ownership */
246#define	TXSTAT_URCNT		0x00C00000U	/* underrun count */
247#define	TXSTAT_TXERR		0x00008000U	/* error summary */
248#define	TXSTAT_JABBER		0x00004000U	/* jabber timeout */
249#define	TXSTAT_CARRLOST		0x00000800U	/* lost carrier */
250#define	TXSTAT_NOCARR		0x00000400U	/* no carrier */
251#define	TXSTAT_LATECOL		0x00000200U	/* late collision */
252#define	TXSTAT_EXCOLL		0x00000100U	/* excessive collisions */
253#define	TXSTAT_SQE		0x00000080U	/* heartbeat failure */
254#define	TXSTAT_COLLCNT		0x00000078U	/* collision count */
255#define	TXSTAT_UFLOW		0x00000002U	/* underflow */
256#define	TXSTAT_DEFER		0x00000001U	/* deferred */
257#define	TXCOLLCNT(x)		((x & TXSTAT_COLLCNT) >> 3)
258#define	TXUFLOWCNT(x)		((x & TXSTAT_URCNT) >> 22)
259
260#define	TXCTL_INTCMPLTE		0x80000000U	/* interrupt completed */
261#define	TXCTL_LAST		0x40000000U	/* last descriptor */
262#define	TXCTL_FIRST		0x20000000U	/* first descriptor */
263#define	TXCTL_NOCRC		0x04000000U	/* disable crc */
264#define	TXCTL_ENDRING		0x02000000U	/* end of ring */
265#define	TXCTL_CHAIN		0x01000000U	/* chained descriptors */
266#define	TXCTL_NOPAD		0x00800000U	/* disable padding */
267#define	TXCTL_HASHPERF		0x00400000U	/* hash perfect mode */
268#define	TXCTL_BUFLEN2		0x003FF800U	/* buffer length 2 */
269#define	TXCTL_BUFLEN1		0x000007FFU	/* buffer length 1 */
270
271
272/*
273 * Interface flags.
274 */
275#define	AFE_RUNNING	0x1	/* chip is initialized */
276#define	AFE_SUSPENDED	0x2	/* interface is suspended */
277#define	AFE_HASFIBER	0x4	/* internal phy supports fiber (AFE_PHY_MCR) */
278
279#define	AFE_MODEL(afep)		((afep)->afe_cardp->card_model)
280
281
282/*
283 * Register definitions located in afe.h exported header file.
284 */
285
286/*
287 * Macros to simplify hardware access.
288 */
289#define	GETCSR(afep, reg)	\
290	ddi_get32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg))
291
292#define	GETCSR16(afep, reg)	\
293	ddi_get16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg))
294
295#define	PUTCSR(afep, reg, val)	\
296	ddi_put32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg), val)
297
298#define	PUTCSR16(afep, reg, val)	\
299	ddi_put16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg), val)
300
301#define	SETBIT(afep, reg, val)	PUTCSR(afep, reg, GETCSR(afep, reg) | (val))
302
303#define	CLRBIT(afep, reg, val)	PUTCSR(afep, reg, GETCSR(afep, reg) & ~(val))
304
305#define	SYNCTXDESC(afep, index, who)	\
306	(void) ddi_dma_sync(afep->afe_txdesc_dmah, \
307	    (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who)
308
309#define	SYNCTXBUF(txb, len, who)	\
310	(void) ddi_dma_sync(txb->txb_dmah, 0, len, who)
311
312#define	SYNCRXDESC(afep, index, who)	\
313	(void) ddi_dma_sync(afep->afe_rxdesc_dmah, \
314	    (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who)
315
316#define	SYNCRXBUF(rxb, len, who)	\
317	(void) ddi_dma_sync(rxb->rxb_dmah, 0, len, who)
318
319#endif	/* _KERNEL */
320
321#endif	/* _AFEIMPL_H */
322