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