xref: /titanic_41/usr/src/uts/common/io/hme/hme.c (revision 1f0f5e3e328e41529296f756090856aa7f239b1c)
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 (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 
27 /*
28  * SunOS MT STREAMS FEPS(SBus)/Cheerio(PCI) 10/100Mb Ethernet Device Driver
29  */
30 
31 #include	<sys/types.h>
32 #include	<sys/debug.h>
33 #include	<sys/stream.h>
34 #include	<sys/cmn_err.h>
35 #include	<sys/kmem.h>
36 #include	<sys/crc32.h>
37 #include	<sys/modctl.h>
38 #include	<sys/conf.h>
39 #include	<sys/strsun.h>
40 #include	<sys/kstat.h>
41 #include	<sys/pattr.h>
42 #include	<sys/dlpi.h>
43 #include	<sys/strsubr.h>
44 #include	<sys/mac_provider.h>
45 #include	<sys/mac_ether.h>
46 #include	<sys/mii.h>
47 #include	<sys/ethernet.h>
48 #include	<sys/vlan.h>
49 #include	<sys/pci.h>
50 #include	<sys/policy.h>
51 #include	<sys/ddi.h>
52 #include	<sys/sunddi.h>
53 #include	"hme_phy.h"
54 #include	"hme_mac.h"
55 #include	"hme.h"
56 
57 typedef void	(*fptrv_t)();
58 
59 typedef enum {
60 	NO_MSG		= 0,
61 	AUTOCONFIG_MSG,
62 	DISPLAY_MSG,
63 	INIT_MSG,
64 	UNINIT_MSG,
65 	CONFIG_MSG,
66 	MII_MSG,
67 	FATAL_ERR_MSG,
68 	NFATAL_ERR_MSG,
69 	XCVR_MSG,
70 	NOXCVR_MSG,
71 	ERX_MSG,
72 	DDI_MSG,
73 } msg_t;
74 
75 msg_t	hme_debug_level =	NO_MSG;
76 
77 static char	*msg_string[] = {
78 	"NONE       ",
79 	"AUTOCONFIG ",
80 	"DISPLAY	"
81 	"INIT       ",
82 	"UNINIT		",
83 	"CONFIG	",
84 	"MII	",
85 	"FATAL_ERR	",
86 	"NFATAL_ERR	",
87 	"XCVR	",
88 	"NOXCVR	",
89 	"ERX	",
90 	"DDI	",
91 };
92 
93 #define	SEVERITY_NONE	0
94 #define	SEVERITY_LOW	0
95 #define	SEVERITY_MID	1
96 #define	SEVERITY_HIGH	2
97 #define	SEVERITY_UNKNOWN 99
98 
99 #define	FEPS_URUN_BUG
100 #define	HME_CODEVIOL_BUG
101 
102 #define	KIOIP	KSTAT_INTR_PTR(hmep->hme_intrstats)
103 
104 /*
105  * The following variables are used for checking fixes in Sbus/FEPS 2.0
106  */
107 static	int	hme_urun_fix = 0;	/* Bug fixed in Sbus/FEPS 2.0 */
108 
109 /*
110  * The following variables are used for configuring various features
111  */
112 static	int	hme_64bit_enable =	1;	/* Use 64-bit sbus transfers */
113 static	int	hme_reject_own =	1;	/* Reject packets with own SA */
114 static	int	hme_ngu_enable =	0;	/* Never Give Up mode */
115 
116 mac_priv_prop_t hme_priv_prop[] = {
117 	{	"_ipg0",	MAC_PROP_PERM_RW	},
118 	{	"_ipg1",	MAC_PROP_PERM_RW	},
119 	{	"_ipg2",	MAC_PROP_PERM_RW	},
120 	{	"_lance_mode",	MAC_PROP_PERM_RW	},
121 };
122 
123 static	int	hme_lance_mode =	1;	/* to enable lance mode */
124 static	int	hme_ipg0 =		16;
125 static	int	hme_ipg1 =		8;
126 static	int	hme_ipg2 =		4;
127 
128 /*
129  * The following parameters may be configured by the user. If they are not
130  * configured by the user, the values will be based on the capabilities of
131  * the transceiver.
132  * The value "HME_NOTUSR" is ORed with the parameter value to indicate values
133  * which are NOT configured by the user.
134  */
135 
136 #define	HME_NOTUSR	0x0f000000
137 #define	HME_MASK_1BIT	0x1
138 #define	HME_MASK_5BIT	0x1f
139 #define	HME_MASK_8BIT	0xff
140 
141 /*
142  * All strings used by hme messaging functions
143  */
144 
145 static	char *no_xcvr_msg =
146 	"No transceiver found.";
147 
148 static	char *burst_size_msg =
149 	"Could not identify the burst size";
150 
151 static	char *unk_rx_ringsz_msg =
152 	"Unknown receive RINGSZ";
153 
154 static  char *add_intr_fail_msg =
155 	"ddi_add_intr(9F) failed";
156 
157 static  char *mregs_4global_reg_fail_msg =
158 	"ddi_regs_map_setup(9F) for global reg failed";
159 
160 static	char *mregs_4etx_reg_fail_msg =
161 	"ddi_map_regs for etx reg failed";
162 
163 static	char *mregs_4erx_reg_fail_msg =
164 	"ddi_map_regs for erx reg failed";
165 
166 static	char *mregs_4bmac_reg_fail_msg =
167 	"ddi_map_regs for bmac reg failed";
168 
169 static	char *mregs_4mif_reg_fail_msg =
170 	"ddi_map_regs for mif reg failed";
171 
172 static	char *init_fail_gen_msg =
173 	"Failed to initialize hardware/driver";
174 
175 static	char *ddi_nregs_fail_msg =
176 	"ddi_dev_nregs failed(9F), returned %d";
177 
178 static	char *bad_num_regs_msg =
179 	"Invalid number of registers.";
180 
181 
182 /* FATAL ERR msgs */
183 /*
184  * Function prototypes.
185  */
186 /* these two are global so that qfe can use them */
187 int hmeattach(dev_info_t *, ddi_attach_cmd_t);
188 int hmedetach(dev_info_t *, ddi_detach_cmd_t);
189 int hmequiesce(dev_info_t *);
190 static	boolean_t hmeinit_xfer_params(struct hme *);
191 static	uint_t hmestop(struct hme *);
192 static	void hmestatinit(struct hme *);
193 static	int hmeallocthings(struct hme *);
194 static	void hmefreethings(struct hme *);
195 static	int hmeallocbuf(struct hme *, hmebuf_t *, int);
196 static	int hmeallocbufs(struct hme *);
197 static	void hmefreebufs(struct hme *);
198 static	void hmeget_hm_rev_property(struct hme *);
199 static	boolean_t hmestart(struct hme *, mblk_t *);
200 static	uint_t hmeintr(caddr_t);
201 static	void hmereclaim(struct hme *);
202 static	int hmeinit(struct hme *);
203 static	void hmeuninit(struct hme *hmep);
204 static 	mblk_t *hmeread(struct hme *, hmebuf_t *, uint32_t);
205 static	void hmesavecntrs(struct hme *);
206 static	void hme_fatal_err(struct hme *, uint_t);
207 static	void hme_nonfatal_err(struct hme *, uint_t);
208 static	int hmeburstsizes(struct hme *);
209 static	void send_bit(struct hme *, uint16_t);
210 static	uint16_t get_bit_std(uint8_t, struct hme *);
211 static	uint16_t hme_bb_mii_read(struct hme *, uint8_t, uint8_t);
212 static	void hme_bb_mii_write(struct hme *, uint8_t, uint8_t, uint16_t);
213 static	void hme_bb_force_idle(struct hme *);
214 static	uint16_t hme_mii_read(void *, uint8_t, uint8_t);
215 static	void hme_mii_write(void *, uint8_t, uint8_t, uint16_t);
216 static	void hme_setup_mac_address(struct hme *, dev_info_t *);
217 static	void hme_mii_notify(void *, link_state_t);
218 
219 static void hme_fault_msg(struct hme *, uint_t, msg_t, char *, ...);
220 
221 static void hme_check_acc_handle(char *, uint_t, struct hme *,
222     ddi_acc_handle_t);
223 
224 /*
225  * Nemo (GLDv3) Functions.
226  */
227 static int	hme_m_stat(void *, uint_t, uint64_t *);
228 static int	hme_m_start(void *);
229 static void	hme_m_stop(void *);
230 static int	hme_m_promisc(void *, boolean_t);
231 static int	hme_m_multicst(void *, boolean_t, const uint8_t *);
232 static int	hme_m_unicst(void *, const uint8_t *);
233 static mblk_t	*hme_m_tx(void *, mblk_t *);
234 static boolean_t	hme_m_getcapab(void *, mac_capab_t, void *);
235 static int hme_m_getprop(void *, const char *, mac_prop_id_t, uint_t,
236     uint_t, void *, uint_t *);
237 static int hme_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
238     const void *);
239 
240 static mii_ops_t hme_mii_ops = {
241 	MII_OPS_VERSION,
242 	hme_mii_read,
243 	hme_mii_write,
244 	hme_mii_notify,
245 	NULL
246 };
247 
248 static mac_callbacks_t hme_m_callbacks = {
249 	MC_GETCAPAB | MC_SETPROP | MC_GETPROP,
250 	hme_m_stat,
251 	hme_m_start,
252 	hme_m_stop,
253 	hme_m_promisc,
254 	hme_m_multicst,
255 	hme_m_unicst,
256 	hme_m_tx,
257 	NULL,
258 	hme_m_getcapab,
259 	NULL,
260 	NULL,
261 	hme_m_setprop,
262 	hme_m_getprop,
263 };
264 
265 DDI_DEFINE_STREAM_OPS(hme_dev_ops, nulldev, nulldev, hmeattach, hmedetach,
266     nodev, NULL, D_MP, NULL, hmequiesce);
267 
268 #define	HME_FAULT_MSG1(p, s, t, f) \
269     hme_fault_msg((p), (s), (t), (f));
270 
271 #define	HME_FAULT_MSG2(p, s, t, f, a) \
272     hme_fault_msg((p), (s), (t), (f), (a));
273 
274 #define	HME_FAULT_MSG3(p, s, t, f, a, b) \
275     hme_fault_msg((p), (s), (t), (f), (a), (b));
276 
277 #define	HME_FAULT_MSG4(p, s, t, f, a, b, c) \
278     hme_fault_msg((p), (s), (t), (f), (a), (b), (c));
279 
280 #define	CHECK_MIFREG() \
281 	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_mifregh)
282 #define	CHECK_ETXREG() \
283 	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_etxregh)
284 #define	CHECK_ERXREG() \
285 	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_erxregh)
286 #define	CHECK_MACREG() \
287 	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_bmacregh)
288 #define	CHECK_GLOBREG() \
289 	hme_check_acc_handle(__FILE__, __LINE__, hmep, hmep->hme_globregh)
290 
291 /*
292  * Claim the device is ultra-capable of burst in the beginning.  Use
293  * the value returned by ddi_dma_burstsizes() to actually set the HME
294  * global configuration register later.
295  *
296  * Sbus/FEPS supports burst sizes of 16, 32 and 64 bytes. Also, it supports
297  * 32-bit and 64-bit Sbus transfers. Hence the dlim_burstsizes field contains
298  * the the burstsizes in both the lo and hi words.
299  */
300 #define	HMELIMADDRLO	((uint64_t)0x00000000)
301 #define	HMELIMADDRHI	((uint64_t)0xffffffff)
302 
303 /*
304  * Note that rx and tx data buffers can be arbitrarily aligned, but
305  * that the descriptor rings need to be aligned on 2K boundaries, per
306  * the spec.
307  */
308 static ddi_dma_attr_t hme_dma_attr = {
309 	DMA_ATTR_V0,		/* version number. */
310 	(uint64_t)HMELIMADDRLO,	/* low address */
311 	(uint64_t)HMELIMADDRHI,	/* high address */
312 	(uint64_t)0x00ffffff,	/* address counter max */
313 	(uint64_t)HME_HMDALIGN,	/* alignment */
314 	(uint_t)0x00700070,	/* dlim_burstsizes for 32 and 64 bit xfers */
315 	(uint32_t)0x1,		/* minimum transfer size */
316 	(uint64_t)0x7fffffff,	/* maximum transfer size */
317 	(uint64_t)0x00ffffff,	/* maximum segment size */
318 	1,			/* scatter/gather list length */
319 	512,			/* granularity */
320 	0			/* attribute flags */
321 };
322 
323 static ddi_device_acc_attr_t hme_buf_attr = {
324 	DDI_DEVICE_ATTR_V0,
325 	DDI_NEVERSWAP_ACC,
326 	DDI_STRICTORDER_ACC,	/* probably could allow merging & caching */
327 	DDI_DEFAULT_ACC,
328 };
329 
330 static uchar_t pci_latency_timer = 0;
331 
332 /*
333  * Module linkage information for the kernel.
334  */
335 static struct modldrv modldrv = {
336 	&mod_driverops,	/* Type of module.  This one is a driver */
337 	"Sun HME 10/100 Mb Ethernet",
338 	&hme_dev_ops,	/* driver ops */
339 };
340 
341 static struct modlinkage modlinkage = {
342 	MODREV_1, &modldrv, NULL
343 };
344 
345 /* <<<<<<<<<<<<<<<<<<<<<<  Register operations >>>>>>>>>>>>>>>>>>>>> */
346 
347 #define	GET_MIFREG(reg) \
348 	ddi_get32(hmep->hme_mifregh, (uint32_t *)&hmep->hme_mifregp->reg)
349 #define	PUT_MIFREG(reg, value) \
350 	ddi_put32(hmep->hme_mifregh, (uint32_t *)&hmep->hme_mifregp->reg, value)
351 
352 #define	GET_ETXREG(reg) \
353 	ddi_get32(hmep->hme_etxregh, (uint32_t *)&hmep->hme_etxregp->reg)
354 #define	PUT_ETXREG(reg, value) \
355 	ddi_put32(hmep->hme_etxregh, (uint32_t *)&hmep->hme_etxregp->reg, value)
356 #define	GET_ERXREG(reg) \
357 	ddi_get32(hmep->hme_erxregh, (uint32_t *)&hmep->hme_erxregp->reg)
358 #define	PUT_ERXREG(reg, value) \
359 	ddi_put32(hmep->hme_erxregh, (uint32_t *)&hmep->hme_erxregp->reg, value)
360 #define	GET_MACREG(reg) \
361 	ddi_get32(hmep->hme_bmacregh, (uint32_t *)&hmep->hme_bmacregp->reg)
362 #define	PUT_MACREG(reg, value) \
363 	ddi_put32(hmep->hme_bmacregh, \
364 		(uint32_t *)&hmep->hme_bmacregp->reg, value)
365 #define	GET_GLOBREG(reg) \
366 	ddi_get32(hmep->hme_globregh, (uint32_t *)&hmep->hme_globregp->reg)
367 #define	PUT_GLOBREG(reg, value) \
368 	ddi_put32(hmep->hme_globregh, \
369 		(uint32_t *)&hmep->hme_globregp->reg, value)
370 #define	PUT_TMD(ptr, paddr, len, flags)					\
371 	ddi_put32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_addr, paddr); \
372 	ddi_put32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_flags,	\
373 	    len | flags)
374 #define	GET_TMD_FLAGS(ptr)					\
375 	ddi_get32(hmep->hme_tmd_acch, &hmep->hme_tmdp[ptr].tmd_flags)
376 #define	PUT_RMD(ptr, paddr) \
377 	ddi_put32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_addr, paddr); \
378 	ddi_put32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_flags,	\
379 	    (uint32_t)(HMEBUFSIZE << HMERMD_BUFSIZE_SHIFT) | HMERMD_OWN)
380 #define	GET_RMD_FLAGS(ptr)					\
381 	ddi_get32(hmep->hme_rmd_acch, &hmep->hme_rmdp[ptr].rmd_flags)
382 
383 #define	GET_ROM8(offset) \
384 	ddi_get8((hmep->hme_romh), (offset))
385 
386 /*
387  * Ether_copy is not endian-correct. Define an endian-correct version.
388  */
389 #define	ether_bcopy(a, b) (bcopy(a, b, 6))
390 
391 /*
392  * Ether-type is specifically big-endian, but data region is unknown endian
393  */
394 #define	get_ether_type(ptr) \
395 	(((((uint8_t *)ptr)[12] << 8) | (((uint8_t *)ptr)[13])))
396 
397 /* <<<<<<<<<<<<<<<<<<<<<<  Configuration Parameters >>>>>>>>>>>>>>>>>>>>> */
398 
399 #define	BMAC_DEFAULT_JAMSIZE	(0x04)		/* jamsize equals 4 */
400 #define	BMAC_LONG_JAMSIZE	(0x10)		/* jamsize equals 0x10 */
401 static	int 	jamsize = BMAC_DEFAULT_JAMSIZE;
402 
403 
404 /*
405  * Calculate the bit in the multicast address filter that selects the given
406  * address.
407  */
408 
409 static uint32_t
410 hmeladrf_bit(const uint8_t *addr)
411 {
412 	uint32_t crc;
413 
414 	CRC32(crc, addr, ETHERADDRL, -1U, crc32_table);
415 
416 	/*
417 	 * Just want the 6 most significant bits.
418 	 */
419 	return (crc >> 26);
420 }
421 
422 /* <<<<<<<<<<<<<<<<<<<<<<<<  Bit Bang Operations >>>>>>>>>>>>>>>>>>>>>>>> */
423 
424 static void
425 send_bit(struct hme *hmep, uint16_t x)
426 {
427 	PUT_MIFREG(mif_bbdata, x);
428 	PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW);
429 	PUT_MIFREG(mif_bbclk, HME_BBCLK_HIGH);
430 }
431 
432 
433 /*
434  * To read the MII register bits according to the IEEE Standard
435  */
436 static uint16_t
437 get_bit_std(uint8_t phyad, struct hme *hmep)
438 {
439 	uint16_t	x;
440 
441 	PUT_MIFREG(mif_bbclk, HME_BBCLK_LOW);
442 	drv_usecwait(1);	/* wait for  >330 ns for stable data */
443 	if (phyad == HME_INTERNAL_PHYAD)
444 		x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM0) ? 1 : 0;
445 	else
446 		x = (GET_MIFREG(mif_cfg) & HME_MIF_CFGM1) ? 1 : 0;
447 	PUT_MIFREG(mif_bbclk, HME_BBCLK_HIGH);
448 	return (x);
449 }
450 
451 #define	SEND_BIT(x)		send_bit(hmep, x)
452 #define	GET_BIT_STD(phyad, x)	x = get_bit_std(phyad, hmep)
453 
454 
455 static void
456 hme_bb_mii_write(struct hme *hmep, uint8_t phyad, uint8_t regad, uint16_t data)
457 {
458 	int	i;
459 
460 	PUT_MIFREG(mif_bbopenb, 1);	/* Enable the MII driver */
461 	(void) hme_bb_force_idle(hmep);
462 	SEND_BIT(0); SEND_BIT(1);	/* <ST> */
463 	SEND_BIT(0); SEND_BIT(1);	/* <OP> */
464 
465 	for (i = 4; i >= 0; i--) {		/* <AAAAA> */
466 		SEND_BIT((phyad >> i) & 1);
467 	}
468 
469 	for (i = 4; i >= 0; i--) {		/* <RRRRR> */
470 		SEND_BIT((regad >> i) & 1);
471 	}
472 
473 	SEND_BIT(1); SEND_BIT(0);	/* <TA> */
474 
475 	for (i = 0xf; i >= 0; i--) {	/* <DDDDDDDDDDDDDDDD> */
476 		SEND_BIT((data >> i) & 1);
477 	}
478 
479 	PUT_MIFREG(mif_bbopenb, 0);	/* Disable the MII driver */
480 	CHECK_MIFREG();
481 }
482 
483 /* Return 0 if OK, 1 if error (Transceiver does not talk management) */
484 static uint16_t
485 hme_bb_mii_read(struct hme *hmep, uint8_t phyad, uint8_t regad)
486 {
487 	int		i;
488 	uint32_t	x;
489 	uint16_t	data = 0;
490 
491 	PUT_MIFREG(mif_bbopenb, 1);	/* Enable the MII driver */
492 	(void) hme_bb_force_idle(hmep);
493 	SEND_BIT(0); SEND_BIT(1);	/* <ST> */
494 	SEND_BIT(1); SEND_BIT(0);	/* <OP> */
495 	for (i = 4; i >= 0; i--) {		/* <AAAAA> */
496 		SEND_BIT((phyad >> i) & 1);
497 	}
498 	for (i = 4; i >= 0; i--) {		/* <RRRRR> */
499 		SEND_BIT((regad >> i) & 1);
500 	}
501 
502 	PUT_MIFREG(mif_bbopenb, 0);	/* Disable the MII driver */
503 
504 	GET_BIT_STD(phyad, x);
505 	GET_BIT_STD(phyad, x);		/* <TA> */
506 	for (i = 0xf; i >= 0; i--) {	/* <DDDDDDDDDDDDDDDD> */
507 		GET_BIT_STD(phyad, x);
508 		data += (x << i);
509 	}
510 	/*
511 	 * Kludge to get the Transceiver out of hung mode
512 	 */
513 	GET_BIT_STD(phyad, x);
514 	GET_BIT_STD(phyad, x);
515 	GET_BIT_STD(phyad, x);
516 	CHECK_MIFREG();
517 	return (data);
518 }
519 
520 
521 static void
522 hme_bb_force_idle(struct hme *hmep)
523 {
524 	int	i;
525 
526 	for (i = 0; i < 33; i++) {
527 		SEND_BIT(1);
528 	}
529 }
530 
531 /* <<<<<<<<<<<<<<<<<<<<End of Bit Bang Operations >>>>>>>>>>>>>>>>>>>>>>>> */
532 
533 
534 /* <<<<<<<<<<<<< Frame Register used for MII operations >>>>>>>>>>>>>>>>>>>> */
535 
536 /* Return 0 if OK, 1 if error (Transceiver does not talk management) */
537 static uint16_t
538 hme_mii_read(void *arg, uint8_t phyad, uint8_t regad)
539 {
540 	struct hme	*hmep = arg;
541 	uint32_t	frame;
542 	uint32_t	tmp_mif;
543 	uint32_t	tmp_xif;
544 
545 	tmp_mif = GET_MIFREG(mif_cfg);
546 	tmp_xif = GET_MACREG(xifc);
547 
548 	switch (phyad) {
549 	case HME_EXTERNAL_PHYAD:
550 		PUT_MIFREG(mif_cfg, tmp_mif | HME_MIF_CFGPS);
551 		PUT_MACREG(xifc, tmp_xif | BMAC_XIFC_MIIBUFDIS);
552 		break;
553 	case HME_INTERNAL_PHYAD:
554 		PUT_MIFREG(mif_cfg, tmp_mif & ~(HME_MIF_CFGPS));
555 		PUT_MACREG(xifc, tmp_xif & ~(BMAC_XIFC_MIIBUFDIS));
556 		break;
557 	default:
558 		return (0xffff);
559 	}
560 
561 	if (!hmep->hme_frame_enable) {
562 		frame = (hme_bb_mii_read(hmep, phyad, regad));
563 		PUT_MACREG(xifc, tmp_xif);
564 		PUT_MIFREG(mif_cfg, tmp_mif);
565 		return (frame & 0xffff);
566 	}
567 
568 	PUT_MIFREG(mif_frame,
569 	    HME_MIF_FRREAD | (phyad << HME_MIF_FRPHYAD_SHIFT) |
570 	    (regad << HME_MIF_FRREGAD_SHIFT));
571 /*
572  *	HMEDELAY((*framerp & HME_MIF_FRTA0), HMEMAXRSTDELAY);
573  */
574 	HMEDELAY((GET_MIFREG(mif_frame) & HME_MIF_FRTA0), 300);
575 	frame = GET_MIFREG(mif_frame);
576 	CHECK_MIFREG();
577 
578 	PUT_MACREG(xifc, tmp_xif);
579 	PUT_MIFREG(mif_cfg, tmp_mif);
580 
581 	if ((frame & HME_MIF_FRTA0) == 0) {
582 
583 
584 		HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, MII_MSG,
585 		    "MIF Read failure");
586 		return (0xffff);
587 	}
588 	return ((uint16_t)(frame & HME_MIF_FRDATA));
589 }
590 
591 static void
592 hme_mii_write(void *arg, uint8_t phyad, uint8_t regad, uint16_t data)
593 {
594 	struct hme *hmep = arg;
595 	uint32_t frame;
596 	uint32_t tmp_mif;
597 	uint32_t tmp_xif;
598 
599 	tmp_mif = GET_MIFREG(mif_cfg);
600 	tmp_xif = GET_MACREG(xifc);
601 
602 	switch (phyad) {
603 	case HME_EXTERNAL_PHYAD:
604 		PUT_MIFREG(mif_cfg, tmp_mif | HME_MIF_CFGPS);
605 		PUT_MACREG(xifc, tmp_xif | BMAC_XIFC_MIIBUFDIS);
606 		break;
607 	case HME_INTERNAL_PHYAD:
608 		PUT_MIFREG(mif_cfg, tmp_mif & ~(HME_MIF_CFGPS));
609 		PUT_MACREG(xifc, tmp_xif & ~(BMAC_XIFC_MIIBUFDIS));
610 		break;
611 	default:
612 		return;
613 	}
614 
615 	if (!hmep->hme_frame_enable) {
616 		hme_bb_mii_write(hmep, phyad, regad, data);
617 		PUT_MACREG(xifc, tmp_xif);
618 		PUT_MIFREG(mif_cfg, tmp_mif);
619 		return;
620 	}
621 
622 	PUT_MIFREG(mif_frame,
623 	    HME_MIF_FRWRITE | (phyad << HME_MIF_FRPHYAD_SHIFT) |
624 	    (regad << HME_MIF_FRREGAD_SHIFT) | data);
625 /*
626  *	HMEDELAY((*framerp & HME_MIF_FRTA0), HMEMAXRSTDELAY);
627  */
628 	HMEDELAY((GET_MIFREG(mif_frame) & HME_MIF_FRTA0), 300);
629 	frame = GET_MIFREG(mif_frame);
630 	PUT_MACREG(xifc, tmp_xif);
631 	PUT_MIFREG(mif_cfg, tmp_mif);
632 	CHECK_MIFREG();
633 	if ((frame & HME_MIF_FRTA0) == 0) {
634 		HME_FAULT_MSG1(hmep, SEVERITY_MID, MII_MSG,
635 		    "MIF Write failure");
636 	}
637 }
638 
639 static void
640 hme_mii_notify(void *arg, link_state_t link)
641 {
642 	struct hme *hmep = arg;
643 
644 	if (link == LINK_STATE_UP) {
645 		(void) hmeinit(hmep);
646 	}
647 	mac_link_update(hmep->hme_mh, link);
648 }
649 
650 /* <<<<<<<<<<<<<<<<<<<<<<<<<<<  LOADABLE ENTRIES  >>>>>>>>>>>>>>>>>>>>>>> */
651 
652 int
653 _init(void)
654 {
655 	int	status;
656 
657 	mac_init_ops(&hme_dev_ops, "hme");
658 	if ((status = mod_install(&modlinkage)) != 0) {
659 		mac_fini_ops(&hme_dev_ops);
660 	}
661 	return (status);
662 }
663 
664 int
665 _fini(void)
666 {
667 	int	status;
668 
669 	if ((status = mod_remove(&modlinkage)) == 0) {
670 		mac_fini_ops(&hme_dev_ops);
671 	}
672 	return (status);
673 }
674 
675 int
676 _info(struct modinfo *modinfop)
677 {
678 	return (mod_info(&modlinkage, modinfop));
679 }
680 
681 /*
682  * ddi_dma_sync() a TMD or RMD descriptor.
683  */
684 #define	HMESYNCRMD(num, who)				\
685 	(void) ddi_dma_sync(hmep->hme_rmd_dmah,		\
686 	    (num * sizeof (struct hme_rmd)),		\
687 	    sizeof (struct hme_rmd),			\
688 	    who)
689 
690 #define	HMESYNCTMD(num, who)				\
691 	(void) ddi_dma_sync(hmep->hme_tmd_dmah,		\
692 	    (num * sizeof (struct hme_tmd)),		\
693 	    sizeof (struct hme_tmd),			\
694 	    who)
695 
696 /*
697  * Ethernet broadcast address definition.
698  */
699 static	struct ether_addr	etherbroadcastaddr = {
700 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff
701 };
702 
703 /*
704  * MIB II broadcast/multicast packets
705  */
706 #define	IS_BROADCAST(pkt) (bcmp(pkt, &etherbroadcastaddr, ETHERADDRL) == 0)
707 #define	IS_MULTICAST(pkt) ((pkt[0] & 01) == 1)
708 #define	BUMP_InNUcast(hmep, pkt) \
709 	if (IS_MULTICAST(pkt)) {			       \
710 		if (IS_BROADCAST(pkt)) {		       \
711 			hmep->hme_brdcstrcv++;		       \
712 		} else {				       \
713 			hmep->hme_multircv++;		       \
714 		}					       \
715 	}
716 #define	BUMP_OutNUcast(hmep, pkt) \
717 	if (IS_MULTICAST(pkt)) {			       \
718 		if (IS_BROADCAST(pkt)) {		       \
719 			hmep->hme_brdcstxmt++;		       \
720 		} else {				       \
721 			hmep->hme_multixmt++;		       \
722 		}					       \
723 	}
724 
725 static int
726 hme_create_prop_from_kw(dev_info_t *dip, char *vpdname, char *vpdstr)
727 {
728 	char propstr[80];
729 	int i, needprop = 0;
730 	struct ether_addr local_mac;
731 
732 	if (strcmp(vpdname, "NA") == 0) {
733 		(void) strcpy(propstr, "local-mac-address");
734 		needprop = 1;
735 	} else if (strcmp(vpdname, "Z0") == 0) {
736 		(void) strcpy(propstr, "model");
737 		needprop = 1;
738 	} else if (strcmp(vpdname, "Z1") == 0) {
739 		(void) strcpy(propstr, "board-model");
740 		needprop = 1;
741 	}
742 
743 	if (needprop == 1) {
744 
745 		if (strcmp(propstr, "local-mac-address") == 0) {
746 			for (i = 0; i < ETHERADDRL; i++)
747 				local_mac.ether_addr_octet[i] =
748 				    (uchar_t)vpdstr[i];
749 			if (ddi_prop_create(DDI_DEV_T_NONE, dip,
750 			    DDI_PROP_CANSLEEP, propstr,
751 			    (char *)local_mac.ether_addr_octet, ETHERADDRL)
752 			    != DDI_SUCCESS) {
753 				return (DDI_FAILURE);
754 			}
755 		} else {
756 			if (ddi_prop_create(DDI_DEV_T_NONE, dip,
757 			    DDI_PROP_CANSLEEP, propstr, vpdstr,
758 			    strlen(vpdstr)+1) != DDI_SUCCESS) {
759 				return (DDI_FAILURE);
760 			}
761 		}
762 	}
763 	return (0);
764 }
765 
766 /*
767  * Get properties from old VPD
768  * for PCI cards
769  */
770 static int
771 hme_get_oldvpd_props(dev_info_t *dip, int vpd_base)
772 {
773 	struct hme *hmep;
774 	int vpd_start, vpd_len, kw_start, kw_len, kw_ptr;
775 	char kw_namestr[3];
776 	char kw_fieldstr[256];
777 	int i;
778 
779 	hmep = ddi_get_driver_private(dip);
780 
781 	vpd_start = vpd_base;
782 
783 	if ((GET_ROM8(&hmep->hme_romp[vpd_start]) & 0xff) != 0x90) {
784 		return (1); /* error */
785 	} else {
786 		vpd_len = 9;
787 	}
788 
789 	/* Get local-mac-address */
790 	kw_start = vpd_start + 3; /* Location of 1st keyword */
791 	kw_ptr = kw_start;
792 	while ((kw_ptr - kw_start) < vpd_len) { /* Get all keywords */
793 		kw_namestr[0] = GET_ROM8(&hmep->hme_romp[kw_ptr]);
794 		kw_namestr[1] = GET_ROM8(&hmep->hme_romp[kw_ptr+1]);
795 		kw_namestr[2] = '\0';
796 		kw_len = (int)(GET_ROM8(&hmep->hme_romp[kw_ptr+2]) & 0xff);
797 		for (i = 0, kw_ptr += 3; i < kw_len; i++)
798 			kw_fieldstr[i] = GET_ROM8(&hmep->hme_romp[kw_ptr+i]);
799 		kw_fieldstr[i] = '\0';
800 		if (hme_create_prop_from_kw(dip, kw_namestr, kw_fieldstr)) {
801 			return (DDI_FAILURE);
802 		}
803 		kw_ptr += kw_len;
804 	} /* next keyword */
805 
806 	if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, "model",
807 	    "SUNW,cheerio", strlen("SUNW,cheerio")+1) != DDI_SUCCESS) {
808 		return (DDI_FAILURE);
809 	}
810 	return (0);
811 }
812 
813 
814 /*
815  * Get properties from new VPD
816  * for CompactPCI cards
817  */
818 static int
819 hme_get_newvpd_props(dev_info_t *dip, int vpd_base)
820 {
821 	struct hme *hmep;
822 	int vpd_start, vpd_len, kw_start, kw_len, kw_ptr;
823 	char kw_namestr[3];
824 	char kw_fieldstr[256];
825 	int maxvpdsize, i;
826 
827 	hmep = ddi_get_driver_private(dip);
828 
829 	maxvpdsize = 1024; /* Real size not known until after it is read */
830 
831 	vpd_start = (int)((GET_ROM8(&(hmep->hme_romp[vpd_base+1])) & 0xff) |
832 	    ((GET_ROM8(&hmep->hme_romp[vpd_base+2]) & 0xff) << 8)) +3;
833 	vpd_start = vpd_base + vpd_start;
834 	while (vpd_start < (vpd_base + maxvpdsize)) { /* Get all VPDs */
835 		if ((GET_ROM8(&hmep->hme_romp[vpd_start]) & 0xff) != 0x90) {
836 			break; /* no VPD found */
837 		} else {
838 			vpd_len = (int)((GET_ROM8(&hmep->hme_romp[vpd_start
839 			    + 1]) & 0xff) | (GET_ROM8(&hmep->hme_romp[vpd_start
840 			    + 2]) & 0xff) << 8);
841 		}
842 		/* Get all keywords in this VPD */
843 		kw_start = vpd_start + 3; /* Location of 1st keyword */
844 		kw_ptr = kw_start;
845 		while ((kw_ptr - kw_start) < vpd_len) { /* Get all keywords */
846 			kw_namestr[0] = GET_ROM8(&hmep->hme_romp[kw_ptr]);
847 			kw_namestr[1] = GET_ROM8(&hmep->hme_romp[kw_ptr+1]);
848 			kw_namestr[2] = '\0';
849 			kw_len =
850 			    (int)(GET_ROM8(&hmep->hme_romp[kw_ptr+2]) & 0xff);
851 			for (i = 0, kw_ptr += 3; i < kw_len; i++)
852 				kw_fieldstr[i] =
853 				    GET_ROM8(&hmep->hme_romp[kw_ptr+i]);
854 			kw_fieldstr[i] = '\0';
855 			if (hme_create_prop_from_kw(dip, kw_namestr,
856 			    kw_fieldstr)) {
857 				return (DDI_FAILURE);
858 			}
859 			kw_ptr += kw_len;
860 		} /* next keyword */
861 		vpd_start += (vpd_len + 3);
862 	} /* next VPD */
863 	return (0);
864 }
865 
866 
867 /*
868  * Get properties from VPD
869  */
870 static int
871 hme_get_vpd_props(dev_info_t *dip)
872 {
873 	struct hme *hmep;
874 	int v0, v1, vpd_base;
875 	int i, epromsrchlimit;
876 
877 
878 	hmep = ddi_get_driver_private(dip);
879 
880 	v0 = (int)(GET_ROM8(&(hmep->hme_romp[0])));
881 	v1 = (int)(GET_ROM8(&(hmep->hme_romp[1])));
882 	v0 = ((v0 & 0xff) << 8 | v1);
883 
884 	if ((v0 & 0xffff) != 0x55aa) {
885 		cmn_err(CE_NOTE, " Valid pci prom not found \n");
886 		return (1);
887 	}
888 
889 	epromsrchlimit = 4096;
890 	for (i = 2; i < epromsrchlimit; i++) {
891 		/* "PCIR" */
892 		if (((GET_ROM8(&(hmep->hme_romp[i])) & 0xff) == 'P') &&
893 		    ((GET_ROM8(&(hmep->hme_romp[i+1])) & 0xff) == 'C') &&
894 		    ((GET_ROM8(&(hmep->hme_romp[i+2])) & 0xff) == 'I') &&
895 		    ((GET_ROM8(&(hmep->hme_romp[i+3])) & 0xff) == 'R')) {
896 			vpd_base =
897 			    (int)((GET_ROM8(&(hmep->hme_romp[i+8])) & 0xff) |
898 			    (GET_ROM8(&(hmep->hme_romp[i+9])) & 0xff) << 8);
899 			break; /* VPD pointer found */
900 		}
901 	}
902 
903 	/* No VPD found */
904 	if (vpd_base == 0) {
905 		cmn_err(CE_NOTE, " Vital Product Data pointer not found \n");
906 		return (1);
907 	}
908 
909 	v0 = (int)(GET_ROM8(&(hmep->hme_romp[vpd_base])));
910 	if (v0 == 0x82) {
911 		if (hme_get_newvpd_props(dip, vpd_base))
912 			return (1);
913 		return (0);
914 	} else if (v0 == 0x90) {
915 		/* If we are are SUNW,qfe card, look for the Nth "NA" descr */
916 		if ((GET_ROM8(&hmep->hme_romp[vpd_base + 12])  != 0x79) &&
917 		    GET_ROM8(&hmep->hme_romp[vpd_base + 4 * 12]) == 0x79) {
918 			vpd_base += hmep->hme_devno * 12;
919 		}
920 		if (hme_get_oldvpd_props(dip, vpd_base))
921 			return (1);
922 		return (0);
923 	} else
924 		return (1);	/* unknown start byte in VPD */
925 }
926 
927 /*
928  * For x86, the BIOS doesn't map the PCI Rom register for the qfe
929  * cards, so we have to extract it from the ebus bridge that is
930  * function zero of the same device.  This is a bit of an ugly hack.
931  * (The ebus bridge leaves the entire ROM mapped at base address
932  * register 0x10.)
933  */
934 
935 typedef struct {
936 	struct hme 		*hmep;
937 	dev_info_t		*parent;
938 	uint8_t			bus, dev;
939 	ddi_acc_handle_t	acch;
940 	caddr_t			romp;
941 } ebus_rom_t;
942 
943 static int
944 hme_mapebusrom(dev_info_t *dip, void *arg)
945 {
946 	int		*regs;
947 	unsigned	nregs;
948 	int		reg;
949 	ebus_rom_t	*rom = arg;
950 	struct hme	*hmep = rom->hmep;
951 
952 	/*
953 	 * We only want to look at our peers.  Skip our parent.
954 	 */
955 	if (dip == rom->parent) {
956 		return (DDI_WALK_PRUNESIB);
957 	}
958 
959 	if (ddi_get_parent(dip) != rom->parent)
960 		return (DDI_WALK_CONTINUE);
961 
962 	if ((ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0,
963 	    "reg", &regs, &nregs)) != DDI_PROP_SUCCESS) {
964 		return (DDI_WALK_PRUNECHILD);
965 	}
966 
967 	if (nregs < 1) {
968 		ddi_prop_free(regs);
969 		return (DDI_WALK_PRUNECHILD);
970 	}
971 	reg = regs[0];
972 	ddi_prop_free(regs);
973 
974 	/*
975 	 * Look for function 0 on our bus and device.  If the device doesn't
976 	 * match, it might be an alternate peer, in which case we don't want
977 	 * to examine any of its children.
978 	 */
979 	if ((PCI_REG_BUS_G(reg) != rom->bus) ||
980 	    (PCI_REG_DEV_G(reg) != rom->dev) ||
981 	    (PCI_REG_FUNC_G(reg) != 0)) {
982 		return (DDI_WALK_PRUNECHILD);
983 	}
984 
985 	(void) ddi_regs_map_setup(dip, 1, &rom->romp, 0, 0, &hmep->hme_dev_attr,
986 	    &rom->acch);
987 	/*
988 	 * If we can't map the registers, the caller will notice that
989 	 * the acch is NULL.
990 	 */
991 	return (DDI_WALK_TERMINATE);
992 }
993 
994 static int
995 hmeget_promebus(dev_info_t *dip)
996 {
997 	ebus_rom_t	rom;
998 	int		*regs;
999 	unsigned	nregs;
1000 	struct hme	*hmep;
1001 
1002 	hmep = ddi_get_driver_private(dip);
1003 
1004 	bzero(&rom, sizeof (rom));
1005 
1006 	/*
1007 	 * For x86, the BIOS doesn't map the PCI Rom register for the qfe
1008 	 * cards, so we have to extract it from the eBus bridge that is
1009 	 * function zero.  This is a bit of an ugly hack.
1010 	 */
1011 	if ((ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 0,
1012 	    "reg", &regs, &nregs)) != DDI_PROP_SUCCESS) {
1013 		return (DDI_FAILURE);
1014 	}
1015 
1016 	if (nregs < 5) {
1017 		ddi_prop_free(regs);
1018 		return (DDI_FAILURE);
1019 	}
1020 	rom.hmep = hmep;
1021 	rom.bus = PCI_REG_BUS_G(regs[0]);
1022 	rom.dev = PCI_REG_DEV_G(regs[0]);
1023 	hmep->hme_devno = rom.dev;
1024 	rom.parent = ddi_get_parent(dip);
1025 
1026 	/*
1027 	 * The implementation of ddi_walk_devs says that we must not
1028 	 * be called during autoconfiguration.  However, it turns out
1029 	 * that it is safe to call this during our attach routine,
1030 	 * because we are not a nexus device.
1031 	 *
1032 	 * Previously we rooted our search at our immediate parent,
1033 	 * but this triggered an assertion panic in debug kernels.
1034 	 */
1035 	ddi_walk_devs(ddi_root_node(), hme_mapebusrom, &rom);
1036 
1037 	if (rom.acch) {
1038 		hmep->hme_romh = rom.acch;
1039 		hmep->hme_romp = (unsigned char *)rom.romp;
1040 		return (DDI_SUCCESS);
1041 	}
1042 	return (DDI_FAILURE);
1043 }
1044 
1045 static int
1046 hmeget_promprops(dev_info_t *dip)
1047 {
1048 	struct hme *hmep;
1049 	int rom_bar;
1050 	ddi_acc_handle_t cfg_handle;
1051 	struct {
1052 		uint16_t vendorid;
1053 		uint16_t devid;
1054 		uint16_t command;
1055 		uint16_t status;
1056 		uint32_t junk1;
1057 		uint8_t cache_line;
1058 		uint8_t latency;
1059 		uint8_t header;
1060 		uint8_t bist;
1061 		uint32_t base;
1062 		uint32_t base14;
1063 		uint32_t base18;
1064 		uint32_t base1c;
1065 		uint32_t base20;
1066 		uint32_t base24;
1067 		uint32_t base28;
1068 		uint32_t base2c;
1069 		uint32_t base30;
1070 	} *cfg_ptr;
1071 
1072 	hmep = ddi_get_driver_private(dip);
1073 
1074 
1075 	/*
1076 	 * map configuration space
1077 	 */
1078 	if (ddi_regs_map_setup(hmep->dip, 0, (caddr_t *)&cfg_ptr,
1079 	    0, 0, &hmep->hme_dev_attr, &cfg_handle)) {
1080 		return (DDI_FAILURE);
1081 	}
1082 
1083 	/*
1084 	 * Enable bus-master and memory accesses
1085 	 */
1086 	ddi_put16(cfg_handle, &cfg_ptr->command,
1087 	    PCI_COMM_SERR_ENABLE | PCI_COMM_PARITY_DETECT |
1088 	    PCI_COMM_MAE | PCI_COMM_ME);
1089 
1090 	/*
1091 	 * Enable rom accesses
1092 	 */
1093 	rom_bar = ddi_get32(cfg_handle, &cfg_ptr->base30);
1094 	ddi_put32(cfg_handle, &cfg_ptr->base30, rom_bar | 1);
1095 
1096 
1097 	if ((ddi_regs_map_setup(dip, 2, (caddr_t *)&(hmep->hme_romp), 0, 0,
1098 	    &hmep->hme_dev_attr, &hmep->hme_romh) != DDI_SUCCESS) &&
1099 	    (hmeget_promebus(dip) != DDI_SUCCESS)) {
1100 
1101 		if (cfg_ptr)
1102 			ddi_regs_map_free(&cfg_handle);
1103 		return (DDI_FAILURE);
1104 	} else {
1105 		if (hme_get_vpd_props(dip))
1106 			return (DDI_FAILURE);
1107 	}
1108 	if (hmep->hme_romp)
1109 		ddi_regs_map_free(&hmep->hme_romh);
1110 	if (cfg_ptr)
1111 		ddi_regs_map_free(&cfg_handle);
1112 	return (DDI_SUCCESS);
1113 
1114 }
1115 
1116 static void
1117 hmeget_hm_rev_property(struct hme *hmep)
1118 {
1119 	int	hm_rev;
1120 
1121 
1122 	hm_rev = hmep->asic_rev;
1123 	switch (hm_rev) {
1124 	case HME_2P1_REVID:
1125 	case HME_2P1_REVID_OBP:
1126 		HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG,
1127 		    "SBus 2.1 Found (Rev Id = %x)", hm_rev);
1128 		hmep->hme_frame_enable = 1;
1129 		break;
1130 
1131 	case HME_2P0_REVID:
1132 		HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG,
1133 		    "SBus 2.0 Found (Rev Id = %x)", hm_rev);
1134 		break;
1135 
1136 	case HME_1C0_REVID:
1137 		HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG,
1138 		    "PCI IO 1.0 Found (Rev Id = %x)", hm_rev);
1139 		break;
1140 
1141 	default:
1142 		HME_FAULT_MSG3(hmep, SEVERITY_NONE, DISPLAY_MSG,
1143 		    "%s (Rev Id = %x) Found",
1144 		    (hm_rev == HME_2C0_REVID) ? "PCI IO 2.0" : "Sbus", hm_rev);
1145 		hmep->hme_frame_enable = 1;
1146 		hmep->hme_lance_mode_enable = 1;
1147 		hmep->hme_rxcv_enable = 1;
1148 		break;
1149 	}
1150 }
1151 
1152 /*
1153  * Interface exists: make available by filling in network interface
1154  * record.  System will initialize the interface when it is ready
1155  * to accept packets.
1156  */
1157 int
1158 hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1159 {
1160 	struct hme *hmep;
1161 	mac_register_t *macp = NULL;
1162 	int 	regno;
1163 	int hm_rev = 0;
1164 	int prop_len = sizeof (int);
1165 	ddi_acc_handle_t cfg_handle;
1166 	struct {
1167 		uint16_t vendorid;
1168 		uint16_t devid;
1169 		uint16_t command;
1170 		uint16_t status;
1171 		uint8_t revid;
1172 		uint8_t j1;
1173 		uint16_t j2;
1174 	} *cfg_ptr;
1175 
1176 	switch (cmd) {
1177 	case DDI_ATTACH:
1178 		break;
1179 
1180 	case DDI_RESUME:
1181 		if ((hmep = ddi_get_driver_private(dip)) == NULL)
1182 			return (DDI_FAILURE);
1183 
1184 		hmep->hme_flags &= ~HMESUSPENDED;
1185 
1186 		mii_resume(hmep->hme_mii);
1187 
1188 		if (hmep->hme_started)
1189 			(void) hmeinit(hmep);
1190 		return (DDI_SUCCESS);
1191 
1192 	default:
1193 		return (DDI_FAILURE);
1194 	}
1195 
1196 	/*
1197 	 * Allocate soft device data structure
1198 	 */
1199 	hmep = kmem_zalloc(sizeof (*hmep), KM_SLEEP);
1200 
1201 	/*
1202 	 * Might as well set up elements of data structure
1203 	 */
1204 	hmep->dip =		dip;
1205 	hmep->instance = 	ddi_get_instance(dip);
1206 	hmep->pagesize =	ddi_ptob(dip, (ulong_t)1); /* IOMMU PSize */
1207 
1208 	/*
1209 	 *  Might as well setup the driver private
1210 	 * structure as part of the dip.
1211 	 */
1212 	ddi_set_driver_private(dip, hmep);
1213 
1214 	/*
1215 	 * Reject this device if it's in a slave-only slot.
1216 	 */
1217 	if (ddi_slaveonly(dip) == DDI_SUCCESS) {
1218 		HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1219 		    "Dev not used - dev in slave only slot");
1220 		goto error_state;
1221 	}
1222 
1223 	/*
1224 	 * Map in the device registers.
1225 	 *
1226 	 * Reg # 0 is the Global register set
1227 	 * Reg # 1 is the ETX register set
1228 	 * Reg # 2 is the ERX register set
1229 	 * Reg # 3 is the BigMAC register set.
1230 	 * Reg # 4 is the MIF register set
1231 	 */
1232 	if (ddi_dev_nregs(dip, &regno) != (DDI_SUCCESS)) {
1233 		HME_FAULT_MSG2(hmep, SEVERITY_HIGH, INIT_MSG,
1234 		    ddi_nregs_fail_msg, regno);
1235 		goto error_state;
1236 	}
1237 
1238 	switch (regno) {
1239 	case 5:
1240 		hmep->hme_cheerio_mode = 0;
1241 		break;
1242 	case 2:
1243 	case 3: /* for hot swap/plug, there will be 3 entries in "reg" prop */
1244 		hmep->hme_cheerio_mode = 1;
1245 		break;
1246 	default:
1247 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
1248 		    bad_num_regs_msg);
1249 		goto error_state;
1250 	}
1251 
1252 	/* Initialize device attributes structure */
1253 	hmep->hme_dev_attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
1254 
1255 	if (hmep->hme_cheerio_mode)
1256 		hmep->hme_dev_attr.devacc_attr_endian_flags =
1257 		    DDI_STRUCTURE_LE_ACC;
1258 	else
1259 		hmep->hme_dev_attr.devacc_attr_endian_flags =
1260 		    DDI_STRUCTURE_BE_ACC;
1261 
1262 	hmep->hme_dev_attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
1263 
1264 	if (hmep->hme_cheerio_mode) {
1265 		uint8_t		oldLT;
1266 		uint8_t		newLT = 0;
1267 		dev_info_t	*pdip;
1268 		const char	*pdrvname;
1269 
1270 		/*
1271 		 * Map the PCI config space
1272 		 */
1273 		if (pci_config_setup(dip, &hmep->pci_config_handle) !=
1274 		    DDI_SUCCESS) {
1275 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1276 			    "pci_config_setup() failed..");
1277 			goto error_state;
1278 		}
1279 
1280 		if (ddi_regs_map_setup(dip, 1,
1281 		    (caddr_t *)&(hmep->hme_globregp), 0, 0,
1282 		    &hmep->hme_dev_attr, &hmep->hme_globregh)) {
1283 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1284 			    mregs_4global_reg_fail_msg);
1285 			goto error_unmap;
1286 		}
1287 		hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh =
1288 		    hmep->hme_mifregh = hmep->hme_globregh;
1289 
1290 		hmep->hme_etxregp =
1291 		    (void *)(((caddr_t)hmep->hme_globregp) + 0x2000);
1292 		hmep->hme_erxregp =
1293 		    (void *)(((caddr_t)hmep->hme_globregp) + 0x4000);
1294 		hmep->hme_bmacregp =
1295 		    (void *)(((caddr_t)hmep->hme_globregp) + 0x6000);
1296 		hmep->hme_mifregp =
1297 		    (void *)(((caddr_t)hmep->hme_globregp) + 0x7000);
1298 
1299 		/*
1300 		 * Get parent pci bridge info.
1301 		 */
1302 		pdip = ddi_get_parent(dip);
1303 		pdrvname = ddi_driver_name(pdip);
1304 
1305 		oldLT = pci_config_get8(hmep->pci_config_handle,
1306 		    PCI_CONF_LATENCY_TIMER);
1307 		/*
1308 		 * Honor value set in /etc/system
1309 		 * "set hme:pci_latency_timer=0xYY"
1310 		 */
1311 		if (pci_latency_timer)
1312 			newLT = pci_latency_timer;
1313 		/*
1314 		 * Modify LT for simba
1315 		 */
1316 		else if (strcmp("simba", pdrvname) == 0)
1317 			newLT = 0xf0;
1318 		/*
1319 		 * Ensure minimum cheerio latency timer of 0x50
1320 		 * Usually OBP or pci bridge should set this value
1321 		 * based on cheerio
1322 		 * min_grant * 8(33MHz) = 0x50 = 0xa * 0x8
1323 		 * Some system set cheerio LT at 0x40
1324 		 */
1325 		else if (oldLT < 0x40)
1326 			newLT = 0x50;
1327 
1328 		/*
1329 		 * Now program cheerio's pci latency timer with newLT
1330 		 */
1331 		if (newLT)
1332 			pci_config_put8(hmep->pci_config_handle,
1333 			    PCI_CONF_LATENCY_TIMER, (uchar_t)newLT);
1334 	} else { /* Map register sets */
1335 		if (ddi_regs_map_setup(dip, 0,
1336 		    (caddr_t *)&(hmep->hme_globregp), 0, 0,
1337 		    &hmep->hme_dev_attr, &hmep->hme_globregh)) {
1338 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1339 			    mregs_4global_reg_fail_msg);
1340 			goto error_state;
1341 		}
1342 		if (ddi_regs_map_setup(dip, 1,
1343 		    (caddr_t *)&(hmep->hme_etxregp), 0, 0,
1344 		    &hmep->hme_dev_attr, &hmep->hme_etxregh)) {
1345 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1346 			    mregs_4etx_reg_fail_msg);
1347 			goto error_unmap;
1348 		}
1349 		if (ddi_regs_map_setup(dip, 2,
1350 		    (caddr_t *)&(hmep->hme_erxregp), 0, 0,
1351 		    &hmep->hme_dev_attr, &hmep->hme_erxregh)) {
1352 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1353 			    mregs_4erx_reg_fail_msg);
1354 			goto error_unmap;
1355 		}
1356 		if (ddi_regs_map_setup(dip, 3,
1357 		    (caddr_t *)&(hmep->hme_bmacregp), 0, 0,
1358 		    &hmep->hme_dev_attr, &hmep->hme_bmacregh)) {
1359 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1360 			    mregs_4bmac_reg_fail_msg);
1361 			goto error_unmap;
1362 		}
1363 
1364 		if (ddi_regs_map_setup(dip, 4,
1365 		    (caddr_t *)&(hmep->hme_mifregp), 0, 0,
1366 		    &hmep->hme_dev_attr, &hmep->hme_mifregh)) {
1367 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1368 			    mregs_4mif_reg_fail_msg);
1369 			goto error_unmap;
1370 		}
1371 	} /* Endif cheerio_mode */
1372 
1373 	/*
1374 	 * Based on the hm-rev, set some capabilities
1375 	 * Set up default capabilities for HM 2.0
1376 	 */
1377 	hmep->hme_frame_enable = 0;
1378 	hmep->hme_lance_mode_enable = 0;
1379 	hmep->hme_rxcv_enable = 0;
1380 
1381 	/* NEW routine to get the properties */
1382 
1383 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, hmep->dip, 0, "hm-rev",
1384 	    (caddr_t)&hm_rev, &prop_len) == DDI_PROP_SUCCESS) {
1385 
1386 		hmep->asic_rev = hm_rev;
1387 		hmeget_hm_rev_property(hmep);
1388 	} else {
1389 		/*
1390 		 * hm_rev property not found so, this is
1391 		 * case of hot insertion of card without interpreting fcode.
1392 		 * Get it from revid in config space after mapping it.
1393 		 */
1394 		if (ddi_regs_map_setup(hmep->dip, 0, (caddr_t *)&cfg_ptr,
1395 		    0, 0, &hmep->hme_dev_attr, &cfg_handle)) {
1396 			return (DDI_FAILURE);
1397 		}
1398 		/*
1399 		 * Since this is cheerio-based PCI card, we write 0xC in the
1400 		 * top 4 bits(4-7) of hm-rev and retain the bottom(0-3) bits
1401 		 * for Cheerio version(1.0 or 2.0 = 0xC0 or 0xC1)
1402 		 */
1403 		hm_rev = ddi_get8(cfg_handle, &cfg_ptr->revid);
1404 		hm_rev = HME_1C0_REVID | (hm_rev & HME_REV_VERS_MASK);
1405 		hmep->asic_rev = hm_rev;
1406 		if (ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP,
1407 		    "hm-rev", (caddr_t)&hm_rev, sizeof (hm_rev)) !=
1408 		    DDI_SUCCESS) {
1409 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTOCONFIG_MSG,
1410 			    "ddi_prop_create error for hm_rev");
1411 		}
1412 		ddi_regs_map_free(&cfg_handle);
1413 
1414 		hmeget_hm_rev_property(hmep);
1415 
1416 		/* get info via VPD */
1417 		if (hmeget_promprops(dip) != DDI_SUCCESS) {
1418 			HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, AUTOCONFIG_MSG,
1419 			    "no promprops");
1420 		}
1421 	}
1422 
1423 	if (ddi_intr_hilevel(dip, 0)) {
1424 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, NFATAL_ERR_MSG,
1425 		    " high-level interrupts are not supported");
1426 		goto error_unmap;
1427 	}
1428 
1429 	/*
1430 	 * Get intr. block cookie so that mutex locks can be initialized.
1431 	 */
1432 	if (ddi_get_iblock_cookie(dip, 0, &hmep->hme_cookie) != DDI_SUCCESS)
1433 		goto error_unmap;
1434 
1435 	/*
1436 	 * Initialize mutex's for this device.
1437 	 */
1438 	mutex_init(&hmep->hme_xmitlock, NULL, MUTEX_DRIVER, hmep->hme_cookie);
1439 	mutex_init(&hmep->hme_intrlock, NULL, MUTEX_DRIVER, hmep->hme_cookie);
1440 
1441 	/*
1442 	 * Quiesce the hardware.
1443 	 */
1444 	(void) hmestop(hmep);
1445 
1446 	/*
1447 	 * Add interrupt to system
1448 	 */
1449 	if (ddi_add_intr(dip, 0, (ddi_iblock_cookie_t *)NULL,
1450 	    (ddi_idevice_cookie_t *)NULL, hmeintr, (caddr_t)hmep)) {
1451 		HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, CONFIG_MSG,
1452 		    add_intr_fail_msg);
1453 		goto error_mutex;
1454 	}
1455 
1456 	/*
1457 	 * Set up the ethernet mac address.
1458 	 */
1459 	hme_setup_mac_address(hmep, dip);
1460 
1461 	if (!hmeinit_xfer_params(hmep))
1462 		goto error_intr;
1463 
1464 	if (hmeburstsizes(hmep) == DDI_FAILURE) {
1465 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG, burst_size_msg);
1466 		goto error_intr;
1467 	}
1468 
1469 	if (hmeallocthings(hmep) != DDI_SUCCESS) {
1470 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG,
1471 		    "resource allocation failed");
1472 		goto error_intr;
1473 	}
1474 
1475 	if (hmeallocbufs(hmep) != DDI_SUCCESS) {
1476 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG,
1477 		    "buffer allocation failed");
1478 		goto error_intr;
1479 	}
1480 
1481 	hmestatinit(hmep);
1482 
1483 	/* our external (preferred) PHY is at address 0 */
1484 	(void) ddi_prop_update_int(DDI_DEV_T_NONE, dip, "first-phy", 0);
1485 
1486 	hmep->hme_mii = mii_alloc(hmep, dip, &hme_mii_ops);
1487 	if (hmep->hme_mii == NULL) {
1488 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG,
1489 		    "mii_alloc failed");
1490 		goto error_intr;
1491 	}
1492 	/* force a probe for the PHY */
1493 	mii_probe(hmep->hme_mii);
1494 
1495 	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
1496 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, CONFIG_MSG,
1497 		    "mac_alloc failed");
1498 		goto error_intr;
1499 	}
1500 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
1501 	macp->m_driver = hmep;
1502 	macp->m_dip = dip;
1503 	macp->m_src_addr = hmep->hme_ouraddr.ether_addr_octet;
1504 	macp->m_callbacks = &hme_m_callbacks;
1505 	macp->m_min_sdu = 0;
1506 	macp->m_max_sdu = ETHERMTU;
1507 	macp->m_margin = VLAN_TAGSZ;
1508 	macp->m_priv_props = hme_priv_prop;
1509 	macp->m_priv_prop_count =
1510 	    sizeof (hme_priv_prop) / sizeof (hme_priv_prop[0]);
1511 	if (mac_register(macp, &hmep->hme_mh) != 0) {
1512 		mac_free(macp);
1513 		goto error_intr;
1514 	}
1515 
1516 	mac_free(macp);
1517 
1518 	ddi_report_dev(dip);
1519 	return (DDI_SUCCESS);
1520 
1521 	/*
1522 	 * Failure Exit
1523 	 */
1524 
1525 error_intr:
1526 	if (hmep->hme_cookie)
1527 		ddi_remove_intr(dip, 0, (ddi_iblock_cookie_t)0);
1528 
1529 	if (hmep->hme_mii)
1530 		mii_free(hmep->hme_mii);
1531 
1532 error_mutex:
1533 	mutex_destroy(&hmep->hme_xmitlock);
1534 	mutex_destroy(&hmep->hme_intrlock);
1535 
1536 error_unmap:
1537 	if (hmep->hme_globregh)
1538 		ddi_regs_map_free(&hmep->hme_globregh);
1539 	if (hmep->hme_cheerio_mode == 0) {
1540 		if (hmep->hme_etxregh)
1541 			ddi_regs_map_free(&hmep->hme_etxregh);
1542 		if (hmep->hme_erxregh)
1543 			ddi_regs_map_free(&hmep->hme_erxregh);
1544 		if (hmep->hme_bmacregh)
1545 			ddi_regs_map_free(&hmep->hme_bmacregh);
1546 		if (hmep->hme_mifregh)
1547 			ddi_regs_map_free(&hmep->hme_mifregh);
1548 	} else {
1549 		if (hmep->pci_config_handle)
1550 			(void) pci_config_teardown(&hmep->pci_config_handle);
1551 		hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh =
1552 		    hmep->hme_mifregh = hmep->hme_globregh = NULL;
1553 	}
1554 
1555 error_state:
1556 	hmefreethings(hmep);
1557 	hmefreebufs(hmep);
1558 
1559 	if (hmep) {
1560 		kmem_free((caddr_t)hmep, sizeof (*hmep));
1561 		ddi_set_driver_private(dip, NULL);
1562 	}
1563 
1564 	return (DDI_FAILURE);
1565 }
1566 
1567 int
1568 hmedetach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1569 {
1570 	struct hme *hmep;
1571 
1572 	if ((hmep = ddi_get_driver_private(dip)) == NULL)
1573 		return (DDI_FAILURE);
1574 
1575 	switch (cmd) {
1576 	case DDI_DETACH:
1577 		break;
1578 
1579 	case DDI_SUSPEND:
1580 		mii_suspend(hmep->hme_mii);
1581 		hmep->hme_flags |= HMESUSPENDED;
1582 		hmeuninit(hmep);
1583 		return (DDI_SUCCESS);
1584 
1585 	default:
1586 		return (DDI_FAILURE);
1587 	}
1588 
1589 
1590 	if (mac_unregister(hmep->hme_mh) != 0) {
1591 		return (DDI_FAILURE);
1592 	}
1593 
1594 	/*
1595 	 * Make driver quiescent, we don't want to prevent the
1596 	 * detach on failure.  Note that this should be redundant,
1597 	 * since mac_stop should already have called hmeuninit().
1598 	 */
1599 	if (!(hmep->hme_flags & HMESUSPENDED)) {
1600 		(void) hmestop(hmep);
1601 	}
1602 
1603 	if (hmep->hme_mii)
1604 		mii_free(hmep->hme_mii);
1605 
1606 	/*
1607 	 * Remove instance of the intr
1608 	 */
1609 	ddi_remove_intr(dip, 0, (ddi_iblock_cookie_t)0);
1610 
1611 	/*
1612 	 * Unregister kstats.
1613 	 */
1614 	if (hmep->hme_ksp != NULL)
1615 		kstat_delete(hmep->hme_ksp);
1616 	if (hmep->hme_intrstats != NULL)
1617 		kstat_delete(hmep->hme_intrstats);
1618 
1619 	hmep->hme_ksp = NULL;
1620 	hmep->hme_intrstats = NULL;
1621 
1622 	/*
1623 	 * Destroy all mutexes and data structures allocated during
1624 	 * attach time.
1625 	 *
1626 	 * Note: at this time we should be the only thread accessing
1627 	 * the structures for this instance.
1628 	 */
1629 
1630 	if (hmep->hme_globregh)
1631 		ddi_regs_map_free(&hmep->hme_globregh);
1632 	if (hmep->hme_cheerio_mode == 0) {
1633 		if (hmep->hme_etxregh)
1634 			ddi_regs_map_free(&hmep->hme_etxregh);
1635 		if (hmep->hme_erxregh)
1636 			ddi_regs_map_free(&hmep->hme_erxregh);
1637 		if (hmep->hme_bmacregh)
1638 			ddi_regs_map_free(&hmep->hme_bmacregh);
1639 		if (hmep->hme_mifregh)
1640 			ddi_regs_map_free(&hmep->hme_mifregh);
1641 	} else {
1642 		if (hmep->pci_config_handle)
1643 			(void) pci_config_teardown(&hmep->pci_config_handle);
1644 		hmep->hme_etxregh = hmep->hme_erxregh = hmep->hme_bmacregh =
1645 		    hmep->hme_mifregh = hmep->hme_globregh = NULL;
1646 	}
1647 
1648 	mutex_destroy(&hmep->hme_xmitlock);
1649 	mutex_destroy(&hmep->hme_intrlock);
1650 
1651 	hmefreethings(hmep);
1652 	hmefreebufs(hmep);
1653 
1654 	ddi_set_driver_private(dip, NULL);
1655 	kmem_free(hmep, sizeof (struct hme));
1656 
1657 	return (DDI_SUCCESS);
1658 }
1659 
1660 int
1661 hmequiesce(dev_info_t *dip)
1662 {
1663 	struct hme *hmep;
1664 
1665 	if ((hmep = ddi_get_driver_private(dip)) == NULL)
1666 		return (DDI_FAILURE);
1667 
1668 	(void) hmestop(hmep);
1669 	return (DDI_SUCCESS);
1670 }
1671 
1672 static boolean_t
1673 hmeinit_xfer_params(struct hme *hmep)
1674 {
1675 	int hme_ipg1_conf, hme_ipg2_conf;
1676 	int hme_ipg0_conf, hme_lance_mode_conf;
1677 	int prop_len = sizeof (int);
1678 	dev_info_t *dip;
1679 
1680 	dip = hmep->dip;
1681 
1682 	/*
1683 	 * Set up the start-up values for user-configurable parameters
1684 	 * Get the values from the global variables first.
1685 	 * Use the MASK to limit the value to allowed maximum.
1686 	 */
1687 	hmep->hme_ipg1 = hme_ipg1 & HME_MASK_8BIT;
1688 	hmep->hme_ipg2 = hme_ipg2 & HME_MASK_8BIT;
1689 	hmep->hme_ipg0 = hme_ipg0 & HME_MASK_5BIT;
1690 
1691 	/*
1692 	 * Get the parameter values configured in .conf file.
1693 	 */
1694 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg1",
1695 	    (caddr_t)&hme_ipg1_conf, &prop_len) == DDI_PROP_SUCCESS) {
1696 		hmep->hme_ipg1 = hme_ipg1_conf & HME_MASK_8BIT;
1697 	}
1698 
1699 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg2",
1700 	    (caddr_t)&hme_ipg2_conf, &prop_len) == DDI_PROP_SUCCESS) {
1701 		hmep->hme_ipg2 = hme_ipg2_conf & HME_MASK_8BIT;
1702 	}
1703 
1704 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "ipg0",
1705 	    (caddr_t)&hme_ipg0_conf, &prop_len) == DDI_PROP_SUCCESS) {
1706 		hmep->hme_ipg0 = hme_ipg0_conf & HME_MASK_5BIT;
1707 	}
1708 
1709 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, 0, "lance_mode",
1710 	    (caddr_t)&hme_lance_mode_conf, &prop_len) == DDI_PROP_SUCCESS) {
1711 		hmep->hme_lance_mode = hme_lance_mode_conf & HME_MASK_1BIT;
1712 	}
1713 
1714 	return (B_TRUE);
1715 }
1716 
1717 /*
1718  * Return 0 upon success, 1 on failure.
1719  */
1720 static uint_t
1721 hmestop(struct hme *hmep)
1722 {
1723 	/*
1724 	 * Disable the Tx dma engine.
1725 	 */
1726 	PUT_ETXREG(config, (GET_ETXREG(config) & ~HMET_CONFIG_TXDMA_EN));
1727 	HMEDELAY(((GET_ETXREG(state_mach) & 0x1f) == 0x1), HMEMAXRSTDELAY);
1728 
1729 	/*
1730 	 * Disable the Rx dma engine.
1731 	 */
1732 	PUT_ERXREG(config, (GET_ERXREG(config) & ~HMER_CONFIG_RXDMA_EN));
1733 	HMEDELAY(((GET_ERXREG(state_mach) & 0x3f) == 0), HMEMAXRSTDELAY);
1734 
1735 	/*
1736 	 * By this time all things should be quiet, so hit the
1737 	 * chip with a reset.
1738 	 */
1739 	PUT_GLOBREG(reset, HMEG_RESET_GLOBAL);
1740 
1741 	HMEDELAY((GET_GLOBREG(reset) == 0), HMEMAXRSTDELAY);
1742 	if (GET_GLOBREG(reset)) {
1743 		return (1);
1744 	}
1745 
1746 	CHECK_GLOBREG();
1747 	return (0);
1748 }
1749 
1750 static int
1751 hmestat_kstat_update(kstat_t *ksp, int rw)
1752 {
1753 	struct hme *hmep;
1754 	struct hmekstat *hkp;
1755 
1756 	hmep = (struct hme *)ksp->ks_private;
1757 	hkp = (struct hmekstat *)ksp->ks_data;
1758 
1759 	if (rw != KSTAT_READ)
1760 		return (EACCES);
1761 
1762 	/*
1763 	 * Update all the stats by reading all the counter registers.
1764 	 * Counter register stats are not updated till they overflow
1765 	 * and interrupt.
1766 	 */
1767 
1768 	mutex_enter(&hmep->hme_xmitlock);
1769 	if (hmep->hme_flags & HMERUNNING) {
1770 		hmereclaim(hmep);
1771 		hmesavecntrs(hmep);
1772 	}
1773 	mutex_exit(&hmep->hme_xmitlock);
1774 
1775 	hkp->hk_cvc.value.ul		= hmep->hme_cvc;
1776 	hkp->hk_lenerr.value.ul		= hmep->hme_lenerr;
1777 	hkp->hk_buff.value.ul		= hmep->hme_buff;
1778 	hkp->hk_missed.value.ul		= hmep->hme_missed;
1779 	hkp->hk_allocbfail.value.ul	= hmep->hme_allocbfail;
1780 	hkp->hk_babl.value.ul		= hmep->hme_babl;
1781 	hkp->hk_tmder.value.ul		= hmep->hme_tmder;
1782 	hkp->hk_txlaterr.value.ul	= hmep->hme_txlaterr;
1783 	hkp->hk_rxlaterr.value.ul	= hmep->hme_rxlaterr;
1784 	hkp->hk_slvparerr.value.ul	= hmep->hme_slvparerr;
1785 	hkp->hk_txparerr.value.ul	= hmep->hme_txparerr;
1786 	hkp->hk_rxparerr.value.ul	= hmep->hme_rxparerr;
1787 	hkp->hk_slverrack.value.ul	= hmep->hme_slverrack;
1788 	hkp->hk_txerrack.value.ul	= hmep->hme_txerrack;
1789 	hkp->hk_rxerrack.value.ul	= hmep->hme_rxerrack;
1790 	hkp->hk_txtagerr.value.ul	= hmep->hme_txtagerr;
1791 	hkp->hk_rxtagerr.value.ul	= hmep->hme_rxtagerr;
1792 	hkp->hk_eoperr.value.ul		= hmep->hme_eoperr;
1793 	hkp->hk_notmds.value.ul		= hmep->hme_notmds;
1794 	hkp->hk_notbufs.value.ul	= hmep->hme_notbufs;
1795 	hkp->hk_norbufs.value.ul	= hmep->hme_norbufs;
1796 
1797 	/*
1798 	 * Debug kstats
1799 	 */
1800 	hkp->hk_inits.value.ul		= hmep->inits;
1801 	hkp->hk_phyfail.value.ul	= hmep->phyfail;
1802 
1803 	/*
1804 	 * xcvr kstats
1805 	 */
1806 	hkp->hk_asic_rev.value.ul	= hmep->asic_rev;
1807 
1808 	return (0);
1809 }
1810 
1811 static void
1812 hmestatinit(struct hme *hmep)
1813 {
1814 	struct	kstat	*ksp;
1815 	struct	hmekstat	*hkp;
1816 	const char *driver;
1817 	int	instance;
1818 	char	buf[16];
1819 
1820 	instance = hmep->instance;
1821 	driver = ddi_driver_name(hmep->dip);
1822 
1823 	if ((ksp = kstat_create(driver, instance,
1824 	    "driver_info", "net", KSTAT_TYPE_NAMED,
1825 	    sizeof (struct hmekstat) / sizeof (kstat_named_t), 0)) == NULL) {
1826 		HME_FAULT_MSG1(hmep, SEVERITY_UNKNOWN, INIT_MSG,
1827 		    "kstat_create failed");
1828 		return;
1829 	}
1830 
1831 	(void) snprintf(buf, sizeof (buf), "%sc%d", driver, instance);
1832 	hmep->hme_intrstats = kstat_create(driver, instance, buf, "controller",
1833 	    KSTAT_TYPE_INTR, 1, KSTAT_FLAG_PERSISTENT);
1834 	if (hmep->hme_intrstats)
1835 		kstat_install(hmep->hme_intrstats);
1836 
1837 	hmep->hme_ksp = ksp;
1838 	hkp = (struct hmekstat *)ksp->ks_data;
1839 	kstat_named_init(&hkp->hk_cvc,			"code_violations",
1840 	    KSTAT_DATA_ULONG);
1841 	kstat_named_init(&hkp->hk_lenerr,		"len_errors",
1842 	    KSTAT_DATA_ULONG);
1843 	kstat_named_init(&hkp->hk_buff,			"buff",
1844 	    KSTAT_DATA_ULONG);
1845 	kstat_named_init(&hkp->hk_missed,		"missed",
1846 	    KSTAT_DATA_ULONG);
1847 	kstat_named_init(&hkp->hk_nocanput,		"nocanput",
1848 	    KSTAT_DATA_ULONG);
1849 	kstat_named_init(&hkp->hk_allocbfail,		"allocbfail",
1850 	    KSTAT_DATA_ULONG);
1851 	kstat_named_init(&hkp->hk_babl,			"babble",
1852 	    KSTAT_DATA_ULONG);
1853 	kstat_named_init(&hkp->hk_tmder,		"tmd_error",
1854 	    KSTAT_DATA_ULONG);
1855 	kstat_named_init(&hkp->hk_txlaterr,		"tx_late_error",
1856 	    KSTAT_DATA_ULONG);
1857 	kstat_named_init(&hkp->hk_rxlaterr,		"rx_late_error",
1858 	    KSTAT_DATA_ULONG);
1859 	kstat_named_init(&hkp->hk_slvparerr,		"slv_parity_error",
1860 	    KSTAT_DATA_ULONG);
1861 	kstat_named_init(&hkp->hk_txparerr,		"tx_parity_error",
1862 	    KSTAT_DATA_ULONG);
1863 	kstat_named_init(&hkp->hk_rxparerr,		"rx_parity_error",
1864 	    KSTAT_DATA_ULONG);
1865 	kstat_named_init(&hkp->hk_slverrack,		"slv_error_ack",
1866 	    KSTAT_DATA_ULONG);
1867 	kstat_named_init(&hkp->hk_txerrack,		"tx_error_ack",
1868 	    KSTAT_DATA_ULONG);
1869 	kstat_named_init(&hkp->hk_rxerrack,		"rx_error_ack",
1870 	    KSTAT_DATA_ULONG);
1871 	kstat_named_init(&hkp->hk_txtagerr,		"tx_tag_error",
1872 	    KSTAT_DATA_ULONG);
1873 	kstat_named_init(&hkp->hk_rxtagerr,		"rx_tag_error",
1874 	    KSTAT_DATA_ULONG);
1875 	kstat_named_init(&hkp->hk_eoperr,		"eop_error",
1876 	    KSTAT_DATA_ULONG);
1877 	kstat_named_init(&hkp->hk_notmds,		"no_tmds",
1878 	    KSTAT_DATA_ULONG);
1879 	kstat_named_init(&hkp->hk_notbufs,		"no_tbufs",
1880 	    KSTAT_DATA_ULONG);
1881 	kstat_named_init(&hkp->hk_norbufs,		"no_rbufs",
1882 	    KSTAT_DATA_ULONG);
1883 
1884 	/*
1885 	 * Debugging kstats
1886 	 */
1887 	kstat_named_init(&hkp->hk_inits,		"inits",
1888 	    KSTAT_DATA_ULONG);
1889 	kstat_named_init(&hkp->hk_phyfail,		"phy_failures",
1890 	    KSTAT_DATA_ULONG);
1891 
1892 	/*
1893 	 * xcvr kstats
1894 	 */
1895 	kstat_named_init(&hkp->hk_asic_rev,		"asic_rev",
1896 	    KSTAT_DATA_ULONG);
1897 
1898 	ksp->ks_update = hmestat_kstat_update;
1899 	ksp->ks_private = (void *) hmep;
1900 	kstat_install(ksp);
1901 }
1902 
1903 int
1904 hme_m_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t flags,
1905     uint_t sz, void *val, uint_t *perm)
1906 {
1907 	struct hme *hmep = arg;
1908 	int value;
1909 	boolean_t is_default;
1910 	int rv;
1911 
1912 	rv = mii_m_getprop(hmep->hme_mii, name, num, flags, sz, val, perm);
1913 	if (rv != ENOTSUP)
1914 		return (rv);
1915 
1916 	switch (num) {
1917 	case MAC_PROP_PRIVATE:
1918 		break;
1919 	default:
1920 		return (ENOTSUP);
1921 	}
1922 
1923 	*perm = MAC_PROP_PERM_RW;
1924 
1925 	is_default = (flags & MAC_PROP_DEFAULT) ? B_TRUE : B_FALSE;
1926 	if (strcmp(name, "_ipg0") == 0) {
1927 		value = is_default ? hme_ipg0 : hmep->hme_ipg0;
1928 
1929 	} else if (strcmp(name, "_ipg1") == 0) {
1930 		value = is_default ? hme_ipg1 : hmep->hme_ipg1;
1931 	} else if (strcmp(name, "_ipg2") == 0) {
1932 		value = is_default ? hme_ipg2 : hmep->hme_ipg2;
1933 	} else if (strcmp(name, "_lance_mode") == 0) {
1934 		value = is_default ? hme_lance_mode : hmep->hme_lance_mode;
1935 	} else {
1936 		return (ENOTSUP);
1937 	}
1938 	(void) snprintf(val, sz, "%d", value);
1939 	return (0);
1940 }
1941 
1942 int
1943 hme_m_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
1944     const void *val)
1945 {
1946 	struct hme *hmep = arg;
1947 	int rv;
1948 	long lval;
1949 	boolean_t init = B_FALSE;
1950 
1951 	rv = mii_m_setprop(hmep->hme_mii, name, num, sz, val);
1952 	if (rv != ENOTSUP)
1953 		return (rv);
1954 	rv = 0;
1955 
1956 	switch (num) {
1957 	case MAC_PROP_PRIVATE:
1958 		break;
1959 	default:
1960 		return (ENOTSUP);
1961 	}
1962 
1963 	(void) ddi_strtol(val, NULL, 0, &lval);
1964 
1965 	if (strcmp(name, "_ipg1") == 0) {
1966 		if ((lval >= 0) && (lval <= 255)) {
1967 			hmep->hme_ipg1 = lval & 0xff;
1968 			init = B_TRUE;
1969 		} else {
1970 			return (EINVAL);
1971 		}
1972 
1973 	} else if (strcmp(name, "_ipg2") == 0) {
1974 		if ((lval >= 0) && (lval <= 255)) {
1975 			hmep->hme_ipg2 = lval & 0xff;
1976 			init = B_TRUE;
1977 		} else {
1978 			return (EINVAL);
1979 		}
1980 
1981 	} else if (strcmp(name, "_ipg0") == 0) {
1982 		if ((lval >= 0) && (lval <= 31)) {
1983 			hmep->hme_ipg0 = lval & 0xff;
1984 			init = B_TRUE;
1985 		} else {
1986 			return (EINVAL);
1987 		}
1988 	} else if (strcmp(name, "_lance_mode") == 0) {
1989 		if ((lval >= 0) && (lval <= 1)) {
1990 			hmep->hme_lance_mode = lval & 0xff;
1991 			init = B_TRUE;
1992 		} else {
1993 			return (EINVAL);
1994 		}
1995 
1996 	} else {
1997 		rv = ENOTSUP;
1998 	}
1999 
2000 	if (init) {
2001 		(void) hmeinit(hmep);
2002 	}
2003 	return (rv);
2004 }
2005 
2006 
2007 /*ARGSUSED*/
2008 static boolean_t
2009 hme_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
2010 {
2011 	switch (cap) {
2012 	case MAC_CAPAB_HCKSUM:
2013 		*(uint32_t *)cap_data = HCKSUM_INET_PARTIAL;
2014 		return (B_TRUE);
2015 	default:
2016 		return (B_FALSE);
2017 	}
2018 }
2019 
2020 static int
2021 hme_m_promisc(void *arg, boolean_t on)
2022 {
2023 	struct hme *hmep = arg;
2024 
2025 	hmep->hme_promisc = on;
2026 	(void) hmeinit(hmep);
2027 	return (0);
2028 }
2029 
2030 static int
2031 hme_m_unicst(void *arg, const uint8_t *macaddr)
2032 {
2033 	struct hme *hmep = arg;
2034 
2035 	/*
2036 	 * Set new interface local address and re-init device.
2037 	 * This is destructive to any other streams attached
2038 	 * to this device.
2039 	 */
2040 	mutex_enter(&hmep->hme_intrlock);
2041 	bcopy(macaddr, &hmep->hme_ouraddr, ETHERADDRL);
2042 	mutex_exit(&hmep->hme_intrlock);
2043 	(void) hmeinit(hmep);
2044 	return (0);
2045 }
2046 
2047 static int
2048 hme_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr)
2049 {
2050 	struct hme	*hmep = arg;
2051 	uint32_t	ladrf_bit;
2052 	boolean_t	doinit = B_FALSE;
2053 
2054 	/*
2055 	 * If this address's bit was not already set in the local address
2056 	 * filter, add it and re-initialize the Hardware.
2057 	 */
2058 	ladrf_bit = hmeladrf_bit(macaddr);
2059 
2060 	mutex_enter(&hmep->hme_intrlock);
2061 	if (add) {
2062 		hmep->hme_ladrf_refcnt[ladrf_bit]++;
2063 		if (hmep->hme_ladrf_refcnt[ladrf_bit] == 1) {
2064 			hmep->hme_ladrf[ladrf_bit >> 4] |=
2065 			    1 << (ladrf_bit & 0xf);
2066 			hmep->hme_multi++;
2067 			doinit = B_TRUE;
2068 		}
2069 	} else {
2070 		hmep->hme_ladrf_refcnt[ladrf_bit]--;
2071 		if (hmep->hme_ladrf_refcnt[ladrf_bit] == 0) {
2072 			hmep->hme_ladrf[ladrf_bit >> 4] &=
2073 			    ~(1 << (ladrf_bit & 0xf));
2074 			doinit = B_TRUE;
2075 		}
2076 	}
2077 	mutex_exit(&hmep->hme_intrlock);
2078 
2079 	if (doinit) {
2080 		(void) hmeinit(hmep);
2081 	}
2082 
2083 	return (0);
2084 }
2085 
2086 static int
2087 hme_m_start(void *arg)
2088 {
2089 	struct hme *hmep = arg;
2090 
2091 	if (hmeinit(hmep) != 0) {
2092 		/* initialization failed -- really want DL_INITFAILED */
2093 		return (EIO);
2094 	} else {
2095 		hmep->hme_started = B_TRUE;
2096 		mii_start(hmep->hme_mii);
2097 		return (0);
2098 	}
2099 }
2100 
2101 static void
2102 hme_m_stop(void *arg)
2103 {
2104 	struct hme *hmep = arg;
2105 
2106 	mii_stop(hmep->hme_mii);
2107 	hmep->hme_started = B_FALSE;
2108 	hmeuninit(hmep);
2109 }
2110 
2111 static int
2112 hme_m_stat(void *arg, uint_t stat, uint64_t *val)
2113 {
2114 	struct hme	*hmep = arg;
2115 
2116 	mutex_enter(&hmep->hme_xmitlock);
2117 	if (hmep->hme_flags & HMERUNNING) {
2118 		hmereclaim(hmep);
2119 		hmesavecntrs(hmep);
2120 	}
2121 	mutex_exit(&hmep->hme_xmitlock);
2122 
2123 
2124 	if (mii_m_getstat(hmep->hme_mii, stat, val) == 0) {
2125 		return (0);
2126 	}
2127 	switch (stat) {
2128 	case MAC_STAT_IPACKETS:
2129 		*val = hmep->hme_ipackets;
2130 		break;
2131 	case MAC_STAT_RBYTES:
2132 		*val = hmep->hme_rbytes;
2133 		break;
2134 	case MAC_STAT_IERRORS:
2135 		*val = hmep->hme_ierrors;
2136 		break;
2137 	case MAC_STAT_OPACKETS:
2138 		*val = hmep->hme_opackets;
2139 		break;
2140 	case MAC_STAT_OBYTES:
2141 		*val = hmep->hme_obytes;
2142 		break;
2143 	case MAC_STAT_OERRORS:
2144 		*val = hmep->hme_oerrors;
2145 		break;
2146 	case MAC_STAT_MULTIRCV:
2147 		*val = hmep->hme_multircv;
2148 		break;
2149 	case MAC_STAT_MULTIXMT:
2150 		*val = hmep->hme_multixmt;
2151 		break;
2152 	case MAC_STAT_BRDCSTRCV:
2153 		*val = hmep->hme_brdcstrcv;
2154 		break;
2155 	case MAC_STAT_BRDCSTXMT:
2156 		*val = hmep->hme_brdcstxmt;
2157 		break;
2158 	case MAC_STAT_UNDERFLOWS:
2159 		*val = hmep->hme_uflo;
2160 		break;
2161 	case MAC_STAT_OVERFLOWS:
2162 		*val = hmep->hme_oflo;
2163 		break;
2164 	case MAC_STAT_COLLISIONS:
2165 		*val = hmep->hme_coll;
2166 		break;
2167 	case MAC_STAT_NORCVBUF:
2168 		*val = hmep->hme_norcvbuf;
2169 		break;
2170 	case MAC_STAT_NOXMTBUF:
2171 		*val = hmep->hme_noxmtbuf;
2172 		break;
2173 	case ETHER_STAT_LINK_DUPLEX:
2174 		*val = hmep->hme_duplex;
2175 		break;
2176 	case ETHER_STAT_ALIGN_ERRORS:
2177 		*val = hmep->hme_align_errors;
2178 		break;
2179 	case ETHER_STAT_FCS_ERRORS:
2180 		*val = hmep->hme_fcs_errors;
2181 		break;
2182 	case ETHER_STAT_EX_COLLISIONS:
2183 		*val = hmep->hme_excol;
2184 		break;
2185 	case ETHER_STAT_DEFER_XMTS:
2186 		*val = hmep->hme_defer_xmts;
2187 		break;
2188 	case ETHER_STAT_SQE_ERRORS:
2189 		*val = hmep->hme_sqe_errors;
2190 		break;
2191 	case ETHER_STAT_FIRST_COLLISIONS:
2192 		*val = hmep->hme_fstcol;
2193 		break;
2194 	case ETHER_STAT_TX_LATE_COLLISIONS:
2195 		*val = hmep->hme_tlcol;
2196 		break;
2197 	case ETHER_STAT_TOOLONG_ERRORS:
2198 		*val = hmep->hme_toolong_errors;
2199 		break;
2200 	case ETHER_STAT_TOOSHORT_ERRORS:
2201 		*val = hmep->hme_runt;
2202 		break;
2203 	case ETHER_STAT_CARRIER_ERRORS:
2204 		*val = hmep->hme_carrier_errors;
2205 		break;
2206 	default:
2207 		return (EINVAL);
2208 	}
2209 	return (0);
2210 }
2211 
2212 static mblk_t *
2213 hme_m_tx(void *arg, mblk_t *mp)
2214 {
2215 	struct hme *hmep = arg;
2216 	mblk_t *next;
2217 
2218 	while (mp != NULL) {
2219 		next = mp->b_next;
2220 		mp->b_next = NULL;
2221 		if (!hmestart(hmep, mp)) {
2222 			mp->b_next = next;
2223 			break;
2224 		}
2225 		mp = next;
2226 	}
2227 	return (mp);
2228 }
2229 
2230 /*
2231  * Software IP checksum, for the edge cases that the
2232  * hardware can't handle.  See hmestart for more info.
2233  */
2234 static uint16_t
2235 hme_cksum(void *data, int len)
2236 {
2237 	uint16_t	*words = data;
2238 	int		i, nwords = len / 2;
2239 	uint32_t	sum = 0;
2240 
2241 	/* just add up the words */
2242 	for (i = 0; i < nwords; i++) {
2243 		sum += *words++;
2244 	}
2245 
2246 	/* pick up residual byte ... assume even half-word allocations */
2247 	if (len % 2) {
2248 		sum += (*words & htons(0xff00));
2249 	}
2250 
2251 	sum = (sum >> 16) + (sum & 0xffff);
2252 	sum = (sum >> 16) + (sum & 0xffff);
2253 
2254 	return (~(sum & 0xffff));
2255 }
2256 
2257 static boolean_t
2258 hmestart(struct hme *hmep, mblk_t *mp)
2259 {
2260 	uint32_t	len;
2261 	boolean_t	retval = B_TRUE;
2262 	hmebuf_t	*tbuf;
2263 	uint32_t	txptr;
2264 
2265 	uint32_t	csflags = 0;
2266 	uint32_t	flags;
2267 	uint32_t	start_offset;
2268 	uint32_t	stuff_offset;
2269 
2270 	hcksum_retrieve(mp, NULL, NULL, &start_offset, &stuff_offset,
2271 	    NULL, NULL, &flags);
2272 
2273 	if (flags & HCK_PARTIALCKSUM) {
2274 		if (get_ether_type(mp->b_rptr) == ETHERTYPE_VLAN) {
2275 			start_offset += sizeof (struct ether_header) + 4;
2276 			stuff_offset += sizeof (struct ether_header) + 4;
2277 		} else {
2278 			start_offset += sizeof (struct ether_header);
2279 			stuff_offset += sizeof (struct ether_header);
2280 		}
2281 		csflags = HMETMD_CSENABL |
2282 		    (start_offset << HMETMD_CSSTART_SHIFT) |
2283 		    (stuff_offset << HMETMD_CSSTUFF_SHIFT);
2284 	}
2285 
2286 	mutex_enter(&hmep->hme_xmitlock);
2287 
2288 	if (hmep->hme_flags & HMESUSPENDED) {
2289 		hmep->hme_carrier_errors++;
2290 		hmep->hme_oerrors++;
2291 		goto bad;
2292 	}
2293 
2294 	if (hmep->hme_txindex != hmep->hme_txreclaim) {
2295 		hmereclaim(hmep);
2296 	}
2297 	if ((hmep->hme_txindex - HME_TMDMAX) == hmep->hme_txreclaim)
2298 		goto notmds;
2299 	txptr = hmep->hme_txindex % HME_TMDMAX;
2300 	tbuf = &hmep->hme_tbuf[txptr];
2301 
2302 	/*
2303 	 * Note that for checksum offload, the hardware cannot
2304 	 * generate correct checksums if the packet is smaller than
2305 	 * 64-bytes.  In such a case, we bcopy the packet and use
2306 	 * a software checksum.
2307 	 */
2308 
2309 	len = msgsize(mp);
2310 	if (len < 64) {
2311 		/* zero fill the padding */
2312 		bzero(tbuf->kaddr, 64);
2313 	}
2314 	mcopymsg(mp, tbuf->kaddr);
2315 
2316 	if ((csflags != 0) && (len < 64)) {
2317 		uint16_t sum;
2318 		sum = hme_cksum(tbuf->kaddr + start_offset,
2319 		    len - start_offset);
2320 		bcopy(&sum, tbuf->kaddr + stuff_offset, sizeof (sum));
2321 		csflags = 0;
2322 	}
2323 
2324 	if (ddi_dma_sync(tbuf->dmah, 0, len, DDI_DMA_SYNC_FORDEV) ==
2325 	    DDI_FAILURE) {
2326 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, DDI_MSG,
2327 		    "ddi_dma_sync failed");
2328 	}
2329 
2330 	/*
2331 	 * update MIB II statistics
2332 	 */
2333 	BUMP_OutNUcast(hmep, tbuf->kaddr);
2334 
2335 	PUT_TMD(txptr, tbuf->paddr, len,
2336 	    HMETMD_OWN | HMETMD_SOP | HMETMD_EOP | csflags);
2337 
2338 	HMESYNCTMD(txptr, DDI_DMA_SYNC_FORDEV);
2339 	hmep->hme_txindex++;
2340 
2341 	PUT_ETXREG(txpend, HMET_TXPEND_TDMD);
2342 	CHECK_ETXREG();
2343 
2344 	mutex_exit(&hmep->hme_xmitlock);
2345 
2346 	hmep->hme_starts++;
2347 	return (B_TRUE);
2348 
2349 bad:
2350 	mutex_exit(&hmep->hme_xmitlock);
2351 	freemsg(mp);
2352 	return (B_TRUE);
2353 
2354 notmds:
2355 	hmep->hme_notmds++;
2356 	hmep->hme_wantw = B_TRUE;
2357 	hmereclaim(hmep);
2358 	retval = B_FALSE;
2359 done:
2360 	mutex_exit(&hmep->hme_xmitlock);
2361 
2362 	return (retval);
2363 }
2364 
2365 /*
2366  * Initialize channel.
2367  * Return 0 on success, nonzero on error.
2368  *
2369  * The recommended sequence for initialization is:
2370  * 1. Issue a Global Reset command to the Ethernet Channel.
2371  * 2. Poll the Global_Reset bits until the execution of the reset has been
2372  *    completed.
2373  * 2(a). Use the MIF Frame/Output register to reset the transceiver.
2374  *	 Poll Register 0 to till the Resetbit is 0.
2375  * 2(b). Use the MIF Frame/Output register to set the PHY in in Normal-Op,
2376  *	 100Mbps and Non-Isolated mode. The main point here is to bring the
2377  *	 PHY out of Isolate mode so that it can generate the rx_clk and tx_clk
2378  *	 to the MII interface so that the Bigmac core can correctly reset
2379  *	 upon a software reset.
2380  * 2(c).  Issue another Global Reset command to the Ethernet Channel and poll
2381  *	  the Global_Reset bits till completion.
2382  * 3. Set up all the data structures in the host memory.
2383  * 4. Program the TX_MAC registers/counters (excluding the TX_MAC Configuration
2384  *    Register).
2385  * 5. Program the RX_MAC registers/counters (excluding the RX_MAC Configuration
2386  *    Register).
2387  * 6. Program the Transmit Descriptor Ring Base Address in the ETX.
2388  * 7. Program the Receive Descriptor Ring Base Address in the ERX.
2389  * 8. Program the Global Configuration and the Global Interrupt Mask Registers.
2390  * 9. Program the ETX Configuration register (enable the Transmit DMA channel).
2391  * 10. Program the ERX Configuration register (enable the Receive DMA channel).
2392  * 11. Program the XIF Configuration Register (enable the XIF).
2393  * 12. Program the RX_MAC Configuration Register (Enable the RX_MAC).
2394  * 13. Program the TX_MAC Configuration Register (Enable the TX_MAC).
2395  */
2396 
2397 
2398 #ifdef FEPS_URUN_BUG
2399 static int hme_palen = 32;
2400 #endif
2401 
2402 static int
2403 hmeinit(struct hme *hmep)
2404 {
2405 	uint32_t		i;
2406 	int			ret;
2407 	boolean_t		fdx;
2408 	int			phyad;
2409 
2410 	/*
2411 	 * Lock sequence:
2412 	 *	hme_intrlock, hme_xmitlock.
2413 	 */
2414 	mutex_enter(&hmep->hme_intrlock);
2415 
2416 	/*
2417 	 * Don't touch the hardware if we are suspended.  But don't
2418 	 * fail either.  Some time later we may be resumed, and then
2419 	 * we'll be back here to program the device using the settings
2420 	 * in the soft state.
2421 	 */
2422 	if (hmep->hme_flags & HMESUSPENDED) {
2423 		mutex_exit(&hmep->hme_intrlock);
2424 		return (0);
2425 	}
2426 
2427 	/*
2428 	 * This should prevent us from clearing any interrupts that
2429 	 * may occur by temporarily stopping interrupts from occurring
2430 	 * for a short time.  We need to update the interrupt mask
2431 	 * later in this function.
2432 	 */
2433 	PUT_GLOBREG(intmask, ~HMEG_MASK_MIF_INTR);
2434 
2435 
2436 	/*
2437 	 * Rearranged the mutex acquisition order to solve the deadlock
2438 	 * situation as described in bug ID 4065896.
2439 	 */
2440 
2441 	mutex_enter(&hmep->hme_xmitlock);
2442 
2443 	hmep->hme_flags = 0;
2444 	hmep->hme_wantw = B_FALSE;
2445 
2446 	if (hmep->inits)
2447 		hmesavecntrs(hmep);
2448 
2449 	/*
2450 	 * Perform Global reset of the Sbus/FEPS ENET channel.
2451 	 */
2452 	(void) hmestop(hmep);
2453 
2454 	/*
2455 	 * Clear all descriptors.
2456 	 */
2457 	bzero(hmep->hme_rmdp, HME_RMDMAX * sizeof (struct hme_rmd));
2458 	bzero(hmep->hme_tmdp, HME_TMDMAX * sizeof (struct hme_tmd));
2459 
2460 	/*
2461 	 * Hang out receive buffers.
2462 	 */
2463 	for (i = 0; i < HME_RMDMAX; i++) {
2464 		PUT_RMD(i, hmep->hme_rbuf[i].paddr);
2465 	}
2466 
2467 	/*
2468 	 * DMA sync descriptors.
2469 	 */
2470 	(void) ddi_dma_sync(hmep->hme_rmd_dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
2471 	(void) ddi_dma_sync(hmep->hme_tmd_dmah, 0, 0, DDI_DMA_SYNC_FORDEV);
2472 
2473 	/*
2474 	 * Reset RMD and TMD 'walking' pointers.
2475 	 */
2476 	hmep->hme_rxindex = 0;
2477 	hmep->hme_txindex = hmep->hme_txreclaim = 0;
2478 
2479 	/*
2480 	 * This is the right place to initialize MIF !!!
2481 	 */
2482 
2483 	PUT_MIFREG(mif_imask, HME_MIF_INTMASK);	/* mask all interrupts */
2484 
2485 	if (!hmep->hme_frame_enable)
2486 		PUT_MIFREG(mif_cfg, GET_MIFREG(mif_cfg) | HME_MIF_CFGBB);
2487 	else
2488 		PUT_MIFREG(mif_cfg, GET_MIFREG(mif_cfg) & ~HME_MIF_CFGBB);
2489 						/* enable frame mode */
2490 
2491 	/*
2492 	 * Depending on the transceiver detected, select the source
2493 	 * of the clocks for the MAC. Without the clocks, TX_MAC does
2494 	 * not reset. When the Global Reset is issued to the Sbus/FEPS
2495 	 * ASIC, it selects Internal by default.
2496 	 */
2497 
2498 	switch ((phyad = mii_get_addr(hmep->hme_mii))) {
2499 	case -1:
2500 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, XCVR_MSG, no_xcvr_msg);
2501 		goto init_fail;	/* abort initialization */
2502 
2503 	case HME_INTERNAL_PHYAD:
2504 		PUT_MACREG(xifc, 0);
2505 		break;
2506 	case HME_EXTERNAL_PHYAD:
2507 		/* Isolate the Int. xcvr */
2508 		PUT_MACREG(xifc, BMAC_XIFC_MIIBUFDIS);
2509 		break;
2510 	}
2511 
2512 	hmep->inits++;
2513 
2514 	/*
2515 	 * Initialize BigMAC registers.
2516 	 * First set the tx enable bit in tx config reg to 0 and poll on
2517 	 * it till it turns to 0. Same for rx config, hash and address
2518 	 * filter reg.
2519 	 * Here is the sequence per the spec.
2520 	 * MADD2 - MAC Address 2
2521 	 * MADD1 - MAC Address 1
2522 	 * MADD0 - MAC Address 0
2523 	 * HASH3, HASH2, HASH1, HASH0 for group address
2524 	 * AFR2, AFR1, AFR0 and AFMR for address filter mask
2525 	 * Program RXMIN and RXMAX for packet length if not 802.3
2526 	 * RXCFG - Rx config for not stripping CRC
2527 	 * XXX Anything else to hme configured in RXCFG
2528 	 * IPG1, IPG2, ALIMIT, SLOT, PALEN, PAPAT, TXSFD, JAM, TXMAX, TXMIN
2529 	 * if not 802.3 compliant
2530 	 * XIF register for speed selection
2531 	 * MASK  - Interrupt mask
2532 	 * Set bit 0 of TXCFG
2533 	 * Set bit 0 of RXCFG
2534 	 */
2535 
2536 	/*
2537 	 * Initialize the TX_MAC registers
2538 	 * Initialization of jamsize to work around rx crc bug
2539 	 */
2540 	PUT_MACREG(jam, jamsize);
2541 
2542 #ifdef	FEPS_URUN_BUG
2543 	if (hme_urun_fix)
2544 		PUT_MACREG(palen, hme_palen);
2545 #endif
2546 
2547 	PUT_MACREG(ipg1, hmep->hme_ipg1);
2548 	PUT_MACREG(ipg2, hmep->hme_ipg2);
2549 
2550 	PUT_MACREG(rseed,
2551 	    ((hmep->hme_ouraddr.ether_addr_octet[0] << 8) & 0x3) |
2552 	    hmep->hme_ouraddr.ether_addr_octet[1]);
2553 
2554 	/* Initialize the RX_MAC registers */
2555 
2556 	/*
2557 	 * Program BigMAC with local individual ethernet address.
2558 	 */
2559 	PUT_MACREG(madd2, (hmep->hme_ouraddr.ether_addr_octet[4] << 8) |
2560 	    hmep->hme_ouraddr.ether_addr_octet[5]);
2561 	PUT_MACREG(madd1, (hmep->hme_ouraddr.ether_addr_octet[2] << 8) |
2562 	    hmep->hme_ouraddr.ether_addr_octet[3]);
2563 	PUT_MACREG(madd0, (hmep->hme_ouraddr.ether_addr_octet[0] << 8) |
2564 	    hmep->hme_ouraddr.ether_addr_octet[1]);
2565 
2566 	/*
2567 	 * Set up multicast address filter by passing all multicast
2568 	 * addresses through a crc generator, and then using the
2569 	 * low order 6 bits as a index into the 64 bit logical
2570 	 * address filter. The high order three bits select the word,
2571 	 * while the rest of the bits select the bit within the word.
2572 	 */
2573 	PUT_MACREG(hash0, hmep->hme_ladrf[0]);
2574 	PUT_MACREG(hash1, hmep->hme_ladrf[1]);
2575 	PUT_MACREG(hash2, hmep->hme_ladrf[2]);
2576 	PUT_MACREG(hash3, hmep->hme_ladrf[3]);
2577 
2578 	/*
2579 	 * Configure parameters to support VLAN.  (VLAN encapsulation adds
2580 	 * four bytes.)
2581 	 */
2582 	PUT_MACREG(txmax, ETHERMAX + ETHERFCSL + 4);
2583 	PUT_MACREG(rxmax, ETHERMAX + ETHERFCSL + 4);
2584 
2585 	/*
2586 	 * Initialize HME Global registers, ETX registers and ERX registers.
2587 	 */
2588 
2589 	PUT_ETXREG(txring, hmep->hme_tmd_paddr);
2590 	PUT_ERXREG(rxring, hmep->hme_rmd_paddr);
2591 
2592 	/*
2593 	 * ERX registers can be written only if they have even no. of bits set.
2594 	 * So, if the value written is not read back, set the lsb and write
2595 	 * again.
2596 	 * static	int	hme_erx_fix = 1;   : Use the fix for erx bug
2597 	 */
2598 	{
2599 		uint32_t temp;
2600 		temp  = hmep->hme_rmd_paddr;
2601 
2602 		if (GET_ERXREG(rxring) != temp)
2603 			PUT_ERXREG(rxring, (temp | 4));
2604 	}
2605 
2606 	PUT_GLOBREG(config, (hmep->hme_config |
2607 	    (hmep->hme_64bit_xfer << HMEG_CONFIG_64BIT_SHIFT)));
2608 
2609 	/*
2610 	 * Significant performance improvements can be achieved by
2611 	 * disabling transmit interrupt. Thus TMD's are reclaimed only
2612 	 * when we run out of them in hmestart().
2613 	 */
2614 	PUT_GLOBREG(intmask,
2615 	    HMEG_MASK_INTR | HMEG_MASK_TINT | HMEG_MASK_TX_ALL);
2616 
2617 	PUT_ETXREG(txring_size, ((HME_TMDMAX -1)>> HMET_RINGSZ_SHIFT));
2618 	PUT_ETXREG(config, (GET_ETXREG(config) | HMET_CONFIG_TXDMA_EN
2619 	    | HMET_CONFIG_TXFIFOTH));
2620 	/* get the rxring size bits */
2621 	switch (HME_RMDMAX) {
2622 	case 32:
2623 		i = HMER_CONFIG_RXRINGSZ32;
2624 		break;
2625 	case 64:
2626 		i = HMER_CONFIG_RXRINGSZ64;
2627 		break;
2628 	case 128:
2629 		i = HMER_CONFIG_RXRINGSZ128;
2630 		break;
2631 	case 256:
2632 		i = HMER_CONFIG_RXRINGSZ256;
2633 		break;
2634 	default:
2635 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2636 		    unk_rx_ringsz_msg);
2637 		goto init_fail;
2638 	}
2639 	i |= (HME_FSTBYTE_OFFSET << HMER_CONFIG_FBO_SHIFT)
2640 	    | HMER_CONFIG_RXDMA_EN;
2641 
2642 	/* h/w checks start offset in half words */
2643 	i |= ((sizeof (struct ether_header) / 2) << HMER_RX_CSSTART_SHIFT);
2644 
2645 	PUT_ERXREG(config, i);
2646 
2647 	/*
2648 	 * Bug related to the parity handling in ERX. When erxp-config is
2649 	 * read back.
2650 	 * Sbus/FEPS drives the parity bit. This value is used while
2651 	 * writing again.
2652 	 * This fixes the RECV problem in SS5.
2653 	 * static	int	hme_erx_fix = 1;   : Use the fix for erx bug
2654 	 */
2655 	{
2656 		uint32_t temp;
2657 		temp = GET_ERXREG(config);
2658 		PUT_ERXREG(config, i);
2659 
2660 		if (GET_ERXREG(config) != i)
2661 			HME_FAULT_MSG4(hmep, SEVERITY_UNKNOWN, ERX_MSG,
2662 			    "error:temp = %x erxp->config = %x, should be %x",
2663 			    temp, GET_ERXREG(config), i);
2664 	}
2665 
2666 	/*
2667 	 * Set up the rxconfig, txconfig and seed register without enabling
2668 	 * them the former two at this time
2669 	 *
2670 	 * BigMAC strips the CRC bytes by default. Since this is
2671 	 * contrary to other pieces of hardware, this bit needs to
2672 	 * enabled to tell BigMAC not to strip the CRC bytes.
2673 	 * Do not filter this node's own packets.
2674 	 */
2675 
2676 	if (hme_reject_own) {
2677 		PUT_MACREG(rxcfg,
2678 		    ((hmep->hme_promisc ? BMAC_RXCFG_PROMIS : 0) |
2679 		    BMAC_RXCFG_MYOWN | BMAC_RXCFG_HASH));
2680 	} else {
2681 		PUT_MACREG(rxcfg,
2682 		    ((hmep->hme_promisc ? BMAC_RXCFG_PROMIS : 0) |
2683 		    BMAC_RXCFG_HASH));
2684 	}
2685 
2686 	drv_usecwait(10);	/* wait after setting Hash Enable bit */
2687 
2688 	fdx = (mii_get_duplex(hmep->hme_mii) == LINK_DUPLEX_FULL);
2689 
2690 	if (hme_ngu_enable)
2691 		PUT_MACREG(txcfg, (fdx ? BMAC_TXCFG_FDX : 0) |
2692 		    BMAC_TXCFG_NGU);
2693 	else
2694 		PUT_MACREG(txcfg, (fdx ? BMAC_TXCFG_FDX: 0));
2695 
2696 	i = 0;
2697 	if ((hmep->hme_lance_mode) && (hmep->hme_lance_mode_enable))
2698 		i = ((hmep->hme_ipg0 & HME_MASK_5BIT) << BMAC_XIFC_IPG0_SHIFT)
2699 		    | BMAC_XIFC_LANCE_ENAB;
2700 	if (phyad == HME_INTERNAL_PHYAD)
2701 		PUT_MACREG(xifc, i | (BMAC_XIFC_ENAB));
2702 	else
2703 		PUT_MACREG(xifc, i | (BMAC_XIFC_ENAB | BMAC_XIFC_MIIBUFDIS));
2704 
2705 	PUT_MACREG(rxcfg, GET_MACREG(rxcfg) | BMAC_RXCFG_ENAB);
2706 	PUT_MACREG(txcfg, GET_MACREG(txcfg) | BMAC_TXCFG_ENAB);
2707 
2708 	hmep->hme_flags |= (HMERUNNING | HMEINITIALIZED);
2709 	/*
2710 	 * Update the interrupt mask : this will re-allow interrupts to occur
2711 	 */
2712 	PUT_GLOBREG(intmask, HMEG_MASK_INTR);
2713 	mac_tx_update(hmep->hme_mh);
2714 
2715 init_fail:
2716 	/*
2717 	 * Release the locks in reverse order
2718 	 */
2719 	mutex_exit(&hmep->hme_xmitlock);
2720 	mutex_exit(&hmep->hme_intrlock);
2721 
2722 	ret = !(hmep->hme_flags & HMERUNNING);
2723 	if (ret) {
2724 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2725 		    init_fail_gen_msg);
2726 	}
2727 
2728 	/*
2729 	 * Hardware checks.
2730 	 */
2731 	CHECK_GLOBREG();
2732 	CHECK_MIFREG();
2733 	CHECK_MACREG();
2734 	CHECK_ERXREG();
2735 	CHECK_ETXREG();
2736 
2737 init_exit:
2738 	return (ret);
2739 }
2740 
2741 /*
2742  * Calculate the dvma burstsize by setting up a dvma temporarily.  Return
2743  * 0 as burstsize upon failure as it signifies no burst size.
2744  * Requests for 64-bit transfer setup, if the platform supports it.
2745  * NOTE: Do not use ddi_dma_alloc_handle(9f) then ddi_dma_burstsize(9f),
2746  * sun4u Ultra-2 incorrectly returns a 32bit transfer.
2747  */
2748 static int
2749 hmeburstsizes(struct hme *hmep)
2750 {
2751 	int burstsizes;
2752 	ddi_dma_handle_t handle;
2753 
2754 	if (ddi_dma_alloc_handle(hmep->dip, &hme_dma_attr,
2755 	    DDI_DMA_DONTWAIT, NULL, &handle)) {
2756 		return (0);
2757 	}
2758 
2759 	hmep->hme_burstsizes = burstsizes = ddi_dma_burstsizes(handle);
2760 	ddi_dma_free_handle(&handle);
2761 
2762 	/*
2763 	 * Use user-configurable parameter for enabling 64-bit transfers
2764 	 */
2765 	burstsizes = (hmep->hme_burstsizes >> 16);
2766 	if (burstsizes)
2767 		hmep->hme_64bit_xfer = hme_64bit_enable; /* user config value */
2768 	else
2769 		burstsizes = hmep->hme_burstsizes;
2770 
2771 	if (hmep->hme_cheerio_mode)
2772 		hmep->hme_64bit_xfer = 0; /* Disable for cheerio */
2773 
2774 	if (burstsizes & 0x40)
2775 		hmep->hme_config = HMEG_CONFIG_BURST64;
2776 	else if (burstsizes & 0x20)
2777 		hmep->hme_config = HMEG_CONFIG_BURST32;
2778 	else
2779 		hmep->hme_config = HMEG_CONFIG_BURST16;
2780 
2781 	return (DDI_SUCCESS);
2782 }
2783 
2784 static int
2785 hmeallocbuf(struct hme *hmep, hmebuf_t *buf, int dir)
2786 {
2787 	ddi_dma_cookie_t	dmac;
2788 	size_t			len;
2789 	unsigned		ccnt;
2790 
2791 	if (ddi_dma_alloc_handle(hmep->dip, &hme_dma_attr,
2792 	    DDI_DMA_DONTWAIT, NULL, &buf->dmah) != DDI_SUCCESS) {
2793 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2794 		    "cannot allocate buf dma handle - failed");
2795 		return (DDI_FAILURE);
2796 	}
2797 
2798 	if (ddi_dma_mem_alloc(buf->dmah, ROUNDUP(HMEBUFSIZE, 512),
2799 	    &hme_buf_attr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, NULL,
2800 	    &buf->kaddr, &len, &buf->acch) != DDI_SUCCESS) {
2801 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2802 		    "cannot allocate buf memory - failed");
2803 		return (DDI_FAILURE);
2804 	}
2805 
2806 	if (ddi_dma_addr_bind_handle(buf->dmah, NULL, buf->kaddr,
2807 	    len, dir | DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
2808 	    &dmac, &ccnt) != DDI_DMA_MAPPED) {
2809 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2810 		    "cannot map buf for dma - failed");
2811 		return (DDI_FAILURE);
2812 	}
2813 	buf->paddr = dmac.dmac_address;
2814 
2815 	/* apparently they don't handle multiple cookies */
2816 	if (ccnt > 1) {
2817 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2818 		    "too many buf dma cookies");
2819 		return (DDI_FAILURE);
2820 	}
2821 	return (DDI_SUCCESS);
2822 }
2823 
2824 static int
2825 hmeallocbufs(struct hme *hmep)
2826 {
2827 	hmep->hme_tbuf = kmem_zalloc(HME_TMDMAX * sizeof (hmebuf_t), KM_SLEEP);
2828 	hmep->hme_rbuf = kmem_zalloc(HME_RMDMAX * sizeof (hmebuf_t), KM_SLEEP);
2829 
2830 	/* Alloc RX buffers. */
2831 	for (int i = 0; i < HME_RMDMAX; i++) {
2832 		if (hmeallocbuf(hmep, &hmep->hme_rbuf[i], DDI_DMA_READ) !=
2833 		    DDI_SUCCESS) {
2834 			return (DDI_FAILURE);
2835 		}
2836 	}
2837 
2838 	/* Alloc TX buffers. */
2839 	for (int i = 0; i < HME_TMDMAX; i++) {
2840 		if (hmeallocbuf(hmep, &hmep->hme_tbuf[i], DDI_DMA_WRITE) !=
2841 		    DDI_SUCCESS) {
2842 			return (DDI_FAILURE);
2843 		}
2844 	}
2845 	return (DDI_SUCCESS);
2846 }
2847 
2848 static void
2849 hmefreebufs(struct hme *hmep)
2850 {
2851 	int i;
2852 
2853 	if (hmep->hme_rbuf == NULL)
2854 		return;
2855 
2856 	/*
2857 	 * Free and unload pending xmit and recv buffers.
2858 	 * Maintaining the 1-to-1 ordered sequence of
2859 	 * We have written the routine to be idempotent.
2860 	 */
2861 
2862 	for (i = 0; i < HME_TMDMAX; i++) {
2863 		hmebuf_t *tbuf = &hmep->hme_tbuf[i];
2864 		if (tbuf->paddr) {
2865 			(void) ddi_dma_unbind_handle(tbuf->dmah);
2866 		}
2867 		if (tbuf->kaddr) {
2868 			ddi_dma_mem_free(&tbuf->acch);
2869 		}
2870 		if (tbuf->dmah) {
2871 			ddi_dma_free_handle(&tbuf->dmah);
2872 		}
2873 	}
2874 	for (i = 0; i < HME_RMDMAX; i++) {
2875 		hmebuf_t *rbuf = &hmep->hme_rbuf[i];
2876 		if (rbuf->paddr) {
2877 			(void) ddi_dma_unbind_handle(rbuf->dmah);
2878 		}
2879 		if (rbuf->kaddr) {
2880 			ddi_dma_mem_free(&rbuf->acch);
2881 		}
2882 		if (rbuf->dmah) {
2883 			ddi_dma_free_handle(&rbuf->dmah);
2884 		}
2885 	}
2886 	kmem_free(hmep->hme_rbuf, HME_RMDMAX * sizeof (hmebuf_t));
2887 	kmem_free(hmep->hme_tbuf, HME_TMDMAX * sizeof (hmebuf_t));
2888 }
2889 
2890 /*
2891  * Un-initialize (STOP) HME channel.
2892  */
2893 static void
2894 hmeuninit(struct hme *hmep)
2895 {
2896 	/*
2897 	 * Allow up to 'HMEDRAINTIME' for pending xmit's to complete.
2898 	 */
2899 	HMEDELAY((hmep->hme_txindex == hmep->hme_txreclaim), HMEDRAINTIME);
2900 
2901 	mutex_enter(&hmep->hme_intrlock);
2902 	mutex_enter(&hmep->hme_xmitlock);
2903 
2904 	hmep->hme_flags &= ~HMERUNNING;
2905 
2906 	(void) hmestop(hmep);
2907 
2908 	mutex_exit(&hmep->hme_xmitlock);
2909 	mutex_exit(&hmep->hme_intrlock);
2910 }
2911 
2912 /*
2913  * Allocate CONSISTENT memory for rmds and tmds with appropriate alignment and
2914  * map it in IO space. Allocate space for transmit and receive ddi_dma_handle
2915  * structures to use the DMA interface.
2916  */
2917 static int
2918 hmeallocthings(struct hme *hmep)
2919 {
2920 	int			size;
2921 	int			rval;
2922 	size_t			real_len;
2923 	uint_t			cookiec;
2924 	ddi_dma_cookie_t	dmac;
2925 	dev_info_t		*dip = hmep->dip;
2926 
2927 	/*
2928 	 * Allocate the TMD and RMD descriptors and extra for page alignment.
2929 	 */
2930 
2931 	rval = ddi_dma_alloc_handle(dip, &hme_dma_attr, DDI_DMA_DONTWAIT, NULL,
2932 	    &hmep->hme_rmd_dmah);
2933 	if (rval != DDI_SUCCESS) {
2934 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2935 		    "cannot allocate rmd handle - failed");
2936 		return (DDI_FAILURE);
2937 	}
2938 	size = HME_RMDMAX * sizeof (struct hme_rmd);
2939 	rval = ddi_dma_mem_alloc(hmep->hme_rmd_dmah, size,
2940 	    &hmep->hme_dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
2941 	    &hmep->hme_rmd_kaddr, &real_len, &hmep->hme_rmd_acch);
2942 	if (rval != DDI_SUCCESS) {
2943 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2944 		    "cannot allocate rmd dma mem - failed");
2945 		return (DDI_FAILURE);
2946 	}
2947 	hmep->hme_rmdp = (void *)(hmep->hme_rmd_kaddr);
2948 	rval = ddi_dma_addr_bind_handle(hmep->hme_rmd_dmah, NULL,
2949 	    hmep->hme_rmd_kaddr, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2950 	    DDI_DMA_DONTWAIT, NULL, &dmac, &cookiec);
2951 	if (rval != DDI_DMA_MAPPED) {
2952 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2953 		    "cannot allocate rmd dma - failed");
2954 		return (DDI_FAILURE);
2955 	}
2956 	hmep->hme_rmd_paddr = dmac.dmac_address;
2957 	if (cookiec != 1) {
2958 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2959 		    "too many rmd cookies - failed");
2960 		return (DDI_FAILURE);
2961 	}
2962 
2963 	rval = ddi_dma_alloc_handle(dip, &hme_dma_attr, DDI_DMA_DONTWAIT, NULL,
2964 	    &hmep->hme_tmd_dmah);
2965 	if (rval != DDI_SUCCESS) {
2966 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2967 		    "cannot allocate tmd handle - failed");
2968 		return (DDI_FAILURE);
2969 	}
2970 	size = HME_TMDMAX * sizeof (struct hme_rmd);
2971 	rval = ddi_dma_mem_alloc(hmep->hme_tmd_dmah, size,
2972 	    &hmep->hme_dev_attr, DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL,
2973 	    &hmep->hme_tmd_kaddr, &real_len, &hmep->hme_tmd_acch);
2974 	if (rval != DDI_SUCCESS) {
2975 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2976 		    "cannot allocate tmd dma mem - failed");
2977 		return (DDI_FAILURE);
2978 	}
2979 	hmep->hme_tmdp = (void *)(hmep->hme_tmd_kaddr);
2980 	rval = ddi_dma_addr_bind_handle(hmep->hme_tmd_dmah, NULL,
2981 	    hmep->hme_tmd_kaddr, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2982 	    DDI_DMA_DONTWAIT, NULL, &dmac, &cookiec);
2983 	if (rval != DDI_DMA_MAPPED) {
2984 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2985 		    "cannot allocate tmd dma - failed");
2986 		return (DDI_FAILURE);
2987 	}
2988 	hmep->hme_tmd_paddr = dmac.dmac_address;
2989 	if (cookiec != 1) {
2990 		HME_FAULT_MSG1(hmep, SEVERITY_HIGH, INIT_MSG,
2991 		    "too many tmd cookies - failed");
2992 		return (DDI_FAILURE);
2993 	}
2994 
2995 	return (DDI_SUCCESS);
2996 }
2997 
2998 static void
2999 hmefreethings(struct hme *hmep)
3000 {
3001 	if (hmep->hme_rmd_paddr) {
3002 		(void) ddi_dma_unbind_handle(hmep->hme_rmd_dmah);
3003 		hmep->hme_rmd_paddr = 0;
3004 	}
3005 	if (hmep->hme_rmd_acch)
3006 		ddi_dma_mem_free(&hmep->hme_rmd_acch);
3007 	if (hmep->hme_rmd_dmah)
3008 		ddi_dma_free_handle(&hmep->hme_rmd_dmah);
3009 
3010 	if (hmep->hme_tmd_paddr) {
3011 		(void) ddi_dma_unbind_handle(hmep->hme_tmd_dmah);
3012 		hmep->hme_tmd_paddr = 0;
3013 	}
3014 	if (hmep->hme_tmd_acch)
3015 		ddi_dma_mem_free(&hmep->hme_tmd_acch);
3016 	if (hmep->hme_tmd_dmah)
3017 		ddi_dma_free_handle(&hmep->hme_tmd_dmah);
3018 }
3019 
3020 /*
3021  *	First check to see if it our device interrupting.
3022  */
3023 static uint_t
3024 hmeintr(caddr_t arg)
3025 {
3026 	struct hme	*hmep = (void *)arg;
3027 	uint32_t	hmesbits;
3028 	uint32_t	serviced = DDI_INTR_UNCLAIMED;
3029 	uint32_t	num_reads = 0;
3030 	uint32_t	rflags;
3031 	mblk_t		*mp, *head, **tail;
3032 
3033 
3034 	head = NULL;
3035 	tail = &head;
3036 
3037 	mutex_enter(&hmep->hme_intrlock);
3038 
3039 	/*
3040 	 * The status register auto-clears on read except for
3041 	 * MIF Interrupt bit
3042 	 */
3043 	hmesbits = GET_GLOBREG(status);
3044 	CHECK_GLOBREG();
3045 
3046 	/*
3047 	 * Note: TINT is sometimes enabled in thr hmereclaim()
3048 	 */
3049 
3050 	/*
3051 	 * Bugid 1227832 - to handle spurious interrupts on fusion systems.
3052 	 * Claim the first interrupt after initialization
3053 	 */
3054 	if (hmep->hme_flags & HMEINITIALIZED) {
3055 		hmep->hme_flags &= ~HMEINITIALIZED;
3056 		serviced = DDI_INTR_CLAIMED;
3057 	}
3058 
3059 	if ((hmesbits & (HMEG_STATUS_INTR | HMEG_STATUS_TINT)) == 0) {
3060 						/* No interesting interrupt */
3061 		if (hmep->hme_intrstats) {
3062 			if (serviced == DDI_INTR_UNCLAIMED)
3063 				KIOIP->intrs[KSTAT_INTR_SPURIOUS]++;
3064 			else
3065 				KIOIP->intrs[KSTAT_INTR_HARD]++;
3066 		}
3067 		mutex_exit(&hmep->hme_intrlock);
3068 		return (serviced);
3069 	}
3070 
3071 	serviced = DDI_INTR_CLAIMED;
3072 
3073 	if (!(hmep->hme_flags & HMERUNNING)) {
3074 		if (hmep->hme_intrstats)
3075 			KIOIP->intrs[KSTAT_INTR_HARD]++;
3076 		mutex_exit(&hmep->hme_intrlock);
3077 		hmeuninit(hmep);
3078 		return (serviced);
3079 	}
3080 
3081 	if (hmesbits & (HMEG_STATUS_FATAL_ERR | HMEG_STATUS_NONFATAL_ERR)) {
3082 		if (hmesbits & HMEG_STATUS_FATAL_ERR) {
3083 
3084 			if (hmep->hme_intrstats)
3085 				KIOIP->intrs[KSTAT_INTR_HARD]++;
3086 			hme_fatal_err(hmep, hmesbits);
3087 
3088 			mutex_exit(&hmep->hme_intrlock);
3089 			(void) hmeinit(hmep);
3090 			return (serviced);
3091 		}
3092 		hme_nonfatal_err(hmep, hmesbits);
3093 	}
3094 
3095 	if (hmesbits & (HMEG_STATUS_TX_ALL | HMEG_STATUS_TINT)) {
3096 		mutex_enter(&hmep->hme_xmitlock);
3097 
3098 		hmereclaim(hmep);
3099 		mutex_exit(&hmep->hme_xmitlock);
3100 	}
3101 
3102 	if (hmesbits & HMEG_STATUS_RINT) {
3103 
3104 		/*
3105 		 * This dummy PIO is required to flush the SBus
3106 		 * Bridge buffers in QFE.
3107 		 */
3108 		(void) GET_GLOBREG(config);
3109 
3110 		/*
3111 		 * Loop through each RMD no more than once.
3112 		 */
3113 		while (num_reads++ < HME_RMDMAX) {
3114 			hmebuf_t *rbuf;
3115 			int rxptr;
3116 
3117 			rxptr = hmep->hme_rxindex % HME_RMDMAX;
3118 			HMESYNCRMD(rxptr, DDI_DMA_SYNC_FORKERNEL);
3119 
3120 			rflags = GET_RMD_FLAGS(rxptr);
3121 			if (rflags & HMERMD_OWN) {
3122 				/*
3123 				 * Chip still owns it.  We're done.
3124 				 */
3125 				break;
3126 			}
3127 
3128 			/*
3129 			 * Retrieve the packet.
3130 			 */
3131 			rbuf = &hmep->hme_rbuf[rxptr];
3132 			mp = hmeread(hmep, rbuf, rflags);
3133 
3134 			/*
3135 			 * Return ownership of the RMD.
3136 			 */
3137 			PUT_RMD(rxptr, rbuf->paddr);
3138 			HMESYNCRMD(rxptr, DDI_DMA_SYNC_FORDEV);
3139 
3140 			if (mp != NULL) {
3141 				*tail = mp;
3142 				tail = &mp->b_next;
3143 			}
3144 
3145 			/*
3146 			 * Advance to the next RMD.
3147 			 */
3148 			hmep->hme_rxindex++;
3149 		}
3150 	}
3151 
3152 	if (hmep->hme_intrstats)
3153 		KIOIP->intrs[KSTAT_INTR_HARD]++;
3154 
3155 	mutex_exit(&hmep->hme_intrlock);
3156 
3157 	if (head != NULL)
3158 		mac_rx(hmep->hme_mh, NULL, head);
3159 
3160 	return (serviced);
3161 }
3162 
3163 /*
3164  * Transmit completion reclaiming.
3165  */
3166 static void
3167 hmereclaim(struct hme *hmep)
3168 {
3169 	boolean_t	reclaimed = B_FALSE;
3170 
3171 	/*
3172 	 * Loop through each TMD.
3173 	 */
3174 	while (hmep->hme_txindex > hmep->hme_txreclaim) {
3175 
3176 		int		reclaim;
3177 		uint32_t	flags;
3178 
3179 		reclaim = hmep->hme_txreclaim % HME_TMDMAX;
3180 		HMESYNCTMD(reclaim, DDI_DMA_SYNC_FORKERNEL);
3181 
3182 		flags = GET_TMD_FLAGS(reclaim);
3183 		if (flags & HMETMD_OWN) {
3184 			/*
3185 			 * Chip still owns it.  We're done.
3186 			 */
3187 			break;
3188 		}
3189 
3190 		/*
3191 		 * Count a chained packet only once.
3192 		 */
3193 		if (flags & HMETMD_SOP) {
3194 			hmep->hme_opackets++;
3195 		}
3196 
3197 		/*
3198 		 * MIB II
3199 		 */
3200 		hmep->hme_obytes += flags & HMETMD_BUFSIZE;
3201 
3202 		reclaimed = B_TRUE;
3203 		hmep->hme_txreclaim++;
3204 	}
3205 
3206 	if (reclaimed) {
3207 		/*
3208 		 * we could reclaim some TMDs so turn off interrupts
3209 		 */
3210 		if (hmep->hme_wantw) {
3211 			PUT_GLOBREG(intmask,
3212 			    HMEG_MASK_INTR | HMEG_MASK_TINT |
3213 			    HMEG_MASK_TX_ALL);
3214 			hmep->hme_wantw = B_FALSE;
3215 			mac_tx_update(hmep->hme_mh);
3216 		}
3217 	} else {
3218 		/*
3219 		 * enable TINTS: so that even if there is no further activity
3220 		 * hmereclaim will get called
3221 		 */
3222 		if (hmep->hme_wantw)
3223 			PUT_GLOBREG(intmask,
3224 			    GET_GLOBREG(intmask) & ~HMEG_MASK_TX_ALL);
3225 	}
3226 	CHECK_GLOBREG();
3227 }
3228 
3229 /*
3230  * Handle interrupts for fatal errors
3231  * Need reinitialization of the ENET channel.
3232  */
3233 static void
3234 hme_fatal_err(struct hme *hmep, uint_t hmesbits)
3235 {
3236 
3237 	if (hmesbits & HMEG_STATUS_SLV_PAR_ERR) {
3238 		hmep->hme_slvparerr++;
3239 	}
3240 
3241 	if (hmesbits & HMEG_STATUS_SLV_ERR_ACK) {
3242 		hmep->hme_slverrack++;
3243 	}
3244 
3245 	if (hmesbits & HMEG_STATUS_TX_TAG_ERR) {
3246 		hmep->hme_txtagerr++;
3247 		hmep->hme_oerrors++;
3248 	}
3249 
3250 	if (hmesbits & HMEG_STATUS_TX_PAR_ERR) {
3251 		hmep->hme_txparerr++;
3252 		hmep->hme_oerrors++;
3253 	}
3254 
3255 	if (hmesbits & HMEG_STATUS_TX_LATE_ERR) {
3256 		hmep->hme_txlaterr++;
3257 		hmep->hme_oerrors++;
3258 	}
3259 
3260 	if (hmesbits & HMEG_STATUS_TX_ERR_ACK) {
3261 		hmep->hme_txerrack++;
3262 		hmep->hme_oerrors++;
3263 	}
3264 
3265 	if (hmesbits & HMEG_STATUS_EOP_ERR) {
3266 		hmep->hme_eoperr++;
3267 	}
3268 
3269 	if (hmesbits & HMEG_STATUS_RX_TAG_ERR) {
3270 		hmep->hme_rxtagerr++;
3271 		hmep->hme_ierrors++;
3272 	}
3273 
3274 	if (hmesbits & HMEG_STATUS_RX_PAR_ERR) {
3275 		hmep->hme_rxparerr++;
3276 		hmep->hme_ierrors++;
3277 	}
3278 
3279 	if (hmesbits & HMEG_STATUS_RX_LATE_ERR) {
3280 		hmep->hme_rxlaterr++;
3281 		hmep->hme_ierrors++;
3282 	}
3283 
3284 	if (hmesbits & HMEG_STATUS_RX_ERR_ACK) {
3285 		hmep->hme_rxerrack++;
3286 		hmep->hme_ierrors++;
3287 	}
3288 }
3289 
3290 /*
3291  * Handle interrupts regarding non-fatal errors.
3292  */
3293 static void
3294 hme_nonfatal_err(struct hme *hmep, uint_t hmesbits)
3295 {
3296 
3297 	if (hmesbits & HMEG_STATUS_RX_DROP) {
3298 		hmep->hme_missed++;
3299 		hmep->hme_ierrors++;
3300 	}
3301 
3302 	if (hmesbits & HMEG_STATUS_DEFTIMR_EXP) {
3303 		hmep->hme_defer_xmts++;
3304 	}
3305 
3306 	if (hmesbits & HMEG_STATUS_FSTCOLC_EXP) {
3307 		hmep->hme_fstcol += 256;
3308 	}
3309 
3310 	if (hmesbits & HMEG_STATUS_LATCOLC_EXP) {
3311 		hmep->hme_tlcol += 256;
3312 		hmep->hme_oerrors += 256;
3313 	}
3314 
3315 	if (hmesbits & HMEG_STATUS_EXCOLC_EXP) {
3316 		hmep->hme_excol += 256;
3317 		hmep->hme_oerrors += 256;
3318 	}
3319 
3320 	if (hmesbits & HMEG_STATUS_NRMCOLC_EXP) {
3321 		hmep->hme_coll += 256;
3322 	}
3323 
3324 	if (hmesbits & HMEG_STATUS_MXPKTSZ_ERR) {
3325 		hmep->hme_babl++;
3326 		hmep->hme_oerrors++;
3327 	}
3328 
3329 	/*
3330 	 * This error is fatal and the board needs to
3331 	 * be reinitialized. Comments?
3332 	 */
3333 	if (hmesbits & HMEG_STATUS_TXFIFO_UNDR) {
3334 		hmep->hme_uflo++;
3335 		hmep->hme_oerrors++;
3336 	}
3337 
3338 	if (hmesbits & HMEG_STATUS_SQE_TST_ERR) {
3339 		hmep->hme_sqe_errors++;
3340 	}
3341 
3342 	if (hmesbits & HMEG_STATUS_RCV_CNT_EXP) {
3343 		if (hmep->hme_rxcv_enable) {
3344 			hmep->hme_cvc += 256;
3345 		}
3346 	}
3347 
3348 	if (hmesbits & HMEG_STATUS_RXFIFO_OVFL) {
3349 		hmep->hme_oflo++;
3350 		hmep->hme_ierrors++;
3351 	}
3352 
3353 	if (hmesbits & HMEG_STATUS_LEN_CNT_EXP) {
3354 		hmep->hme_lenerr += 256;
3355 		hmep->hme_ierrors += 256;
3356 	}
3357 
3358 	if (hmesbits & HMEG_STATUS_ALN_CNT_EXP) {
3359 		hmep->hme_align_errors += 256;
3360 		hmep->hme_ierrors += 256;
3361 	}
3362 
3363 	if (hmesbits & HMEG_STATUS_CRC_CNT_EXP) {
3364 		hmep->hme_fcs_errors += 256;
3365 		hmep->hme_ierrors += 256;
3366 	}
3367 }
3368 
3369 static mblk_t *
3370 hmeread(struct hme *hmep, hmebuf_t *rbuf, uint32_t rflags)
3371 {
3372 	mblk_t		*bp;
3373 	uint32_t	len;
3374 	t_uscalar_t	type;
3375 
3376 	len = (rflags & HMERMD_BUFSIZE) >> HMERMD_BUFSIZE_SHIFT;
3377 
3378 	/*
3379 	 * Check for short packet
3380 	 * and check for overflow packet also. The processing is the
3381 	 * same for both the cases - reuse the buffer. Update the Buffer
3382 	 * overflow counter.
3383 	 */
3384 	if ((len < ETHERMIN) || (rflags & HMERMD_OVFLOW) ||
3385 	    (len > (ETHERMAX + 4))) {
3386 		if (len < ETHERMIN)
3387 			hmep->hme_runt++;
3388 
3389 		else {
3390 			hmep->hme_buff++;
3391 			hmep->hme_toolong_errors++;
3392 		}
3393 		hmep->hme_ierrors++;
3394 		return (NULL);
3395 	}
3396 
3397 	/*
3398 	 * Sync the received buffer before looking at it.
3399 	 */
3400 
3401 	(void) ddi_dma_sync(rbuf->dmah, 0, 0, DDI_DMA_SYNC_FORKERNEL);
3402 
3403 	/*
3404 	 * copy the packet data and then recycle the descriptor.
3405 	 */
3406 
3407 	if ((bp = allocb(len + HME_FSTBYTE_OFFSET, BPRI_HI)) == NULL) {
3408 
3409 		hmep->hme_allocbfail++;
3410 		hmep->hme_norcvbuf++;
3411 
3412 		return (NULL);
3413 	}
3414 
3415 	bcopy(rbuf->kaddr, bp->b_rptr, len + HME_FSTBYTE_OFFSET);
3416 
3417 	hmep->hme_ipackets++;
3418 
3419 	/*  Add the First Byte offset to the b_rptr and copy */
3420 	bp->b_rptr += HME_FSTBYTE_OFFSET;
3421 	bp->b_wptr = bp->b_rptr + len;
3422 
3423 	/*
3424 	 * update MIB II statistics
3425 	 */
3426 	BUMP_InNUcast(hmep, bp->b_rptr);
3427 	hmep->hme_rbytes += len;
3428 
3429 	type = get_ether_type(bp->b_rptr);
3430 
3431 	/*
3432 	 * TCP partial checksum in hardware
3433 	 */
3434 	if (type == ETHERTYPE_IP || type == ETHERTYPE_IPV6) {
3435 		uint16_t cksum = ~rflags & HMERMD_CKSUM;
3436 		uint_t end = len - sizeof (struct ether_header);
3437 		(void) hcksum_assoc(bp, NULL, NULL, 0,
3438 		    0, end, htons(cksum), HCK_PARTIALCKSUM, 0);
3439 	}
3440 
3441 	return (bp);
3442 }
3443 
3444 /*VARARGS*/
3445 static void
3446 hme_fault_msg(struct hme *hmep, uint_t severity, msg_t type, char *fmt, ...)
3447 {
3448 	char	msg_buffer[255];
3449 	va_list	ap;
3450 
3451 	va_start(ap, fmt);
3452 	(void) vsnprintf(msg_buffer, sizeof (msg_buffer), fmt, ap);
3453 
3454 	if (hmep == NULL) {
3455 		cmn_err(CE_NOTE, "hme : %s", msg_buffer);
3456 
3457 	} else if (type == DISPLAY_MSG) {
3458 		cmn_err(CE_CONT, "?%s%d : %s\n", ddi_driver_name(hmep->dip),
3459 		    hmep->instance, msg_buffer);
3460 	} else if (severity == SEVERITY_HIGH) {
3461 		cmn_err(CE_WARN, "%s%d : %s, SEVERITY_HIGH, %s\n",
3462 		    ddi_driver_name(hmep->dip), hmep->instance,
3463 		    msg_buffer, msg_string[type]);
3464 	} else {
3465 		cmn_err(CE_CONT, "%s%d : %s\n", ddi_driver_name(hmep->dip),
3466 		    hmep->instance, msg_buffer);
3467 	}
3468 	va_end(ap);
3469 }
3470 
3471 /*
3472  * if this is the first init do not bother to save the
3473  * counters. They should be 0, but do not count on it.
3474  */
3475 static void
3476 hmesavecntrs(struct hme *hmep)
3477 {
3478 	uint32_t fecnt, aecnt, lecnt, rxcv;
3479 	uint32_t ltcnt, excnt;
3480 
3481 	/* XXX What all gets added in ierrors and oerrors? */
3482 	fecnt = GET_MACREG(fecnt);
3483 	PUT_MACREG(fecnt, 0);
3484 
3485 	aecnt = GET_MACREG(aecnt);
3486 	hmep->hme_align_errors += aecnt;
3487 	PUT_MACREG(aecnt, 0);
3488 
3489 	lecnt = GET_MACREG(lecnt);
3490 	hmep->hme_lenerr += lecnt;
3491 	PUT_MACREG(lecnt, 0);
3492 
3493 	rxcv = GET_MACREG(rxcv);
3494 #ifdef HME_CODEVIOL_BUG
3495 	/*
3496 	 * Ignore rxcv errors for Sbus/FEPS 2.1 or earlier
3497 	 */
3498 	if (!hmep->hme_rxcv_enable) {
3499 		rxcv = 0;
3500 	}
3501 #endif
3502 	hmep->hme_cvc += rxcv;
3503 	PUT_MACREG(rxcv, 0);
3504 
3505 	ltcnt = GET_MACREG(ltcnt);
3506 	hmep->hme_tlcol += ltcnt;
3507 	PUT_MACREG(ltcnt, 0);
3508 
3509 	excnt = GET_MACREG(excnt);
3510 	hmep->hme_excol += excnt;
3511 	PUT_MACREG(excnt, 0);
3512 
3513 	hmep->hme_fcs_errors += fecnt;
3514 	hmep->hme_ierrors += (fecnt + aecnt + lecnt);
3515 	hmep->hme_oerrors += (ltcnt + excnt);
3516 	hmep->hme_coll += (GET_MACREG(nccnt) + ltcnt);
3517 
3518 	PUT_MACREG(nccnt, 0);
3519 	CHECK_MACREG();
3520 }
3521 
3522 /*
3523  * To set up the mac address for the network interface:
3524  * The adapter card may support a local mac address which is published
3525  * in a device node property "local-mac-address". This mac address is
3526  * treated as the factory-installed mac address for DLPI interface.
3527  * If the adapter firmware has used the device for diskless boot
3528  * operation it publishes a property called "mac-address" for use by
3529  * inetboot and the device driver.
3530  * If "mac-address" is not found, the system options property
3531  * "local-mac-address" is used to select the mac-address. If this option
3532  * is set to "true", and "local-mac-address" has been found, then
3533  * local-mac-address is used; otherwise the system mac address is used
3534  * by calling the "localetheraddr()" function.
3535  */
3536 static void
3537 hme_setup_mac_address(struct hme *hmep, dev_info_t *dip)
3538 {
3539 	char	*prop;
3540 	int	prop_len = sizeof (int);
3541 
3542 	hmep->hme_addrflags = 0;
3543 
3544 	/*
3545 	 * Check if it is an adapter with its own local mac address
3546 	 * If it is present, save it as the "factory-address"
3547 	 * for this adapter.
3548 	 */
3549 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3550 	    "local-mac-address",
3551 	    (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) {
3552 		if (prop_len == ETHERADDRL) {
3553 			hmep->hme_addrflags = HME_FACTADDR_PRESENT;
3554 			ether_bcopy(prop, &hmep->hme_factaddr);
3555 			HME_FAULT_MSG2(hmep, SEVERITY_NONE, DISPLAY_MSG,
3556 			    "Local Ethernet address = %s",
3557 			    ether_sprintf(&hmep->hme_factaddr));
3558 		}
3559 		kmem_free(prop, prop_len);
3560 	}
3561 
3562 	/*
3563 	 * Check if the adapter has published "mac-address" property.
3564 	 * If it is present, use it as the mac address for this device.
3565 	 */
3566 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3567 	    "mac-address", (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) {
3568 		if (prop_len >= ETHERADDRL) {
3569 			ether_bcopy(prop, &hmep->hme_ouraddr);
3570 			kmem_free(prop, prop_len);
3571 			return;
3572 		}
3573 		kmem_free(prop, prop_len);
3574 	}
3575 
3576 #ifdef	__sparc
3577 	/*
3578 	 * On sparc, we might be able to use the mac address from the
3579 	 * system.  However, on all other systems, we need to use the
3580 	 * address from the PROM.
3581 	 */
3582 	if (ddi_getlongprop(DDI_DEV_T_ANY, dip, 0, "local-mac-address?",
3583 	    (caddr_t)&prop, &prop_len) == DDI_PROP_SUCCESS) {
3584 		if ((strncmp("true", prop, prop_len) == 0) &&
3585 		    (hmep->hme_addrflags & HME_FACTADDR_PRESENT)) {
3586 			hmep->hme_addrflags |= HME_FACTADDR_USE;
3587 			ether_bcopy(&hmep->hme_factaddr, &hmep->hme_ouraddr);
3588 			kmem_free(prop, prop_len);
3589 			HME_FAULT_MSG1(hmep, SEVERITY_NONE, DISPLAY_MSG,
3590 			    "Using local MAC address");
3591 			return;
3592 		}
3593 		kmem_free(prop, prop_len);
3594 	}
3595 
3596 	/*
3597 	 * Get the system ethernet address.
3598 	 */
3599 	(void) localetheraddr((struct ether_addr *)NULL, &hmep->hme_ouraddr);
3600 #else
3601 	ether_bcopy(&hmep->hme_factaddr, &hmep->hme_ouraddr);
3602 #endif
3603 }
3604 
3605 /* ARGSUSED */
3606 static void
3607 hme_check_acc_handle(char *file, uint_t line, struct hme *hmep,
3608     ddi_acc_handle_t handle)
3609 {
3610 }
3611