summaryrefslogtreecommitdiff
path: root/usr/src/uts/sun4u/sys/dmfe_impl.h
blob: 2699b9dc513f6550cafe35099368619bba9e5a2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_DMFE_IMPL_H
#define	_SYS_DMFE_IMPL_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#ifdef __cplusplus
extern "C" {
#endif

#include <sys/types.h>
#include <sys/stream.h>
#include <sys/strsun.h>
#include <sys/stat.h>
#include <sys/pci.h>
#include <sys/note.h>
#include <sys/modctl.h>
#include <sys/kstat.h>
#include <sys/ethernet.h>
#include <sys/devops.h>
#include <sys/debug.h>
#include <sys/conf.h>

#include <inet/common.h>
#include <inet/nd.h>
#include <inet/mi.h>

#include <sys/vlan.h>

#include <sys/dditypes.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>

#include <sys/miiregs.h>
#include <sys/dmfe.h>
#include <sys/mac.h>
#include <sys/mac_ether.h>

#define	DMFE_MAX_PKT_SIZE	(VLAN_TAGSZ + ETHERMAX + ETHERFCSL)


#define	DRIVER_NAME		"dmfe"

/*
 * Describes the identity of a specific chip
 */
typedef struct {
	uint16_t		vendor;
	uint16_t		device;
	uint8_t			revision;
	uint8_t			spare;
} chip_id_t;

/*
 * Describes the state of a descriptor ring
 *
 * NOTE: n_free and next_busy are only used for the Tx descriptors
 * and are not valid on the receive side.
 */
typedef struct {
	uint32_t		n_desc;		/* # of descriptors	    */
	uint32_t		n_free;		/* # of free descriptors    */
	uint32_t		next_free;	/* next index to use/check  */
	uint32_t		next_busy;	/* next index to reclaim    */
} desc_state_t;

/*
 * Describes one chunk of allocated DMA-able memory
 */
typedef struct {
	ddi_dma_handle_t	dma_hdl;
	ddi_acc_handle_t	acc_hdl;
	size_t			alength;	/* allocated size	*/
	caddr_t			mem_va;		/* CPU VA of memory	*/
	uint32_t		spare1;
	uint32_t		mem_dvma;	/* DVMA addr of memory	*/
	caddr_t			setup_va;
	uint32_t		spare2;
	uint32_t		setup_dvma;
	int			spare3;
	int			ncookies;
} dma_area_t;

/*
 * Named Data (ND) Parameter Management Structure
 */
typedef struct {
	uint32_t		ndp_info;
	uint32_t		ndp_min;
	uint32_t		ndp_max;
	uint32_t		ndp_val;
	char			*ndp_name;
} nd_param_t;

/*
 * NDD parameter indexes, divided into:
 *
 *	read-only parameters describing the link state
 *	read-write parameters controlling the advertised link capabilities
 *	read-only parameters describing the device link capabilities
 *	read-only parameters describing the link-partner's link capabilities
 */
enum {
	PARAM_LINK_STATUS,
	PARAM_LINK_SPEED,
	PARAM_LINK_MODE,

	PARAM_ADV_AUTONEG_CAP,
	PARAM_ADV_100T4_CAP,
	PARAM_ADV_100FDX_CAP,
	PARAM_ADV_100HDX_CAP,
	PARAM_ADV_10FDX_CAP,
	PARAM_ADV_10HDX_CAP,
	PARAM_ADV_REMFAULT,

	PARAM_BMSR_AUTONEG_CAP,
	PARAM_BMSR_100T4_CAP,
	PARAM_BMSR_100FDX_CAP,
	PARAM_BMSR_100HDX_CAP,
	PARAM_BMSR_10FDX_CAP,
	PARAM_BMSR_10HDX_CAP,
	PARAM_BMSR_REMFAULT,

	PARAM_LP_AUTONEG_CAP,
	PARAM_LP_100T4_CAP,
	PARAM_LP_100FDX_CAP,
	PARAM_LP_100HDX_CAP,
	PARAM_LP_10FDX_CAP,
	PARAM_LP_10HDX_CAP,
	PARAM_LP_REMFAULT,

	PARAM_COUNT
};

/*
 * Indexes into the driver-specific kstats, divided into:
 *
 *	cyclic activity
 *	reasons for waking the factotum
 *	the factotum's activities
 *      link state updates
 *      MII-level register values
 */
enum {
	KS_CYCLIC_RUN,

	KS_TICK_LINK_STATE,
	KS_TICK_LINK_POLL,
	KS_INTERRUPT,
	KS_TX_STALL,
	KS_CHIP_ERROR,

	KS_FACTOTUM_RUN,
	KS_RECOVERY,
	KS_LINK_CHECK,

	KS_LINK_UP_CNT,
	KS_LINK_DROP_CNT,

	KS_MIIREG_BMSR,
	KS_MIIREG_ANAR,
	KS_MIIREG_ANLPAR,
	KS_MIIREG_ANER,
	KS_MIIREG_DSCSR,

	KS_DRV_COUNT
};

/*
 * Actual state of the DM9102A chip
 */
enum chip_state {
	CHIP_ERROR = -1,			/* error, need reset	*/
	CHIP_UNKNOWN,				/* Initial state only	*/
	CHIP_RESET,				/* reset, need init	*/
	CHIP_STOPPED,				/* Tx/Rx stopped	*/
	CHIP_TX_ONLY,				/* Tx (re)started	*/
	CHIP_TX_RX,				/* Tx & Rx (re)started	*/
	CHIP_RUNNING				/* with interrupts	*/
};

/*
 * Required state according to MAC
 */
enum mac_state {
	DMFE_MAC_UNKNOWN,
	DMFE_MAC_RESET,
	DMFE_MAC_STOPPED,
	DMFE_MAC_STARTED
};

/*
 * (Internal) return values from ioctl subroutines
 */
enum ioc_reply {
	IOC_INVAL = -1,				/* bad, NAK with EINVAL	*/
	IOC_DONE,				/* OK, reply sent	*/
	IOC_REPLY,				/* OK, just send reply	*/
	IOC_ACK,				/* OK, just send ACK	*/
	IOC_RESTART,				/* OK, restart & reply	*/
	IOC_RESTART_ACK				/* OK, restart & ACK	*/
};

/*
 * Per-instance soft-state structure
 */
typedef struct {
	/*
	 * These fields are set by attach() and unchanged thereafter ...
	 */
	dev_info_t		*devinfo;	/* device instance	*/
	mac_handle_t		mh;		/* MAC instance data	*/
	ddi_acc_handle_t	io_handle;	/* DDI I/O handle	*/
	caddr_t			io_reg;		/* mapped registers	*/

	uint32_t		debug;		/* per-instance debug	*/
	uint32_t		progress;	/* attach tracking	*/
	chip_id_t		chipid;
	uint8_t			vendor_addr[ETHERADDRL];
	char			ifname[12];	/* "dmfeXXXX"		*/

	dma_area_t		tx_desc;	/* transmit descriptors	*/
	dma_area_t		tx_buff;	/* transmit buffers	*/
	dma_area_t		rx_desc;	/* receive descriptors	*/
	dma_area_t		rx_buff;	/* receive buffers	*/

	ddi_periodic_t		cycid;		/* periodical callback 	*/
	ddi_softintr_t		factotum_id;	/* identity of factotum	*/
	ddi_iblock_cookie_t	iblk;

	/*
	 * Locks:
	 *
	 * <milock> is used only by the MII (PHY) level code, to ensure
	 *	exclusive access during the bit-twiddling needed to send
	 *	signals along the MII serial bus.  These operations are
	 *	--S--L--O--W-- so we keep this lock separate, so that
	 *	faster operations (e.g. interrupts) aren't delayed by
	 *	waiting for it.
	 *
	 * <oplock> is a general "outer" lock, protecting most r/w data
	 *	and chip state.  It is also acquired by the interrupt
	 *	handler.
	 *
	 * <rxlock> is used to protect the Rx-side buffers, descriptors,
	 *	and statistics during a single call to dmfe_getp().
	 *	This is called from inside the interrupt handler, but
	 *	<oplock> is not held across this call.
	 *
	 * <txlock> is an "inner" lock, and protects only the Tx-side
	 *	data below and in the ring buffers/descriptors.  The
	 *	Tx-side code uses only this lock, avoiding contention
	 *	with the receive-side code.
	 *
	 * Any of the locks can be acquired singly, but where multiple
	 * locks are acquired, they *must* be in the order:
	 *
	 *	milock >>> oplock >>> rxlock >>> txlock.
	 *
	 * *None* of these locks may be held across calls out to the
	 * MAC routines mac_rx() or mac_tx_notify(); MAC locks must
	 * be regarded as *outermost* locks in all cases, as they will
	 * already be held before calling the ioctl() or get_stats()
	 * entry points - which then have to acquire multiple locks, in
	 * the order described here.
	 */
	kmutex_t		milock[1];
	kmutex_t		oplock[1];
	kmutex_t		rxlock[1];
	kmutex_t		txlock[1];

	/*
	 * DMFE Extended kstats, protected by <oplock>
	 */
	kstat_t			*ksp_drv;
	kstat_named_t		*knp_drv;

	/*
	 * GLD statistics; the prefix tells which lock each is protected by.
	 */
	uint64_t		op_stats_speed;
	uint64_t		op_stats_duplex;

	uint64_t		rx_stats_ipackets;
	uint64_t		rx_stats_multi;
	uint64_t		rx_stats_bcast;
	uint64_t		rx_stats_ierrors;
	uint64_t		rx_stats_norcvbuf;
	uint64_t		rx_stats_rbytes;
	uint64_t		rx_stats_missed;
	uint64_t		rx_stats_align;
	uint64_t		rx_stats_fcs;
	uint64_t		rx_stats_toolong;
	uint64_t		rx_stats_macrcv_errors;
	uint64_t		rx_stats_overflow;
	uint64_t		rx_stats_short;

	uint64_t		tx_stats_oerrors;
	uint64_t		tx_stats_opackets;
	uint64_t		tx_stats_multi;
	uint64_t		tx_stats_bcast;
	uint64_t		tx_stats_obytes;
	uint64_t		tx_stats_collisions;
	uint64_t		tx_stats_nocarrier;
	uint64_t		tx_stats_xmtlatecoll;
	uint64_t		tx_stats_excoll;
	uint64_t		tx_stats_macxmt_errors;
	uint64_t		tx_stats_jabber;
	uint64_t		tx_stats_defer;
	uint64_t		tx_stats_first_coll;
	uint64_t		tx_stats_multi_coll;
	uint64_t		tx_stats_underflow;

	/*
	 * These two sets of desciptors are manipulated during
	 * packet receive/transmit respectively.
	 */
	desc_state_t		rx;		/* describes Rx ring	*/
	desc_state_t		tx;		/* describes Tx ring	*/

	/*
	 * Miscellaneous Tx-side variables (protected by txlock)
	 */
	uint32_t		tx_pending_tix;	/* tix since reclaim	*/
	uint8_t			*tx_mcast;	/* bitmask: pkt is mcast */
	uint8_t			*tx_bcast;	/* bitmask: pkt is bcast */

	/*
	 * Miscellaneous operating variables (protected by oplock)
	 */
	uint32_t		link_poll_tix;	/* tix until link poll	 */
	uint16_t		factotum_flag;	/* callback pending	 */
	uint16_t		need_setup;	/* send-setup pending	 */
	uint32_t		opmode;		/* operating mode shadow */
	uint32_t		imask;		/* interrupt mask shadow */
	enum mac_state		mac_state;	/* RESET/STOPPED/STARTED */
	enum chip_state		chip_state;	/* see above		 */

	/*
	 * Physical link state data (protected by oplock)
	 */
	link_state_t		link_state;	/* See above		*/

	/*
	 * PHYceiver state data (protected by milock)
	 */
	int			phy_inuse;
	int			phy_addr;	/* should be -1!	*/
	uint16_t		phy_control;	/* last value written	*/
	uint16_t		phy_anar_w;	/* last value written	*/
	uint16_t		phy_anar_r;	/* latest value read	*/
	uint16_t		phy_anlpar;	/* latest value read	*/
	uint16_t		phy_aner;
	uint16_t		phy_dscsr;	/* latest value read	*/
	uint16_t		phy_bmsr;	/* latest value read	*/
	uint16_t		rsvd;		/* reserved for future use */
	uint32_t		phy_bmsr_lbolt;	/* time of BMSR change	*/
	uint32_t		phy_id; 	/* vendor+device (OUI)	*/

	/*
	 * Current Ethernet address & multicast map ...
	 */
	uint8_t			curr_addr[ETHERADDRL];
	uint8_t			mcast_refs[MCASTBUF_SIZE];
	boolean_t		addr_set;
	boolean_t		update_phy;	/* Need to update_phy? */

	/*
	 * NDD parameters
	 */
	caddr_t			nd_data_p;
	nd_param_t		nd_params[PARAM_COUNT];

	/*
	 * Guard element used to check data integrity
	 */
	uint64_t		dmfe_guard;
} dmfe_t;

/*
 * 'Progress' bit flags ...
 */
#define	PROGRESS_CONFIG		0x0001	/* config space initialised	*/
#define	PROGRESS_NDD		0x0002	/* NDD parameters set up	*/
#define	PROGRESS_REGS		0x0004	/* registers mapped		*/
#define	PROGRESS_BUFS		0x0008	/* buffers allocated		*/
#define	PROGRESS_SOFTINT	0x0010	/* softint registered		*/
#define	PROGRESS_HWINT		0x0020	/* h/w interrupt registered	*/

/*
 * Type of transceiver currently in use
 */
#define	PHY_TYPE_UNDEFINED	0
#define	PHY_TYPE_10BASE_MNCHSTR	2
#define	PHY_TYPE_100BASE_X	4

/*
 * Shorthand for the NDD parameters
 */
#define	param_linkup		nd_params[PARAM_LINK_STATUS].ndp_val
#define	param_speed		nd_params[PARAM_LINK_SPEED].ndp_val
#define	param_duplex		nd_params[PARAM_LINK_MODE].ndp_val
#define	param_autoneg		nd_params[PARAM_ADV_AUTONEG_CAP].ndp_val
#define	param_anar_100T4	nd_params[PARAM_ADV_100T4_CAP].ndp_val
#define	param_anar_100fdx	nd_params[PARAM_ADV_100FDX_CAP].ndp_val
#define	param_anar_100hdx	nd_params[PARAM_ADV_100HDX_CAP].ndp_val
#define	param_anar_10fdx	nd_params[PARAM_ADV_10FDX_CAP].ndp_val
#define	param_anar_10hdx	nd_params[PARAM_ADV_10HDX_CAP].ndp_val
#define	param_anar_remfault	nd_params[PARAM_ADV_REMFAULT].ndp_val
#define	param_bmsr_autoneg	nd_params[PARAM_BMSR_AUTONEG_CAP].ndp_val
#define	param_bmsr_100T4	nd_params[PARAM_BMSR_100T4_CAP].ndp_val
#define	param_bmsr_100fdx	nd_params[PARAM_BMSR_100FDX_CAP].ndp_val
#define	param_bmsr_100hdx	nd_params[PARAM_BMSR_100HDX_CAP].ndp_val
#define	param_bmsr_10fdx	nd_params[PARAM_BMSR_10FDX_CAP].ndp_val
#define	param_bmsr_10hdx	nd_params[PARAM_BMSR_10HDX_CAP].ndp_val
#define	param_bmsr_remfault	nd_params[PARAM_BMSR_REMFAULT].ndp_val
#define	param_lp_autoneg	nd_params[PARAM_LP_AUTONEG_CAP].ndp_val
#define	param_lp_100T4		nd_params[PARAM_LP_100T4_CAP].ndp_val
#define	param_lp_100fdx		nd_params[PARAM_LP_100FDX_CAP].ndp_val
#define	param_lp_100hdx		nd_params[PARAM_LP_100HDX_CAP].ndp_val
#define	param_lp_10fdx		nd_params[PARAM_LP_10FDX_CAP].ndp_val
#define	param_lp_10hdx		nd_params[PARAM_LP_10HDX_CAP].ndp_val
#define	param_lp_remfault	nd_params[PARAM_LP_REMFAULT].ndp_val

/*
 * Sync a DMA area described by a dma_area_t
 */
#define	DMA_SYNC(descp, flag)	((void) ddi_dma_sync((descp)->dma_hdl,	\
					0, (descp)->alength, flag))

/*
 * Next value of a cyclic index
 */
#define	NEXT(index, limit)	((index)+1 < (limit) ? (index)+1 : 0);

/*
 * Utility Macros
 */
#define	U32TOPTR(x)		((void *)(uintptr_t)(uint32_t)(x))
#define	PTRTOU32(x)		((uint32_t)(uintptr_t)(void *)(x))

/*
 * Copy an ethernet address
 */
#define	ethaddr_copy(src, dst)	bcopy((src), (dst), ETHERADDRL)
#define	MII_KS_GET(dmfep, id)						\
	(((dmfep)->knp_mii) ? ((dmfep)->knp_mii)[id].value.ui32 : 0)

#define	MII_KS_SET(dmfep, id, val)					\
	do {								\
		if ((dmfep)->knp_mii != NULL)				\
			((dmfep)->knp_mii)[id].value.ui32 = (val);	\
		_NOTE(CONSTANTCONDITION)				\
	} while (0)

#define	MII_KS_INC(dmfep, id)						\
	do {								\
		if ((dmfep)->knp_mii != NULL)				\
			((dmfep)->knp_mii)[id].value.ui32 += 1;		\
		_NOTE(CONSTANTCONDITION)				\
	} while (0)

/*
 * Get/set/increment a (64-bit) driver-private kstat
 */
#define	DRV_KS_GET(dmfep, id)						\
	(((dmfep)->knp_drv) ? ((dmfep)->knp_drv)[id].value.ui64 : 0)

#define	DRV_KS_SET(dmfep, id, val)					\
	do {								\
		if ((dmfep)->knp_drv)					\
			((dmfep)->knp_drv)[id].value.ui64 = (val);	\
		_NOTE(CONSTANTCONDITION)				\
	} while (0)

#define	DRV_KS_INC(dmfep, id)						\
	do {								\
		if ((dmfep)->knp_drv)					\
			((dmfep)->knp_drv)[id].value.ui64 += 1;		\
		_NOTE(CONSTANTCONDITION)				\
	} while (0)

/*
 * Bit test macros, returning boolean_t values
 */
#define	BIS(w, b)		((w) & (b))
#define	BIC(w, b)		!BIS(w, b)

#define	DMFE_GUARD		0x1919603003090218

/*
 * 'Debug' bit flags ...
 */
#define	DMFE_DBG_TRACE		0x0001		/* general flow tracing	*/
#define	DMFE_DBG_REGS		0x0002		/* low-level accesses	*/
#define	DMFE_DBG_RECV		0x0004		/* receive-side code	*/
#define	DMFE_DBG_SEND		0x0008		/* packet-send code	*/
#define	DMFE_DBG_ADDR		0x0010		/* address-setting code	*/
#define	DMFE_DBG_GLD		0x0020		/* GLD entry points	*/
#define	DMFE_DBG_FACT		0x0040		/* factotum (softint)	*/
#define	DMFE_DBG_TICK		0x0080		/* GPT ticker		*/
#define	DMFE_DBG_INT		0x0100		/* interrupt handler	*/
#define	DMFE_DBG_STATS		0x0200		/* statistics		*/
#define	DMFE_DBG_IOCTL		0x0400		/* ioctl/loopback code	*/
#define	DMFE_DBG_INIT		0x0800		/* initialisation	*/
#define	DMFE_DBG_MII		0x1000		/* low-level MII/PHY	*/
#define	DMFE_DBG_LINK		0x2000		/* Link status check	*/
#define	DMFE_DBG_NDD		0x4000		/* NDD parameters	*/

/*
 * Debugging ...
 */
#if defined(DEBUG) || defined(lint)
#define	DMFEDEBUG		1
#else
#define	DMFEDEBUG		0
#endif

#if	DMFEDEBUG

extern uint32_t dmfe_debug;
extern void (*dmfe_gdb())(const char *fmt, ...);
extern void (*dmfe_db(dmfe_t *dmfep))(const char *fmt, ...);

/*
 * Define DMFE_DBG to be the relevant flag from the set above before
 * using the DMFE_GDEBUG() or DMFE_DEBUG() macros.  The 'G' versions
 * look at the Global debug flag word (dmfe_debug); the non-G versions
 * look in the per-instance data (dmfep->debug) and so require a variable
 * called 'dmfep' to be in scope (and initialised!)
 *
 * You could redefine DMFE_TRC too if you really need two different
 * flavours of debugging output in the same area of code, but I don't
 * really recommend it.
 */

#define	DMFE_TRC		DMFE_DBG_TRACE	/* default 'trace' bit	*/

#define	DMFE_GDEBUG(args)	do {					\
					if (dmfe_debug & (DMFE_DBG))	\
						(*dmfe_gdb()) args;	\
					_NOTE(CONSTANTCONDITION)	\
				} while (0)

#define	DMFE_GTRACE(args)	do {					\
					if (dmfe_debug & (DMFE_TRC))	\
						(*dmfe_gdb()) args;	\
					_NOTE(CONSTANTCONDITION)	\
				} while (0)

#define	DMFE_DEBUG(args)	do {					\
					if (dmfep->debug & (DMFE_DBG))	\
						(*dmfe_db(dmfep)) args;	\
					_NOTE(CONSTANTCONDITION)	\
				} while (0)

#define	DMFE_TRACE(args)	do {					\
					if (dmfep->debug & (DMFE_TRC))	\
						(*dmfe_db(dmfep)) args;	\
					_NOTE(CONSTANTCONDITION)	\
				} while (0)

#else

#define	DMFE_DEBUG(args)	do ; _NOTE(CONSTANTCONDITION) while (0)
#define	DMFE_TRACE(args)	do ; _NOTE(CONSTANTCONDITION) while (0)
#define	DMFE_GDEBUG(args)	do ; _NOTE(CONSTANTCONDITION) while (0)
#define	DMFE_GTRACE(args)	do ; _NOTE(CONSTANTCONDITION) while (0)

#endif	/* DMFEDEBUG */


/*
 * Inter-source-file linkage ...
 */

/* dmfe_log.c */
void dmfe_warning(dmfe_t *dmfep, const char *fmt, ...);
void dmfe_error(dmfe_t *dmfep, const char *fmt, ...);
void dmfe_notice(dmfe_t *dmfep, const char *fmt, ...);
void dmfe_log(dmfe_t *dmfep, const char *fmt, ...);
void dmfe_log_init(void);
void dmfe_log_fini(void);

/* dmfe_main.c */
uint32_t dmfe_chip_get32(dmfe_t *dmfep, off_t offset);
void dmfe_chip_put32(dmfe_t *dmfep, off_t offset, uint32_t value);

/* dmfe_mii.c */
boolean_t dmfe_init_phy(dmfe_t *dmfep);
void dmfe_update_phy(dmfe_t *dmfep);
boolean_t dmfe_check_link(dmfe_t *dmfep);
void dmfe_recheck_link(dmfe_t *dmfep, boolean_t ioctl);

/* dmfe_ndd.c */
int dmfe_nd_init(dmfe_t *dmfep);
enum ioc_reply dmfe_nd_ioctl(dmfe_t *dmfep, queue_t *wq, mblk_t *mp, int cmd);
void dmfe_nd_cleanup(dmfe_t *dmfep);

#ifdef __cplusplus
}
#endif

#endif	/* _SYS_DMFE_IMPL_H */