xref: /titanic_51/usr/src/uts/common/io/rge/rge.h (revision 0b758ccb089b0acb5d2aaef246c2f29285db8c13)
1c7fd2ed0Sgs150176 /*
2c7fd2ed0Sgs150176  * CDDL HEADER START
3c7fd2ed0Sgs150176  *
4c7fd2ed0Sgs150176  * The contents of this file are subject to the terms of the
5ba2e4443Sseb  * Common Development and Distribution License (the "License").
6ba2e4443Sseb  * You may not use this file except in compliance with the License.
7c7fd2ed0Sgs150176  *
8c7fd2ed0Sgs150176  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9c7fd2ed0Sgs150176  * or http://www.opensolaris.org/os/licensing.
10c7fd2ed0Sgs150176  * See the License for the specific language governing permissions
11c7fd2ed0Sgs150176  * and limitations under the License.
12c7fd2ed0Sgs150176  *
13c7fd2ed0Sgs150176  * When distributing Covered Code, include this CDDL HEADER in each
14c7fd2ed0Sgs150176  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15c7fd2ed0Sgs150176  * If applicable, add the following below this CDDL HEADER, with the
16c7fd2ed0Sgs150176  * fields enclosed by brackets "[]" replaced with your own identifying
17c7fd2ed0Sgs150176  * information: Portions Copyright [yyyy] [name of copyright owner]
18c7fd2ed0Sgs150176  *
19c7fd2ed0Sgs150176  * CDDL HEADER END
20c7fd2ed0Sgs150176  */
21c7fd2ed0Sgs150176 /*
227b114c4bSWinson Wang - Sun Microsystems - Beijing China  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23c7fd2ed0Sgs150176  * Use is subject to license terms.
24c7fd2ed0Sgs150176  */
25c7fd2ed0Sgs150176 
26c7fd2ed0Sgs150176 #ifndef _RGE_H
27c7fd2ed0Sgs150176 #define	_RGE_H
28c7fd2ed0Sgs150176 
29c7fd2ed0Sgs150176 #ifdef __cplusplus
30c7fd2ed0Sgs150176 extern "C" {
31c7fd2ed0Sgs150176 #endif
32c7fd2ed0Sgs150176 
33c7fd2ed0Sgs150176 #include <sys/types.h>
34c7fd2ed0Sgs150176 #include <sys/stream.h>
35c7fd2ed0Sgs150176 #include <sys/strsun.h>
36c7fd2ed0Sgs150176 #include <sys/strsubr.h>
37c7fd2ed0Sgs150176 #include <sys/stat.h>
38c7fd2ed0Sgs150176 #include <sys/pci.h>
393a84c50fSWinson Wang - Sun Microsystems - Beijing China #include <sys/pci_cap.h>
40c7fd2ed0Sgs150176 #include <sys/note.h>
41c7fd2ed0Sgs150176 #include <sys/modctl.h>
42c7fd2ed0Sgs150176 #include <sys/kstat.h>
43c7fd2ed0Sgs150176 #include <sys/ethernet.h>
44c7fd2ed0Sgs150176 #include <sys/vlan.h>
45c7fd2ed0Sgs150176 #include <sys/errno.h>
46c7fd2ed0Sgs150176 #include <sys/dlpi.h>
47c7fd2ed0Sgs150176 #include <sys/devops.h>
48c7fd2ed0Sgs150176 #include <sys/debug.h>
49c7fd2ed0Sgs150176 #include <sys/conf.h>
50c7fd2ed0Sgs150176 
51c7fd2ed0Sgs150176 #include <netinet/ip6.h>
52c7fd2ed0Sgs150176 #include <inet/common.h>
53c7fd2ed0Sgs150176 #include <inet/ip.h>
54c7fd2ed0Sgs150176 #include <inet/mi.h>
55c7fd2ed0Sgs150176 #include <inet/nd.h>
56c7fd2ed0Sgs150176 #include <sys/pattr.h>
57c7fd2ed0Sgs150176 
58c7fd2ed0Sgs150176 #include <sys/ddi.h>
59c7fd2ed0Sgs150176 #include <sys/sunddi.h>
60c7fd2ed0Sgs150176 
61da14cebeSEric Cheng #include <sys/mac_provider.h>
62ba2e4443Sseb #include <sys/mac_ether.h>
63c7fd2ed0Sgs150176 
64c7fd2ed0Sgs150176 /*
65c7fd2ed0Sgs150176  * Reconfiguring the network devices requires the net_config privilege
66aa817493Sgs150176  * in Solaris 10+.
67c7fd2ed0Sgs150176  */
68c7fd2ed0Sgs150176 extern int secpolicy_net_config(const cred_t *, boolean_t);
69c7fd2ed0Sgs150176 
70c7fd2ed0Sgs150176 #include <sys/netlb.h>			/* originally from cassini	*/
71c7fd2ed0Sgs150176 #include <sys/miiregs.h>		/* by fjlite out of intel 	*/
72c7fd2ed0Sgs150176 
73c7fd2ed0Sgs150176 #include "rge_hw.h"
74aa817493Sgs150176 
75c7fd2ed0Sgs150176 /*
76c7fd2ed0Sgs150176  * Name of the driver
77c7fd2ed0Sgs150176  */
78c7fd2ed0Sgs150176 #define	RGE_DRIVER_NAME		"rge"
79c7fd2ed0Sgs150176 
80c7fd2ed0Sgs150176 /*
81c7fd2ed0Sgs150176  * The driver supports the NDD ioctls ND_GET/ND_SET, and the loopback
82c7fd2ed0Sgs150176  * ioctls LB_GET_INFO_SIZE/LB_GET_INFO/LB_GET_MODE/LB_SET_MODE
83c7fd2ed0Sgs150176  *
84c7fd2ed0Sgs150176  * These are the values to use with LD_SET_MODE.
85c7fd2ed0Sgs150176  */
86c7fd2ed0Sgs150176 #define	RGE_LOOP_NONE		0
87c7fd2ed0Sgs150176 #define	RGE_LOOP_INTERNAL_PHY	1
88c7fd2ed0Sgs150176 #define	RGE_LOOP_INTERNAL_MAC	2
89c7fd2ed0Sgs150176 
90c7fd2ed0Sgs150176 /*
91c7fd2ed0Sgs150176  * RGE-specific ioctls ...
92c7fd2ed0Sgs150176  */
93c7fd2ed0Sgs150176 #define	RGE_IOC			((((('R' << 8) + 'G') << 8) + 'E') << 8)
94c7fd2ed0Sgs150176 
95c7fd2ed0Sgs150176 /*
96c7fd2ed0Sgs150176  * PHY register read/write ioctls, used by cable test software
97c7fd2ed0Sgs150176  */
98c7fd2ed0Sgs150176 #define	RGE_MII_READ		(RGE_IOC|1)
99c7fd2ed0Sgs150176 #define	RGE_MII_WRITE		(RGE_IOC|2)
100c7fd2ed0Sgs150176 
101c7fd2ed0Sgs150176 struct rge_mii_rw {
102c7fd2ed0Sgs150176 	uint32_t	mii_reg;	/* PHY register number [0..31]	*/
103c7fd2ed0Sgs150176 	uint32_t	mii_data;	/* data to write/data read	*/
104c7fd2ed0Sgs150176 };
105c7fd2ed0Sgs150176 
106c7fd2ed0Sgs150176 /*
107c7fd2ed0Sgs150176  * These diagnostic IOCTLS are enabled only in DEBUG drivers
108c7fd2ed0Sgs150176  */
109c7fd2ed0Sgs150176 #define	RGE_DIAG		(RGE_IOC|10)	/* currently a no-op	*/
110c7fd2ed0Sgs150176 #define	RGE_PEEK		(RGE_IOC|11)
111c7fd2ed0Sgs150176 #define	RGE_POKE		(RGE_IOC|12)
112c7fd2ed0Sgs150176 #define	RGE_PHY_RESET		(RGE_IOC|13)
113c7fd2ed0Sgs150176 #define	RGE_SOFT_RESET		(RGE_IOC|14)
114c7fd2ed0Sgs150176 #define	RGE_HARD_RESET		(RGE_IOC|15)
115c7fd2ed0Sgs150176 
116c7fd2ed0Sgs150176 typedef struct {
117c7fd2ed0Sgs150176 	uint64_t		pp_acc_size;	/* in bytes: 1,2,4,8	*/
118c7fd2ed0Sgs150176 	uint64_t		pp_acc_space;	/* See #defines below	*/
119c7fd2ed0Sgs150176 	uint64_t		pp_acc_offset;
120c7fd2ed0Sgs150176 	uint64_t		pp_acc_data;	/* output for peek	*/
121c7fd2ed0Sgs150176 						/* input for poke	*/
122c7fd2ed0Sgs150176 } rge_peekpoke_t;
123c7fd2ed0Sgs150176 
124c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_CFG	0		/* PCI config space	*/
125c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_REG	1		/* PCI memory space	*/
126c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_MII	2		/* PHY's MII registers	*/
127c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_RGE	3		/* driver's soft state	*/
128c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_TXDESC	4		/* TX descriptors	*/
129c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_TXBUFF	5		/* TX buffers		*/
130c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_RXDESC	6		/* RX descriptors	*/
131c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_RXBUFF	7		/* RX buffers		*/
132c7fd2ed0Sgs150176 #define	RGE_PP_SPACE_STATISTICS	8		/* statistics block	*/
133c7fd2ed0Sgs150176 
134c7fd2ed0Sgs150176 /*
135c7fd2ed0Sgs150176  * RTL8169 CRC poly
136c7fd2ed0Sgs150176  */
137c7fd2ed0Sgs150176 #define	RGE_HASH_POLY		0x04C11DB7	/* 0x04C11DB6 */
138c7fd2ed0Sgs150176 #define	RGE_HASH_CRC		0xFFFFFFFFU
139c7fd2ed0Sgs150176 #define	RGE_MCAST_BUF_SIZE	64	/* multicast hash table size in bits */
140c7fd2ed0Sgs150176 
141c7fd2ed0Sgs150176 /*
142c7fd2ed0Sgs150176  * Rx/Tx buffer parameters
143c7fd2ed0Sgs150176  */
144c7fd2ed0Sgs150176 #define	RGE_BUF_SLOTS		2048
145c7fd2ed0Sgs150176 #define	RGE_RECV_COPY_SIZE	256
146c7fd2ed0Sgs150176 #define	RGE_HEADROOM		6
147c7fd2ed0Sgs150176 
148c7fd2ed0Sgs150176 /*
149c7fd2ed0Sgs150176  * Driver chip operation parameters
150c7fd2ed0Sgs150176  */
151c7fd2ed0Sgs150176 #define	RGE_CYCLIC_PERIOD	(1000000000)	/* ~1s */
152c7fd2ed0Sgs150176 #define	CHIP_RESET_LOOP		1000
15352643194Sgs150176 #define	PHY_RESET_LOOP		10
154c7fd2ed0Sgs150176 #define	STATS_DUMP_LOOP		1000
155c7fd2ed0Sgs150176 #define	RXBUFF_FREE_LOOP	1000
156c7fd2ed0Sgs150176 #define	RGE_RX_INT_TIME		128
157c7fd2ed0Sgs150176 #define	RGE_RX_INT_PKTS		8
158c7fd2ed0Sgs150176 
159c7fd2ed0Sgs150176 /*
160c7fd2ed0Sgs150176  * Named Data (ND) Parameter Management Structure
161c7fd2ed0Sgs150176  */
162c7fd2ed0Sgs150176 typedef struct {
163c7fd2ed0Sgs150176 	int			ndp_info;
164c7fd2ed0Sgs150176 	int			ndp_min;
165c7fd2ed0Sgs150176 	int			ndp_max;
166c7fd2ed0Sgs150176 	int			ndp_val;
167c7fd2ed0Sgs150176 	char			*ndp_name;
168c7fd2ed0Sgs150176 } nd_param_t;				/* 0x18 (24) bytes	*/
169c7fd2ed0Sgs150176 
170c7fd2ed0Sgs150176 /*
171c7fd2ed0Sgs150176  * NDD parameter indexes, divided into:
172c7fd2ed0Sgs150176  *
173c7fd2ed0Sgs150176  *	read-only parameters describing the hardware's capabilities
174c7fd2ed0Sgs150176  *	read-write parameters controlling the advertised capabilities
175c7fd2ed0Sgs150176  *	read-only parameters describing the partner's capabilities
176c7fd2ed0Sgs150176  *	read-only parameters describing the link state
177c7fd2ed0Sgs150176  */
178c7fd2ed0Sgs150176 enum {
179c7fd2ed0Sgs150176 	PARAM_AUTONEG_CAP = 0,
180c7fd2ed0Sgs150176 	PARAM_PAUSE_CAP,
181c7fd2ed0Sgs150176 	PARAM_ASYM_PAUSE_CAP,
182c7fd2ed0Sgs150176 	PARAM_1000FDX_CAP,
183c7fd2ed0Sgs150176 	PARAM_1000HDX_CAP,
184c7fd2ed0Sgs150176 	PARAM_100T4_CAP,
185c7fd2ed0Sgs150176 	PARAM_100FDX_CAP,
186c7fd2ed0Sgs150176 	PARAM_100HDX_CAP,
187c7fd2ed0Sgs150176 	PARAM_10FDX_CAP,
188c7fd2ed0Sgs150176 	PARAM_10HDX_CAP,
189c7fd2ed0Sgs150176 
190c7fd2ed0Sgs150176 	PARAM_ADV_AUTONEG_CAP,
191c7fd2ed0Sgs150176 	PARAM_ADV_PAUSE_CAP,
192c7fd2ed0Sgs150176 	PARAM_ADV_ASYM_PAUSE_CAP,
193c7fd2ed0Sgs150176 	PARAM_ADV_1000FDX_CAP,
194c7fd2ed0Sgs150176 	PARAM_ADV_1000HDX_CAP,
195c7fd2ed0Sgs150176 	PARAM_ADV_100T4_CAP,
196c7fd2ed0Sgs150176 	PARAM_ADV_100FDX_CAP,
197c7fd2ed0Sgs150176 	PARAM_ADV_100HDX_CAP,
198c7fd2ed0Sgs150176 	PARAM_ADV_10FDX_CAP,
199c7fd2ed0Sgs150176 	PARAM_ADV_10HDX_CAP,
200c7fd2ed0Sgs150176 
201c7fd2ed0Sgs150176 	PARAM_LINK_STATUS,
202c7fd2ed0Sgs150176 	PARAM_LINK_SPEED,
203c7fd2ed0Sgs150176 	PARAM_LINK_DUPLEX,
204c7fd2ed0Sgs150176 
205c7fd2ed0Sgs150176 	PARAM_LOOP_MODE,
206c7fd2ed0Sgs150176 
207c7fd2ed0Sgs150176 	PARAM_COUNT
208c7fd2ed0Sgs150176 };
209c7fd2ed0Sgs150176 
210c7fd2ed0Sgs150176 enum rge_chip_state {
211c7fd2ed0Sgs150176 	RGE_CHIP_FAULT = -2,			/* fault, need reset	*/
212c7fd2ed0Sgs150176 	RGE_CHIP_ERROR,				/* error, want reset	*/
213c7fd2ed0Sgs150176 	RGE_CHIP_INITIAL,			/* Initial state only	*/
214c7fd2ed0Sgs150176 	RGE_CHIP_RESET,				/* reset, need init	*/
215c7fd2ed0Sgs150176 	RGE_CHIP_STOPPED,			/* Tx/Rx stopped	*/
216c7fd2ed0Sgs150176 	RGE_CHIP_RUNNING			/* with interrupts	*/
217c7fd2ed0Sgs150176 };
218c7fd2ed0Sgs150176 
219c7fd2ed0Sgs150176 enum rge_mac_state {
220aa817493Sgs150176 	RGE_MAC_ATTACH = 0,
221aa817493Sgs150176 	RGE_MAC_STOPPED,
222c7fd2ed0Sgs150176 	RGE_MAC_STARTED,
223c7fd2ed0Sgs150176 	RGE_MAC_UNATTACH
224c7fd2ed0Sgs150176 };
225c7fd2ed0Sgs150176 
226c7fd2ed0Sgs150176 enum rge_sync_op {
227c7fd2ed0Sgs150176 	RGE_OP_NULL,
228c7fd2ed0Sgs150176 	RGE_GET_MAC,				/* get mac address operation */
229c7fd2ed0Sgs150176 	RGE_SET_MAC,				/* set mac address operation */
230c7fd2ed0Sgs150176 	RGE_SET_MUL,				/* set multicast address op */
231c7fd2ed0Sgs150176 	RGE_SET_PROMISC				/* set promisc mode */
232c7fd2ed0Sgs150176 };
233c7fd2ed0Sgs150176 
234c7fd2ed0Sgs150176 /*
235c7fd2ed0Sgs150176  * (Internal) return values from ioctl subroutines
236c7fd2ed0Sgs150176  */
237c7fd2ed0Sgs150176 enum ioc_reply {
238c7fd2ed0Sgs150176 	IOC_INVAL = -1,				/* bad, NAK with EINVAL	*/
239c7fd2ed0Sgs150176 	IOC_DONE,				/* OK, reply sent	*/
240c7fd2ed0Sgs150176 	IOC_ACK,				/* OK, just send ACK	*/
241c7fd2ed0Sgs150176 	IOC_REPLY,				/* OK, just send reply	*/
242c7fd2ed0Sgs150176 	IOC_RESTART_ACK,			/* OK, restart & ACK	*/
243c7fd2ed0Sgs150176 	IOC_RESTART_REPLY			/* OK, restart & reply	*/
244c7fd2ed0Sgs150176 };
245c7fd2ed0Sgs150176 
246c7fd2ed0Sgs150176 /*
247c7fd2ed0Sgs150176  * (Internal) enumeration of this driver's kstats
248c7fd2ed0Sgs150176  */
249c7fd2ed0Sgs150176 enum {
2500d2a8e5eSgd78059 	RGE_KSTAT_DRIVER = 0,
251c7fd2ed0Sgs150176 	RGE_KSTAT_COUNT
252c7fd2ed0Sgs150176 };
253c7fd2ed0Sgs150176 
254c7fd2ed0Sgs150176 /*
255c7fd2ed0Sgs150176  * Basic data types, for clarity in distinguishing 'numbers'
256c7fd2ed0Sgs150176  * used for different purposes ...
257c7fd2ed0Sgs150176  *
258c7fd2ed0Sgs150176  * A <rge_regno_t> is a register 'address' (offset) in any one of
259c7fd2ed0Sgs150176  * various address spaces (PCI config space, PCI memory-mapped I/O
260c7fd2ed0Sgs150176  * register space, MII registers, etc).  None of these exceeds 64K,
261c7fd2ed0Sgs150176  * so we could use a 16-bit representation but pointer-sized objects
262c7fd2ed0Sgs150176  * are more "natural" in most architectures; they seem to be handled
263c7fd2ed0Sgs150176  * more efficiently on SPARC and no worse on x86.
264c7fd2ed0Sgs150176  *
265c7fd2ed0Sgs150176  * RGE_REGNO_NONE represents the non-existent value in this space.
266c7fd2ed0Sgs150176  */
267c7fd2ed0Sgs150176 typedef uintptr_t rge_regno_t;			/* register # (offset)	*/
268c7fd2ed0Sgs150176 #define	RGE_REGNO_NONE		(~(uintptr_t)0u)
269c7fd2ed0Sgs150176 
270c7fd2ed0Sgs150176 /*
271c7fd2ed0Sgs150176  * Describes one chunk of allocated DMA-able memory
272c7fd2ed0Sgs150176  *
273c7fd2ed0Sgs150176  * In some cases, this is a single chunk as allocated from the system;
274c7fd2ed0Sgs150176  * but we also use this structure to represent slices carved off such
275c7fd2ed0Sgs150176  * a chunk.  Even when we don't really need all the information, we
276c7fd2ed0Sgs150176  * use this structure as a convenient way of correlating the various
277c7fd2ed0Sgs150176  * ways of looking at a piece of memory (kernel VA, IO space DVMA,
278c7fd2ed0Sgs150176  * handle+offset, etc).
279c7fd2ed0Sgs150176  */
280c7fd2ed0Sgs150176 typedef struct {
281c7fd2ed0Sgs150176 	ddi_acc_handle_t	acc_hdl;	/* handle for memory	*/
282c7fd2ed0Sgs150176 	void			*mem_va;	/* CPU VA of memory	*/
283c7fd2ed0Sgs150176 	uint32_t		nslots;		/* number of slots	*/
284c7fd2ed0Sgs150176 	uint32_t		size;		/* size per slot	*/
285c7fd2ed0Sgs150176 	size_t			alength;	/* allocated size */
286c7fd2ed0Sgs150176 	ddi_dma_handle_t	dma_hdl;	/* DMA handle */
287c7fd2ed0Sgs150176 	offset_t		offset;		/* relative to handle	*/
288c7fd2ed0Sgs150176 	ddi_dma_cookie_t	cookie;		/* associated cookie */
289c7fd2ed0Sgs150176 	uint32_t		ncookies;	/* must be 1 */
290c7fd2ed0Sgs150176 	uint32_t		token;		/* arbitrary identifier	*/
291c7fd2ed0Sgs150176 } dma_area_t;
292c7fd2ed0Sgs150176 
293c7fd2ed0Sgs150176 /*
294c7fd2ed0Sgs150176  * Software version of the Receive Buffer Descriptor
295c7fd2ed0Sgs150176  */
296c7fd2ed0Sgs150176 typedef struct {
297c7fd2ed0Sgs150176 	caddr_t			private;	/* pointer to rge */
298c7fd2ed0Sgs150176 	dma_area_t		pbuf;		/* (const) related	*/
299c7fd2ed0Sgs150176 						/* buffer area		*/
300c7fd2ed0Sgs150176 	frtn_t			rx_recycle;	/* recycle function */
301c7fd2ed0Sgs150176 	mblk_t			*mp;
302c7fd2ed0Sgs150176 } dma_buf_t;
303c7fd2ed0Sgs150176 
304c7fd2ed0Sgs150176 typedef struct sw_rbd {
305c7fd2ed0Sgs150176 	dma_buf_t		*rx_buf;
306c7fd2ed0Sgs150176 	uint8_t			flags;
307c7fd2ed0Sgs150176 } sw_rbd_t;
308c7fd2ed0Sgs150176 
309c7fd2ed0Sgs150176 /*
310c7fd2ed0Sgs150176  * Software version of the Send Buffer Descriptor
311c7fd2ed0Sgs150176  */
312c7fd2ed0Sgs150176 typedef struct sw_sbd {
313c7fd2ed0Sgs150176 	dma_area_t		desc;		/* (const) related h/w	*/
314c7fd2ed0Sgs150176 						/* descriptor area	*/
315c7fd2ed0Sgs150176 	dma_area_t		pbuf;		/* (const) related	*/
316c7fd2ed0Sgs150176 						/* buffer area		*/
317c7fd2ed0Sgs150176 } sw_sbd_t;
318c7fd2ed0Sgs150176 
319c7fd2ed0Sgs150176 
3203a84c50fSWinson Wang - Sun Microsystems - Beijing China #define	HW_RBD_INIT(rbd, slot) {				\
3213a84c50fSWinson Wang - Sun Microsystems - Beijing China 	(rbd)->vlan_tag = 0;					\
3223a84c50fSWinson Wang - Sun Microsystems - Beijing China 	if ((slot) == (RGE_RECV_SLOTS -1)) {			\
3233a84c50fSWinson Wang - Sun Microsystems - Beijing China 		(rbd)->flags_len |=				\
3243a84c50fSWinson Wang - Sun Microsystems - Beijing China 		    RGE_BSWAP_32(BD_FLAG_EOR | BD_FLAG_HW_OWN);	\
3253a84c50fSWinson Wang - Sun Microsystems - Beijing China 	} else {						\
3263a84c50fSWinson Wang - Sun Microsystems - Beijing China 		(rbd)->flags_len |= RGE_BSWAP_32(BD_FLAG_HW_OWN);	\
3273a84c50fSWinson Wang - Sun Microsystems - Beijing China 	}							\
3283a84c50fSWinson Wang - Sun Microsystems - Beijing China }
3293a84c50fSWinson Wang - Sun Microsystems - Beijing China #define	HW_SBD_SET(sbd, slot) {					\
3303a84c50fSWinson Wang - Sun Microsystems - Beijing China 	if ((slot) == (RGE_SEND_SLOTS -1)) {			\
3313a84c50fSWinson Wang - Sun Microsystems - Beijing China 		(sbd)->flags_len |=				\
3323a84c50fSWinson Wang - Sun Microsystems - Beijing China 		    RGE_BSWAP_32(BD_FLAG_EOR | SBD_FLAG_TX_PKT);	\
3333a84c50fSWinson Wang - Sun Microsystems - Beijing China 	} else {						\
3343a84c50fSWinson Wang - Sun Microsystems - Beijing China 		(sbd)->flags_len |= RGE_BSWAP_32(SBD_FLAG_TX_PKT); \
3353a84c50fSWinson Wang - Sun Microsystems - Beijing China 	}							\
3363a84c50fSWinson Wang - Sun Microsystems - Beijing China }
337c7fd2ed0Sgs150176 
338c7fd2ed0Sgs150176 /*
339c7fd2ed0Sgs150176  * Describes the characteristics of a specific chip
340c7fd2ed0Sgs150176  */
341c7fd2ed0Sgs150176 typedef struct {
342c7fd2ed0Sgs150176 	uint16_t		command;	/* saved during attach	*/
343c7fd2ed0Sgs150176 	uint16_t		vendor;		/* vendor-id		*/
344c7fd2ed0Sgs150176 	uint16_t		device;		/* device-id		*/
345c7fd2ed0Sgs150176 	uint16_t		subven;		/* subsystem-vendor-id	*/
346c7fd2ed0Sgs150176 	uint16_t		subdev;		/* subsystem-id		*/
347c7fd2ed0Sgs150176 	uint8_t			revision;	/* revision-id		*/
348c7fd2ed0Sgs150176 	uint8_t			clsize;		/* cache-line-size	*/
349c7fd2ed0Sgs150176 	uint8_t			latency;	/* latency-timer	*/
350aa817493Sgs150176 	boolean_t		is_pcie;
351*0b758ccbSAlexander Eremin 	boolean_t		enable_mac_first;
352c7fd2ed0Sgs150176 	uint32_t		mac_ver;
353c7fd2ed0Sgs150176 	uint32_t		phy_ver;
354c7fd2ed0Sgs150176 	uint32_t		rxconfig;
355c7fd2ed0Sgs150176 	uint32_t		txconfig;
356c7fd2ed0Sgs150176 } chip_id_t;
357c7fd2ed0Sgs150176 
358c7fd2ed0Sgs150176 typedef struct rge_stats {
35922dc2133Smx205022 	uint64_t	rpackets;
360c7fd2ed0Sgs150176 	uint64_t	rbytes;
36122dc2133Smx205022 	uint64_t	opackets;
362c7fd2ed0Sgs150176 	uint64_t	obytes;
363c7fd2ed0Sgs150176 	uint32_t	overflow;
364c7fd2ed0Sgs150176 	uint32_t	defer;		/* dot3StatsDeferredTransmissions */
365c7fd2ed0Sgs150176 	uint32_t	crc_err;	/* dot3StatsFCSErrors */
366c7fd2ed0Sgs150176 	uint32_t	in_short;
367c7fd2ed0Sgs150176 	uint32_t	no_rcvbuf;	/* ifInDiscards */
368c7fd2ed0Sgs150176 	uint32_t	intr;		/* interrupt count */
369c7fd2ed0Sgs150176 	uint16_t	chip_reset;
370c7fd2ed0Sgs150176 	uint16_t	phy_reset;
37122dc2133Smx205022 	boolean_t	tx_pre_ismax;
37222dc2133Smx205022 	boolean_t	tx_cur_ismax;
373c7fd2ed0Sgs150176 } rge_stats_t;
374c7fd2ed0Sgs150176 
375c7fd2ed0Sgs150176 /*
376c7fd2ed0Sgs150176  * Per-instance soft-state structure
377c7fd2ed0Sgs150176  */
378c7fd2ed0Sgs150176 typedef struct rge {
379c7fd2ed0Sgs150176 	dev_info_t		*devinfo;	/* device instance	*/
380ba2e4443Sseb 	mac_handle_t		mh;		/* mac module handle	*/
381c7fd2ed0Sgs150176 	ddi_acc_handle_t	cfg_handle;	/* DDI I/O handle	*/
382c7fd2ed0Sgs150176 	ddi_acc_handle_t	io_handle;	/* DDI I/O handle	*/
383c7fd2ed0Sgs150176 	caddr_t			io_regs;	/* mapped registers	*/
384dd4eeefdSeota 	ddi_periodic_t		periodic_id;	/* periodical callback	*/
385aa817493Sgs150176 	ddi_softint_handle_t	resched_hdl;	/* reschedule callback	*/
386aa817493Sgs150176 	ddi_softint_handle_t	factotum_hdl;	/* factotum callback	*/
387aa817493Sgs150176 	uint_t			soft_pri;
388aa817493Sgs150176 	ddi_intr_handle_t 	*htable;	/* For array of interrupts */
389aa817493Sgs150176 	int			intr_type;	/* What type of interrupt */
390aa817493Sgs150176 	int			intr_rqst;	/* # of request intrs count */
391aa817493Sgs150176 	int			intr_cnt;	/* # of intrs count returned */
392aa817493Sgs150176 	uint_t			intr_pri;	/* Interrupt priority	*/
393aa817493Sgs150176 	int			intr_cap;	/* Interrupt capabilities */
394aa817493Sgs150176 	boolean_t		msi_enable;
395aa817493Sgs150176 
396c7fd2ed0Sgs150176 	uint32_t		ethmax_size;
397aa817493Sgs150176 	uint32_t		default_mtu;
398c7fd2ed0Sgs150176 	uint32_t		rxbuf_size;
399c7fd2ed0Sgs150176 	uint32_t		txbuf_size;
400aa817493Sgs150176 	uint32_t		chip_flags;
401aa817493Sgs150176 	uint32_t		head_room;
402c7fd2ed0Sgs150176 	char			ifname[8];	/* "rge0" ... "rge999"	*/
403c7fd2ed0Sgs150176 	int32_t			instance;
404c7fd2ed0Sgs150176 	uint32_t		progress;	/* attach tracking	*/
405c7fd2ed0Sgs150176 	uint32_t		debug;		/* per-instance debug	*/
406c7fd2ed0Sgs150176 	chip_id_t		chipid;
407c7fd2ed0Sgs150176 
408c7fd2ed0Sgs150176 	/*
409c7fd2ed0Sgs150176 	 * These structures describe the blocks of memory allocated during
410c7fd2ed0Sgs150176 	 * attach().  They remain unchanged thereafter, although the memory
411c7fd2ed0Sgs150176 	 * they describe is carved up into various separate regions and may
412c7fd2ed0Sgs150176 	 * therefore be described by other structures as well.
413c7fd2ed0Sgs150176 	 */
414c7fd2ed0Sgs150176 	dma_area_t		dma_area_rxdesc;
415c7fd2ed0Sgs150176 	dma_area_t		dma_area_txdesc;
416c7fd2ed0Sgs150176 	dma_area_t		dma_area_stats;
417c7fd2ed0Sgs150176 				/* describes hardware statistics area	*/
418c7fd2ed0Sgs150176 
419c7fd2ed0Sgs150176 	uint8_t			netaddr[ETHERADDRL];	/* mac address	*/
420c7fd2ed0Sgs150176 	uint16_t		int_mask;	/* interrupt mask	*/
421c7fd2ed0Sgs150176 
422c7fd2ed0Sgs150176 	/* used for multicast/promisc mode set */
423c7fd2ed0Sgs150176 	char			mcast_refs[RGE_MCAST_BUF_SIZE];
424aa817493Sgs150176 	uint8_t			mcast_hash[RGE_MCAST_NUM];
425c7fd2ed0Sgs150176 	boolean_t		promisc;	/* promisc state flag	*/
426c7fd2ed0Sgs150176 
427c7fd2ed0Sgs150176 	/* used for recv */
428c7fd2ed0Sgs150176 	rge_bd_t		*rx_ring;
429c7fd2ed0Sgs150176 	dma_area_t		rx_desc;
430c7fd2ed0Sgs150176 	boolean_t		rx_bcopy;
431c7fd2ed0Sgs150176 	uint32_t		rx_next;	/* current rx bd index	*/
432c7fd2ed0Sgs150176 	sw_rbd_t		*sw_rbds;
433aa817493Sgs150176 	sw_rbd_t		*free_srbds;
434c7fd2ed0Sgs150176 	uint32_t		rf_next;	/* current free buf index */
435c7fd2ed0Sgs150176 	uint32_t		rc_next;	/* current recycle buf index */
436c7fd2ed0Sgs150176 	uint32_t		rx_free;	/* number of rx free buf */
437c7fd2ed0Sgs150176 
438c7fd2ed0Sgs150176 	/* used for send */
439c7fd2ed0Sgs150176 	rge_bd_t		*tx_ring;
440c7fd2ed0Sgs150176 	dma_area_t		tx_desc;
441c7fd2ed0Sgs150176 	uint32_t		tx_free;	/* number of free tx bd */
442c7fd2ed0Sgs150176 	uint32_t		tx_next;	/* current tx bd index	*/
443c7fd2ed0Sgs150176 	uint32_t		tc_next;	/* current tx recycle index */
444c7fd2ed0Sgs150176 	uint32_t		tx_flow;
445c7fd2ed0Sgs150176 	uint32_t		tc_tail;
446c7fd2ed0Sgs150176 	sw_sbd_t		*sw_sbds;
447c7fd2ed0Sgs150176 
448c7fd2ed0Sgs150176 	/* mutex */
449c7fd2ed0Sgs150176 	kmutex_t		genlock[1];	/* i/o reg access	*/
450c7fd2ed0Sgs150176 	krwlock_t		errlock[1];	/* rge restart */
451c7fd2ed0Sgs150176 	kmutex_t		tx_lock[1];	/* send access		*/
452c7fd2ed0Sgs150176 	kmutex_t		tc_lock[1];	/* send recycle access */
453c7fd2ed0Sgs150176 	kmutex_t		rx_lock[1];	/* receive access	*/
454c7fd2ed0Sgs150176 	kmutex_t		rc_lock[1];	/* receive recycle access */
455c7fd2ed0Sgs150176 
456c7fd2ed0Sgs150176 	/*
457c7fd2ed0Sgs150176 	 * Miscellaneous operating variables (not synchronised)
458c7fd2ed0Sgs150176 	 */
459c7fd2ed0Sgs150176 	uint32_t		watchdog;	/* watches for Tx stall	*/
460c7fd2ed0Sgs150176 	boolean_t		resched_needed;
461c7fd2ed0Sgs150176 	uint32_t		factotum_flag;	/* softint pending	*/
462c7fd2ed0Sgs150176 
463c7fd2ed0Sgs150176 	/*
464c7fd2ed0Sgs150176 	 * Physical layer
465c7fd2ed0Sgs150176 	 */
466c7fd2ed0Sgs150176 	rge_regno_t		phy_mii_addr;	/* should be (const) 1!	*/
467c7fd2ed0Sgs150176 	uint16_t		link_down_count;
468c7fd2ed0Sgs150176 
469c7fd2ed0Sgs150176 	/*
470c7fd2ed0Sgs150176 	 * NDD parameters (protected by genlock)
471c7fd2ed0Sgs150176 	 */
472c7fd2ed0Sgs150176 	caddr_t			nd_data_p;
473c7fd2ed0Sgs150176 	nd_param_t		nd_params[PARAM_COUNT];
474c7fd2ed0Sgs150176 
475c7fd2ed0Sgs150176 	/*
476c7fd2ed0Sgs150176 	 * Driver kstats, protected by <genlock> where necessary
477c7fd2ed0Sgs150176 	 */
478c7fd2ed0Sgs150176 	kstat_t			*rge_kstats[RGE_KSTAT_COUNT];
479c7fd2ed0Sgs150176 
480c7fd2ed0Sgs150176 	/* H/W statistics */
481c7fd2ed0Sgs150176 	rge_hw_stats_t		*hw_stats;
482c7fd2ed0Sgs150176 	rge_stats_t		stats;
483c7fd2ed0Sgs150176 	enum rge_mac_state	rge_mac_state;	/* definitions above	*/
484c7fd2ed0Sgs150176 	enum rge_chip_state	rge_chip_state;	/* definitions above	*/
485343c2616Smx205022 
486343c2616Smx205022 	boolean_t		suspended;
4873a84c50fSWinson Wang - Sun Microsystems - Beijing China 
4883a84c50fSWinson Wang - Sun Microsystems - Beijing China 	/*
4893a84c50fSWinson Wang - Sun Microsystems - Beijing China 	 * Polling
4903a84c50fSWinson Wang - Sun Microsystems - Beijing China 	 */
4913a84c50fSWinson Wang - Sun Microsystems - Beijing China #define	TX_COALESC	max(RGE_BUF_SLOTS/32LL, 8)
4923a84c50fSWinson Wang - Sun Microsystems - Beijing China #define	RX_COALESC	8LL
4933a84c50fSWinson Wang - Sun Microsystems - Beijing China #define	CLK_TICK	100
4943a84c50fSWinson Wang - Sun Microsystems - Beijing China 	clock_t			curr_tick;
4953a84c50fSWinson Wang - Sun Microsystems - Beijing China 	clock_t			tick_delta;
4963a84c50fSWinson Wang - Sun Microsystems - Beijing China 	uint64_t		last_opackets;
4973a84c50fSWinson Wang - Sun Microsystems - Beijing China 	uint64_t		last_rpackets;
4987b114c4bSWinson Wang - Sun Microsystems - Beijing China 	uint32_t		rx_fifo_ovf;
499c7fd2ed0Sgs150176 } rge_t;
500c7fd2ed0Sgs150176 
501c7fd2ed0Sgs150176 /*
502c7fd2ed0Sgs150176  * 'Progress' bit flags ...
503c7fd2ed0Sgs150176  */
504c7fd2ed0Sgs150176 #define	PROGRESS_CFG		0x0001	/* config space mapped		*/
505c7fd2ed0Sgs150176 #define	PROGRESS_REGS		0x0002	/* registers mapped		*/
506c7fd2ed0Sgs150176 #define	PROGRESS_RESCHED	0x0010	/* resched softint registered	*/
507c7fd2ed0Sgs150176 #define	PROGRESS_FACTOTUM	0x0020	/* factotum softint registered	*/
508c7fd2ed0Sgs150176 #define	PROGRESS_INTR		0X0040	/* h/w interrupt registered	*/
509c7fd2ed0Sgs150176 					/* and mutexen initialised	*/
510aa817493Sgs150176 #define	PROGRESS_INIT		0x0080	/* rx/buf/tx ring initialised	*/
511c7fd2ed0Sgs150176 #define	PROGRESS_PHY		0x0100	/* PHY initialised		*/
512c7fd2ed0Sgs150176 #define	PROGRESS_NDD		0x1000	/* NDD parameters set up	*/
513c7fd2ed0Sgs150176 #define	PROGRESS_KSTATS		0x2000	/* kstats created		*/
514c7fd2ed0Sgs150176 #define	PROGRESS_READY		0x8000	/* ready for work		*/
515c7fd2ed0Sgs150176 
516c7fd2ed0Sgs150176 /*
517aa817493Sgs150176  * Special chip flags
518aa817493Sgs150176  */
519aa817493Sgs150176 #define	CHIP_FLAG_FORCE_BCOPY	0x10000000
520aa817493Sgs150176 
521aa817493Sgs150176 /*
522c7fd2ed0Sgs150176  * Shorthand for the NDD parameters
523c7fd2ed0Sgs150176  */
524c7fd2ed0Sgs150176 #define	param_adv_autoneg	nd_params[PARAM_ADV_AUTONEG_CAP].ndp_val
525c7fd2ed0Sgs150176 #define	param_adv_pause		nd_params[PARAM_ADV_PAUSE_CAP].ndp_val
526c7fd2ed0Sgs150176 #define	param_adv_asym_pause	nd_params[PARAM_ADV_ASYM_PAUSE_CAP].ndp_val
527c7fd2ed0Sgs150176 #define	param_adv_1000fdx	nd_params[PARAM_ADV_1000FDX_CAP].ndp_val
528c7fd2ed0Sgs150176 #define	param_adv_1000hdx	nd_params[PARAM_ADV_1000HDX_CAP].ndp_val
529c7fd2ed0Sgs150176 #define	param_adv_100fdx	nd_params[PARAM_ADV_100FDX_CAP].ndp_val
530c7fd2ed0Sgs150176 #define	param_adv_100hdx	nd_params[PARAM_ADV_100HDX_CAP].ndp_val
531c7fd2ed0Sgs150176 #define	param_adv_10fdx		nd_params[PARAM_ADV_10FDX_CAP].ndp_val
532c7fd2ed0Sgs150176 #define	param_adv_10hdx		nd_params[PARAM_ADV_10HDX_CAP].ndp_val
533c7fd2ed0Sgs150176 
534c7fd2ed0Sgs150176 #define	param_link_up		nd_params[PARAM_LINK_STATUS].ndp_val
535c7fd2ed0Sgs150176 #define	param_link_speed	nd_params[PARAM_LINK_SPEED].ndp_val
536c7fd2ed0Sgs150176 #define	param_link_duplex	nd_params[PARAM_LINK_DUPLEX].ndp_val
537c7fd2ed0Sgs150176 
538c7fd2ed0Sgs150176 #define	param_loop_mode		nd_params[PARAM_LOOP_MODE].ndp_val
539c7fd2ed0Sgs150176 
540c7fd2ed0Sgs150176 /*
541c7fd2ed0Sgs150176  * Sync a DMA area described by a dma_area_t
542c7fd2ed0Sgs150176  */
543c7fd2ed0Sgs150176 #define	DMA_SYNC(area, flag)	((void) ddi_dma_sync((area).dma_hdl,	\
544c7fd2ed0Sgs150176 				    (area).offset, (area).alength, (flag)))
545c7fd2ed0Sgs150176 
546c7fd2ed0Sgs150176 /*
547c7fd2ed0Sgs150176  * Find the (kernel virtual) address of block of memory
548c7fd2ed0Sgs150176  * described by a dma_area_t
549c7fd2ed0Sgs150176  */
550c7fd2ed0Sgs150176 #define	DMA_VPTR(area)		((area).mem_va)
551c7fd2ed0Sgs150176 
552c7fd2ed0Sgs150176 /*
553c7fd2ed0Sgs150176  * Zero a block of memory described by a dma_area_t
554c7fd2ed0Sgs150176  */
555c7fd2ed0Sgs150176 #define	DMA_ZERO(area)		bzero(DMA_VPTR(area), (area).alength)
556c7fd2ed0Sgs150176 
557c7fd2ed0Sgs150176 /*
558c7fd2ed0Sgs150176  * Next/Last value of a cyclic index
559c7fd2ed0Sgs150176  */
560c7fd2ed0Sgs150176 #define	NEXT(index, limit)	((index)+1 < (limit) ? (index)+1 : 0);
561c7fd2ed0Sgs150176 #define	LAST(index, limit)	((index) ? (index)-1 : (limit - 1));
562c7fd2ed0Sgs150176 /*
563c7fd2ed0Sgs150176  * Property lookups
564c7fd2ed0Sgs150176  */
565c7fd2ed0Sgs150176 #define	RGE_PROP_EXISTS(d, n)	ddi_prop_exists(DDI_DEV_T_ANY, (d),	\
566c7fd2ed0Sgs150176 					DDI_PROP_DONTPASS, (n))
567c7fd2ed0Sgs150176 #define	RGE_PROP_GET_INT(d, n)	ddi_prop_get_int(DDI_DEV_T_ANY, (d),	\
568c7fd2ed0Sgs150176 					DDI_PROP_DONTPASS, (n), -1)
569c7fd2ed0Sgs150176 
570c7fd2ed0Sgs150176 /*
571c7fd2ed0Sgs150176  * Endian swap
572c7fd2ed0Sgs150176  */
573c7fd2ed0Sgs150176 #ifdef	_BIG_ENDIAN
574c7fd2ed0Sgs150176 #define	RGE_BSWAP_16(x)		((((x) & 0xff00) >> 8)	|		\
575c7fd2ed0Sgs150176 				    (((x) & 0x00ff) << 8))
576c7fd2ed0Sgs150176 #define	RGE_BSWAP_32(x)		((((x) & 0xff000000) >> 24)	|	\
577c7fd2ed0Sgs150176 				    (((x) & 0x00ff0000) >> 8)	|	\
578c7fd2ed0Sgs150176 				    (((x) & 0x0000ff00) << 8)	|	\
579c7fd2ed0Sgs150176 				    (((x) & 0x000000ff) << 24))
580c7fd2ed0Sgs150176 #define	RGE_BSWAP_64(x)		(RGE_BSWAP_32((x) >> 32)	|	\
581c7fd2ed0Sgs150176 				    (RGE_BSWAP_32(x) << 32))
582c7fd2ed0Sgs150176 #else
583c7fd2ed0Sgs150176 #define	RGE_BSWAP_16(x)		(x)
584c7fd2ed0Sgs150176 #define	RGE_BSWAP_32(x)		(x)
585c7fd2ed0Sgs150176 #define	RGE_BSWAP_64(x)		(x)
586c7fd2ed0Sgs150176 #endif
587c7fd2ed0Sgs150176 
588c7fd2ed0Sgs150176 /*
589c7fd2ed0Sgs150176  * Bit test macros, returning boolean_t values
590c7fd2ed0Sgs150176  */
591c7fd2ed0Sgs150176 #define	BIS(w, b)	(((w) & (b)) ? B_TRUE : B_FALSE)
592c7fd2ed0Sgs150176 #define	BIC(w, b)	(((w) & (b)) ? B_FALSE : B_TRUE)
593c7fd2ed0Sgs150176 #define	UPORDOWN(x)	((x) ? "up" : "down")
594c7fd2ed0Sgs150176 
595c7fd2ed0Sgs150176 /*
596c7fd2ed0Sgs150176  * Bit flags in the 'debug' word ...
597c7fd2ed0Sgs150176  */
598c7fd2ed0Sgs150176 #define	RGE_DBG_STOP		0x00000001	/* early debug_enter()	*/
599c7fd2ed0Sgs150176 #define	RGE_DBG_TRACE		0x00000002	/* general flow tracing	*/
600c7fd2ed0Sgs150176 
601c7fd2ed0Sgs150176 #define	RGE_DBG_REGS		0x00000010	/* low-level accesses	*/
602c7fd2ed0Sgs150176 #define	RGE_DBG_MII		0x00000020	/* low-level MII access	*/
603c7fd2ed0Sgs150176 #define	RGE_DBG_SEEPROM		0x00000040	/* low-level SEEPROM IO	*/
604c7fd2ed0Sgs150176 #define	RGE_DBG_CHIP		0x00000080	/* low(ish)-level code	*/
605c7fd2ed0Sgs150176 
606c7fd2ed0Sgs150176 #define	RGE_DBG_RECV		0x00000100	/* receive-side code	*/
607c7fd2ed0Sgs150176 #define	RGE_DBG_SEND		0x00000200	/* packet-send code	*/
608c7fd2ed0Sgs150176 
609c7fd2ed0Sgs150176 #define	RGE_DBG_INT		0x00001000	/* interrupt handler	*/
610c7fd2ed0Sgs150176 #define	RGE_DBG_FACT		0x00002000	/* factotum (softint)	*/
611c7fd2ed0Sgs150176 
612c7fd2ed0Sgs150176 #define	RGE_DBG_PHY		0x00010000	/* Copper PHY code	*/
613c7fd2ed0Sgs150176 #define	RGE_DBG_SERDES		0x00020000	/* SerDes code		*/
614c7fd2ed0Sgs150176 #define	RGE_DBG_PHYS		0x00040000	/* Physical layer code	*/
615c7fd2ed0Sgs150176 #define	RGE_DBG_LINK		0x00080000	/* Link status check	*/
616c7fd2ed0Sgs150176 
617c7fd2ed0Sgs150176 #define	RGE_DBG_INIT		0x00100000	/* initialisation	*/
618c7fd2ed0Sgs150176 #define	RGE_DBG_NEMO		0x00200000	/* nemo interaction	*/
619c7fd2ed0Sgs150176 #define	RGE_DBG_ADDR		0x00400000	/* address-setting code	*/
620c7fd2ed0Sgs150176 #define	RGE_DBG_STATS		0x00800000	/* statistics		*/
621c7fd2ed0Sgs150176 
622c7fd2ed0Sgs150176 #define	RGE_DBG_IOCTL		0x01000000	/* ioctl handling	*/
623c7fd2ed0Sgs150176 #define	RGE_DBG_LOOP		0x02000000	/* loopback ioctl code	*/
624c7fd2ed0Sgs150176 #define	RGE_DBG_PPIO		0x04000000	/* Peek/poke ioctls	*/
625c7fd2ed0Sgs150176 #define	RGE_DBG_BADIOC		0x08000000	/* unknown ioctls	*/
626c7fd2ed0Sgs150176 
627c7fd2ed0Sgs150176 #define	RGE_DBG_MCTL		0x10000000	/* mctl (csum) code	*/
628c7fd2ed0Sgs150176 #define	RGE_DBG_NDD		0x20000000	/* NDD operations	*/
629c7fd2ed0Sgs150176 
630c7fd2ed0Sgs150176 /*
631c7fd2ed0Sgs150176  * Debugging ...
632c7fd2ed0Sgs150176  */
633c7fd2ed0Sgs150176 #ifdef	DEBUG
634c7fd2ed0Sgs150176 #define	RGE_DEBUGGING		1
635c7fd2ed0Sgs150176 #else
636c7fd2ed0Sgs150176 #define	RGE_DEBUGGING		0
637c7fd2ed0Sgs150176 #endif	/* DEBUG */
638c7fd2ed0Sgs150176 
639c7fd2ed0Sgs150176 
640c7fd2ed0Sgs150176 /*
641c7fd2ed0Sgs150176  * 'Do-if-debugging' macro.  The parameter <command> should be one or more
642c7fd2ed0Sgs150176  * C statements (but without the *final* semicolon), which will either be
643c7fd2ed0Sgs150176  * compiled inline or completely ignored, depending on the RGE_DEBUGGING
644c7fd2ed0Sgs150176  * compile-time flag.
645c7fd2ed0Sgs150176  *
646c7fd2ed0Sgs150176  * You should get a compile-time error (at least on a DEBUG build) if
647c7fd2ed0Sgs150176  * your statement isn't actually a statement, rather than unexpected
648c7fd2ed0Sgs150176  * run-time behaviour caused by unintended matching of if-then-elses etc.
649c7fd2ed0Sgs150176  *
650c7fd2ed0Sgs150176  * Note that the RGE_DDB() macro itself can only be used as a statement,
651c7fd2ed0Sgs150176  * not an expression, and should always be followed by a semicolon.
652c7fd2ed0Sgs150176  */
653c7fd2ed0Sgs150176 #if	RGE_DEBUGGING
654c7fd2ed0Sgs150176 #define	RGE_DDB(command)	do {					\
655c7fd2ed0Sgs150176 					{ command; }			\
656c7fd2ed0Sgs150176 					_NOTE(CONSTANTCONDITION)	\
657c7fd2ed0Sgs150176 				} while (0)
658c7fd2ed0Sgs150176 #else 	/* RGE_DEBUGGING */
659c7fd2ed0Sgs150176 #define	RGE_DDB(command)	do {					\
660c7fd2ed0Sgs150176 					{ _NOTE(EMPTY); }		\
661c7fd2ed0Sgs150176 					_NOTE(CONSTANTCONDITION)	\
662c7fd2ed0Sgs150176 				} while (0)
663c7fd2ed0Sgs150176 #endif	/* RGE_DEBUGGING */
664c7fd2ed0Sgs150176 
665c7fd2ed0Sgs150176 /*
666c7fd2ed0Sgs150176  * 'Internal' macros used to construct the TRACE/DEBUG macros below.
667c7fd2ed0Sgs150176  * These provide the primitive conditional-call capability required.
668c7fd2ed0Sgs150176  * Note: the parameter <args> is a parenthesised list of the actual
669c7fd2ed0Sgs150176  * printf-style arguments to be passed to the debug function ...
670c7fd2ed0Sgs150176  */
671c7fd2ed0Sgs150176 #define	RGE_XDB(b, w, f, args)	RGE_DDB(if ((b) & (w)) f args)
672c7fd2ed0Sgs150176 #define	RGE_GDB(b, args)	RGE_XDB(b, rge_debug, (*rge_gdb()), args)
673c7fd2ed0Sgs150176 #define	RGE_LDB(b, args)	RGE_XDB(b, rgep->debug, (*rge_db(rgep)), args)
674c7fd2ed0Sgs150176 #define	RGE_CDB(f, args)	RGE_XDB(RGE_DBG, rgep->debug, f, args)
675c7fd2ed0Sgs150176 
676c7fd2ed0Sgs150176 /*
677c7fd2ed0Sgs150176  * Conditional-print macros.
678c7fd2ed0Sgs150176  *
679c7fd2ed0Sgs150176  * Define RGE_DBG to be the relevant member of the set of RGE_DBG_* values
680c7fd2ed0Sgs150176  * above before using the RGE_GDEBUG() or RGE_DEBUG() macros.  The 'G'
681c7fd2ed0Sgs150176  * versions look at the Global debug flag word (rge_debug); the non-G
682c7fd2ed0Sgs150176  * versions look in the per-instance data (rgep->debug) and so require a
683c7fd2ed0Sgs150176  * variable called 'rgep' to be in scope (and initialised!) before use.
684c7fd2ed0Sgs150176  *
685c7fd2ed0Sgs150176  * You could redefine RGE_TRC too if you really need two different
686c7fd2ed0Sgs150176  * flavours of debugging output in the same area of code, but I don't
687c7fd2ed0Sgs150176  * really recommend it.
688c7fd2ed0Sgs150176  *
689c7fd2ed0Sgs150176  * Note: the parameter <args> is a parenthesised list of the actual
690c7fd2ed0Sgs150176  * arguments to be passed to the debug function, usually a printf-style
691c7fd2ed0Sgs150176  * format string and corresponding values to be formatted.
692c7fd2ed0Sgs150176  */
693c7fd2ed0Sgs150176 
694c7fd2ed0Sgs150176 #define	RGE_TRC			RGE_DBG_TRACE	/* default 'trace' bit	*/
695c7fd2ed0Sgs150176 #define	RGE_GTRACE(args)	RGE_GDB(RGE_TRC, args)
696c7fd2ed0Sgs150176 #define	RGE_GDEBUG(args)	RGE_GDB(RGE_DBG, args)
697c7fd2ed0Sgs150176 #define	RGE_TRACE(args)		RGE_LDB(RGE_TRC, args)
698c7fd2ed0Sgs150176 #define	RGE_DEBUG(args)		RGE_LDB(RGE_DBG, args)
699c7fd2ed0Sgs150176 
700c7fd2ed0Sgs150176 /*
701c7fd2ed0Sgs150176  * Debug-only action macros
702c7fd2ed0Sgs150176  */
703c7fd2ed0Sgs150176 #define	RGE_BRKPT(rgep, s)	RGE_DDB(rge_dbg_enter(rgep, s))
704c7fd2ed0Sgs150176 #define	RGE_MARK(rgep)		RGE_DDB(rge_led_mark(rgep))
705c7fd2ed0Sgs150176 #define	RGE_PCICHK(rgep)	RGE_DDB(rge_pci_check(rgep))
706c7fd2ed0Sgs150176 #define	RGE_PKTDUMP(args)	RGE_DDB(rge_pkt_dump args)
707c7fd2ed0Sgs150176 #define	RGE_REPORT(args)	RGE_DDB(rge_log args)
708c7fd2ed0Sgs150176 
709c7fd2ed0Sgs150176 /*
710c7fd2ed0Sgs150176  * Inter-source-file linkage ...
711c7fd2ed0Sgs150176  */
712c7fd2ed0Sgs150176 
713c7fd2ed0Sgs150176 /* rge_chip.c */
714c7fd2ed0Sgs150176 uint16_t rge_mii_get16(rge_t *rgep, uintptr_t mii);
715c7fd2ed0Sgs150176 void rge_mii_put16(rge_t *rgep, uintptr_t mii, uint16_t data);
716c7fd2ed0Sgs150176 void rge_chip_cfg_init(rge_t *rgep, chip_id_t *cidp);
717c7fd2ed0Sgs150176 void rge_chip_ident(rge_t *rgep);
718c7fd2ed0Sgs150176 int rge_chip_reset(rge_t *rgep);
719c7fd2ed0Sgs150176 void rge_chip_init(rge_t *rgep);
720c7fd2ed0Sgs150176 void rge_chip_start(rge_t *rgep);
721c7fd2ed0Sgs150176 void rge_chip_stop(rge_t *rgep, boolean_t fault);
722c7fd2ed0Sgs150176 void rge_chip_sync(rge_t *rgep, enum rge_sync_op todo);
723da14cebeSEric Cheng void rge_chip_blank(void *arg, time_t ticks, uint_t count, int flag);
724c7fd2ed0Sgs150176 void rge_tx_trigger(rge_t *rgep);
725c7fd2ed0Sgs150176 void rge_hw_stats_dump(rge_t *rgep);
726aa817493Sgs150176 uint_t rge_intr(caddr_t arg1, caddr_t arg2);
727aa817493Sgs150176 uint_t rge_chip_factotum(caddr_t arg1, caddr_t arg2);
728c7fd2ed0Sgs150176 void rge_chip_cyclic(void *arg);
729c7fd2ed0Sgs150176 enum ioc_reply rge_chip_ioctl(rge_t *rgep, queue_t *wq, mblk_t *mp,
730c7fd2ed0Sgs150176 	struct iocblk *iocp);
731c7fd2ed0Sgs150176 boolean_t rge_phy_reset(rge_t *rgep);
732c7fd2ed0Sgs150176 void rge_phy_init(rge_t *rgep);
733c7fd2ed0Sgs150176 void rge_phy_update(rge_t *rgep);
734c7fd2ed0Sgs150176 
735c7fd2ed0Sgs150176 /* rge_kstats.c */
736c7fd2ed0Sgs150176 void rge_init_kstats(rge_t *rgep, int instance);
737c7fd2ed0Sgs150176 void rge_fini_kstats(rge_t *rgep);
738ba2e4443Sseb int rge_m_stat(void *arg, uint_t stat, uint64_t *val);
739c7fd2ed0Sgs150176 
740c7fd2ed0Sgs150176 /* rge_log.c */
741c7fd2ed0Sgs150176 #if	RGE_DEBUGGING
742c7fd2ed0Sgs150176 void (*rge_db(rge_t *rgep))(const char *fmt, ...);
743c7fd2ed0Sgs150176 void (*rge_gdb(void))(const char *fmt, ...);
744c7fd2ed0Sgs150176 void rge_pkt_dump(rge_t *rgep, rge_bd_t *hbp, sw_rbd_t *sdp, const char *msg);
745c7fd2ed0Sgs150176 void rge_dbg_enter(rge_t *rgep, const char *msg);
746c7fd2ed0Sgs150176 #endif	/* RGE_DEBUGGING */
747c7fd2ed0Sgs150176 void rge_problem(rge_t *rgep, const char *fmt, ...);
748c7fd2ed0Sgs150176 void rge_notice(rge_t *rgep, const char *fmt, ...);
749c7fd2ed0Sgs150176 void rge_log(rge_t *rgep, const char *fmt, ...);
750c7fd2ed0Sgs150176 void rge_error(rge_t *rgep, const char *fmt, ...);
751c7fd2ed0Sgs150176 extern kmutex_t rge_log_mutex[1];
752c7fd2ed0Sgs150176 extern uint32_t rge_debug;
753c7fd2ed0Sgs150176 
754c7fd2ed0Sgs150176 /* rge_main.c */
755c7fd2ed0Sgs150176 void rge_restart(rge_t *rgep);
756c7fd2ed0Sgs150176 
757c7fd2ed0Sgs150176 /* rge_ndd.c */
758c7fd2ed0Sgs150176 int rge_nd_init(rge_t *rgep);
759c7fd2ed0Sgs150176 enum ioc_reply rge_nd_ioctl(rge_t *rgep, queue_t *wq, mblk_t *mp,
760c7fd2ed0Sgs150176 	struct iocblk *iocp);
761c7fd2ed0Sgs150176 void rge_nd_cleanup(rge_t *rgep);
762c7fd2ed0Sgs150176 
763c7fd2ed0Sgs150176 /* rge_rxtx.c */
764c7fd2ed0Sgs150176 void rge_rx_recycle(caddr_t arg);
765c7fd2ed0Sgs150176 void rge_receive(rge_t *rgep);
7669e1a9180SLi-Zhen You void rge_send_recycle(rge_t *rgep);
767c7fd2ed0Sgs150176 mblk_t *rge_m_tx(void *arg, mblk_t *mp);
768aa817493Sgs150176 uint_t rge_reschedule(caddr_t arg1, caddr_t arg2);
769c7fd2ed0Sgs150176 
770c7fd2ed0Sgs150176 #ifdef __cplusplus
771c7fd2ed0Sgs150176 }
772c7fd2ed0Sgs150176 #endif
773c7fd2ed0Sgs150176 
774c7fd2ed0Sgs150176 #endif	/* _RGE_H */
775