xref: /titanic_50/usr/src/uts/intel/io/dnet/dnet.c (revision 62224350e5355e6834f7deb9d8a7d062a50cb7c2)
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 /*
23  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 
28 /*
29  * dnet -- DEC 21x4x
30  *
31  * Currently supports:
32  *	21040, 21041, 21140, 21142, 21143
33  *	SROM versions 1, 3, 3.03, 4
34  *	TP, AUI, BNC, 100BASETX, 100BASET4
35  *
36  * XXX NEEDSWORK
37  *	All media SHOULD work, FX is untested
38  *
39  * Depends on the Generic LAN Driver utility functions in /kernel/misc/gld
40  */
41 
42 #define	BUG_4010796	/* See 4007871, 4010796 */
43 
44 #include <sys/types.h>
45 #include <sys/errno.h>
46 #include <sys/param.h>
47 #include <sys/stropts.h>
48 #include <sys/stream.h>
49 #include <sys/kmem.h>
50 #include <sys/conf.h>
51 #include <sys/devops.h>
52 #include <sys/ksynch.h>
53 #include <sys/stat.h>
54 #include <sys/modctl.h>
55 #include <sys/debug.h>
56 #include <sys/dlpi.h>
57 #include <sys/ethernet.h>
58 #include <sys/gld.h>
59 #include <sys/pci.h>
60 #include <sys/ddi.h>
61 #include <sys/sunddi.h>
62 
63 #include "dnet_mii.h"
64 #include "dnet.h"
65 
66 char _depends_on[] = "misc/gld";
67 
68 /*
69  *	Declarations and Module Linkage
70  */
71 
72 #define	IDENT	"DNET 21x4x"
73 
74 /*
75  * #define	DNET_NOISY
76  * #define	SROMDEBUG
77  * #define	SROMDUMPSTRUCTURES
78  */
79 
80 #ifdef DNETDEBUG
81 #ifdef DNET_NOISY
82 int	dnetdebug = -1;
83 #else
84 int	dnetdebug = 0;
85 #endif
86 #endif
87 
88 /* used for message allocated using desballoc() */
89 struct free_ptr {
90 	struct free_rtn	free_rtn;
91 	caddr_t buf;
92 };
93 
94 struct rbuf_list {
95 	struct rbuf_list	*rbuf_next;	/* next in the list */
96 	caddr_t			rbuf_vaddr;	/* virual addr of the buf */
97 	uint32_t		rbuf_paddr;	/* physical addr of the buf */
98 	uint32_t		rbuf_endpaddr;	/* physical addr at the end */
99 	ddi_dma_handle_t	rbuf_dmahdl;	/* dma handle */
100 	ddi_acc_handle_t	rbuf_acchdl;	/* handle for DDI functions */
101 };
102 
103 /* Required system entry points */
104 static int dnetdevinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
105 static int dnetprobe(dev_info_t *);
106 static int dnetattach(dev_info_t *, ddi_attach_cmd_t);
107 static int dnetdetach(dev_info_t *, ddi_detach_cmd_t);
108 
109 /* Required driver entry points for GLD */
110 static int dnet_reset(gld_mac_info_t *);
111 static int dnet_start_board(gld_mac_info_t *);
112 static int dnet_stop_board(gld_mac_info_t *);
113 static int dnet_set_mac_addr(gld_mac_info_t *, uchar_t *);
114 static int dnet_set_multicast(gld_mac_info_t *, uchar_t *, int);
115 static int dnet_set_promiscuous(gld_mac_info_t *, int);
116 static int dnet_get_stats(gld_mac_info_t *, struct gld_stats *);
117 static int dnet_send(gld_mac_info_t *, mblk_t *);
118 static uint_t dnetintr(gld_mac_info_t *);
119 
120 /* Internal functions used by the above entry points */
121 static void write_gpr(struct dnetinstance *dnetp, uint32_t val);
122 static void dnet_reset_board(gld_mac_info_t *);
123 static void dnet_init_board(gld_mac_info_t *);
124 static void dnet_chip_init(gld_mac_info_t *);
125 static unsigned int hashindex(uchar_t *);
126 static int dnet_start(gld_mac_info_t *);
127 static int dnet_set_addr(gld_mac_info_t *);
128 
129 static void dnet_getp(gld_mac_info_t *);
130 static void update_rx_stats(gld_mac_info_t *, int);
131 static void update_tx_stats(gld_mac_info_t *, int);
132 
133 /* Media Selection Setup Routines */
134 static void set_gpr(gld_mac_info_t *macinfo);
135 static void set_opr(gld_mac_info_t *macinfo);
136 static void set_sia(gld_mac_info_t *macinfo);
137 
138 /* Buffer Management Routines */
139 static int dnet_alloc_bufs(gld_mac_info_t *);
140 static void dnet_free_bufs(gld_mac_info_t *);
141 static void dnet_init_txrx_bufs(gld_mac_info_t *);
142 static int alloc_descriptor(gld_mac_info_t *);
143 static void dnet_reclaim_Tx_desc(gld_mac_info_t *);
144 static int dnet_rbuf_init(dev_info_t *, int);
145 static int dnet_rbuf_destroy();
146 static struct rbuf_list *dnet_rbuf_alloc(dev_info_t *, int);
147 static void dnet_rbuf_free(caddr_t);
148 static void dnet_freemsg_buf(struct free_ptr *);
149 
150 static void setup_block(gld_mac_info_t *macinfo);
151 
152 /* SROM read functions */
153 static int dnet_read_srom(dev_info_t *, int, ddi_acc_handle_t, caddr_t,
154     uchar_t *, int);
155 static void dnet_read21040addr(dev_info_t *, ddi_acc_handle_t, caddr_t,
156     uchar_t *, int *);
157 static void dnet_read21140srom(ddi_acc_handle_t, caddr_t, uchar_t *, int);
158 static int get_alternative_srom_image(dev_info_t *, uchar_t *, int);
159 static void dnet_print_srom(SROM_FORMAT *sr);
160 static void dnet_dump_leaf(LEAF_FORMAT *leaf);
161 static void dnet_dump_block(media_block_t *block);
162 #ifdef BUG_4010796
163 static void set_alternative_srom_image(dev_info_t *, uchar_t *, int);
164 static int dnethack(dev_info_t *);
165 #endif
166 
167 static int dnet_hack_interrupts(gld_mac_info_t *, int);
168 static int dnet_detach_hacked_interrupt(dev_info_t *devinfo);
169 static void enable_interrupts(struct dnetinstance *dnetp, int enable_xmit);
170 
171 /* SROM parsing functions */
172 static void dnet_parse_srom(struct dnetinstance *dnetp, SROM_FORMAT *sr,
173     uchar_t *vi);
174 static void parse_controller_leaf(struct dnetinstance *dnetp, LEAF_FORMAT *leaf,
175     uchar_t *vi);
176 static uchar_t *parse_media_block(struct dnetinstance *dnetp,
177     media_block_t *block, uchar_t *vi);
178 static int check_srom_valid(uchar_t *);
179 static void dnet_dumpbin(char *msg, uchar_t *, int size, int len);
180 static void setup_legacy_blocks();
181 /* Active Media Determination Routines */
182 static void find_active_media(gld_mac_info_t *);
183 static int send_test_packet(gld_mac_info_t *);
184 static int dnet_link_sense(gld_mac_info_t *macinfo);
185 
186 /* PHY MII Routines */
187 static ushort_t dnet_mii_read(dev_info_t *dip, int phy_addr, int reg_num);
188 static void dnet_mii_write(dev_info_t *dip, int phy_addr, int reg_num,
189 			int reg_dat);
190 static void write_mii(struct dnetinstance *, uint32_t, int);
191 static void mii_tristate(struct dnetinstance *);
192 static void do_phy(gld_mac_info_t *);
193 static void dnet_mii_link_cb(dev_info_t *, int, enum mii_phy_state);
194 static void set_leaf(SROM_FORMAT *sr, LEAF_FORMAT *leaf);
195 
196 #ifdef DNETDEBUG
197 uint32_t dnet_usecelapsed(struct dnetinstance *dnetp);
198 void dnet_timestamp(struct dnetinstance *, char *);
199 void dnet_usectimeout(struct dnetinstance *, uint32_t, int, timercb_t);
200 #endif
201 static char *media_str[] = {
202 	"10BaseT",
203 	"10Base2",
204 	"10Base5",
205 	"100BaseTX",
206 	"10BaseT FD",
207 	"100BaseTX FD",
208 	"100BaseT4",
209 	"100BaseFX",
210 	"100BaseFX FD",
211 	"MII"
212 };
213 
214 /* default SROM info for cards with no SROMs */
215 static LEAF_FORMAT leaf_default_100;
216 static LEAF_FORMAT leaf_asante;
217 static LEAF_FORMAT leaf_phylegacy;
218 static LEAF_FORMAT leaf_cogent_100;
219 static LEAF_FORMAT leaf_21041;
220 static LEAF_FORMAT leaf_21040;
221 
222 int rx_buf_size = (ETHERMAX + ETHERFCSL + 3) & ~3;	/* roundup to 4 */
223 
224 int max_rx_desc_21040 = MAX_RX_DESC_21040;
225 int max_rx_desc_21140 = MAX_RX_DESC_21140;
226 int max_tx_desc = MAX_TX_DESC;
227 int dnet_xmit_threshold = MAX_TX_DESC >> 2;	/* XXX need tuning? */
228 
229 static kmutex_t dnet_rbuf_lock;		/* mutex to protect rbuf_list data */
230 
231 /* used for buffers allocated by ddi_dma_mem_alloc() */
232 static ddi_dma_attr_t dma_attr = {
233 	DMA_ATTR_V0,		/* dma_attr version */
234 	0,			/* dma_attr_addr_lo */
235 	(uint64_t)0xFFFFFFFF,	/* dma_attr_addr_hi */
236 	0x7FFFFFFF,		/* dma_attr_count_max */
237 	4,			/* dma_attr_align */
238 	0x3F,			/* dma_attr_burstsizes */
239 	1,			/* dma_attr_minxfer */
240 	(uint64_t)0xFFFFFFFF,	/* dma_attr_maxxfer */
241 	(uint64_t)0xFFFFFFFF,	/* dma_attr_seg */
242 	1,			/* dma_attr_sgllen */
243 	1,			/* dma_attr_granular */
244 	0,			/* dma_attr_flags */
245 };
246 
247 /* used for buffers allocated for rbuf, allow 2 cookies */
248 static ddi_dma_attr_t dma_attr_rb = {
249 	DMA_ATTR_V0,		/* dma_attr version */
250 	0,			/* dma_attr_addr_lo */
251 	(uint64_t)0xFFFFFFFF,	/* dma_attr_addr_hi */
252 	0x7FFFFFFF,		/* dma_attr_count_max */
253 	4,			/* dma_attr_align */
254 	0x3F,			/* dma_attr_burstsizes */
255 	1,			/* dma_attr_minxfer */
256 	(uint64_t)0xFFFFFFFF,	/* dma_attr_maxxfer */
257 	(uint64_t)0xFFFFFFFF,	/* dma_attr_seg */
258 	2,			/* dma_attr_sgllen */
259 	1,			/* dma_attr_granular */
260 	0,			/* dma_attr_flags */
261 };
262 /* used for buffers which are NOT from ddi_dma_mem_alloc() - xmit side */
263 static ddi_dma_attr_t dma_attr_tx = {
264 	DMA_ATTR_V0,		/* dma_attr version */
265 	0,			/* dma_attr_addr_lo */
266 	(uint64_t)0xFFFFFFFF,	/* dma_attr_addr_hi */
267 	0x7FFFFFFF,		/* dma_attr_count_max */
268 	1,			/* dma_attr_align */
269 	0x3F,			/* dma_attr_burstsizes */
270 	1,			/* dma_attr_minxfer */
271 	(uint64_t)0xFFFFFFFF,	/* dma_attr_maxxfer */
272 	(uint64_t)0xFFFFFFFF,	/* dma_attr_seg */
273 	0x7FFF,			/* dma_attr_sgllen */
274 	1,			/* dma_attr_granular */
275 	0,			/* dma_attr_flags */
276 };
277 
278 static ddi_device_acc_attr_t accattr = {
279 	DDI_DEVICE_ATTR_V0,
280 	DDI_NEVERSWAP_ACC,
281 	DDI_STRICTORDER_ACC,
282 };
283 
284 uchar_t dnet_broadcastaddr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
285 
286 /* Standard Streams initialization */
287 static struct module_info minfo = {
288 	DNETIDNUM, "dnet", 0, INFPSZ, DNETHIWAT, DNETLOWAT
289 };
290 
291 static struct qinit rinit = {	/* read queues */
292 	NULL, gld_rsrv, gld_open, gld_close, NULL, &minfo, NULL
293 };
294 
295 static struct qinit winit = {	/* write queues */
296 	gld_wput, gld_wsrv, NULL, NULL, NULL, &minfo, NULL
297 };
298 
299 static struct streamtab dnetinfo = {&rinit, &winit, NULL, NULL};
300 
301 /* Standard Module linkage initialization for a Streams driver */
302 extern struct mod_ops mod_driverops;
303 
304 static struct cb_ops cb_dnetops = {
305 	nulldev,		/* cb_open */
306 	nulldev,		/* cb_close */
307 	nodev,			/* cb_strategy */
308 	nodev,			/* cb_print */
309 	nodev,			/* cb_dump */
310 	nodev,			/* cb_read */
311 	nodev,			/* cb_write */
312 	nodev,			/* cb_ioctl */
313 	nodev,			/* cb_devmap */
314 	nodev,			/* cb_mmap */
315 	nodev,			/* cb_segmap */
316 	nochpoll,		/* cb_chpoll */
317 	ddi_prop_op,		/* cb_prop_op */
318 	&dnetinfo,		/* cb_stream */
319 	(int)(D_MP | D_HOTPLUG)	/* cb_flag */
320 };
321 
322 static struct dev_ops dnetops = {
323 	DEVO_REV,		/* devo_rev */
324 	0,			/* devo_refcnt */
325 	gld_getinfo,		/* devo_getinfo */
326 	nulldev,		/* devo_identify */
327 	dnetprobe,		/* devo_probe */
328 	dnetattach,		/* devo_attach */
329 	dnetdetach,		/* devo_detach */
330 	nodev,			/* devo_reset */
331 	&cb_dnetops,		/* devo_cb_ops */
332 	(struct bus_ops *)NULL,	/* devo_bus_ops */
333 	NULL,			/* devo_power */
334 	ddi_quiesce_not_supported,	/* devo_quiesce */
335 };
336 
337 static struct modldrv modldrv = {
338 	&mod_driverops,		/* Type of module.  This one is a driver */
339 	IDENT,			/* short description */
340 	&dnetops		/* driver specific ops */
341 };
342 
343 static struct modlinkage modlinkage = {
344 	MODREV_1, (void *)&modldrv, NULL
345 };
346 
347 
348 /*
349  * Passed to the hacked interrupt for multiport Cogent and ZNYX cards with
350  * dodgy interrupt routing
351  */
352 #define	MAX_INST 8 /* Maximum instances on a multiport adapter. */
353 struct hackintr_inf
354 {
355 	gld_mac_info_t *macinfos[MAX_INST]; /* macinfos for each port */
356 	dev_info_t *devinfo;		    /* Devinfo of the primary device */
357 	kmutex_t lock;
358 		/* Ensures the interrupt doesn't get called while detaching */
359 };
360 static char hackintr_propname[] = "InterruptData";
361 static char macoffset_propname[] = "MAC_offset";
362 static char speed_propname[] = "speed";
363 static char ofloprob_propname[] = "dmaworkaround";
364 static char duplex_propname[] = "full-duplex"; /* Must agree with MII */
365 static char printsrom_propname[] = "print-srom";
366 
367 static uint_t dnet_hack_intr(struct hackintr_inf *);
368 
369 /*
370  *	========== Module Loading Entry Points ==========
371  */
372 
373 int
374 _init(void)
375 {
376 	int i;
377 
378 	/* Configure fake sroms for legacy cards */
379 	mutex_init(&dnet_rbuf_lock, NULL, MUTEX_DRIVER, NULL);
380 	setup_legacy_blocks();
381 	if ((i = mod_install(&modlinkage)) != 0) {
382 		mutex_destroy(&dnet_rbuf_lock);
383 	}
384 	return (i);
385 }
386 
387 int
388 _fini(void)
389 {
390 	int i;
391 	if ((i = mod_remove(&modlinkage)) == 0) { /* module can be unloaded */
392 		/* loop until all the receive buffers are freed */
393 		while (dnet_rbuf_destroy() != 0) {
394 			delay(drv_usectohz(100000));
395 #ifdef DNETDEBUG
396 			if (dnetdebug & DNETDDI)
397 				cmn_err(CE_WARN, "dnet _fini delay");
398 #endif
399 		}
400 		mutex_destroy(&dnet_rbuf_lock);
401 	}
402 	return (i);
403 }
404 
405 int
406 _info(struct modinfo *modinfop)
407 {
408 	return (mod_info(&modlinkage, modinfop));
409 }
410 
411 /*
412  *	========== DDI Entry Points ==========
413  */
414 
415 /*
416  * probe(9E) -- Determine if a device is present
417  */
418 static int
419 dnetprobe(dev_info_t *devinfo)
420 {
421 	ddi_acc_handle_t handle;
422 	uint16_t	vendorid;
423 	uint16_t	deviceid;
424 
425 #ifdef DNETDEBUG
426 	if (dnetdebug & DNETDDI)
427 		cmn_err(CE_NOTE, "dnetprobe(0x%p)", (void *) devinfo);
428 #endif
429 
430 	if (pci_config_setup(devinfo, &handle) != DDI_SUCCESS)
431 		return (DDI_PROBE_FAILURE);
432 
433 	vendorid = pci_config_get16(handle, PCI_CONF_VENID);
434 
435 	if (vendorid != DEC_VENDOR_ID) {
436 		pci_config_teardown(&handle);
437 		return (DDI_PROBE_FAILURE);
438 	}
439 
440 	deviceid = pci_config_get16(handle, PCI_CONF_DEVID);
441 	switch (deviceid) {
442 	case DEVICE_ID_21040:
443 	case DEVICE_ID_21041:
444 	case DEVICE_ID_21140:
445 	case DEVICE_ID_21143: /* And 142 */
446 		break;
447 	default:
448 		pci_config_teardown(&handle);
449 		return (DDI_PROBE_FAILURE);
450 	}
451 
452 	pci_config_teardown(&handle);
453 #ifndef BUG_4010796
454 	return (DDI_PROBE_SUCCESS);
455 #else
456 	return (dnethack(devinfo));
457 #endif
458 }
459 
460 #ifdef BUG_4010796
461 /*
462  * If we have a device, but we cannot presently access its SROM data,
463  * then we return DDI_PROBE_PARTIAL and hope that sometime later we
464  * will be able to get at the SROM data.  This can only happen if we
465  * are a secondary port with no SROM, and the bootstrap failed to set
466  * our DNET_SROM property, and our primary sibling has not yet probed.
467  */
468 static int
469 dnethack(dev_info_t *devinfo)
470 {
471 	uchar_t 	vendor_info[SROM_SIZE];
472 	uint32_t	csr;
473 	uint16_t	deviceid;
474 	ddi_acc_handle_t handle;
475 	uint32_t	retval;
476 	int		secondary;
477 	ddi_acc_handle_t io_handle;
478 	caddr_t		io_reg;
479 
480 #define	DNET_PCI_RNUMBER	1
481 
482 #ifdef DNETDEBUG
483 	if (dnetdebug & DNETDDI)
484 		cmn_err(CE_NOTE, "dnethack(0x%p)", (void *) devinfo);
485 #endif
486 
487 	if (pci_config_setup(devinfo, &handle) != DDI_SUCCESS)
488 		return (DDI_PROBE_FAILURE);
489 
490 	deviceid = pci_config_get16(handle, PCI_CONF_DEVID);
491 
492 	/*
493 	 * Turn on Master Enable and IO Enable bits.
494 	 */
495 	csr = pci_config_get32(handle, PCI_CONF_COMM);
496 	pci_config_put32(handle, PCI_CONF_COMM, (csr |PCI_COMM_ME|PCI_COMM_IO));
497 
498 	pci_config_teardown(&handle);
499 
500 	/* Now map I/O register */
501 	if (ddi_regs_map_setup(devinfo, DNET_PCI_RNUMBER,
502 	    &io_reg, 0, 0, &accattr, &io_handle) != DDI_SUCCESS) {
503 		return (DDI_PROBE_FAILURE);
504 	}
505 
506 	/*
507 	 * Reset the chip
508 	 */
509 	ddi_put32(io_handle, REG32(io_reg, BUS_MODE_REG), SW_RESET);
510 	drv_usecwait(3);
511 	ddi_put32(io_handle, REG32(io_reg, BUS_MODE_REG), 0);
512 	drv_usecwait(8);
513 
514 	secondary = dnet_read_srom(devinfo, deviceid, io_handle,
515 	    io_reg, vendor_info, sizeof (vendor_info));
516 
517 	switch (secondary) {
518 	case -1:
519 		/* We can't access our SROM data! */
520 		retval = DDI_PROBE_PARTIAL;
521 		break;
522 	case 0:
523 		retval = DDI_PROBE_SUCCESS;
524 		break;
525 	default:
526 		retval = DDI_PROBE_SUCCESS;
527 	}
528 
529 	ddi_regs_map_free(&io_handle);
530 	return (retval);
531 }
532 #endif /* BUG_4010796 */
533 
534 /*
535  * attach(9E) -- Attach a device to the system
536  *
537  * Called once for each board successfully probed.
538  */
539 static int
540 dnetattach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
541 {
542 	uint16_t revid;
543 	struct dnetinstance 	*dnetp;		/* Our private device info */
544 	gld_mac_info_t		*macinfo;		/* GLD structure */
545 	uchar_t 		vendor_info[SROM_SIZE];
546 	uint32_t		csr;
547 	uint16_t		deviceid;
548 	ddi_acc_handle_t 	handle;
549 	int			secondary;
550 
551 #define	DNET_PCI_RNUMBER	1
552 
553 #ifdef DNETDEBUG
554 	if (dnetdebug & DNETDDI)
555 		cmn_err(CE_NOTE, "dnetattach(0x%p)", (void *) devinfo);
556 #endif
557 
558 	switch (cmd) {
559 	case DDI_ATTACH:
560 		break;
561 
562 	case DDI_RESUME:
563 
564 		/* Get the driver private (gld_mac_info_t) structure */
565 		macinfo = ddi_get_driver_private(devinfo);
566 		dnetp = (struct dnetinstance *)(macinfo->gldm_private);
567 
568 		mutex_enter(&dnetp->intrlock);
569 		mutex_enter(&dnetp->txlock);
570 		dnet_reset_board(macinfo);
571 		dnet_init_board(macinfo);
572 		dnetp->suspended = B_FALSE;
573 
574 		if (dnetp->running) {
575 			dnetp->need_gld_sched = 0;
576 			mutex_exit(&dnetp->txlock);
577 			(void) dnet_start(macinfo);
578 			mutex_exit(&dnetp->intrlock);
579 			gld_sched(macinfo);
580 		} else {
581 			mutex_exit(&dnetp->txlock);
582 			mutex_exit(&dnetp->intrlock);
583 		}
584 		return (DDI_SUCCESS);
585 	default:
586 		return (DDI_FAILURE);
587 	}
588 	if (pci_config_setup(devinfo, &handle) != DDI_SUCCESS)
589 		return (DDI_FAILURE);
590 
591 	deviceid = pci_config_get16(handle, PCI_CONF_DEVID);
592 	switch (deviceid) {
593 	case DEVICE_ID_21040:
594 	case DEVICE_ID_21041:
595 	case DEVICE_ID_21140:
596 	case DEVICE_ID_21143: /* And 142 */
597 		break;
598 	default:
599 		pci_config_teardown(&handle);
600 		return (DDI_FAILURE);
601 	}
602 
603 	/*
604 	 * Turn on Master Enable and IO Enable bits.
605 	 */
606 	csr = pci_config_get32(handle, PCI_CONF_COMM);
607 	pci_config_put32(handle, PCI_CONF_COMM, (csr |PCI_COMM_ME|PCI_COMM_IO));
608 
609 	/* Make sure the device is not asleep */
610 	csr = pci_config_get32(handle, PCI_DNET_CONF_CFDD);
611 	pci_config_put32(handle, PCI_DNET_CONF_CFDD,
612 	    csr &  ~(CFDD_SLEEP|CFDD_SNOOZE));
613 
614 	revid = pci_config_get8(handle, PCI_CONF_REVID);
615 	pci_config_teardown(&handle);
616 
617 	/*
618 	 *	Allocate gld_mac_info_t and dnetinstance structures
619 	 */
620 	if ((macinfo = gld_mac_alloc(devinfo)) == NULL)
621 		return (DDI_FAILURE);
622 
623 	if ((dnetp = (struct dnetinstance *)
624 	    kmem_zalloc(sizeof (struct dnetinstance), KM_SLEEP)) == NULL) {
625 		gld_mac_free(macinfo);
626 		return (DDI_FAILURE);
627 	}
628 
629 	/* Now map I/O register */
630 	if (ddi_regs_map_setup(devinfo, DNET_PCI_RNUMBER, &dnetp->io_reg,
631 	    0, 0, &accattr, &dnetp->io_handle) != DDI_SUCCESS) {
632 		kmem_free(dnetp, sizeof (struct dnetinstance));
633 		gld_mac_free(macinfo);
634 		return (DDI_FAILURE);
635 	}
636 
637 	dnetp->devinfo = devinfo;
638 	dnetp->board_type = deviceid;
639 
640 	/*
641 	 * Initialize our private fields in macinfo and dnetinstance
642 	 */
643 	macinfo->gldm_private = (caddr_t)dnetp;
644 
645 	/*
646 	 * Initialize pointers to device specific functions which will be
647 	 * used by the generic layer.
648 	 */
649 	macinfo->gldm_reset	= dnet_reset;
650 	macinfo->gldm_start	= dnet_start_board;
651 	macinfo->gldm_stop	= dnet_stop_board;
652 	macinfo->gldm_set_mac_addr	= dnet_set_mac_addr;
653 	macinfo->gldm_set_multicast	= dnet_set_multicast;
654 	macinfo->gldm_set_promiscuous	= dnet_set_promiscuous;
655 	macinfo->gldm_get_stats	= dnet_get_stats;
656 	macinfo->gldm_send	= dnet_send;
657 	macinfo->gldm_intr	= dnetintr;
658 	macinfo->gldm_ioctl	= NULL;
659 
660 	/*
661 	 *	Initialize board characteristics needed by the generic layer.
662 	 */
663 	macinfo->gldm_ident = IDENT;
664 	macinfo->gldm_type = DL_ETHER;
665 	macinfo->gldm_minpkt = 0;		/* assumes we pad ourselves */
666 	macinfo->gldm_maxpkt = DNETMAXPKT;
667 	macinfo->gldm_addrlen = ETHERADDRL;
668 	macinfo->gldm_saplen = -2;
669 
670 	/* Other required initialization */
671 	macinfo->gldm_ppa = ddi_get_instance(devinfo);
672 	macinfo->gldm_vendor_addr = dnetp->vendor_addr;
673 	macinfo->gldm_broadcast_addr = dnet_broadcastaddr;
674 	macinfo->gldm_devinfo = devinfo;
675 
676 
677 	/*
678 	 * Get the iblock cookie with which to initialize the mutexes.
679 	 */
680 	if (ddi_get_iblock_cookie(devinfo, 0, &macinfo->gldm_cookie)
681 	    != DDI_SUCCESS)
682 		goto fail;
683 
684 	/*
685 	 * Initialize mutex's for this device.
686 	 * Do this before registering the interrupt handler to avoid
687 	 * condition where interrupt handler can try using uninitialized
688 	 * mutex.
689 	 * Lock ordering rules: always lock intrlock first before
690 	 * txlock if both are required.
691 	 */
692 	mutex_init(&dnetp->txlock,
693 	    NULL, MUTEX_DRIVER, macinfo->gldm_cookie);
694 	mutex_init(&dnetp->intrlock,
695 	    NULL, MUTEX_DRIVER, macinfo->gldm_cookie);
696 
697 	/*
698 	 * Get the BNC/TP indicator from the conf file for 21040
699 	 */
700 	dnetp->bnc_indicator =
701 	    ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
702 	    "bncaui", -1);
703 
704 	/*
705 	 * For 21140 check the data rate set in the conf file. Default is
706 	 * 100Mb/s. Disallow connections at settings that would conflict
707 	 * with what's in the conf file
708 	 */
709 	dnetp->speed =
710 	    ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
711 	    speed_propname, 0);
712 	dnetp->full_duplex =
713 	    ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
714 	    duplex_propname, -1);
715 
716 	if (dnetp->speed == 100) {
717 		dnetp->disallowed_media |= (1UL<<MEDIA_TP) | (1UL<<MEDIA_TP_FD);
718 	} else if (dnetp->speed == 10) {
719 		dnetp->disallowed_media |=
720 		    (1UL<<MEDIA_SYM_SCR) | (1UL<<MEDIA_SYM_SCR_FD);
721 	}
722 
723 	if (dnetp->full_duplex == 1) {
724 		dnetp->disallowed_media |=
725 		    (1UL<<MEDIA_TP) | (1UL<<MEDIA_SYM_SCR);
726 	} else if (dnetp->full_duplex == 0) {
727 		dnetp->disallowed_media |=
728 		    (1UL<<MEDIA_TP_FD) | (1UL<<MEDIA_SYM_SCR_FD);
729 	}
730 
731 	if (dnetp->bnc_indicator == 0) /* Disable BNC and AUI media */
732 		dnetp->disallowed_media |= (1UL<<MEDIA_BNC) | (1UL<<MEDIA_AUI);
733 	else if (dnetp->bnc_indicator == 1) /* Force BNC only */
734 		dnetp->disallowed_media =  (uint32_t)~(1U<<MEDIA_BNC);
735 	else if (dnetp->bnc_indicator == 2) /* Force AUI only */
736 		dnetp->disallowed_media = (uint32_t)~(1U<<MEDIA_AUI);
737 
738 	dnet_reset_board(macinfo);
739 
740 	secondary = dnet_read_srom(devinfo, dnetp->board_type, dnetp->io_handle,
741 	    dnetp->io_reg, vendor_info, sizeof (vendor_info));
742 
743 	if (secondary == -1) /* ASSERT (vendor_info not big enough) */
744 		goto fail1;
745 
746 	dnet_parse_srom(dnetp, &dnetp->sr, vendor_info);
747 
748 	if (ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
749 	    printsrom_propname, 0))
750 		dnet_print_srom(&dnetp->sr);
751 
752 	dnetp->sr.netaddr[ETHERADDRL-1] += secondary;	/* unique ether addr */
753 
754 	BCOPY((caddr_t)dnetp->sr.netaddr,
755 	    (caddr_t)dnetp->vendor_addr, ETHERADDRL);
756 
757 	BCOPY((caddr_t)dnetp->sr.netaddr,
758 	    (caddr_t)dnetp->curr_macaddr, ETHERADDRL);
759 
760 
761 	/*
762 	 * determine whether to implement workaround from DEC
763 	 * for DMA overrun errata.
764 	 */
765 	dnetp->overrun_workaround =
766 	    ((dnetp->board_type == DEVICE_ID_21140 && revid >= 0x20) ||
767 	    (dnetp->board_type == DEVICE_ID_21143 && revid <= 0x30)) ? 1 : 0;
768 
769 	dnetp->overrun_workaround =
770 	    ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
771 	    ofloprob_propname, dnetp->overrun_workaround);
772 
773 	/*
774 	 * Add the interrupt handler if dnet_hack_interrupts() returns 0.
775 	 * Otherwise dnet_hack_interrupts() itself adds the handler.
776 	 */
777 	if (!dnet_hack_interrupts(macinfo, secondary)) {
778 		(void) ddi_add_intr(devinfo, 0, NULL,
779 		    NULL, gld_intr, (caddr_t)macinfo);
780 	}
781 
782 	dnetp->max_tx_desc = max_tx_desc;
783 	dnetp->max_rx_desc = max_rx_desc_21040;
784 	if (dnetp->board_type != DEVICE_ID_21040 &&
785 	    dnetp->board_type != DEVICE_ID_21041 &&
786 	    dnetp->speed != 10)
787 		dnetp->max_rx_desc = max_rx_desc_21140;
788 
789 	/* Allocate the TX and RX descriptors/buffers. */
790 	if (dnet_alloc_bufs(macinfo) == FAILURE) {
791 		cmn_err(CE_WARN, "DNET: Not enough DMA memory for buffers.");
792 		goto fail2;
793 	}
794 
795 	/*
796 	 *	Register ourselves with the GLD interface
797 	 *
798 	 *	gld_register will:
799 	 *	link us with the GLD system;
800 	 *	set our ddi_set_driver_private(9F) data to the macinfo pointer;
801 	 *	save the devinfo pointer in macinfo->gldm_devinfo;
802 	 *	map the registers, putting the kvaddr into macinfo->gldm_memp;
803 	 *	add the interrupt, putting the cookie in gldm_cookie;
804 	 *	init the gldm_intrlock mutex which will block that interrupt;
805 	 *	create the minor node.
806 	 */
807 
808 	if (gld_register(devinfo, "dnet", macinfo) == DDI_SUCCESS) {
809 		mutex_enter(&dnetp->intrlock);
810 		dnetp->phyaddr = -1;
811 		if (dnetp->board_type == DEVICE_ID_21140 ||
812 		    dnetp->board_type == DEVICE_ID_21143)
813 			do_phy(macinfo);	/* Initialize the PHY, if any */
814 		find_active_media(macinfo);
815 
816 		/* if the chosen media is non-MII, stop the port monitor */
817 		if (dnetp->selected_media_block->media_code != MEDIA_MII &&
818 		    dnetp->mii != NULL) {
819 			mii_destroy(dnetp->mii);
820 			dnetp->mii = NULL;
821 			dnetp->phyaddr = -1;
822 		}
823 
824 #ifdef DNETDEBUG
825 		if (dnetdebug & DNETSENSE)
826 			cmn_err(CE_NOTE, "dnet: link configured : %s",
827 			    media_str[dnetp->selected_media_block->media_code]);
828 #endif
829 		bzero(dnetp->setup_buf_vaddr, SETUPBUF_SIZE);
830 		dnet_reset_board(macinfo);
831 		dnet_init_board(macinfo);
832 		/* XXX function return value ignored */
833 		mutex_exit(&dnetp->intrlock);
834 		/* dropped intrlock as dnet_stop_board() grabs intrlock */
835 		(void) dnet_stop_board(macinfo);
836 		return (DDI_SUCCESS);
837 	}
838 fail2:
839 	/* XXX function return value ignored */
840 	/*
841 	 * dnet_detach_hacked_interrupt() will remove
842 	 * interrupt for the non-hacked case also.
843 	 */
844 	(void) dnet_detach_hacked_interrupt(devinfo);
845 	dnet_free_bufs(macinfo);
846 fail1:
847 	mutex_destroy(&dnetp->txlock);
848 	mutex_destroy(&dnetp->intrlock);
849 fail:
850 	ddi_regs_map_free(&dnetp->io_handle);
851 	kmem_free(dnetp, sizeof (struct dnetinstance));
852 	gld_mac_free(macinfo);
853 	return (DDI_FAILURE);
854 }
855 
856 /*
857  * detach(9E) -- Detach a device from the system
858  */
859 static int
860 dnetdetach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
861 {
862 	int32_t rc;
863 	gld_mac_info_t	*macinfo;		/* GLD structure */
864 	struct dnetinstance *dnetp;		/* Our private device info */
865 	int32_t		proplen;
866 
867 #ifdef DNETDEBUG
868 	if (dnetdebug & DNETDDI)
869 		cmn_err(CE_NOTE, "dnetdetach(0x%p)", (void *) devinfo);
870 #endif
871 
872 	/* Get the driver private (gld_mac_info_t) structure */
873 	macinfo = ddi_get_driver_private(devinfo);
874 	dnetp = (struct dnetinstance *)(macinfo->gldm_private);
875 
876 	switch (cmd) {
877 	case DDI_DETACH:
878 		break;
879 
880 	case DDI_SUSPEND:
881 		/*
882 		 * NB: dnetp->suspended can only be modified (marked true)
883 		 * if both intrlock and txlock are held.  This keeps both
884 		 * tx and rx code paths excluded.
885 		 */
886 		mutex_enter(&dnetp->intrlock);
887 		mutex_enter(&dnetp->txlock);
888 		dnetp->suspended = B_TRUE;
889 		dnet_reset_board(macinfo);
890 		mutex_exit(&dnetp->txlock);
891 		mutex_exit(&dnetp->intrlock);
892 		return (DDI_SUCCESS);
893 
894 	default:
895 		return (DDI_FAILURE);
896 	}
897 
898 	/*
899 	 *	Unregister ourselves from the GLD interface
900 	 *
901 	 *	gld_unregister will:
902 	 *	remove the minor node;
903 	 *	unmap the registers;
904 	 *	remove the interrupt;
905 	 *	destroy the gldm_intrlock mutex;
906 	 *	unlink us from the GLD system.
907 	 */
908 	if (gld_unregister(macinfo) != DDI_SUCCESS)
909 		return (DDI_FAILURE);
910 
911 	/* stop the board if it is running */
912 	dnet_reset_board(macinfo);
913 
914 	if ((rc = dnet_detach_hacked_interrupt(devinfo)) != DDI_SUCCESS)
915 		return (rc);
916 
917 	if (dnetp->mii != NULL)
918 		mii_destroy(dnetp->mii);
919 
920 	/* Free leaf information */
921 	set_leaf(&dnetp->sr, NULL);
922 
923 	ddi_regs_map_free(&dnetp->io_handle);
924 	dnet_free_bufs(macinfo);
925 	mutex_destroy(&dnetp->txlock);
926 	mutex_destroy(&dnetp->intrlock);
927 	kmem_free(dnetp, sizeof (struct dnetinstance));
928 	gld_mac_free(macinfo);
929 
930 #ifdef BUG_4010796
931 	if (ddi_getproplen(DDI_DEV_T_ANY, devinfo, 0,
932 	    "DNET_HACK", &proplen) != DDI_PROP_SUCCESS)
933 		return (DDI_SUCCESS);
934 
935 	/*
936 	 * We must remove the properties we added, because if we leave
937 	 * them in the devinfo nodes and the driver is unloaded, when
938 	 * the driver is reloaded the info will still be there, causing
939 	 * nodes which had returned PROBE_PARTIAL the first time to
940 	 * instead return PROBE_SUCCESS, in turn causing the nodes to be
941 	 * attached in a different order, causing their PPA numbers to
942 	 * be different the second time around, which is undesirable.
943 	 */
944 	(void) ddi_prop_remove(DDI_DEV_T_NONE, devinfo, "DNET_HACK");
945 	(void) ddi_prop_remove(DDI_DEV_T_NONE, ddi_get_parent(devinfo),
946 	    "DNET_SROM");
947 	(void) ddi_prop_remove(DDI_DEV_T_NONE, ddi_get_parent(devinfo),
948 	    "DNET_DEVNUM");
949 #endif
950 
951 	return (DDI_SUCCESS);
952 }
953 
954 /*
955  *	========== GLD Entry Points ==========
956  */
957 
958 /*
959  *	dnet_reset() -- reset the board to initial state;
960  */
961 static int
962 dnet_reset(gld_mac_info_t *macinfo)
963 {
964 	struct dnetinstance *dnetp =		/* Our private device info */
965 	    (struct dnetinstance *)macinfo->gldm_private;
966 #ifdef DNETDEBUG
967 	if (dnetdebug & DNETTRACE)
968 		cmn_err(CE_NOTE, "dnet_reset(0x%p)", (void *) macinfo);
969 #endif
970 
971 	mutex_enter(&dnetp->intrlock);
972 	/*
973 	 * Initialize internal data structures
974 	 */
975 	bzero(dnetp->setup_buf_vaddr, SETUPBUF_SIZE);
976 	bzero(dnetp->multicast_cnt, MCASTBUF_SIZE);
977 	dnetp->promisc = 0;
978 
979 	mutex_enter(&dnetp->txlock);
980 	dnetp->need_saddr = 0;
981 	mutex_exit(&dnetp->txlock);
982 
983 	if (dnetp->suspended) {
984 		mutex_exit(&dnetp->intrlock);
985 		return (0);
986 	}
987 	dnet_reset_board(macinfo);
988 
989 	if (ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo, DDI_PROP_DONTPASS,
990 	    "reset_do_find_active_media", 0)) {
991 		find_active_media(macinfo);	/* Redetermine active media */
992 		/* Go back to a good state */
993 		bzero(dnetp->setup_buf_vaddr, SETUPBUF_SIZE);
994 		dnet_reset_board(macinfo);
995 	}
996 	dnet_init_board(macinfo);
997 	mutex_exit(&dnetp->intrlock);
998 	return (0);
999 }
1000 
1001 static void
1002 dnet_reset_board(gld_mac_info_t *macinfo)
1003 {
1004 	struct dnetinstance *dnetp =		/* Our private device info */
1005 	    (struct dnetinstance *)macinfo->gldm_private;
1006 	uint32_t	val;
1007 
1008 	/*
1009 	 * before initializing the dnet should be in STOP state
1010 	 */
1011 	/* XXX function return value ignored */
1012 	/* (void) dnet_stop_board(macinfo); */
1013 	val = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG));
1014 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG),
1015 	    val & ~(START_TRANSMIT | START_RECEIVE));
1016 
1017 	/*
1018 	 * Reset the chip
1019 	 */
1020 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, INT_MASK_REG), 0);
1021 	ddi_put32(dnetp->io_handle,
1022 	    REG32(dnetp->io_reg, BUS_MODE_REG), SW_RESET);
1023 	drv_usecwait(5);
1024 }
1025 
1026 /*
1027  * dnet_init_board() -- initialize the specified network board short of
1028  * actually starting the board.  Call after dnet_reset_board().
1029  * called with intrlock held.
1030  */
1031 static void
1032 dnet_init_board(gld_mac_info_t *macinfo)
1033 {
1034 #ifdef DNETDEBUG
1035 	if (dnetdebug & DNETTRACE)
1036 		cmn_err(CE_NOTE, "dnet_init_board(0x%p)", (void *) macinfo);
1037 #endif
1038 	set_opr(macinfo);
1039 	set_gpr(macinfo);
1040 	set_sia(macinfo);
1041 	dnet_chip_init(macinfo);
1042 }
1043 
1044 /* dnet_chip_init() - called with intrlock held */
1045 static void
1046 dnet_chip_init(gld_mac_info_t *macinfo)
1047 {
1048 	struct dnetinstance	*dnetp = (struct dnetinstance *)
1049 	    (macinfo->gldm_private);
1050 
1051 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, BUS_MODE_REG),
1052 	    CACHE_ALIGN | BURST_SIZE);		/* CSR0 */
1053 
1054 	/*
1055 	 * Initialize the TX and RX descriptors/buffers
1056 	 */
1057 	dnet_init_txrx_bufs(macinfo);
1058 
1059 	/*
1060 	 * Set the base address of the Rx descriptor list in CSR3
1061 	 */
1062 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, RX_BASE_ADDR_REG),
1063 	    dnetp->rx_desc_paddr);
1064 
1065 	/*
1066 	 * Set the base address of the Tx descrptor list in CSR4
1067 	 */
1068 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, TX_BASE_ADDR_REG),
1069 	    dnetp->tx_desc_paddr);
1070 
1071 	dnetp->tx_current_desc = dnetp->rx_current_desc = 0;
1072 	dnetp->transmitted_desc = 0;
1073 	dnetp->free_desc = dnetp->max_tx_desc;
1074 	enable_interrupts(dnetp, 1);
1075 }
1076 
1077 /*
1078  *	dnet_start() -- start the board receiving and allow transmits.
1079  *  Called with intrlock held.
1080  */
1081 static int
1082 dnet_start(gld_mac_info_t *macinfo)
1083 {
1084 	struct dnetinstance *dnetp =		/* Our private device info */
1085 	    (struct dnetinstance *)macinfo->gldm_private;
1086 	uint32_t		val;
1087 
1088 #ifdef DNETDEBUG
1089 	if (dnetdebug & DNETTRACE)
1090 		cmn_err(CE_NOTE, "dnet_start(0x%p)", (void *) macinfo);
1091 #endif
1092 
1093 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
1094 	/*
1095 	 * start the board and enable receiving
1096 	 */
1097 	val = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG));
1098 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG),
1099 	    val | START_TRANSMIT);
1100 	(void) dnet_set_addr(macinfo);
1101 	val = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG));
1102 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG),
1103 	    val | START_RECEIVE);
1104 	enable_interrupts(dnetp, 1);
1105 	return (0);
1106 }
1107 
1108 /*
1109  *	dnet_start_board() -- start the board receiving and allow transmits.
1110  */
1111 static int
1112 dnet_start_board(gld_mac_info_t *macinfo)
1113 {
1114 	struct dnetinstance *dnetp =		/* Our private device info */
1115 	    (struct dnetinstance *)macinfo->gldm_private;
1116 
1117 #ifdef DNETDEBUG
1118 	if (dnetdebug & DNETTRACE)
1119 		cmn_err(CE_NOTE, "dnet_start_board(0x%p)", (void *) macinfo);
1120 #endif
1121 
1122 	mutex_enter(&dnetp->intrlock);
1123 	dnetp->running = B_TRUE;
1124 	/*
1125 	 * start the board and enable receiving
1126 	 */
1127 	if (!dnetp->suspended)
1128 		(void) dnet_start(macinfo);
1129 	mutex_exit(&dnetp->intrlock);
1130 	return (0);
1131 }
1132 
1133 /*
1134  *	dnet_stop_board() -- stop board receiving
1135  */
1136 static int
1137 dnet_stop_board(gld_mac_info_t *macinfo)
1138 {
1139 	struct dnetinstance *dnetp =		/* Our private device info */
1140 	    (struct dnetinstance *)macinfo->gldm_private;
1141 	uint32_t		val;
1142 
1143 #ifdef DNETDEBUG
1144 	if (dnetdebug & DNETTRACE)
1145 		cmn_err(CE_NOTE, "dnet_stop_board(0x%p)", (void *) macinfo);
1146 #endif
1147 	/*
1148 	 * stop the board and disable transmit/receive
1149 	 */
1150 	mutex_enter(&dnetp->intrlock);
1151 	if (!dnetp->suspended) {
1152 		val = ddi_get32(dnetp->io_handle,
1153 		    REG32(dnetp->io_reg, OPN_MODE_REG));
1154 		ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG),
1155 		    val & ~(START_TRANSMIT | START_RECEIVE));
1156 	}
1157 	dnetp->running = B_FALSE;
1158 	mutex_exit(&dnetp->intrlock);
1159 	return (0);
1160 }
1161 
1162 /*
1163  *	dnet_set_addr() -- set the physical network address on the board
1164  *  Called with intrlock held.
1165  */
1166 static int
1167 dnet_set_addr(gld_mac_info_t *macinfo)
1168 {
1169 	struct dnetinstance *dnetp =		/* Our private device info */
1170 	    (struct dnetinstance *)macinfo->gldm_private;
1171 	struct tx_desc_type *desc;
1172 	int 		current_desc;
1173 	uint32_t	val;
1174 
1175 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
1176 #ifdef DNETDEBUG
1177 	if (dnetdebug & DNETTRACE)
1178 		cmn_err(CE_NOTE, "dnet_set_addr(0x%p)", (void *) macinfo);
1179 #endif
1180 
1181 	val = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG));
1182 	if (!(val & START_TRANSMIT))
1183 		return (0);
1184 
1185 	current_desc = dnetp->tx_current_desc;
1186 	desc = &dnetp->tx_desc[current_desc];
1187 
1188 	mutex_enter(&dnetp->txlock);
1189 	dnetp->need_saddr = 0;
1190 	mutex_exit(&dnetp->txlock);
1191 
1192 	if ((alloc_descriptor(macinfo)) == FAILURE) {
1193 		mutex_enter(&dnetp->txlock);
1194 		dnetp->need_saddr = 1;
1195 		mutex_exit(&dnetp->txlock);
1196 #ifdef DNETDEBUG
1197 		if (dnetdebug & DNETTRACE)
1198 			cmn_err(CE_WARN, "DNET saddr:alloc descriptor failure");
1199 #endif
1200 		return (0);
1201 	}
1202 
1203 	desc->buffer1			= dnetp->setup_buf_paddr;
1204 	desc->buffer2			= 0;
1205 	desc->desc1.buffer_size1 	= SETUPBUF_SIZE;
1206 	desc->desc1.buffer_size2 	= 0;
1207 	desc->desc1.setup_packet	= 1;
1208 	desc->desc1.first_desc		= 0;
1209 	desc->desc1.last_desc 		= 0;
1210 	desc->desc1.filter_type0 	= 1;
1211 	desc->desc1.filter_type1 	= 1;
1212 	desc->desc1.int_on_comp		= 1;
1213 
1214 	desc->desc0.own = 1;
1215 	ddi_put8(dnetp->io_handle, REG8(dnetp->io_reg, TX_POLL_REG),
1216 	    TX_POLL_DEMAND);
1217 	return (0);
1218 }
1219 
1220 /*
1221  *	dnet_set_mac_addr() -- set the physical network address on the board
1222  */
1223 static int
1224 dnet_set_mac_addr(gld_mac_info_t *macinfo, uchar_t *macaddr)
1225 {
1226 	struct dnetinstance *dnetp =		/* Our private device info */
1227 	    (struct dnetinstance *)macinfo->gldm_private;
1228 	uint32_t	index;
1229 	uint32_t	*hashp;
1230 
1231 #ifdef DNETDEBUG
1232 	if (dnetdebug & DNETTRACE)
1233 		cmn_err(CE_NOTE, "dnet_set_mac_addr(0x%p)", (void *) macinfo);
1234 #endif
1235 	mutex_enter(&dnetp->intrlock);
1236 
1237 	bcopy(macaddr, dnetp->curr_macaddr, ETHERADDRL);
1238 
1239 	/*
1240 	 * As we are using Imperfect filtering, the broadcast address has to
1241 	 * be set explicitly in the 512 bit hash table.  Hence the index into
1242 	 * the hash table is calculated and the bit set to enable reception
1243 	 * of broadcast packets.
1244 	 *
1245 	 * We also use HASH_ONLY mode, without using the perfect filter for
1246 	 * our station address, because there appears to be a bug in the
1247 	 * 21140 where it fails to receive the specified perfect filter
1248 	 * address.
1249 	 *
1250 	 * Since dlsdmult comes through here, it doesn't matter that the count
1251 	 * is wrong for the two bits that correspond to the cases below. The
1252 	 * worst that could happen is that we'd leave on a bit for an old
1253 	 * macaddr, in the case where the macaddr gets changed, which is rare.
1254 	 * Since filtering is imperfect, it is OK if that happens.
1255 	 */
1256 	hashp = (uint32_t *)dnetp->setup_buf_vaddr;
1257 	index = hashindex((uchar_t *)dnet_broadcastaddr);
1258 	hashp[ index / 16 ] |= 1 << (index % 16);
1259 
1260 	index = hashindex((uchar_t *)dnetp->curr_macaddr);
1261 	hashp[ index / 16 ] |= 1 << (index % 16);
1262 
1263 	if (!dnetp->suspended)
1264 		(void) dnet_set_addr(macinfo);
1265 	mutex_exit(&dnetp->intrlock);
1266 	return (0);
1267 }
1268 
1269 /*
1270  *	dnet_set_multicast() -- set (enable) or disable a multicast address
1271  *
1272  *	Program the hardware to enable/disable the multicast address
1273  *	in "mcast".  Enable if "op" is non-zero, disable if zero.
1274  */
1275 static int
1276 dnet_set_multicast(gld_mac_info_t *macinfo, uchar_t *mcast, int op)
1277 {
1278 	struct dnetinstance *dnetp =		/* Our private device info */
1279 	    (struct dnetinstance *)macinfo->gldm_private;
1280 	uint32_t	index;
1281 	uint32_t	*hashp;
1282 	uint32_t	retval;
1283 
1284 #ifdef DNETDEBUG
1285 	if (dnetdebug & DNETTRACE)
1286 		cmn_err(CE_NOTE, "dnet_set_multicast(0x%p, %s)",
1287 		    (void *) macinfo, op ? "ON" : "OFF");
1288 #endif
1289 	mutex_enter(&dnetp->intrlock);
1290 	index = hashindex(mcast);
1291 	hashp = (uint32_t *)dnetp->setup_buf_vaddr;
1292 	if (op == GLD_MULTI_ENABLE) {
1293 		if (dnetp->multicast_cnt[index]++) {
1294 			mutex_exit(&dnetp->intrlock);
1295 			return (0);
1296 		}
1297 		hashp[ index / 16 ] |= 1 << (index % 16);
1298 	} else {
1299 		if (--dnetp->multicast_cnt[index]) {
1300 			mutex_exit(&dnetp->intrlock);
1301 			return (0);
1302 		}
1303 		hashp[ index / 16 ] &= ~ (1 << (index % 16));
1304 	}
1305 	if (!dnetp->suspended)
1306 		retval = dnet_set_addr(macinfo);
1307 	else
1308 		retval = 0;
1309 	mutex_exit(&dnetp->intrlock);
1310 	return (retval);
1311 }
1312 
1313 /*
1314  * A hashing function used for setting the
1315  * node address or a multicast address
1316  */
1317 static uint32_t
1318 hashindex(uchar_t *address)
1319 {
1320 	uint32_t	crc = (uint32_t)HASH_CRC;
1321 	uint32_t const 	POLY = HASH_POLY;
1322 	uint32_t	msb;
1323 	int32_t 	byteslength;
1324 	uint8_t 	currentbyte;
1325 	uint32_t 	index;
1326 	int32_t 	bit;
1327 	int32_t		shift;
1328 
1329 	for (byteslength = 0; byteslength < ETHERADDRL; byteslength++) {
1330 		currentbyte = address[byteslength];
1331 		for (bit = 0; bit < 8; bit++) {
1332 			msb = crc >> 31;
1333 			crc <<= 1;
1334 			if (msb ^ (currentbyte & 1)) {
1335 				crc ^= POLY;
1336 				crc |= 0x00000001;
1337 			}
1338 			currentbyte >>= 1;
1339 		}
1340 	}
1341 
1342 	for (index = 0, bit = 23, shift = 8; shift >= 0; bit++, shift--) {
1343 		index |= (((crc >> bit) & 1) << shift);
1344 	}
1345 	return (index);
1346 }
1347 
1348 /*
1349  * dnet_set_promiscuous() -- set or reset promiscuous mode on the board
1350  *
1351  *	Program the hardware to enable/disable promiscuous mode.
1352  *	Enable if "on" is non-zero, disable if zero.
1353  */
1354 
1355 static int
1356 dnet_set_promiscuous(gld_mac_info_t *macinfo, int on)
1357 {
1358 	struct dnetinstance *dnetp;
1359 	uint32_t val;
1360 
1361 #ifdef DNETDEBUG
1362 	if (dnetdebug & DNETTRACE)
1363 		cmn_err(CE_NOTE, "dnet_set_promiscuous(0x%p, %s)",
1364 		    (void *) macinfo, on ? "ON" : "OFF");
1365 #endif
1366 
1367 	dnetp = (struct dnetinstance *)macinfo->gldm_private;
1368 	mutex_enter(&dnetp->intrlock);
1369 	if (dnetp->promisc == on) {
1370 		mutex_exit(&dnetp->intrlock);
1371 		return (SUCCESS);
1372 	}
1373 	dnetp->promisc = on;
1374 
1375 	if (!dnetp->suspended) {
1376 		val = ddi_get32(dnetp->io_handle,
1377 		    REG32(dnetp->io_reg, OPN_MODE_REG));
1378 		if (on != GLD_MAC_PROMISC_NONE)
1379 			ddi_put32(dnetp->io_handle,
1380 			    REG32(dnetp->io_reg, OPN_MODE_REG),
1381 			    val | PROM_MODE);
1382 		else
1383 			ddi_put32(dnetp->io_handle,
1384 			    REG32(dnetp->io_reg, OPN_MODE_REG),
1385 			    val & (~PROM_MODE));
1386 	}
1387 	mutex_exit(&dnetp->intrlock);
1388 	return (DDI_SUCCESS);
1389 }
1390 
1391 /*
1392  * dnet_get_stats() -- update statistics
1393  *
1394  *	GLD calls this routine just before it reads the driver's statistics
1395  *	structure.  If your board maintains statistics, this is the time to
1396  *	read them in and update the values in the structure.  If the driver
1397  *	maintains statistics continuously, this routine need do nothing.
1398  */
1399 
1400 static int
1401 dnet_get_stats(gld_mac_info_t *macinfo, struct gld_stats *sp)
1402 {
1403 	struct dnetinstance *dnetp =		/* Our private device info */
1404 	    (struct dnetinstance *)macinfo->gldm_private;
1405 #ifdef DNETDEBUG
1406 	if (dnetdebug & DNETTRACE)
1407 		cmn_err(CE_NOTE, "dnet_get_stats(0x%p)", (void *) macinfo);
1408 #endif
1409 	sp->glds_errrcv = dnetp->stat_errrcv;
1410 	sp->glds_overflow = dnetp->stat_overflow;
1411 	sp->glds_intr = dnetp->stat_intr;
1412 	sp->glds_defer = dnetp->stat_defer;
1413 	sp->glds_missed	= dnetp->stat_missed;
1414 	sp->glds_norcvbuf = dnetp->stat_norcvbuf;
1415 	sp->glds_crc = dnetp->stat_crc;
1416 	sp->glds_short = dnetp->stat_short;
1417 	sp->glds_frame = dnetp->stat_frame;
1418 	sp->glds_errxmt = dnetp->stat_errxmt;
1419 	sp->glds_collisions	= dnetp->stat_collisions;
1420 	sp->glds_xmtlatecoll = dnetp->stat_xmtlatecoll;
1421 	sp->glds_excoll = dnetp->stat_excoll;
1422 	sp->glds_underflow = dnetp->stat_underflow;
1423 	sp->glds_nocarrier = dnetp->stat_nocarrier;
1424 
1425 	/* stats from instance structure */
1426 	if (dnetp->mii_up) {
1427 		sp->glds_speed = dnetp->mii_speed * 1000000;
1428 		sp->glds_duplex = dnetp->mii_duplex ?
1429 		    GLD_DUPLEX_FULL : GLD_DUPLEX_HALF;
1430 	} else {
1431 		sp->glds_speed = dnetp->speed * 1000000;
1432 		sp->glds_duplex =
1433 		    dnetp->full_duplex ? GLD_DUPLEX_FULL : GLD_DUPLEX_HALF;
1434 	}
1435 
1436 	return (DDI_SUCCESS);
1437 }
1438 
1439 /*
1440  *	dnet_send() -- send a packet
1441  *
1442  *	Called when a packet is ready to be transmitted. A pointer to an
1443  *	M_DATA message that contains the packet is passed to this routine.
1444  *	The complete LLC header is contained in the message's first message
1445  *	block, and the remainder of the packet is contained within
1446  *	additional M_DATA message blocks linked to the first message block.
1447  */
1448 
1449 #define	NextTXIndex(index) (((index)+1) % dnetp->max_tx_desc)
1450 #define	PrevTXIndex(index) (((index)-1) < 0 ? dnetp->max_tx_desc - 1: (index)-1)
1451 
1452 static int
1453 dnet_send(gld_mac_info_t *macinfo, mblk_t *mp)
1454 {
1455 	struct dnetinstance *dnetp =		/* Our private device info */
1456 	    (struct dnetinstance *)macinfo->gldm_private;
1457 	struct tx_desc_type	*ring = dnetp->tx_desc;
1458 	int		mblen, totlen;
1459 	int		index, end_index, start_index;
1460 	int		avail;
1461 	int		error;
1462 	int		bufn;
1463 	int		bp_count;
1464 	int		retval;
1465 	mblk_t		*bp;
1466 	uint32_t	tx_interrupt_mask;
1467 
1468 #ifdef DNETDEBUG
1469 	if (dnetdebug & DNETSEND)
1470 		cmn_err(CE_NOTE, "dnet_send(0x%p, 0x%p)",
1471 		    (void *) macinfo, (void *) mp);
1472 #endif
1473 	mutex_enter(&dnetp->txlock);
1474 	/* if suspended, drop the packet on the floor, we missed it */
1475 	if (dnetp->suspended) {
1476 		mutex_exit(&dnetp->txlock);
1477 		freemsg(mp);
1478 		return (0);
1479 	}
1480 	if (dnetp->need_saddr) {
1481 		/* XXX function return value ignored */
1482 		mutex_exit(&dnetp->txlock);
1483 		mutex_enter(&dnetp->intrlock);
1484 		(void) dnet_set_addr(macinfo);
1485 		mutex_exit(&dnetp->intrlock);
1486 		mutex_enter(&dnetp->txlock);
1487 	}
1488 
1489 	/* reclaim any xmit descriptors completed */
1490 	dnet_reclaim_Tx_desc(macinfo);
1491 
1492 	/*
1493 	 * Use the data buffers from the message and construct the
1494 	 * scatter/gather list by calling ddi_dma_addr_bind_handle().
1495 	 */
1496 	error = bp_count = 0;
1497 	totlen = 0;
1498 	bp = mp;
1499 	bufn = 0;
1500 	index = start_index = dnetp->tx_current_desc;
1501 	avail = dnetp->free_desc;
1502 	while (bp != NULL) {
1503 		uint_t ncookies;
1504 		ddi_dma_cookie_t dma_cookie;
1505 
1506 		if (++bp_count > DNET_MAX_FRAG) {
1507 #ifndef DNET_NOISY
1508 			(void) pullupmsg(bp, -1);
1509 #else
1510 			if (pullupmsg(bp, -1))
1511 				cmn_err(CE_NOTE, "DNET: pulled up send msg");
1512 			else
1513 				cmn_err(CE_NOTE,
1514 				    "DNET: couldn't pullup send msg");
1515 #endif
1516 		}
1517 
1518 		mblen = (int)(bp->b_wptr - bp->b_rptr);
1519 
1520 		if (!mblen) {	/* skip zero-length message blocks */
1521 			bp = bp->b_cont;
1522 			continue;
1523 		}
1524 
1525 		retval = ddi_dma_addr_bind_handle(dnetp->dma_handle_tx, NULL,
1526 		    (caddr_t)bp->b_rptr, mblen,
1527 		    DDI_DMA_WRITE | DDI_DMA_STREAMING, DDI_DMA_SLEEP, 0,
1528 		    &dma_cookie, &ncookies);
1529 
1530 		switch (retval) {
1531 		case DDI_DMA_MAPPED:
1532 			break;		/* everything's fine */
1533 
1534 		case DDI_DMA_NORESOURCES:
1535 			error = 1;	/* allow retry by gld */
1536 			break;
1537 
1538 		case DDI_DMA_NOMAPPING:
1539 		case DDI_DMA_INUSE:
1540 		case DDI_DMA_TOOBIG:
1541 		default:
1542 			error = 2;	/* error, no retry */
1543 			break;
1544 		}
1545 
1546 		/*
1547 		 * we can use two cookies per descriptor (i.e buffer1 and
1548 		 * buffer2) so we need at least (ncookies+1)/2 descriptors.
1549 		 */
1550 		if (((ncookies + 1) >> 1) > dnetp->free_desc) {
1551 			(void) ddi_dma_unbind_handle(dnetp->dma_handle_tx);
1552 			error = 1;
1553 			break;
1554 		}
1555 
1556 		/* setup the descriptors for this data buffer */
1557 		while (ncookies) {
1558 			end_index = index;
1559 			if (bufn % 2) {
1560 				ring[index].buffer2 =
1561 				    (uint32_t)dma_cookie.dmac_address;
1562 				ring[index].desc1.buffer_size2 =
1563 				    dma_cookie.dmac_size;
1564 				index = NextTXIndex(index); /* goto next desc */
1565 			} else {
1566 				/* initialize the descriptor */
1567 				ASSERT(ring[index].desc0.own == 0);
1568 				*(uint32_t *)&ring[index].desc0 = 0;
1569 				*(uint32_t *)&ring[index].desc1 &=
1570 				    DNET_END_OF_RING;
1571 				ring[index].buffer1 =
1572 				    (uint32_t)dma_cookie.dmac_address;
1573 				ring[index].desc1.buffer_size1 =
1574 				    dma_cookie.dmac_size;
1575 				ring[index].buffer2 = (uint32_t)(0);
1576 				dnetp->free_desc--;
1577 				ASSERT(dnetp->free_desc >= 0);
1578 			}
1579 			totlen += dma_cookie.dmac_size;
1580 			bufn++;
1581 			if (--ncookies)
1582 				ddi_dma_nextcookie(dnetp->dma_handle_tx,
1583 				    &dma_cookie);
1584 		}
1585 		(void) ddi_dma_unbind_handle(dnetp->dma_handle_tx);
1586 		bp = bp->b_cont;
1587 	}
1588 
1589 	if (error == 1) {
1590 		dnetp->stat_defer++;
1591 		dnetp->free_desc = avail;
1592 		dnetp->need_gld_sched = 1;
1593 		mutex_exit(&dnetp->txlock);
1594 		return (GLD_TX_RESEND);
1595 	} else if (error) {
1596 		dnetp->free_desc = avail;
1597 		mutex_exit(&dnetp->txlock);
1598 		freemsg(mp);
1599 		return (0);	/* Drop packet, don't retry */
1600 	}
1601 
1602 	if (totlen > ETHERMAX) {
1603 		cmn_err(CE_WARN, "DNET: tried to send large %d packet", totlen);
1604 		dnetp->free_desc = avail;
1605 		mutex_exit(&dnetp->txlock);
1606 		freemsg(mp);
1607 		return (0);	/* We don't want to repeat this attempt */
1608 	}
1609 
1610 	/*
1611 	 * Remeber the message buffer pointer to do freemsg() at xmit
1612 	 * interrupt time.
1613 	 */
1614 	dnetp->tx_msgbufp[end_index] = mp;
1615 
1616 	/*
1617 	 * Now set the first/last buffer and own bits
1618 	 * Since the 21040 looks for these bits set in the
1619 	 * first buffer, work backwards in multiple buffers.
1620 	 */
1621 	ring[end_index].desc1.last_desc = 1;
1622 	ring[end_index].desc1.int_on_comp = 1;
1623 	for (index = end_index; index != start_index;
1624 	    index = PrevTXIndex(index))
1625 		ring[index].desc0.own = 1;
1626 	ring[start_index].desc1.first_desc = 1;
1627 	ring[start_index].desc0.own = 1;
1628 
1629 	dnetp->tx_current_desc = NextTXIndex(end_index);
1630 
1631 	/*
1632 	 * Safety check: make sure end-of-ring is set in last desc.
1633 	 */
1634 	ASSERT(ring[dnetp->max_tx_desc-1].desc1.end_of_ring != 0);
1635 
1636 	/*
1637 	 * Enable xmit interrupt if we are running out of xmit descriptors
1638 	 * or there are more packets on the queue waiting to be transmitted.
1639 	 */
1640 #ifdef GLD_INTR_WAIT	/* XXX This relies on new GLD changes */
1641 	if (dnetp->free_desc <= dnet_xmit_threshold)
1642 		tx_interrupt_mask = TX_INTERRUPT_MASK;
1643 	else
1644 		tx_interrupt_mask = (macinfo->gldm_GLD_flags & GLD_INTR_WAIT) ?
1645 		    TX_INTERRUPT_MASK : 0;
1646 #else
1647 	tx_interrupt_mask = TX_INTERRUPT_MASK;
1648 #endif
1649 
1650 	mutex_exit(&dnetp->txlock);
1651 	mutex_enter(&dnetp->intrlock);
1652 	enable_interrupts(dnetp, tx_interrupt_mask);
1653 
1654 	/*
1655 	 * Kick the transmitter
1656 	 */
1657 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, TX_POLL_REG),
1658 	    TX_POLL_DEMAND);
1659 	mutex_exit(&dnetp->intrlock);
1660 	return (GLD_TX_OK);		/* successful transmit attempt */
1661 }
1662 
1663 /*
1664  *	dnetintr() -- interrupt from board to inform us that a receive or
1665  *	transmit has completed.
1666  */
1667 
1668 
1669 static uint_t
1670 dnetintr(gld_mac_info_t *macinfo)
1671 {
1672 	struct dnetinstance *dnetp =	/* Our private device info */
1673 	    (struct dnetinstance *)macinfo->gldm_private;
1674 	uint32_t		int_status;
1675 	uint32_t		tx_interrupt_mask;
1676 
1677 	mutex_enter(&dnetp->intrlock);
1678 #ifdef DNETDEBUG
1679 	if (dnetdebug & DNETINT)
1680 		cmn_err(CE_NOTE, "dnetintr(0x%p)", (void *)macinfo);
1681 #endif
1682 	if (dnetp->suspended) {
1683 		mutex_exit(&dnetp->intrlock);
1684 		return (DDI_INTR_UNCLAIMED);
1685 	}
1686 
1687 	int_status = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg,
1688 	    STATUS_REG));
1689 
1690 	/*
1691 	 * If interrupt was not from this board
1692 	 */
1693 	if (!(int_status & (NORMAL_INTR_SUMM | ABNORMAL_INTR_SUMM))) {
1694 		mutex_exit(&dnetp->intrlock);
1695 		return (DDI_INTR_UNCLAIMED);
1696 	}
1697 
1698 	dnetp->stat_intr++;
1699 
1700 	if (int_status & GPTIMER_INTR) {
1701 		ddi_put32(dnetp->io_handle,
1702 		    REG32(dnetp->io_reg, STATUS_REG), GPTIMER_INTR);
1703 		if (dnetp->timer.cb)
1704 			dnetp->timer.cb(dnetp);
1705 		else
1706 			cmn_err(CE_WARN, "dnet: unhandled timer interrupt");
1707 	}
1708 
1709 	if (int_status & TX_INTR) {
1710 		ddi_put32(dnetp->io_handle,
1711 		    REG32(dnetp->io_reg, STATUS_REG), TX_INTR);
1712 		mutex_enter(&dnetp->txlock);
1713 		if (dnetp->need_gld_sched) {
1714 			mutex_exit(&dnetp->txlock);
1715 			mutex_exit(&dnetp->intrlock);
1716 			gld_sched(macinfo);
1717 			mutex_enter(&dnetp->intrlock);
1718 			mutex_enter(&dnetp->txlock);
1719 			dnetp->need_gld_sched = 0;
1720 		}
1721 		/* reclaim any xmit descriptors that are completed */
1722 		dnet_reclaim_Tx_desc(macinfo);
1723 		mutex_exit(&dnetp->txlock);
1724 	}
1725 
1726 	/*
1727 	 * Check if receive interrupt bit is set
1728 	 */
1729 	if (int_status & (RX_INTR | RX_UNAVAIL_INTR)) {
1730 		ddi_put32(dnetp->io_handle,
1731 		    REG32(dnetp->io_reg, STATUS_REG),
1732 		    int_status & (RX_INTR | RX_UNAVAIL_INTR));
1733 		dnet_getp(macinfo);
1734 	}
1735 
1736 	if (int_status & ABNORMAL_INTR_SUMM) {
1737 		/*
1738 		 * Check for system error
1739 		 */
1740 		if (int_status & SYS_ERR) {
1741 			if ((int_status & SYS_ERR_BITS) == MASTER_ABORT)
1742 				cmn_err(CE_WARN, "DNET: Bus Master Abort");
1743 			if ((int_status & SYS_ERR_BITS) == TARGET_ABORT)
1744 				cmn_err(CE_WARN, "DNET: Bus Target Abort");
1745 			if ((int_status & SYS_ERR_BITS) == PARITY_ERROR)
1746 				cmn_err(CE_WARN, "DNET: Parity error");
1747 		}
1748 
1749 		/*
1750 		 * If the jabber has timed out then reset the chip
1751 		 */
1752 		if (int_status & TX_JABBER_TIMEOUT)
1753 			cmn_err(CE_WARN, "DNET: Jabber timeout.");
1754 
1755 		/*
1756 		 * If an underflow has occurred, reset the chip
1757 		 */
1758 		if (int_status & TX_UNDERFLOW)
1759 			cmn_err(CE_WARN, "DNET: Tx Underflow.");
1760 
1761 #ifdef DNETDEBUG
1762 		if (dnetdebug & DNETINT)
1763 			cmn_err(CE_NOTE, "Trying to reset...");
1764 #endif
1765 		dnet_reset_board(macinfo);
1766 		dnet_init_board(macinfo);
1767 		/* XXX function return value ignored */
1768 		(void) dnet_start(macinfo);
1769 	}
1770 
1771 	/*
1772 	 * Enable the interrupts. Enable xmit interrupt only if we are
1773 	 * running out of free descriptors or if there are packets
1774 	 * in the queue waiting to be transmitted.
1775 	 */
1776 #ifdef GLD_INTR_WAIT	/* XXX This relies on new GLD changes */
1777 	if (dnetp->free_desc <= dnet_xmit_threshold)
1778 		tx_interrupt_mask = TX_INTERRUPT_MASK;
1779 	else
1780 		tx_interrupt_mask = (macinfo->gldm_GLD_flags & GLD_INTR_WAIT) ?
1781 		    TX_INTERRUPT_MASK : 0;
1782 #else
1783 	tx_interrupt_mask = TX_INTERRUPT_MASK;
1784 #endif
1785 	enable_interrupts(dnetp, tx_interrupt_mask);
1786 	mutex_exit(&dnetp->intrlock);
1787 	return (DDI_INTR_CLAIMED);	/* Indicate it was our interrupt */
1788 }
1789 
1790 static void
1791 dnet_getp(gld_mac_info_t *macinfo)
1792 {
1793 	struct dnetinstance *dnetp =
1794 	    (struct dnetinstance *)macinfo->gldm_private;
1795 	int packet_length, index;
1796 	mblk_t	*mp;
1797 	caddr_t 	virtual_address;
1798 	struct	rx_desc_type *desc = dnetp->rx_desc;
1799 	int marker = dnetp->rx_current_desc;
1800 	int misses;
1801 
1802 #ifdef DNETDEBUG
1803 	if (dnetdebug & DNETRECV)
1804 		cmn_err(CE_NOTE, "dnet_getp(0x%p)", (void *)macinfo);
1805 #endif
1806 
1807 	if (!dnetp->overrun_workaround) {
1808 		/*
1809 		 * If the workaround is not in place, we must still update
1810 		 * the missed frame statistic from the on-chip counter.
1811 		 */
1812 		misses = ddi_get32(dnetp->io_handle,
1813 		    REG32(dnetp->io_reg, MISSED_FRAME_REG));
1814 		dnetp->stat_missed += (misses & MISSED_FRAME_MASK);
1815 	}
1816 
1817 	/* While host owns the current descriptor */
1818 	while (!(desc[dnetp->rx_current_desc].desc0.own)) {
1819 		struct free_ptr *frp;
1820 		caddr_t newbuf;
1821 		struct rbuf_list *rp;
1822 
1823 		index = dnetp->rx_current_desc;
1824 		ASSERT(desc[index].desc0.first_desc != 0);
1825 
1826 		/*
1827 		 * DMA overrun errata from DEC: avoid possible bus hangs
1828 		 * and data corruption
1829 		 */
1830 		if (dnetp->overrun_workaround &&
1831 		    marker == dnetp->rx_current_desc) {
1832 			int opn;
1833 			do {
1834 				marker = (marker+1) % dnetp->max_rx_desc;
1835 			} while (!(dnetp->rx_desc[marker].desc0.own) &&
1836 			    marker != index);
1837 
1838 			misses = ddi_get32(dnetp->io_handle,
1839 			    REG32(dnetp->io_reg, MISSED_FRAME_REG));
1840 			dnetp->stat_missed +=
1841 			    (misses & MISSED_FRAME_MASK);
1842 			if (misses & OVERFLOW_COUNTER_MASK) {
1843 				/*
1844 				 * Overflow(s) have occurred : stop receiver,
1845 				 * and wait until in stopped state
1846 				 */
1847 				opn = ddi_get32(dnetp->io_handle,
1848 				    REG32(dnetp->io_reg, OPN_MODE_REG));
1849 				ddi_put32(dnetp->io_handle,
1850 				    REG32(dnetp->io_reg, OPN_MODE_REG),
1851 				    opn & ~(START_RECEIVE));
1852 
1853 				do {
1854 					drv_usecwait(10);
1855 				} while ((ddi_get32(dnetp->io_handle,
1856 				    REG32(dnetp->io_reg, STATUS_REG)) &
1857 				    RECEIVE_PROCESS_STATE) != 0);
1858 #ifdef DNETDEBUG
1859 				if (dnetdebug & DNETRECV)
1860 					cmn_err(CE_CONT, "^*");
1861 #endif
1862 				/* Discard probably corrupt frames */
1863 				while (!(dnetp->rx_desc[index].desc0.own)) {
1864 					dnetp->rx_desc[index].desc0.own = 1;
1865 					index = (index+1) % dnetp->max_rx_desc;
1866 					dnetp->stat_missed++;
1867 				}
1868 
1869 				/* restart the receiver */
1870 				opn = ddi_get32(dnetp->io_handle,
1871 				    REG32(dnetp->io_reg, OPN_MODE_REG));
1872 				ddi_put32(dnetp->io_handle,
1873 				    REG32(dnetp->io_reg, OPN_MODE_REG),
1874 				    opn | START_RECEIVE);
1875 				marker = dnetp->rx_current_desc = index;
1876 				continue;
1877 			}
1878 			/*
1879 			 * At this point, we know that all packets before
1880 			 * "marker" were received before a dma overrun occurred
1881 			 */
1882 		}
1883 
1884 		/*
1885 		 * If we get an oversized packet it could span multiple
1886 		 * descriptors.  If this happens an error bit should be set.
1887 		 */
1888 		while (desc[index].desc0.last_desc == 0) {
1889 			index = (index + 1) % dnetp->max_rx_desc;
1890 			if (desc[index].desc0.own)
1891 				return;	/* not done receiving large packet */
1892 		}
1893 		while (dnetp->rx_current_desc != index) {
1894 			desc[dnetp->rx_current_desc].desc0.own = 1;
1895 			dnetp->rx_current_desc =
1896 			    (dnetp->rx_current_desc + 1) % dnetp->max_rx_desc;
1897 #ifdef DNETDEBUG
1898 			if (dnetdebug & DNETRECV)
1899 				cmn_err(CE_WARN, "dnet: received large packet");
1900 #endif
1901 		}
1902 
1903 		packet_length = desc[index].desc0.frame_len;
1904 
1905 		/*
1906 		 * Remove CRC from received data. This is an artefact of the
1907 		 * 21x4x chip and should not be passed higher up the network
1908 		 * stack.
1909 		 */
1910 		packet_length -= ETHERFCSL;
1911 
1912 #ifdef DNETDEBUG
1913 		if (dnetdebug & DNETRECV) {
1914 			if (packet_length > ETHERMAX)
1915 				cmn_err(CE_WARN, "dnet: large packet size %d",
1916 				    packet_length);
1917 		}
1918 #endif
1919 
1920 		/* get the virtual address of the packet received */
1921 		virtual_address =
1922 		    dnetp->rx_buf_vaddr[index];
1923 
1924 		/*
1925 		 * If no packet errors then do:
1926 		 * 	1. Allocate a new receive buffer so that we can
1927 		 *	   use the current buffer as streams buffer to
1928 		 *	   avoid bcopy.
1929 		 *	2. If we got a new receive buffer then allocate
1930 		 *	   an mblk using desballoc().
1931 		 *	3. Otherwise use the mblk from allocb() and do
1932 		 *	   the bcopy.
1933 		 */
1934 		frp = NULL;
1935 		rp = NULL;
1936 		newbuf = NULL;
1937 		mp = NULL;
1938 		if (!desc[index].desc0.err_summary) {
1939 			ASSERT(packet_length < rx_buf_size);
1940 			/*
1941 			 * Allocate another receive buffer for this descriptor.
1942 			 * If we fail to allocate then we do the normal bcopy.
1943 			 */
1944 			rp = dnet_rbuf_alloc(dnetp->devinfo, 0);
1945 			if (rp != NULL) {
1946 				newbuf = rp->rbuf_vaddr;
1947 				frp = kmem_zalloc(sizeof (*frp), KM_NOSLEEP);
1948 				if (frp != NULL) {
1949 					frp->free_rtn.free_func =
1950 					    dnet_freemsg_buf;
1951 					frp->free_rtn.free_arg = (char *)frp;
1952 					frp->buf = virtual_address;
1953 					mp = desballoc(
1954 					    (uchar_t *)virtual_address,
1955 					    packet_length, 0, &frp->free_rtn);
1956 					if (mp == NULL) {
1957 						kmem_free(frp, sizeof (*frp));
1958 						dnet_rbuf_free((caddr_t)newbuf);
1959 						frp = NULL;
1960 						newbuf = NULL;
1961 					}
1962 				}
1963 			}
1964 			if (mp == NULL) {
1965 				if (newbuf != NULL)
1966 					dnet_rbuf_free((caddr_t)newbuf);
1967 				mp = allocb(packet_length, 0);
1968 			}
1969 		}
1970 
1971 		if (desc[index].desc0.err_summary || (mp == NULL)) {
1972 
1973 			/* Update gld statistics */
1974 			if (desc[index].desc0.err_summary)
1975 				update_rx_stats(macinfo, index);
1976 			else
1977 				dnetp->stat_norcvbuf++;
1978 
1979 			/*
1980 			 * Reset ownership of the descriptor.
1981 			 */
1982 			desc[index].desc0.own = 1;
1983 			dnetp->rx_current_desc =
1984 			    (dnetp->rx_current_desc+1) % dnetp->max_rx_desc;
1985 
1986 			/* Demand receive polling by the chip */
1987 			ddi_put32(dnetp->io_handle,
1988 			    REG32(dnetp->io_reg, RX_POLL_REG), RX_POLL_DEMAND);
1989 
1990 			continue;
1991 		}
1992 
1993 		if (newbuf != NULL) {
1994 			uint32_t end_paddr;
1995 			/* attach the new buffer to the rx descriptor */
1996 			dnetp->rx_buf_vaddr[index] = newbuf;
1997 			dnetp->rx_buf_paddr[index] = rp->rbuf_paddr;
1998 			desc[index].buffer1 = rp->rbuf_paddr;
1999 			desc[index].desc1.buffer_size1 = rx_buf_size;
2000 			desc[index].desc1.buffer_size2 = 0;
2001 			end_paddr = rp->rbuf_endpaddr;
2002 			if ((desc[index].buffer1 & ~dnetp->pgmask) !=
2003 			    (end_paddr & ~dnetp->pgmask)) {
2004 				/* discontiguous */
2005 				desc[index].buffer2 = end_paddr&~dnetp->pgmask;
2006 				desc[index].desc1.buffer_size2 =
2007 				    (end_paddr & dnetp->pgmask) + 1;
2008 				desc[index].desc1.buffer_size1 =
2009 				    rx_buf_size-desc[index].desc1.buffer_size2;
2010 			}
2011 		} else {
2012 			/* couldn't allocate another buffer; copy the data */
2013 			BCOPY((caddr_t)virtual_address, (caddr_t)mp->b_wptr,
2014 			    packet_length);
2015 		}
2016 
2017 		mp->b_wptr += packet_length;
2018 
2019 		desc[dnetp->rx_current_desc].desc0.own = 1;
2020 
2021 		/*
2022 		 * Increment receive desc index. This is for the scan of
2023 		 * next packet
2024 		 */
2025 		dnetp->rx_current_desc =
2026 		    (dnetp->rx_current_desc+1) % dnetp->max_rx_desc;
2027 
2028 		/* Demand polling by chip */
2029 		ddi_put32(dnetp->io_handle,
2030 		    REG32(dnetp->io_reg, RX_POLL_REG), RX_POLL_DEMAND);
2031 
2032 		/* send the packet upstream */
2033 		mutex_exit(&dnetp->intrlock);
2034 		gld_recv(macinfo, mp);
2035 		mutex_enter(&dnetp->intrlock);
2036 	}
2037 }
2038 /*
2039  * Function to update receive statistics
2040  */
2041 static void
2042 update_rx_stats(gld_mac_info_t *macinfo, int index)
2043 {
2044 	struct	dnetinstance	*dnetp =
2045 	    (struct dnetinstance *)macinfo->gldm_private;
2046 	struct rx_desc_type *descp = &(dnetp->rx_desc[index]);
2047 
2048 	/*
2049 	 * Update gld statistics
2050 	 */
2051 	dnetp->stat_errrcv++;
2052 
2053 	if (descp->desc0.overflow)	{
2054 		/* FIFO Overrun */
2055 		dnetp->stat_overflow++;
2056 	}
2057 
2058 	if (descp->desc0.collision) {
2059 		/*EMPTY*/
2060 		/* Late Colllision on receive */
2061 		/* no appropriate counter */
2062 	}
2063 
2064 	if (descp->desc0.crc) {
2065 		/* CRC Error */
2066 		dnetp->stat_crc++;
2067 	}
2068 
2069 	if (descp->desc0.runt_frame) {
2070 		/* Runt Error */
2071 		dnetp->stat_short++;
2072 	}
2073 
2074 	if (descp->desc0.desc_err) {
2075 		/*EMPTY*/
2076 		/* Not enough receive descriptors */
2077 		/* This condition is accounted in dnetintr() */
2078 		/* macinfo->gldm_stats.glds_missed++; */
2079 	}
2080 
2081 	if (descp->desc0.frame2long) {
2082 		dnetp->stat_frame++;
2083 	}
2084 }
2085 
2086 /*
2087  * Function to update transmit statistics
2088  */
2089 static void
2090 update_tx_stats(gld_mac_info_t *macinfo, int index)
2091 {
2092 	struct	dnetinstance	*dnetp =
2093 	    (struct dnetinstance *)macinfo->gldm_private;
2094 	struct tx_desc_type *descp = &(dnetp->tx_desc[index]);
2095 	int	fd;
2096 	media_block_t	*block = dnetp->selected_media_block;
2097 
2098 
2099 	/* Update gld statistics */
2100 	dnetp->stat_errxmt++;
2101 
2102 	/* If we're in full-duplex don't count collisions or carrier loss. */
2103 	if (dnetp->mii_up) {
2104 		fd = dnetp->mii_duplex;
2105 	} else {
2106 		/* Rely on media code */
2107 		fd = block->media_code == MEDIA_TP_FD ||
2108 		    block->media_code == MEDIA_SYM_SCR_FD;
2109 	}
2110 
2111 	if (descp->desc0.collision_count && !fd) {
2112 		dnetp->stat_collisions += descp->desc0.collision_count;
2113 	}
2114 
2115 	if (descp->desc0.late_collision && !fd) {
2116 		dnetp->stat_xmtlatecoll++;
2117 	}
2118 
2119 	if (descp->desc0.excess_collision && !fd) {
2120 		dnetp->stat_excoll++;
2121 	}
2122 
2123 	if (descp->desc0.underflow) {
2124 		dnetp->stat_underflow++;
2125 	}
2126 
2127 #if 0
2128 	if (descp->desc0.tx_jabber_to) {
2129 		/* no appropriate counter */
2130 	}
2131 #endif
2132 
2133 	if (descp->desc0.carrier_loss && !fd) {
2134 		dnetp->stat_nocarrier++;
2135 	}
2136 
2137 	if (descp->desc0.no_carrier && !fd) {
2138 		dnetp->stat_nocarrier++;
2139 	}
2140 }
2141 
2142 /*
2143  *	========== Media Selection Setup Routines ==========
2144  */
2145 
2146 
2147 static void
2148 write_gpr(struct dnetinstance *dnetp, uint32_t val)
2149 {
2150 #ifdef DEBUG
2151 	if (dnetdebug & DNETREGCFG)
2152 		cmn_err(CE_NOTE, "GPR: %x", val);
2153 #endif
2154 	switch (dnetp->board_type) {
2155 	case DEVICE_ID_21143:
2156 		/* Set the correct bit for a control write */
2157 		if (val & GPR_CONTROL_WRITE)
2158 			val |= CWE_21143, val &= ~GPR_CONTROL_WRITE;
2159 		/* Write to upper half of CSR15 */
2160 		dnetp->gprsia = (dnetp->gprsia & 0xffff) | (val << 16);
2161 		ddi_put32(dnetp->io_handle,
2162 		    REG32(dnetp->io_reg, SIA_GENERAL_REG), dnetp->gprsia);
2163 		break;
2164 	default:
2165 		/* Set the correct bit for a control write */
2166 		if (val & GPR_CONTROL_WRITE)
2167 			val |= CWE_21140, val &= ~GPR_CONTROL_WRITE;
2168 		ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, GP_REG), val);
2169 		break;
2170 	}
2171 }
2172 
2173 static uint32_t
2174 read_gpr(struct dnetinstance *dnetp)
2175 {
2176 	switch (dnetp->board_type) {
2177 	case DEVICE_ID_21143:
2178 		/* Read upper half of CSR15 */
2179 		return (ddi_get32(dnetp->io_handle,
2180 		    REG32(dnetp->io_reg, SIA_GENERAL_REG)) >> 16);
2181 	default:
2182 		return (ddi_get32(dnetp->io_handle,
2183 		    REG32(dnetp->io_reg, GP_REG)));
2184 	}
2185 }
2186 
2187 static void
2188 set_gpr(gld_mac_info_t *macinfo)
2189 {
2190 	uint32_t *sequence;
2191 	int len;
2192 	struct dnetinstance *dnetp = (struct dnetinstance *)
2193 	    macinfo->gldm_private;
2194 	LEAF_FORMAT *leaf = &dnetp->sr.leaf[dnetp->leaf];
2195 	media_block_t *block = dnetp->selected_media_block;
2196 	int i;
2197 
2198 	if (ddi_getlongprop(DDI_DEV_T_ANY, dnetp->devinfo,
2199 	    DDI_PROP_DONTPASS, "gpr-sequence", (caddr_t)&sequence,
2200 	    &len) == DDI_PROP_SUCCESS) {
2201 		for (i = 0; i < len / sizeof (uint32_t); i++)
2202 			write_gpr(dnetp, sequence[i]);
2203 		kmem_free(sequence, len);
2204 	} else {
2205 		/*
2206 		 * Write the reset sequence if this is the first time this
2207 		 * block has been selected.
2208 		 */
2209 		if (block->rstseqlen) {
2210 			for (i = 0; i < block->rstseqlen; i++)
2211 				write_gpr(dnetp, block->rstseq[i]);
2212 			/*
2213 			 * XXX Legacy blocks do not have reset sequences, so the
2214 			 * static blocks will never be modified by this
2215 			 */
2216 			block->rstseqlen = 0;
2217 		}
2218 		if (leaf->gpr)
2219 			write_gpr(dnetp, leaf->gpr | GPR_CONTROL_WRITE);
2220 
2221 		/* write GPR sequence each time */
2222 		for (i = 0; i < block->gprseqlen; i++)
2223 			write_gpr(dnetp, block->gprseq[i]);
2224 	}
2225 
2226 	/* This has possibly caused a PHY to reset.  Let MII know */
2227 	if (dnetp->phyaddr != -1)
2228 		/* XXX function return value ignored */
2229 		(void) mii_sync(dnetp->mii, dnetp->phyaddr);
2230 	drv_usecwait(5);
2231 }
2232 
2233 /* set_opr() - must be called with intrlock held */
2234 
2235 static void
2236 set_opr(gld_mac_info_t *macinfo)
2237 {
2238 	uint32_t fd, mb1, sf;
2239 
2240 	struct dnetinstance *dnetp =
2241 	    (struct dnetinstance *)macinfo->gldm_private;
2242 	int 		opnmode_len;
2243 	uint32_t val;
2244 	media_block_t *block = dnetp->selected_media_block;
2245 
2246 	ASSERT(block);
2247 
2248 	/* Check for custom "opnmode_reg" property */
2249 	opnmode_len = sizeof (val);
2250 	if (ddi_prop_op(DDI_DEV_T_ANY, dnetp->devinfo,
2251 	    PROP_LEN_AND_VAL_BUF, DDI_PROP_DONTPASS, "opnmode_reg",
2252 	    (caddr_t)&val, &opnmode_len) != DDI_PROP_SUCCESS)
2253 		opnmode_len = 0;
2254 
2255 	/* Some bits exist only on 21140 and greater */
2256 	if (dnetp->board_type != DEVICE_ID_21040 &&
2257 	    dnetp->board_type != DEVICE_ID_21041) {
2258 		mb1 = OPN_REG_MB1;
2259 		sf = STORE_AND_FORWARD;
2260 	} else {
2261 		mb1 = sf = 0;
2262 		mb1 = OPN_REG_MB1; /* Needed for 21040? */
2263 	}
2264 
2265 	if (opnmode_len) {
2266 		ddi_put32(dnetp->io_handle,
2267 		    REG32(dnetp->io_reg, OPN_MODE_REG), val);
2268 		dnet_reset_board(macinfo);
2269 		ddi_put32(dnetp->io_handle,
2270 		    REG32(dnetp->io_reg, OPN_MODE_REG), val);
2271 		return;
2272 	}
2273 
2274 	/*
2275 	 * Set each bit in CSR6 that we want
2276 	 */
2277 
2278 	/* Always want these bits set */
2279 	val = HASH_FILTERING | HASH_ONLY | TX_THRESHOLD_160 | mb1 | sf;
2280 
2281 	/* Promiscuous mode */
2282 	val |= dnetp->promisc ? PROM_MODE : 0;
2283 
2284 	/* Scrambler for SYM style media */
2285 	val |= ((block->command & CMD_SCR) && !dnetp->disable_scrambler) ?
2286 	    SCRAMBLER_MODE : 0;
2287 
2288 	/* Full duplex */
2289 	if (dnetp->mii_up) {
2290 		fd = dnetp->mii_duplex;
2291 	} else {
2292 		/* Rely on media code */
2293 		fd = block->media_code == MEDIA_TP_FD ||
2294 		    block->media_code == MEDIA_SYM_SCR_FD;
2295 	}
2296 
2297 	/* Port select (and therefore, heartbeat disable) */
2298 	val |= block->command & CMD_PS ? (PORT_SELECT | HEARTBEAT_DISABLE) : 0;
2299 
2300 	/* PCS function */
2301 	val |= (block->command) & CMD_PCS ? PCS_FUNCTION : 0;
2302 	val |= fd ? FULL_DUPLEX : 0;
2303 
2304 #ifdef DNETDEBUG
2305 	if (dnetdebug & DNETREGCFG)
2306 		cmn_err(CE_NOTE, "OPN: %x", val);
2307 #endif
2308 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG), val);
2309 	dnet_reset_board(macinfo);
2310 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, OPN_MODE_REG), val);
2311 }
2312 
2313 static void
2314 set_sia(gld_mac_info_t *macinfo)
2315 {
2316 	struct dnetinstance *dnetp = (struct dnetinstance *)
2317 	    (macinfo->gldm_private);
2318 	media_block_t *block = dnetp->selected_media_block;
2319 
2320 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
2321 	if (block->type == 2) {
2322 		int sia_delay;
2323 #ifdef DNETDEBUG
2324 		if (dnetdebug & DNETREGCFG)
2325 			cmn_err(CE_NOTE,
2326 			    "SIA: CSR13: %x, CSR14: %x, CSR15: %x",
2327 			    block->un.sia.csr13,
2328 			    block->un.sia.csr14,
2329 			    block->un.sia.csr15);
2330 #endif
2331 		sia_delay = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo,
2332 		    DDI_PROP_DONTPASS, "sia-delay", 10000);
2333 
2334 		ddi_put32(dnetp->io_handle,
2335 		    REG32(dnetp->io_reg, SIA_CONNECT_REG), 0);
2336 
2337 		ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, SIA_TXRX_REG),
2338 		    block->un.sia.csr14);
2339 
2340 		/*
2341 		 * For '143, we need to write through a copy of the register
2342 		 * to keep the GP half intact
2343 		 */
2344 		dnetp->gprsia = (dnetp->gprsia&0xffff0000)|block->un.sia.csr15;
2345 		ddi_put32(dnetp->io_handle,
2346 		    REG32(dnetp->io_reg, SIA_GENERAL_REG),
2347 		    dnetp->gprsia);
2348 
2349 		ddi_put32(dnetp->io_handle,
2350 		    REG32(dnetp->io_reg, SIA_CONNECT_REG),
2351 		    block->un.sia.csr13);
2352 
2353 		drv_usecwait(sia_delay);
2354 
2355 	} else if (dnetp->board_type != DEVICE_ID_21140) {
2356 		ddi_put32(dnetp->io_handle,
2357 		    REG32(dnetp->io_reg, SIA_CONNECT_REG), 0);
2358 		ddi_put32(dnetp->io_handle,
2359 		    REG32(dnetp->io_reg, SIA_TXRX_REG), 0);
2360 	}
2361 }
2362 
2363 /*
2364  *	========== Buffer Management Routines ==========
2365  */
2366 
2367 /*
2368  * This function (re)allocates the receive and transmit buffers and
2369  * descriptors.  It can be called more than once per instance, though
2370  * currently it is only called from attach.  It should only be called
2371  * while the device is reset.
2372  */
2373 static int
2374 dnet_alloc_bufs(gld_mac_info_t *macinfo)
2375 {
2376 	struct dnetinstance	*dnetp = (struct dnetinstance *)
2377 	    (macinfo->gldm_private);
2378 	int i;
2379 	size_t len;
2380 	int page_size;
2381 	int realloc = 0;
2382 	int nrecv_desc_old = 0;
2383 	ddi_dma_cookie_t cookie;
2384 	uint_t ncookies;
2385 
2386 	/*
2387 	 * check if we are trying to reallocate with different xmit/recv
2388 	 * descriptor ring sizes.
2389 	 */
2390 	if ((dnetp->tx_desc != NULL) &&
2391 	    (dnetp->nxmit_desc != dnetp->max_tx_desc))
2392 		realloc = 1;
2393 
2394 	if ((dnetp->rx_desc != NULL) &&
2395 	    (dnetp->nrecv_desc != dnetp->max_rx_desc))
2396 		realloc = 1;
2397 
2398 	/* free up the old buffers if we are reallocating them */
2399 	if (realloc) {
2400 		nrecv_desc_old = dnetp->nrecv_desc;
2401 		dnet_free_bufs(macinfo); /* free the old buffers */
2402 	}
2403 
2404 	if (dnetp->dma_handle == NULL)
2405 		if (ddi_dma_alloc_handle(dnetp->devinfo, &dma_attr,
2406 		    DDI_DMA_SLEEP, 0, &dnetp->dma_handle) != DDI_SUCCESS)
2407 			return (FAILURE);
2408 
2409 	if (dnetp->dma_handle_tx == NULL)
2410 		if (ddi_dma_alloc_handle(dnetp->devinfo, &dma_attr_tx,
2411 		    DDI_DMA_SLEEP, 0, &dnetp->dma_handle_tx) != DDI_SUCCESS)
2412 			return (FAILURE);
2413 
2414 	if (dnetp->dma_handle_txdesc == NULL)
2415 		if (ddi_dma_alloc_handle(dnetp->devinfo, &dma_attr,
2416 		    DDI_DMA_SLEEP, 0, &dnetp->dma_handle_txdesc) != DDI_SUCCESS)
2417 			return (FAILURE);
2418 
2419 	if (dnetp->dma_handle_setbuf == NULL)
2420 		if (ddi_dma_alloc_handle(dnetp->devinfo, &dma_attr,
2421 		    DDI_DMA_SLEEP, 0, &dnetp->dma_handle_setbuf) != DDI_SUCCESS)
2422 			return (FAILURE);
2423 
2424 	page_size = ddi_ptob(dnetp->devinfo, 1);
2425 
2426 	dnetp->pgmask = page_size - 1;
2427 
2428 	/* allocate setup buffer if necessary */
2429 	if (dnetp->setup_buf_vaddr == NULL) {
2430 		if (ddi_dma_mem_alloc(dnetp->dma_handle_setbuf,
2431 		    SETUPBUF_SIZE, &accattr, DDI_DMA_STREAMING,
2432 		    DDI_DMA_DONTWAIT, 0, (caddr_t *)&dnetp->setup_buf_vaddr,
2433 		    &len, &dnetp->setup_buf_acchdl) != DDI_SUCCESS)
2434 			return (FAILURE);
2435 
2436 		if (ddi_dma_addr_bind_handle(dnetp->dma_handle_setbuf,
2437 		    NULL, dnetp->setup_buf_vaddr, SETUPBUF_SIZE,
2438 		    DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP,
2439 		    NULL, &cookie, &ncookies) != DDI_DMA_MAPPED)
2440 			return (FAILURE);
2441 
2442 		dnetp->setup_buf_paddr = cookie.dmac_address;
2443 		bzero(dnetp->setup_buf_vaddr, len);
2444 	}
2445 
2446 	/* allocate xmit descriptor array of size dnetp->max_tx_desc */
2447 	if (dnetp->tx_desc == NULL) {
2448 		if (ddi_dma_mem_alloc(dnetp->dma_handle_txdesc,
2449 		    sizeof (struct tx_desc_type) * dnetp->max_tx_desc,
2450 		    &accattr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0,
2451 		    (caddr_t *)&dnetp->tx_desc, &len,
2452 		    &dnetp->tx_desc_acchdl) != DDI_SUCCESS)
2453 			return (FAILURE);
2454 
2455 		if (ddi_dma_addr_bind_handle(dnetp->dma_handle_txdesc,
2456 		    NULL, (caddr_t)dnetp->tx_desc,
2457 		    sizeof (struct tx_desc_type) * dnetp->max_tx_desc,
2458 		    DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP,
2459 		    NULL, &cookie, &ncookies) != DDI_DMA_MAPPED)
2460 			return (FAILURE);
2461 		dnetp->tx_desc_paddr = cookie.dmac_address;
2462 		bzero(dnetp->tx_desc, len);
2463 		dnetp->nxmit_desc = dnetp->max_tx_desc;
2464 
2465 		dnetp->tx_msgbufp =
2466 		    kmem_zalloc(dnetp->max_tx_desc * sizeof (mblk_t **),
2467 		    KM_SLEEP);
2468 	}
2469 
2470 	/* allocate receive descriptor array of size dnetp->max_rx_desc */
2471 	if (dnetp->rx_desc == NULL) {
2472 		int ndesc;
2473 
2474 		if (ddi_dma_mem_alloc(dnetp->dma_handle,
2475 		    sizeof (struct rx_desc_type) * dnetp->max_rx_desc,
2476 		    &accattr, DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0,
2477 		    (caddr_t *)&dnetp->rx_desc, &len,
2478 		    &dnetp->rx_desc_acchdl) != DDI_SUCCESS)
2479 			return (FAILURE);
2480 
2481 		if (ddi_dma_addr_bind_handle(dnetp->dma_handle,
2482 		    NULL, (caddr_t)dnetp->rx_desc,
2483 		    sizeof (struct rx_desc_type) * dnetp->max_rx_desc,
2484 		    DDI_DMA_RDWR | DDI_DMA_STREAMING, DDI_DMA_SLEEP,
2485 		    NULL, &cookie, &ncookies) != DDI_DMA_MAPPED)
2486 			return (FAILURE);
2487 
2488 		dnetp->rx_desc_paddr = cookie.dmac_address;
2489 		bzero(dnetp->rx_desc, len);
2490 		dnetp->nrecv_desc = dnetp->max_rx_desc;
2491 
2492 		dnetp->rx_buf_vaddr =
2493 		    kmem_zalloc(dnetp->max_rx_desc * sizeof (caddr_t),
2494 		    KM_SLEEP);
2495 		dnetp->rx_buf_paddr =
2496 		    kmem_zalloc(dnetp->max_rx_desc * sizeof (uint32_t),
2497 		    KM_SLEEP);
2498 		/*
2499 		 * Allocate or add to the pool of receive buffers.  The pool
2500 		 * is shared among all instances of dnet.
2501 		 *
2502 		 * XXX NEEDSWORK
2503 		 *
2504 		 * We arbitrarily allocate twice as many receive buffers as
2505 		 * receive descriptors because we use the buffers for streams
2506 		 * messages to pass the packets up the stream.  We should
2507 		 * instead have initialized constants reflecting
2508 		 * MAX_RX_BUF_2104x and MAX_RX_BUF_2114x, and we should also
2509 		 * probably have a total maximum for the free pool, so that we
2510 		 * don't get out of hand when someone puts in an 8-port board.
2511 		 * The maximum for the entire pool should be the total number
2512 		 * of descriptors for all attached instances together, plus the
2513 		 * total maximum for the free pool.  This maximum would only be
2514 		 * reached after some number of instances allocate buffers:
2515 		 * each instance would add (max_rx_buf-max_rx_desc) to the free
2516 		 * pool.
2517 		 */
2518 		ndesc = dnetp->max_rx_desc - nrecv_desc_old;
2519 		if ((ndesc > 0) &&
2520 		    (dnet_rbuf_init(dnetp->devinfo, ndesc * 2) != 0))
2521 			return (FAILURE);
2522 
2523 		for (i = 0; i < dnetp->max_rx_desc; i++) {
2524 			struct rbuf_list *rp;
2525 
2526 			rp = dnet_rbuf_alloc(dnetp->devinfo, 1);
2527 			if (rp == NULL)
2528 				return (FAILURE);
2529 			dnetp->rx_buf_vaddr[i] = rp->rbuf_vaddr;
2530 			dnetp->rx_buf_paddr[i] = rp->rbuf_paddr;
2531 		}
2532 	}
2533 
2534 	return (SUCCESS);
2535 }
2536 /*
2537  * free descriptors/buffers allocated for this device instance.  This routine
2538  * should only be called while the device is reset.
2539  */
2540 static void
2541 dnet_free_bufs(gld_mac_info_t *macinfo)
2542 {
2543 	int i;
2544 	struct dnetinstance	*dnetp = (struct dnetinstance *)
2545 	    (macinfo->gldm_private);
2546 	/* free up any xmit descriptors/buffers */
2547 	if (dnetp->tx_desc != NULL) {
2548 		ddi_dma_mem_free(&dnetp->tx_desc_acchdl);
2549 		dnetp->tx_desc = NULL;
2550 		/* we use streams buffers for DMA in xmit process */
2551 		if (dnetp->tx_msgbufp != NULL) {
2552 			/* free up any streams message buffers unclaimed */
2553 			for (i = 0; i < dnetp->nxmit_desc; i++) {
2554 				if (dnetp->tx_msgbufp[i] != NULL) {
2555 					freemsg(dnetp->tx_msgbufp[i]);
2556 				}
2557 			}
2558 			kmem_free(dnetp->tx_msgbufp,
2559 			    dnetp->nxmit_desc * sizeof (mblk_t **));
2560 			dnetp->tx_msgbufp = NULL;
2561 		}
2562 		dnetp->nxmit_desc = 0;
2563 	}
2564 
2565 	/* free up any receive descriptors/buffers */
2566 	if (dnetp->rx_desc != NULL) {
2567 		ddi_dma_mem_free(&dnetp->rx_desc_acchdl);
2568 		dnetp->rx_desc = NULL;
2569 		if (dnetp->rx_buf_vaddr != NULL) {
2570 			/* free up the attached rbufs if any */
2571 			for (i = 0; i < dnetp->nrecv_desc; i++) {
2572 				if (dnetp->rx_buf_vaddr[i])
2573 					dnet_rbuf_free(
2574 					    (caddr_t)dnetp->rx_buf_vaddr[i]);
2575 			}
2576 			kmem_free(dnetp->rx_buf_vaddr,
2577 			    dnetp->nrecv_desc * sizeof (caddr_t));
2578 			kmem_free(dnetp->rx_buf_paddr,
2579 			    dnetp->nrecv_desc * sizeof (uint32_t));
2580 			dnetp->rx_buf_vaddr = NULL;
2581 			dnetp->rx_buf_paddr = NULL;
2582 		}
2583 		dnetp->nrecv_desc = 0;
2584 	}
2585 
2586 	if (dnetp->setup_buf_vaddr != NULL) {
2587 		ddi_dma_mem_free(&dnetp->setup_buf_acchdl);
2588 		dnetp->setup_buf_vaddr = NULL;
2589 	}
2590 
2591 	if (dnetp->dma_handle != NULL) {
2592 		(void) ddi_dma_unbind_handle(dnetp->dma_handle);
2593 		ddi_dma_free_handle(&dnetp->dma_handle);
2594 		dnetp->dma_handle = NULL;
2595 	}
2596 
2597 	if (dnetp->dma_handle_tx != NULL) {
2598 		(void) ddi_dma_unbind_handle(dnetp->dma_handle_tx);
2599 		ddi_dma_free_handle(&dnetp->dma_handle_tx);
2600 		dnetp->dma_handle_tx = NULL;
2601 	}
2602 
2603 	if (dnetp->dma_handle_txdesc != NULL) {
2604 		(void) ddi_dma_unbind_handle(dnetp->dma_handle_txdesc);
2605 		ddi_dma_free_handle(&dnetp->dma_handle_txdesc);
2606 		dnetp->dma_handle_txdesc = NULL;
2607 	}
2608 
2609 	if (dnetp->dma_handle_setbuf != NULL) {
2610 		(void) ddi_dma_unbind_handle(dnetp->dma_handle_setbuf);
2611 		ddi_dma_free_handle(&dnetp->dma_handle_setbuf);
2612 		dnetp->dma_handle_setbuf = NULL;
2613 	}
2614 
2615 }
2616 
2617 /*
2618  * Initialize transmit and receive descriptors.
2619  */
2620 static void
2621 dnet_init_txrx_bufs(gld_mac_info_t *macinfo)
2622 {
2623 	int		i;
2624 	struct dnetinstance	*dnetp = (struct dnetinstance *)
2625 	    (macinfo->gldm_private);
2626 
2627 	/*
2628 	 * Initilize all the Tx descriptors
2629 	 */
2630 	for (i = 0; i < dnetp->nxmit_desc; i++) {
2631 		/*
2632 		 * We may be resetting the device due to errors,
2633 		 * so free up any streams message buffer unclaimed.
2634 		 */
2635 		if (dnetp->tx_msgbufp[i] != NULL) {
2636 			freemsg(dnetp->tx_msgbufp[i]);
2637 			dnetp->tx_msgbufp[i] = NULL;
2638 		}
2639 		*(uint32_t *)&dnetp->tx_desc[i].desc0 = 0;
2640 		*(uint32_t *)&dnetp->tx_desc[i].desc1 = 0;
2641 		dnetp->tx_desc[i].buffer1 = 0;
2642 		dnetp->tx_desc[i].buffer2 = 0;
2643 	}
2644 	dnetp->tx_desc[i - 1].desc1.end_of_ring = 1;
2645 
2646 	/*
2647 	 * Initialize the Rx descriptors
2648 	 */
2649 	for (i = 0; i < dnetp->nrecv_desc; i++) {
2650 		uint32_t end_paddr;
2651 		*(uint32_t *)&dnetp->rx_desc[i].desc0 = 0;
2652 		*(uint32_t *)&dnetp->rx_desc[i].desc1 = 0;
2653 		dnetp->rx_desc[i].desc0.own = 1;
2654 		dnetp->rx_desc[i].desc1.buffer_size1 = rx_buf_size;
2655 		dnetp->rx_desc[i].buffer1 = dnetp->rx_buf_paddr[i];
2656 		dnetp->rx_desc[i].buffer2 = 0;
2657 		end_paddr = dnetp->rx_buf_paddr[i]+rx_buf_size-1;
2658 
2659 		if ((dnetp->rx_desc[i].buffer1 & ~dnetp->pgmask) !=
2660 		    (end_paddr & ~dnetp->pgmask)) {
2661 			/* discontiguous */
2662 			dnetp->rx_desc[i].buffer2 = end_paddr&~dnetp->pgmask;
2663 			dnetp->rx_desc[i].desc1.buffer_size2 =
2664 			    (end_paddr & dnetp->pgmask) + 1;
2665 			dnetp->rx_desc[i].desc1.buffer_size1 =
2666 			    rx_buf_size-dnetp->rx_desc[i].desc1.buffer_size2;
2667 		}
2668 	}
2669 	dnetp->rx_desc[i - 1].desc1.end_of_ring = 1;
2670 }
2671 
2672 static int
2673 alloc_descriptor(gld_mac_info_t *macinfo)
2674 {
2675 	int index;
2676 	struct dnetinstance *dnetp =	/* Our private device info */
2677 	    (struct dnetinstance *)macinfo->gldm_private;
2678 	struct tx_desc_type    *ring = dnetp->tx_desc;
2679 
2680 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
2681 alloctop:
2682 	mutex_enter(&dnetp->txlock);
2683 	index = dnetp->tx_current_desc;
2684 
2685 	dnet_reclaim_Tx_desc(macinfo);
2686 
2687 	/* we do have free descriptors, right? */
2688 	if (dnetp->free_desc <= 0) {
2689 #ifdef DNETDEBUG
2690 		if (dnetdebug & DNETRECV)
2691 			cmn_err(CE_NOTE, "dnet: Ring buffer is full");
2692 #endif
2693 		mutex_exit(&dnetp->txlock);
2694 		return (FAILURE);
2695 	}
2696 
2697 	/* sanity, make sure the next descriptor is free for use (should be) */
2698 	if (ring[index].desc0.own) {
2699 #ifdef DNETDEBUG
2700 		if (dnetdebug & DNETRECV)
2701 			cmn_err(CE_WARN,
2702 			    "dnet: next descriptor is not free for use");
2703 #endif
2704 		mutex_exit(&dnetp->txlock);
2705 		return (FAILURE);
2706 	}
2707 	if (dnetp->need_saddr) {
2708 		mutex_exit(&dnetp->txlock);
2709 		/* XXX function return value ignored */
2710 		if (!dnetp->suspended)
2711 			(void) dnet_set_addr(macinfo);
2712 		goto alloctop;
2713 	}
2714 
2715 	*(uint32_t *)&ring[index].desc0 = 0;  /* init descs */
2716 	*(uint32_t *)&ring[index].desc1 &= DNET_END_OF_RING;
2717 
2718 	/* hardware will own this descriptor when poll activated */
2719 	dnetp->free_desc--;
2720 
2721 	/* point to next free descriptor to be used */
2722 	dnetp->tx_current_desc = NextTXIndex(index);
2723 
2724 #ifdef DNET_NOISY
2725 	cmn_err(CE_WARN, "sfree 0x%x, transmitted 0x%x, tx_current 0x%x",
2726 	    dnetp->free_desc, dnetp->transmitted_desc, dnetp->tx_current_desc);
2727 #endif
2728 	mutex_exit(&dnetp->txlock);
2729 	return (SUCCESS);
2730 }
2731 
2732 /*
2733  * dnet_reclaim_Tx_desc() - called with txlock held.
2734  */
2735 static void
2736 dnet_reclaim_Tx_desc(gld_mac_info_t *macinfo)
2737 {
2738 	struct dnetinstance	*dnetp = (struct dnetinstance *)
2739 	    (macinfo->gldm_private);
2740 	struct tx_desc_type	*desc = dnetp->tx_desc;
2741 	int index;
2742 
2743 	ASSERT(MUTEX_HELD(&dnetp->txlock));
2744 #ifdef DNETDEBUG
2745 	if (dnetdebug & DNETTRACE)
2746 		cmn_err(CE_NOTE, "dnet_reclaim_Tx_desc(0x%p)",
2747 		    (void *) macinfo);
2748 #endif
2749 
2750 	index = dnetp->transmitted_desc;
2751 	while (((dnetp->free_desc == 0) || (index != dnetp->tx_current_desc)) &&
2752 	    !(desc[index].desc0.own)) {
2753 		/*
2754 		 * Check for Tx Error that gets set
2755 		 * in the last desc.
2756 		 */
2757 		if (desc[index].desc1.setup_packet == 0 &&
2758 		    desc[index].desc1.last_desc &&
2759 		    desc[index].desc0.err_summary)
2760 			update_tx_stats(macinfo, index);
2761 
2762 		/*
2763 		 * If we have used the streams message buffer for this
2764 		 * descriptor then free up the message now.
2765 		 */
2766 		if (dnetp->tx_msgbufp[index] != NULL) {
2767 			freemsg(dnetp->tx_msgbufp[index]);
2768 			dnetp->tx_msgbufp[index] = NULL;
2769 		}
2770 		dnetp->free_desc++;
2771 		index = (index+1) % dnetp->max_tx_desc;
2772 	}
2773 
2774 	dnetp->transmitted_desc = index;
2775 }
2776 
2777 /*
2778  * Receive buffer allocation/freeing routines.
2779  *
2780  * There is a common pool of receive buffers shared by all dnet instances.
2781  *
2782  * XXX NEEDSWORK
2783  *
2784  * We arbitrarily allocate twice as many receive buffers as
2785  * receive descriptors because we use the buffers for streams
2786  * messages to pass the packets up the stream.  We should
2787  * instead have initialized constants reflecting
2788  * MAX_RX_BUF_2104x and MAX_RX_BUF_2114x, and we should also
2789  * probably have a total maximum for the free pool, so that we
2790  * don't get out of hand when someone puts in an 8-port board.
2791  * The maximum for the entire pool should be the total number
2792  * of descriptors for all attached instances together, plus the
2793  * total maximum for the free pool.  This maximum would only be
2794  * reached after some number of instances allocate buffers:
2795  * each instance would add (max_rx_buf-max_rx_desc) to the free
2796  * pool.
2797  */
2798 
2799 static struct rbuf_list *rbuf_usedlist_head;
2800 static struct rbuf_list *rbuf_freelist_head;
2801 static struct rbuf_list *rbuf_usedlist_end;	/* last buffer allocated */
2802 
2803 static int rbuf_freebufs;	/* no. of free buffers in the pool */
2804 static int rbuf_pool_size;	/* total no. of buffers in the pool */
2805 
2806 /* initialize/add 'nbufs' buffers to the rbuf pool */
2807 /* ARGSUSED */
2808 static int
2809 dnet_rbuf_init(dev_info_t *dip, int nbufs)
2810 {
2811 	int i;
2812 	struct rbuf_list *rp;
2813 	ddi_dma_cookie_t cookie;
2814 	uint_t ncookies;
2815 	size_t len;
2816 
2817 	mutex_enter(&dnet_rbuf_lock);
2818 
2819 	/* allocate buffers and add them to the pool */
2820 	for (i = 0; i < nbufs; i++) {
2821 		/* allocate rbuf_list element */
2822 		rp = kmem_zalloc(sizeof (struct rbuf_list), KM_SLEEP);
2823 		if (ddi_dma_alloc_handle(dip, &dma_attr_rb, DDI_DMA_SLEEP,
2824 		    0, &rp->rbuf_dmahdl) != DDI_SUCCESS)
2825 			goto fail_kfree;
2826 
2827 		/* allocate dma memory for the buffer */
2828 		if (ddi_dma_mem_alloc(rp->rbuf_dmahdl, rx_buf_size, &accattr,
2829 		    DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0,
2830 		    &rp->rbuf_vaddr, &len,
2831 		    &rp->rbuf_acchdl) != DDI_SUCCESS)
2832 			goto fail_freehdl;
2833 
2834 		if (ddi_dma_addr_bind_handle(rp->rbuf_dmahdl, NULL,
2835 		    rp->rbuf_vaddr, len, DDI_DMA_RDWR | DDI_DMA_STREAMING,
2836 		    DDI_DMA_SLEEP, NULL, &cookie,
2837 		    &ncookies) != DDI_DMA_MAPPED)
2838 			goto fail_free;
2839 
2840 		if (ncookies > 2)
2841 			goto fail_unbind;
2842 		if (ncookies == 1) {
2843 			rp->rbuf_endpaddr =
2844 			    cookie.dmac_address + rx_buf_size - 1;
2845 		} else {
2846 			ddi_dma_nextcookie(rp->rbuf_dmahdl, &cookie);
2847 			rp->rbuf_endpaddr =
2848 			    cookie.dmac_address + cookie.dmac_size - 1;
2849 		}
2850 		rp->rbuf_paddr = cookie.dmac_address;
2851 
2852 		rp->rbuf_next = rbuf_freelist_head;
2853 		rbuf_freelist_head = rp;
2854 		rbuf_pool_size++;
2855 		rbuf_freebufs++;
2856 	}
2857 
2858 	mutex_exit(&dnet_rbuf_lock);
2859 	return (0);
2860 fail_unbind:
2861 	(void) ddi_dma_unbind_handle(rp->rbuf_dmahdl);
2862 fail_free:
2863 	ddi_dma_mem_free(&rp->rbuf_acchdl);
2864 fail_freehdl:
2865 	ddi_dma_free_handle(&rp->rbuf_dmahdl);
2866 fail_kfree:
2867 	kmem_free(rp, sizeof (struct rbuf_list));
2868 
2869 	mutex_exit(&dnet_rbuf_lock);
2870 	return (-1);
2871 }
2872 
2873 /*
2874  * Try to free up all the rbufs in the pool. Returns 0 if it frees up all
2875  * buffers. The buffers in the used list are considered busy so these
2876  * buffers are not freed.
2877  */
2878 static int
2879 dnet_rbuf_destroy()
2880 {
2881 	struct rbuf_list *rp, *next;
2882 
2883 	mutex_enter(&dnet_rbuf_lock);
2884 
2885 	for (rp = rbuf_freelist_head; rp; rp = next) {
2886 		next = rp->rbuf_next;
2887 		ddi_dma_mem_free(&rp->rbuf_acchdl);
2888 		(void) ddi_dma_unbind_handle(rp->rbuf_dmahdl);
2889 		kmem_free(rp, sizeof (struct rbuf_list));
2890 		rbuf_pool_size--;
2891 		rbuf_freebufs--;
2892 	}
2893 	rbuf_freelist_head = NULL;
2894 
2895 	if (rbuf_pool_size) { /* pool is still not empty */
2896 		mutex_exit(&dnet_rbuf_lock);
2897 		return (-1);
2898 	}
2899 	mutex_exit(&dnet_rbuf_lock);
2900 	return (0);
2901 }
2902 static struct rbuf_list *
2903 dnet_rbuf_alloc(dev_info_t *dip, int cansleep)
2904 {
2905 	struct rbuf_list *rp;
2906 	size_t len;
2907 	ddi_dma_cookie_t cookie;
2908 	uint_t ncookies;
2909 
2910 	mutex_enter(&dnet_rbuf_lock);
2911 
2912 	if (rbuf_freelist_head == NULL) {
2913 
2914 		if (!cansleep) {
2915 			mutex_exit(&dnet_rbuf_lock);
2916 			return (NULL);
2917 		}
2918 
2919 		/* allocate rbuf_list element */
2920 		rp = kmem_zalloc(sizeof (struct rbuf_list), KM_SLEEP);
2921 		if (ddi_dma_alloc_handle(dip, &dma_attr_rb, DDI_DMA_SLEEP,
2922 		    0, &rp->rbuf_dmahdl) != DDI_SUCCESS)
2923 			goto fail_kfree;
2924 
2925 		/* allocate dma memory for the buffer */
2926 		if (ddi_dma_mem_alloc(rp->rbuf_dmahdl, rx_buf_size, &accattr,
2927 		    DDI_DMA_STREAMING, DDI_DMA_DONTWAIT, 0,
2928 		    &rp->rbuf_vaddr, &len,
2929 		    &rp->rbuf_acchdl) != DDI_SUCCESS)
2930 			goto fail_freehdl;
2931 
2932 		if (ddi_dma_addr_bind_handle(rp->rbuf_dmahdl, NULL,
2933 		    rp->rbuf_vaddr, len, DDI_DMA_RDWR | DDI_DMA_STREAMING,
2934 		    DDI_DMA_SLEEP, NULL, &cookie,
2935 		    &ncookies) != DDI_DMA_MAPPED)
2936 			goto fail_free;
2937 
2938 		if (ncookies > 2)
2939 			goto fail_unbind;
2940 		if (ncookies == 1) {
2941 			rp->rbuf_endpaddr =
2942 			    cookie.dmac_address + rx_buf_size - 1;
2943 		} else {
2944 			ddi_dma_nextcookie(rp->rbuf_dmahdl, &cookie);
2945 			rp->rbuf_endpaddr =
2946 			    cookie.dmac_address + cookie.dmac_size - 1;
2947 		}
2948 		rp->rbuf_paddr = cookie.dmac_address;
2949 
2950 		rbuf_freelist_head = rp;
2951 		rbuf_pool_size++;
2952 		rbuf_freebufs++;
2953 	}
2954 
2955 	/* take the buffer from the head of the free list */
2956 	rp = rbuf_freelist_head;
2957 	rbuf_freelist_head = rbuf_freelist_head->rbuf_next;
2958 
2959 	/* update the used list; put the entry at the end */
2960 	if (rbuf_usedlist_head == NULL)
2961 		rbuf_usedlist_head = rp;
2962 	else
2963 		rbuf_usedlist_end->rbuf_next = rp;
2964 	rp->rbuf_next = NULL;
2965 	rbuf_usedlist_end = rp;
2966 	rbuf_freebufs--;
2967 
2968 	mutex_exit(&dnet_rbuf_lock);
2969 
2970 	return (rp);
2971 fail_unbind:
2972 	(void) ddi_dma_unbind_handle(rp->rbuf_dmahdl);
2973 fail_free:
2974 	ddi_dma_mem_free(&rp->rbuf_acchdl);
2975 fail_freehdl:
2976 	ddi_dma_free_handle(&rp->rbuf_dmahdl);
2977 fail_kfree:
2978 	kmem_free(rp, sizeof (struct rbuf_list));
2979 	mutex_exit(&dnet_rbuf_lock);
2980 	return (NULL);
2981 }
2982 
2983 static void
2984 dnet_rbuf_free(caddr_t vaddr)
2985 {
2986 	struct rbuf_list *rp, *prev;
2987 
2988 	ASSERT(vaddr != NULL);
2989 	ASSERT(rbuf_usedlist_head != NULL);
2990 
2991 	mutex_enter(&dnet_rbuf_lock);
2992 
2993 	/* find the entry in the used list */
2994 	for (prev = rp = rbuf_usedlist_head; rp; rp = rp->rbuf_next) {
2995 		if (rp->rbuf_vaddr == vaddr)
2996 			break;
2997 		prev = rp;
2998 	}
2999 
3000 	if (rp == NULL) {
3001 		cmn_err(CE_WARN, "DNET: rbuf_free: bad addr 0x%p",
3002 		    (void *)vaddr);
3003 		mutex_exit(&dnet_rbuf_lock);
3004 		return;
3005 	}
3006 
3007 	/* update the used list and put the buffer back in the free list */
3008 	if (rbuf_usedlist_head != rp) {
3009 		prev->rbuf_next = rp->rbuf_next;
3010 		if (rbuf_usedlist_end == rp)
3011 			rbuf_usedlist_end = prev;
3012 	} else {
3013 		rbuf_usedlist_head = rp->rbuf_next;
3014 		if (rbuf_usedlist_end == rp)
3015 			rbuf_usedlist_end = NULL;
3016 	}
3017 	rp->rbuf_next = rbuf_freelist_head;
3018 	rbuf_freelist_head = rp;
3019 	rbuf_freebufs++;
3020 
3021 	mutex_exit(&dnet_rbuf_lock);
3022 }
3023 
3024 /*
3025  * Free the receive buffer used in a stream's message block allocated
3026  * thru desballoc().
3027  */
3028 static void
3029 dnet_freemsg_buf(struct free_ptr *frp)
3030 {
3031 	dnet_rbuf_free((caddr_t)frp->buf); /* buffer goes back to the pool */
3032 	kmem_free(frp, sizeof (*frp)); /* free up the free_rtn structure */
3033 }
3034 
3035 /*
3036  *	========== SROM Read Routines ==========
3037  */
3038 
3039 /*
3040  * The following code gets the SROM information, either by reading it
3041  * from the device or, failing that, by reading a property.
3042  */
3043 static int
3044 dnet_read_srom(dev_info_t *devinfo, int board_type, ddi_acc_handle_t io_handle,
3045     caddr_t io_reg, uchar_t *vi, int maxlen)
3046 {
3047 	int all_ones, zerocheck, i;
3048 
3049 	/*
3050 	 * Load SROM into vendor_info
3051 	 */
3052 	if (board_type == DEVICE_ID_21040)
3053 		dnet_read21040addr(devinfo, io_handle, io_reg, vi, &maxlen);
3054 	else
3055 		/* 21041/21140 serial rom */
3056 		dnet_read21140srom(io_handle, io_reg, vi, maxlen);
3057 	/*
3058 	 * If the dumpsrom property is present in the conf file, print
3059 	 * the contents of the SROM to the console
3060 	 */
3061 	if (ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
3062 	    "dumpsrom", 0))
3063 		dnet_dumpbin("SROM", vi, 1, maxlen);
3064 
3065 	for (zerocheck = i = 0, all_ones = 0xff; i < maxlen; i++) {
3066 		zerocheck |= vi[i];
3067 		all_ones &= vi[i];
3068 	}
3069 	if (zerocheck == 0 || all_ones == 0xff) {
3070 		return (get_alternative_srom_image(devinfo, vi, maxlen));
3071 	} else {
3072 #ifdef BUG_4010796
3073 		set_alternative_srom_image(devinfo, vi, maxlen);
3074 #endif
3075 		return (0);	/* Primary */
3076 	}
3077 }
3078 
3079 /*
3080  * The function reads the ethernet address of the 21040 adapter
3081  */
3082 static void
3083 dnet_read21040addr(dev_info_t *dip, ddi_acc_handle_t io_handle, caddr_t io_reg,
3084     uchar_t *addr, int *len)
3085 {
3086 	uint32_t	val;
3087 	int		i;
3088 
3089 	/* No point reading more than the ethernet address */
3090 	*len = ddi_getprop(DDI_DEV_T_ANY, dip,
3091 	    DDI_PROP_DONTPASS, macoffset_propname, 0) + ETHERADDRL;
3092 
3093 	/* Reset ROM pointer */
3094 	ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG), 0);
3095 	for (i = 0; i < *len; i++) {
3096 		do {
3097 			val = ddi_get32(io_handle,
3098 			    REG32(io_reg, ETHER_ROM_REG));
3099 		} while (val & 0x80000000);
3100 		addr[i] = val & 0xFF;
3101 	}
3102 }
3103 
3104 #define	drv_nsecwait(x)	drv_usecwait(((x)+999)/1000) /* XXX */
3105 
3106 /*
3107  * The function reads the SROM	of the 21140 adapter
3108  */
3109 static void
3110 dnet_read21140srom(ddi_acc_handle_t io_handle, caddr_t io_reg, uchar_t *addr,
3111     int maxlen)
3112 {
3113 	uint32_t 	i, j;
3114 	uint32_t	dout;
3115 	uint16_t	word;
3116 	uint8_t		rom_addr;
3117 	uint8_t		bit;
3118 
3119 
3120 	rom_addr = 0;
3121 	for (i = 0; i <	maxlen; i += 2) {
3122 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3123 		    READ_OP | SEL_ROM);
3124 		drv_nsecwait(30);
3125 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3126 		    READ_OP | SEL_ROM | SEL_CHIP);
3127 		drv_nsecwait(50);
3128 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3129 		    READ_OP | SEL_ROM | SEL_CHIP | SEL_CLK);
3130 		drv_nsecwait(250);
3131 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3132 		    READ_OP | SEL_ROM | SEL_CHIP);
3133 		drv_nsecwait(100);
3134 
3135 		/* command */
3136 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3137 		    READ_OP | SEL_ROM | SEL_CHIP | DATA_IN);
3138 		drv_nsecwait(150);
3139 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3140 		    READ_OP | SEL_ROM | SEL_CHIP | DATA_IN | SEL_CLK);
3141 		drv_nsecwait(250);
3142 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3143 		    READ_OP | SEL_ROM | SEL_CHIP | DATA_IN);
3144 		drv_nsecwait(250);
3145 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3146 		    READ_OP | SEL_ROM | SEL_CHIP | DATA_IN | SEL_CLK);
3147 		drv_nsecwait(250);
3148 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3149 		    READ_OP | SEL_ROM | SEL_CHIP | DATA_IN);
3150 		drv_nsecwait(100);
3151 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3152 		    READ_OP | SEL_ROM | SEL_CHIP);
3153 		drv_nsecwait(150);
3154 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3155 		    READ_OP | SEL_ROM | SEL_CHIP | SEL_CLK);
3156 		drv_nsecwait(250);
3157 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3158 		    READ_OP | SEL_ROM | SEL_CHIP);
3159 		drv_nsecwait(100);
3160 
3161 		/* Address */
3162 		for (j = HIGH_ADDRESS_BIT; j >= 1; j >>= 1) {
3163 			bit = (rom_addr & j) ? DATA_IN : 0;
3164 			ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3165 			    READ_OP | SEL_ROM | SEL_CHIP | bit);
3166 			drv_nsecwait(150);
3167 			ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3168 			    READ_OP | SEL_ROM | SEL_CHIP | bit | SEL_CLK);
3169 			drv_nsecwait(250);
3170 			ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3171 			    READ_OP | SEL_ROM | SEL_CHIP | bit);
3172 			drv_nsecwait(100);
3173 		}
3174 		drv_nsecwait(150);
3175 
3176 		/* Data */
3177 		word = 0;
3178 		for (j = 0x8000; j >= 1; j >>= 1) {
3179 			ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3180 			    READ_OP | SEL_ROM | SEL_CHIP | SEL_CLK);
3181 			drv_nsecwait(100);
3182 			dout = ddi_get32(io_handle,
3183 			    REG32(io_reg, ETHER_ROM_REG));
3184 			drv_nsecwait(150);
3185 			if (dout & DATA_OUT)
3186 				word |= j;
3187 			ddi_put32(io_handle,
3188 			    REG32(io_reg, ETHER_ROM_REG),
3189 			    READ_OP | SEL_ROM | SEL_CHIP);
3190 			drv_nsecwait(250);
3191 		}
3192 		addr[i] = (word & 0x0000FF);
3193 		addr[i + 1] = (word >> 8);
3194 		rom_addr++;
3195 		ddi_put32(io_handle, REG32(io_reg, ETHER_ROM_REG),
3196 		    READ_OP | SEL_ROM);
3197 		drv_nsecwait(100);
3198 	}
3199 }
3200 
3201 
3202 /*
3203  * XXX NEEDSWORK
3204  *
3205  * Some lame multiport cards have only one SROM, which can be accessed
3206  * only from the "first" 21x4x chip, whichever that one is.  If we can't
3207  * get at our SROM, we look for its contents in a property instead, which
3208  * we rely on the bootstrap to have properly set.
3209  * #ifdef BUG_4010796
3210  * We also have a hack to try to set it ourselves, when the "first" port
3211  * attaches, if it has not already been properly set.  However, this method
3212  * is not reliable, since it makes the unwarrented assumption that the
3213  * "first" port will attach first.
3214  * #endif
3215  */
3216 
3217 static int
3218 get_alternative_srom_image(dev_info_t *devinfo, uchar_t *vi, int len)
3219 {
3220 	int	l = len;
3221 
3222 	if (ddi_getlongprop_buf(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
3223 	    "DNET_SROM", (caddr_t)vi, &len) != DDI_PROP_SUCCESS &&
3224 	    (len = l) && ddi_getlongprop_buf(DDI_DEV_T_ANY,
3225 	    ddi_get_parent(devinfo), DDI_PROP_DONTPASS, "DNET_SROM",
3226 	    (caddr_t)vi, &len) != DDI_PROP_SUCCESS)
3227 		return (-1);	/* Can't find it! */
3228 
3229 	/*
3230 	 * The return value from this routine specifies which port number
3231 	 * we are.  The primary port is denoted port 0.  On a QUAD card we
3232 	 * should return 1, 2, and 3 from this routine.  The return value
3233 	 * is used to modify the ethernet address from the SROM data.
3234 	 */
3235 
3236 #ifdef BUG_4010796
3237 	{
3238 	/*
3239 	 * For the present, we remember the device number of our primary
3240 	 * sibling and hope we and our other siblings are consecutively
3241 	 * numbered up from there.  In the future perhaps the bootstrap
3242 	 * will pass us the necessary information telling us which physical
3243 	 * port we really are.
3244 	 */
3245 	pci_regspec_t	*assignp;
3246 	int		assign_len;
3247 	int 		devnum;
3248 	int		primary_devnum;
3249 
3250 	primary_devnum = ddi_getprop(DDI_DEV_T_ANY, devinfo, 0,
3251 	    "DNET_DEVNUM", -1);
3252 	if (primary_devnum == -1)
3253 		return (1);	/* XXX NEEDSWORK -- We have no better idea */
3254 
3255 	if ((ddi_getlongprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
3256 	    "assigned-addresses", (caddr_t)&assignp,
3257 	    &assign_len)) != DDI_PROP_SUCCESS)
3258 		return (1);	/* XXX NEEDSWORK -- We have no better idea */
3259 
3260 	devnum = PCI_REG_DEV_G(assignp->pci_phys_hi);
3261 	kmem_free(assignp, assign_len);
3262 	return (devnum - primary_devnum);
3263 	}
3264 #else
3265 	return (1);	/* XXX NEEDSWORK -- We have no better idea */
3266 #endif
3267 }
3268 
3269 
3270 #ifdef BUG_4010796
3271 static void
3272 set_alternative_srom_image(dev_info_t *devinfo, uchar_t *vi, int len)
3273 {
3274 	int 		proplen;
3275 	pci_regspec_t	*assignp;
3276 	int		assign_len;
3277 	int 		devnum;
3278 
3279 	if (ddi_getproplen(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
3280 	    "DNET_SROM", &proplen) == DDI_PROP_SUCCESS ||
3281 	    ddi_getproplen(DDI_DEV_T_ANY, ddi_get_parent(devinfo),
3282 	    DDI_PROP_DONTPASS, "DNET_SROM", &proplen) == DDI_PROP_SUCCESS)
3283 		return;		/* Already done! */
3284 
3285 	/* function return value ignored */
3286 	(void) ddi_prop_update_byte_array(DDI_DEV_T_NONE,
3287 	    ddi_get_parent(devinfo), "DNET_SROM", (uchar_t *)vi, len);
3288 	(void) ddi_prop_update_string(DDI_DEV_T_NONE, devinfo,
3289 	    "DNET_HACK", "hack");
3290 
3291 	if ((ddi_getlongprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
3292 	    "assigned-addresses", (caddr_t)&assignp,
3293 	    &assign_len)) == DDI_PROP_SUCCESS) {
3294 		devnum = PCI_REG_DEV_G(assignp->pci_phys_hi);
3295 		kmem_free(assignp, assign_len);
3296 		/* function return value ignored */
3297 		(void) ddi_prop_update_int(DDI_DEV_T_NONE,
3298 		    ddi_get_parent(devinfo), "DNET_DEVNUM", devnum);
3299 	}
3300 }
3301 #endif
3302 
3303 /*
3304  *	========== SROM Parsing Routines ==========
3305  */
3306 
3307 static int
3308 check_srom_valid(uchar_t *vi)
3309 {
3310 	int		word, bit;
3311 	uint8_t		crc;
3312 	uint16_t	*wvi;		/* word16 pointer to vendor info */
3313 	uint16_t	bitval;
3314 
3315 	/* verify that the number of controllers on the card is within range */
3316 	if (vi[SROM_ADAPTER_CNT] < 1 || vi[SROM_ADAPTER_CNT] > MAX_ADAPTERS)
3317 		return (0);
3318 
3319 	/*
3320 	 * version 1 and 3 of this card did not check the id block CRC value
3321 	 * and this can't be changed without retesting every supported card
3322 	 *
3323 	 * however version 4 of the SROM can have this test applied
3324 	 * without fear of breaking something that used to work.
3325 	 * the CRC algorithm is taken from the Intel document
3326 	 *	"21x4 Serial ROM Format"
3327 	 *	version 4.09
3328 	 *	3-Mar-1999
3329 	 */
3330 
3331 	switch (vi[SROM_VERSION]) {
3332 	case 1:
3333 	    /* fallthru */
3334 	case 3:
3335 		return (vi[SROM_MBZ] == 0 &&	/* must be zero */
3336 		    vi[SROM_MBZ2] == 0 &&	/* must be zero */
3337 		    vi[SROM_MBZ3] == 0);	/* must be zero */
3338 
3339 	case 4:
3340 		wvi = (uint16_t *)vi;
3341 		crc = 0xff;
3342 		for (word = 0; word < 9; word++)
3343 			for (bit = 15; bit >= 0; bit--) {
3344 				if (word == 8 && bit == 7)
3345 					return (crc == vi[16]);
3346 				bitval =
3347 				    ((wvi[word] >> bit) & 1) ^ ((crc >> 7) & 1);
3348 				crc <<= 1;
3349 				if (bitval == 1) {
3350 					crc ^= 7;
3351 				}
3352 			}
3353 
3354 	default:
3355 		return (0);
3356 	}
3357 }
3358 
3359 /*
3360  *	========== Active Media Determination Routines ==========
3361  */
3362 
3363 /* This routine is also called for V3 Compact and extended type 0 SROMs */
3364 static int
3365 is_fdmedia(int media)
3366 {
3367 	if (media == MEDIA_TP_FD || media == MEDIA_SYM_SCR_FD)
3368 		return (1);
3369 	else
3370 		return (0);
3371 }
3372 
3373 /*
3374  * "Linkset" is used to merge media that use the same link test check. So,
3375  * if the TP link is added to the linkset, so is the TP Full duplex link.
3376  * Used to avoid checking the same link status twice.
3377  */
3378 static void
3379 linkset_add(uint32_t *set, int media)
3380 {
3381 	if (media == MEDIA_TP_FD || media == MEDIA_TP)
3382 		*set |= (1UL<<MEDIA_TP_FD) | (1UL<<MEDIA_TP);
3383 	else if (media == MEDIA_SYM_SCR_FD || media == MEDIA_SYM_SCR)
3384 		*set |= (1UL<<MEDIA_SYM_SCR_FD) | (1UL<<MEDIA_SYM_SCR);
3385 	else *set |= 1UL<<media;
3386 }
3387 static int
3388 linkset_isset(uint32_t linkset, int media)
3389 {
3390 	return (((1UL<<media)  & linkset) ? 1:0);
3391 }
3392 
3393 /*
3394  * The following code detects which Media is connected for 21041/21140
3395  * Expect to change this code to support new 21140 variants.
3396  * find_active_media() - called with intrlock held.
3397  */
3398 static void
3399 find_active_media(gld_mac_info_t *macinfo)
3400 {
3401 	int i;
3402 	media_block_t *block;
3403 	media_block_t *best_allowed = NULL;
3404 	media_block_t *hd_found = NULL;
3405 	media_block_t *fd_found = NULL;
3406 	struct dnetinstance	*dnetp = (struct dnetinstance *)
3407 	    (macinfo->gldm_private);
3408 	LEAF_FORMAT *leaf = &dnetp->sr.leaf[dnetp->leaf];
3409 	uint32_t checked = 0, links_up = 0;
3410 
3411 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
3412 #ifdef SROMDEBUG
3413 	cmn_err(CE_NOTE, "find_active_media 0x%x,0x%x", sr->version, macinfo);
3414 #endif
3415 	dnetp->selected_media_block = leaf->default_block;
3416 
3417 	if (dnetp->phyaddr != -1) {
3418 		dnetp->selected_media_block = leaf->mii_block;
3419 		setup_block(macinfo);
3420 
3421 		if (ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo,
3422 		    DDI_PROP_DONTPASS, "portmon", 1)) {
3423 			/* XXX return value ignored */
3424 			(void) mii_start_portmon(dnetp->mii, dnet_mii_link_cb,
3425 			    &dnetp->intrlock);
3426 			/*
3427 			 * If the port monitor detects the link is already
3428 			 * up, there is no point going through the rest of the
3429 			 * link sense
3430 			 */
3431 			if (dnetp->mii_up) {
3432 				return;
3433 			}
3434 		}
3435 	}
3436 
3437 	/*
3438 	 * Media is searched for in order of Precedence. This DEC SROM spec
3439 	 * tells us that the first media entry in the SROM is the lowest
3440 	 * precedence and should be checked last. This is why we go to the last
3441 	 * Media block and work back to the beginning.
3442 	 *
3443 	 * However, some older SROMs (Cogent EM110's etc.) have this the wrong
3444 	 * way around. As a result, following the SROM spec would result in a
3445 	 * 10 link being chosen over a 100 link if both media are available.
3446 	 * So we continue trying the media until we have at least tried the
3447 	 * DEFAULT media.
3448 	 */
3449 
3450 	/* Search for an active medium, and select it */
3451 	for (block = leaf->block + leaf->block_count  - 1;
3452 	    block >= leaf->block; block--) {
3453 		int media = block->media_code;
3454 
3455 		/* User settings disallow selection of this block */
3456 		if (dnetp->disallowed_media & (1UL<<media))
3457 			continue;
3458 
3459 		/* We may not be able to pick the default */
3460 		if (best_allowed == NULL || block == leaf->default_block)
3461 			best_allowed = block;
3462 #ifdef DEBUG
3463 		if (dnetdebug & DNETSENSE)
3464 			cmn_err(CE_NOTE, "Testing %s medium (block type %d)",
3465 			    media_str[media], block->type);
3466 #endif
3467 
3468 		dnetp->selected_media_block = block;
3469 		switch (block->type) {
3470 
3471 		case 2: /* SIA Media block: Best we can do is send a packet */
3472 			setup_block(macinfo);
3473 			if (send_test_packet(macinfo)) {
3474 				if (!is_fdmedia(media))
3475 					return;
3476 				if (!fd_found)
3477 					fd_found = block;
3478 			}
3479 			break;
3480 
3481 		/* SYM/SCR or TP block: Use the link-sense bits */
3482 		case 0:
3483 			if (!linkset_isset(checked, media)) {
3484 				linkset_add(&checked, media);
3485 				if (((media == MEDIA_BNC ||
3486 				    media == MEDIA_AUI) &&
3487 				    send_test_packet(macinfo)) ||
3488 				    dnet_link_sense(macinfo))
3489 					linkset_add(&links_up, media);
3490 			}
3491 
3492 			if (linkset_isset(links_up, media)) {
3493 				/*
3494 				 * Half Duplex is *always* the favoured media.
3495 				 * Full Duplex can be set and forced via the
3496 				 * conf file.
3497 				 */
3498 				if (!is_fdmedia(media) &&
3499 				    dnetp->selected_media_block ==
3500 				    leaf->default_block) {
3501 					/*
3502 					 * Cogent cards have the media in
3503 					 * opposite order to the spec.,
3504 					 * this code forces the media test to
3505 					 * keep going until the default media
3506 					 * is tested.
3507 					 *
3508 					 * In Cogent case, 10, 10FD, 100FD, 100
3509 					 * 100 is the default but 10 could have
3510 					 * been detected and would have been
3511 					 * chosen but now we force it through to
3512 					 * 100.
3513 					 */
3514 					setup_block(macinfo);
3515 					return;
3516 				} else if (!is_fdmedia(media)) {
3517 					/*
3518 					 * This allows all the others to work
3519 					 * properly by remembering the media
3520 					 * that works and not defaulting to
3521 					 * a FD link.
3522 					 */
3523 						if (hd_found == NULL)
3524 							hd_found = block;
3525 				} else if (fd_found == NULL) {
3526 					/*
3527 					 * No media have already been found
3528 					 * so far, this is FD, it works so
3529 					 * remember it and if no others are
3530 					 * detected, use it.
3531 					 */
3532 					fd_found = block;
3533 				}
3534 			}
3535 			break;
3536 
3537 		/*
3538 		 * MII block: May take up to a second or so to settle if
3539 		 * setup causes a PHY reset
3540 		 */
3541 		case 1: case 3:
3542 			setup_block(macinfo);
3543 			for (i = 0; ; i++) {
3544 				if (mii_linkup(dnetp->mii, dnetp->phyaddr)) {
3545 					/* XXX function return value ignored */
3546 					(void) mii_getspeed(dnetp->mii,
3547 					    dnetp->phyaddr,
3548 					    &dnetp->mii_speed,
3549 					    &dnetp->mii_duplex);
3550 					dnetp->mii_up = 1;
3551 					leaf->mii_block = block;
3552 					return;
3553 				}
3554 				if (i == 10)
3555 					break;
3556 				delay(drv_usectohz(150000));
3557 			}
3558 			dnetp->mii_up = 0;
3559 			break;
3560 		}
3561 	} /* for loop */
3562 	if (hd_found) {
3563 		dnetp->selected_media_block = hd_found;
3564 	} else if (fd_found) {
3565 		dnetp->selected_media_block = fd_found;
3566 	} else {
3567 		if (best_allowed == NULL)
3568 			best_allowed = leaf->default_block;
3569 		dnetp->selected_media_block = best_allowed;
3570 		cmn_err(CE_WARN, "!dnet: Default media selected\n");
3571 	}
3572 	setup_block(macinfo);
3573 }
3574 
3575 /*
3576  * Do anything neccessary to select the selected_media_block.
3577  * setup_block() - called with intrlock held.
3578  */
3579 static void
3580 setup_block(gld_mac_info_t *macinfo)
3581 {
3582 	dnet_reset_board(macinfo);
3583 	dnet_init_board(macinfo);
3584 	/* XXX function return value ignored */
3585 	(void) dnet_start(macinfo);
3586 }
3587 
3588 /* dnet_link_sense() - called with intrlock held */
3589 static int
3590 dnet_link_sense(gld_mac_info_t *macinfo)
3591 {
3592 	/*
3593 	 * This routine makes use of the command word from the srom config.
3594 	 * Details of the auto-sensing information contained in this can
3595 	 * be found in the "Digital Semiconductor 21X4 Serial ROM Format v3.03"
3596 	 * spec. Section 4.3.2.1, and 4.5.2.1.3
3597 	 */
3598 	struct dnetinstance *dnetp = (struct dnetinstance *)
3599 	    (macinfo->gldm_private);
3600 	media_block_t *block = dnetp->selected_media_block;
3601 	uint32_t link, status, mask, polarity;
3602 	int settletime, stabletime, waittime, upsamples;
3603 	int delay_100, delay_10;
3604 
3605 
3606 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
3607 	/* Don't autosense if the medium does not support it */
3608 	if (block->command & (1 << 15)) {
3609 		/* This should be the default block */
3610 		if (block->command & (1UL<<14))
3611 			dnetp->sr.leaf[dnetp->leaf].default_block = block;
3612 		return (0);
3613 	}
3614 
3615 	delay_100 = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo,
3616 	    DDI_PROP_DONTPASS, "autosense-delay-100", 2000);
3617 
3618 	delay_10 = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo,
3619 	    DDI_PROP_DONTPASS, "autosense-delay-10", 400);
3620 
3621 	/*
3622 	 * Scrambler may need to be disabled for link sensing
3623 	 * to work
3624 	 */
3625 	dnetp->disable_scrambler = 1;
3626 	setup_block(macinfo);
3627 	dnetp->disable_scrambler = 0;
3628 
3629 	if (block->media_code == MEDIA_TP || block->media_code == MEDIA_TP_FD)
3630 		settletime = delay_10;
3631 	else
3632 		settletime = delay_100;
3633 	stabletime = settletime / 4;
3634 
3635 	mask = 1 << ((block->command & CMD_MEDIABIT_MASK) >> 1);
3636 	polarity = block->command & CMD_POL ? 0xffffffff : 0;
3637 
3638 	for (waittime = 0, upsamples = 0;
3639 	    waittime <= settletime + stabletime && upsamples < 8;
3640 	    waittime += stabletime/8) {
3641 		delay(drv_usectohz(stabletime*1000 / 8));
3642 		status = read_gpr(dnetp);
3643 		link = (status^polarity) & mask;
3644 		if (link)
3645 			upsamples++;
3646 		else
3647 			upsamples = 0;
3648 	}
3649 #ifdef DNETDEBUG
3650 	if (dnetdebug & DNETSENSE)
3651 		cmn_err(CE_NOTE, "%s upsamples:%d stat:%x polarity:%x "
3652 		    "mask:%x link:%x",
3653 		    upsamples == 8 ? "UP":"DOWN",
3654 		    upsamples, status, polarity, mask, link);
3655 #endif
3656 	if (upsamples == 8)
3657 		return (1);
3658 	return (0);
3659 }
3660 
3661 static int
3662 send_test_packet(gld_mac_info_t *macinfo)
3663 {
3664 	int packet_delay;
3665 	struct dnetinstance	*dnetp = (struct dnetinstance *)
3666 	    (macinfo->gldm_private);
3667 	struct tx_desc_type *desc;
3668 	int bufindex;
3669 	int media_code = dnetp->selected_media_block->media_code;
3670 	uint32_t del;
3671 
3672 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
3673 	/*
3674 	 * For a successful test packet, the card must have settled into
3675 	 * its current setting.  Almost all cards we've tested manage to
3676 	 * do this with all media within 50ms.  However, the SMC 8432
3677 	 * requires 300ms to settle into BNC mode.  We now only do this
3678 	 * from attach, and we do sleeping delay() instead of drv_usecwait()
3679 	 * so we hope this .2 second delay won't cause too much suffering.
3680 	 * ALSO: with an autonegotiating hub, an aditional 1 second delay is
3681 	 * required. This is done if the media type is TP
3682 	 */
3683 	if (media_code == MEDIA_TP || media_code == MEDIA_TP_FD) {
3684 		packet_delay = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo,
3685 		    DDI_PROP_DONTPASS, "test_packet_delay_tp", 1300000);
3686 	} else {
3687 		packet_delay = ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo,
3688 		    DDI_PROP_DONTPASS, "test_packet_delay", 300000);
3689 	}
3690 	delay(drv_usectohz(packet_delay));
3691 
3692 	desc = dnetp->tx_desc;
3693 
3694 	bufindex = dnetp->tx_current_desc;
3695 	if (alloc_descriptor(macinfo) == FAILURE) {
3696 		cmn_err(CE_WARN, "DNET: send_test_packet: alloc_descriptor"
3697 		    "failed");
3698 		return (0);
3699 	}
3700 
3701 	/*
3702 	 * use setup buffer as the buffer for the test packet
3703 	 * instead of allocating one.
3704 	 */
3705 
3706 	ASSERT(dnetp->setup_buf_vaddr != NULL);
3707 	/* Put something decent in dest address so we don't annoy other cards */
3708 	BCOPY((caddr_t)dnetp->curr_macaddr,
3709 	    (caddr_t)dnetp->setup_buf_vaddr, ETHERADDRL);
3710 	BCOPY((caddr_t)dnetp->curr_macaddr,
3711 	    (caddr_t)dnetp->setup_buf_vaddr+ETHERADDRL, ETHERADDRL);
3712 
3713 	desc[bufindex].buffer1 = dnetp->setup_buf_paddr;
3714 	desc[bufindex].desc1.buffer_size1 = SETUPBUF_SIZE;
3715 	desc[bufindex].buffer2 = (uint32_t)(0);
3716 	desc[bufindex].desc1.first_desc = 1;
3717 	desc[bufindex].desc1.last_desc = 1;
3718 	desc[bufindex].desc1.int_on_comp = 1;
3719 	desc[bufindex].desc0.own = 1;
3720 
3721 	ddi_put8(dnetp->io_handle, REG8(dnetp->io_reg, TX_POLL_REG),
3722 	    TX_POLL_DEMAND);
3723 
3724 	/*
3725 	 * Give enough time for the chip to transmit the packet
3726 	 */
3727 #if 1
3728 	del = 1000;
3729 	while (desc[bufindex].desc0.own && --del)
3730 		drv_usecwait(10);	/* quickly wait up to 10ms */
3731 	if (desc[bufindex].desc0.own)
3732 		delay(drv_usectohz(200000));	/* nicely wait a longer time */
3733 #else
3734 	del = 0x10000;
3735 	while (desc[bufindex].desc0.own && --del)
3736 		drv_usecwait(10);
3737 #endif
3738 
3739 #ifdef DNETDEBUG
3740 	if (dnetdebug & DNETSENSE)
3741 		cmn_err(CE_NOTE, "desc0 bits = %u, %u, %u, %u, %u, %u",
3742 		    desc[bufindex].desc0.own,
3743 		    desc[bufindex].desc0.err_summary,
3744 		    desc[bufindex].desc0.carrier_loss,
3745 		    desc[bufindex].desc0.no_carrier,
3746 		    desc[bufindex].desc0.late_collision,
3747 		    desc[bufindex].desc0.link_fail);
3748 #endif
3749 	if (desc[bufindex].desc0.own) /* it shouldn't take this long, error */
3750 		return (0);
3751 
3752 	return (!desc[bufindex].desc0.err_summary);
3753 }
3754 
3755 /* enable_interrupts - called with intrlock held */
3756 static void
3757 enable_interrupts(struct dnetinstance *dnetp, int enable_xmit)
3758 {
3759 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
3760 	/* Don't enable interrupts if they have been forced off */
3761 	if (dnetp->interrupts_disabled)
3762 		return;
3763 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, INT_MASK_REG),
3764 	    NORMAL_INTR_MASK | ABNORMAL_INTR_MASK | TX_UNDERFLOW_MASK |
3765 	    (enable_xmit ? TX_INTERRUPT_MASK : 0) |
3766 	    (dnetp->timer.cb ? GPTIMER_INTR : 0) |
3767 	    RX_INTERRUPT_MASK | SYSTEM_ERROR_MASK | TX_JABBER_MASK);
3768 
3769 }
3770 
3771 /*
3772  * Some older multiport cards are non-PCI compliant in their interrupt routing.
3773  * Second and subsequent devices are incorrectly configured by the BIOS
3774  * (either in their ILINE configuration or the MP Configuration Table for PC+MP
3775  * systems).
3776  * The hack stops gldregister() registering the interrupt routine for the
3777  * FIRST device on the adapter, and registers its own. It builds up a table
3778  * of macinfo structures for each device, and the new interrupt routine
3779  * calls gldintr for each of them.
3780  * Known cards that suffer from this problem are:
3781  *	All Cogent multiport cards;
3782  * 	Znyx 314;
3783  *	Znyx 315.
3784  *
3785  * XXX NEEDSWORK -- see comments above get_alternative_srom_image(). This
3786  * hack relies on the fact that the offending cards will have only one SROM.
3787  * It uses this fact to identify devices that are on the same multiport
3788  * adapter, as opposed to multiple devices from the same vendor (as
3789  * indicated by "secondary")
3790  */
3791 static int
3792 dnet_hack_interrupts(gld_mac_info_t *macinfo, int secondary)
3793 {
3794 	int i;
3795 	struct hackintr_inf *hackintr_inf;
3796 	struct dnetinstance *dnetp =
3797 	    (struct dnetinstance *)macinfo->gldm_private;
3798 	dev_info_t *devinfo = dnetp->devinfo;
3799 	uint32_t oui = 0;	/* Organizationally Unique ID */
3800 
3801 	if (ddi_getprop(DDI_DEV_T_ANY, devinfo, DDI_PROP_DONTPASS,
3802 	    "no_INTA_workaround", 0) != 0)
3803 		return (0);
3804 
3805 	for (i = 0; i < 3; i++)
3806 		oui = (oui << 8) | dnetp->vendor_addr[i];
3807 
3808 	/* Check wheather or not we need to implement the hack */
3809 
3810 	switch (oui) {
3811 	case ZNYX_ETHER:
3812 		/* Znyx multiport 21040 cards <<==>> ZX314 or ZX315 */
3813 		if (dnetp->board_type != DEVICE_ID_21040)
3814 			return (0);
3815 		break;
3816 
3817 	case COGENT_ETHER:
3818 		/* All known Cogent multiport cards */
3819 		break;
3820 
3821 	case ADAPTEC_ETHER:
3822 		/* Adaptec multiport cards */
3823 		break;
3824 
3825 	default:
3826 		/* Other cards work correctly */
3827 		return (0);
3828 	}
3829 
3830 	/* card is (probably) non-PCI compliant in its interrupt routing */
3831 
3832 
3833 	if (!secondary) {
3834 
3835 		/*
3836 		 * If we have already registered a hacked interrupt, and
3837 		 * this is also a 'primary' adapter, then this is NOT part of
3838 		 * a multiport card, but a second card on the same PCI bus.
3839 		 * BUGID: 4057747
3840 		 */
3841 		if (ddi_getprop(DDI_DEV_T_ANY, ddi_get_parent(devinfo),
3842 		    DDI_PROP_DONTPASS, hackintr_propname, 0) != 0)
3843 			return (0);
3844 				/* ... Primary not part of a multiport device */
3845 
3846 #ifdef DNETDEBUG
3847 		if (dnetdebug & DNETTRACE)
3848 			cmn_err(CE_NOTE, "dnet: Implementing hardware "
3849 			    "interrupt flaw workaround");
3850 #endif
3851 		dnetp->hackintr_inf = hackintr_inf =
3852 		    kmem_zalloc(sizeof (struct hackintr_inf), KM_SLEEP);
3853 		if (hackintr_inf == NULL)
3854 			goto fail;
3855 
3856 		hackintr_inf->macinfos[0] = macinfo;
3857 		hackintr_inf->devinfo = devinfo;
3858 
3859 		/*
3860 		 * Add a property to allow successive attaches to find the
3861 		 * table
3862 		 */
3863 
3864 		if (ddi_prop_update_byte_array(DDI_DEV_T_NONE,
3865 		    ddi_get_parent(devinfo), hackintr_propname,
3866 		    (uchar_t *)&dnetp->hackintr_inf,
3867 		    sizeof (void *)) != DDI_PROP_SUCCESS)
3868 			goto fail;
3869 
3870 
3871 		/* Register our hacked interrupt routine */
3872 		if (ddi_add_intr(devinfo, 0, &macinfo->gldm_cookie, NULL,
3873 		    (uint_t (*)(char *))dnet_hack_intr,
3874 		    (caddr_t)hackintr_inf) != DDI_SUCCESS) {
3875 			/* XXX function return value ignored */
3876 			(void) ddi_prop_remove(DDI_DEV_T_NONE,
3877 			    ddi_get_parent(devinfo),
3878 			    hackintr_propname);
3879 			goto fail;
3880 		}
3881 
3882 		/*
3883 		 * Mutex required to ensure interrupt routine has completed
3884 		 * when detaching devices
3885 		 */
3886 		mutex_init(&hackintr_inf->lock, NULL, MUTEX_DRIVER,
3887 		    macinfo->gldm_cookie);
3888 
3889 		/* Stop GLD registering an interrupt */
3890 		return (-1);
3891 	} else {
3892 
3893 		/* Add the macinfo for this secondary device to the table */
3894 
3895 		hackintr_inf = (struct hackintr_inf *)(uintptr_t)
3896 		    ddi_getprop(DDI_DEV_T_ANY, ddi_get_parent(devinfo),
3897 		    DDI_PROP_DONTPASS, hackintr_propname, 0);
3898 
3899 		if (hackintr_inf == NULL)
3900 			goto fail;
3901 
3902 		/* Find an empty slot */
3903 		for (i = 0; i < MAX_INST; i++)
3904 			if (hackintr_inf->macinfos[i] == NULL)
3905 				break;
3906 
3907 		/* More than 8 ports on adapter ?! */
3908 		if (i == MAX_INST)
3909 			goto fail;
3910 
3911 		hackintr_inf->macinfos[i] = macinfo;
3912 
3913 		/*
3914 		 * Allow GLD to register a handler for this
3915 		 * device. If the card is actually broken, as we suspect, this
3916 		 * handler will never get called. However, by registering the
3917 		 * interrupt handler, we can copy gracefully with new multiport
3918 		 * Cogent cards that decide to fix the hardware problem
3919 		 */
3920 		return (0);
3921 	}
3922 
3923 fail:
3924 	cmn_err(CE_WARN, "dnet: Could not work around hardware interrupt"
3925 	    " routing problem");
3926 	return (0);
3927 }
3928 
3929 /*
3930  * Call gld_intr for all adapters on a multiport card
3931  */
3932 
3933 static uint_t
3934 dnet_hack_intr(struct hackintr_inf *hackintr_inf)
3935 {
3936 	int i;
3937 	int claimed = DDI_INTR_UNCLAIMED;
3938 
3939 	/* Stop detaches while processing interrupts */
3940 	mutex_enter(&hackintr_inf->lock);
3941 
3942 	for (i = 0; i < MAX_INST; i++) {
3943 		if (hackintr_inf->macinfos[i] &&
3944 		    gld_intr(hackintr_inf->macinfos[i]) == DDI_INTR_CLAIMED)
3945 			claimed = DDI_INTR_CLAIMED;
3946 	}
3947 	mutex_exit(&hackintr_inf->lock);
3948 	return (claimed);
3949 }
3950 
3951 /*
3952  * This removes the detaching device from the table procesed by the hacked
3953  * interrupt routine. Because the interrupts from all devices come in to the
3954  * same interrupt handler, ALL devices must stop interrupting once the
3955  * primary device detaches. This isn't a problem at present, because all
3956  * instances of a device are detached when the driver is unloaded.
3957  */
3958 static int
3959 dnet_detach_hacked_interrupt(dev_info_t *devinfo)
3960 {
3961 	int i;
3962 	struct hackintr_inf *hackintr_inf;
3963 	gld_mac_info_t *mac, *macinfo = ddi_get_driver_private(devinfo);
3964 
3965 	hackintr_inf = (struct hackintr_inf *)(uintptr_t)
3966 	    ddi_getprop(DDI_DEV_T_ANY, ddi_get_parent(devinfo),
3967 	    DDI_PROP_DONTPASS, hackintr_propname, 0);
3968 
3969 	/*
3970 	 * No hackintr_inf implies hack was not required or the primary has
3971 	 * detached, and our interrupts are already disabled
3972 	 */
3973 	if (!hackintr_inf) {
3974 		/* remove the interrupt for the non-hacked case */
3975 		ddi_remove_intr(devinfo, 0, macinfo->gldm_cookie);
3976 		return (DDI_SUCCESS);
3977 	}
3978 
3979 	/* Remove this device from the handled table */
3980 	mutex_enter(&hackintr_inf->lock);
3981 	for (i = 0; i < MAX_INST; i++) {
3982 		if (hackintr_inf->macinfos[i] == macinfo) {
3983 			hackintr_inf->macinfos[i] = NULL;
3984 			break;
3985 		}
3986 	}
3987 
3988 	mutex_exit(&hackintr_inf->lock);
3989 
3990 	/* Not the primary card, we are done */
3991 	if (devinfo != hackintr_inf->devinfo)
3992 		return (DDI_SUCCESS);
3993 
3994 	/*
3995 	 * This is the primary card. All remaining adapters on this device
3996 	 * must have their interrupts disabled before we remove the handler
3997 	 */
3998 	for (i = 0; i < MAX_INST; i++) {
3999 		if ((mac = hackintr_inf->macinfos[i]) != NULL) {
4000 			struct dnetinstance *altdnetp =
4001 			    (struct dnetinstance *)mac->gldm_private;
4002 			altdnetp->interrupts_disabled = 1;
4003 			ddi_put32(altdnetp->io_handle,
4004 			    REG32(altdnetp->io_reg, INT_MASK_REG), 0);
4005 		}
4006 	}
4007 
4008 	/* It should now be safe to remove the interrupt handler */
4009 
4010 	ddi_remove_intr(devinfo, 0, macinfo->gldm_cookie);
4011 	mutex_destroy(&hackintr_inf->lock);
4012 	/* XXX function return value ignored */
4013 	(void) ddi_prop_remove(DDI_DEV_T_NONE, ddi_get_parent(devinfo),
4014 	    hackintr_propname);
4015 	kmem_free(hackintr_inf, sizeof (struct hackintr_inf));
4016 	return (DDI_SUCCESS);
4017 }
4018 
4019 /*
4020  *	========== PHY MII Routines ==========
4021  */
4022 
4023 /* do_phy() - called with intrlock held */
4024 static void
4025 do_phy(gld_mac_info_t *macinfo)
4026 {
4027 	dev_info_t *dip;
4028 	struct dnetinstance
4029 	    *dnetp = (struct dnetinstance *)macinfo->gldm_private;
4030 	LEAF_FORMAT *leaf = dnetp->sr.leaf + dnetp->leaf;
4031 	media_block_t *block;
4032 	int phy;
4033 
4034 	dip = dnetp->devinfo;
4035 
4036 	/*
4037 	 * Find and configure the PHY media block. If NO PHY blocks are
4038 	 * found on the SROM, but a PHY device is present, we assume the card
4039 	 * is a legacy device, and that there is ONLY a PHY interface on the
4040 	 * card (ie, no BNC or AUI, and 10BaseT is implemented by the PHY
4041 	 */
4042 
4043 	for (block = leaf->block + leaf->block_count -1;
4044 	    block >= leaf->block; block --) {
4045 		if (block->type == 3 || block->type == 1) {
4046 			leaf->mii_block = block;
4047 			break;
4048 		}
4049 	}
4050 
4051 	/*
4052 	 * If no MII block, select default, and hope this configuration will
4053 	 * allow the phy to be read/written if it is present
4054 	 */
4055 	dnetp->selected_media_block = leaf->mii_block ?
4056 	    leaf->mii_block : leaf->default_block;
4057 
4058 	setup_block(macinfo);
4059 	/* XXX function return value ignored */
4060 	(void) mii_create(dip, dnet_mii_write, dnet_mii_read, &dnetp->mii);
4061 
4062 	/*
4063 	 * We try PHY 0 LAST because it is less likely to be connected
4064 	 */
4065 	for (phy = 1; phy < 33; phy++)
4066 		if (mii_probe_phy(dnetp->mii, phy % 32) == MII_SUCCESS &&
4067 		    mii_init_phy(dnetp->mii, phy % 32) == MII_SUCCESS) {
4068 #ifdef DNETDEBUG
4069 			if (dnetdebug & DNETSENSE)
4070 				cmn_err(CE_NOTE, "dnet: "
4071 				    "PHY at address %d", phy % 32);
4072 #endif
4073 			dnetp->phyaddr = phy % 32;
4074 			if (!leaf->mii_block) {
4075 				/* Legacy card, change the leaf node */
4076 				set_leaf(&dnetp->sr, &leaf_phylegacy);
4077 			}
4078 			return;
4079 		}
4080 #ifdef DNETDEBUG
4081 	if (dnetdebug & DNETSENSE)
4082 		cmn_err(CE_NOTE, "dnet: No PHY found");
4083 #endif
4084 }
4085 
4086 static ushort_t
4087 dnet_mii_read(dev_info_t *dip, int phy_addr, int reg_num)
4088 {
4089 	gld_mac_info_t *macinfo;
4090 	struct dnetinstance *dnetp;
4091 
4092 	uint32_t command_word;
4093 	uint32_t tmp;
4094 	uint32_t data = 0;
4095 	int i;
4096 	int bits_in_ushort = ((sizeof (ushort_t))*8);
4097 	int turned_around = 0;
4098 
4099 	macinfo = ddi_get_driver_private(dip);
4100 	dnetp = (struct dnetinstance *)macinfo->gldm_private;
4101 
4102 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
4103 	/* Write Preamble */
4104 	write_mii(dnetp, MII_PRE, 2*bits_in_ushort);
4105 
4106 	/* Prepare command word */
4107 	command_word = (uint32_t)phy_addr << MII_PHY_ADDR_ALIGN;
4108 	command_word |= (uint32_t)reg_num << MII_REG_ADDR_ALIGN;
4109 	command_word |= MII_READ_FRAME;
4110 
4111 	write_mii(dnetp, command_word, bits_in_ushort-2);
4112 
4113 	mii_tristate(dnetp);
4114 
4115 	/* Check that the PHY generated a zero bit the 2nd clock */
4116 	tmp = ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, ETHER_ROM_REG));
4117 
4118 	turned_around = (tmp & MII_DATA_IN) ? 0 : 1;
4119 
4120 	/* read data WORD */
4121 	for (i = 0; i < bits_in_ushort; i++) {
4122 		ddi_put32(dnetp->io_handle,
4123 		    REG32(dnetp->io_reg, ETHER_ROM_REG), MII_READ);
4124 		drv_usecwait(MII_DELAY);
4125 		ddi_put32(dnetp->io_handle,
4126 		    REG32(dnetp->io_reg, ETHER_ROM_REG), MII_READ | MII_CLOCK);
4127 		drv_usecwait(MII_DELAY);
4128 		tmp = ddi_get32(dnetp->io_handle,
4129 		    REG32(dnetp->io_reg, ETHER_ROM_REG));
4130 		drv_usecwait(MII_DELAY);
4131 		data = (data << 1) | (tmp >> MII_DATA_IN_POSITION) & 0x0001;
4132 	}
4133 
4134 	mii_tristate(dnetp);
4135 	return (turned_around ? data: -1);
4136 }
4137 
4138 static void
4139 dnet_mii_write(dev_info_t *dip, int phy_addr, int reg_num, int reg_dat)
4140 {
4141 	gld_mac_info_t *macinfo;
4142 	struct dnetinstance *dnetp;
4143 	uint32_t command_word;
4144 	int bits_in_ushort = ((sizeof (ushort_t))*8);
4145 
4146 	macinfo = ddi_get_driver_private(dip);
4147 	dnetp = (struct dnetinstance *)macinfo->gldm_private;
4148 
4149 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
4150 	write_mii(dnetp, MII_PRE, 2*bits_in_ushort);
4151 
4152 	/* Prepare command word */
4153 	command_word = ((uint32_t)phy_addr << MII_PHY_ADDR_ALIGN);
4154 	command_word |= ((uint32_t)reg_num << MII_REG_ADDR_ALIGN);
4155 	command_word |= (MII_WRITE_FRAME | (uint32_t)reg_dat);
4156 
4157 	write_mii(dnetp, command_word, 2*bits_in_ushort);
4158 	mii_tristate(dnetp);
4159 }
4160 
4161 /*
4162  * Write data size bits from mii_data to the MII control lines.
4163  */
4164 static void
4165 write_mii(struct dnetinstance *dnetp, uint32_t mii_data, int data_size)
4166 {
4167 	int i;
4168 	uint32_t dbit;
4169 
4170 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
4171 	for (i = data_size; i > 0; i--) {
4172 		dbit = ((mii_data >>
4173 		    (31 - MII_WRITE_DATA_POSITION)) & MII_WRITE_DATA);
4174 		ddi_put32(dnetp->io_handle,
4175 		    REG32(dnetp->io_reg, ETHER_ROM_REG),
4176 		    MII_WRITE | dbit);
4177 		drv_usecwait(MII_DELAY);
4178 		ddi_put32(dnetp->io_handle,
4179 		    REG32(dnetp->io_reg, ETHER_ROM_REG),
4180 		    MII_WRITE | MII_CLOCK | dbit);
4181 		drv_usecwait(MII_DELAY);
4182 		mii_data <<= 1;
4183 	}
4184 }
4185 
4186 /*
4187  * Put the MDIO port in tri-state for the turn around bits
4188  * in MII read and at end of MII management sequence.
4189  */
4190 static void
4191 mii_tristate(struct dnetinstance *dnetp)
4192 {
4193 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
4194 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, ETHER_ROM_REG),
4195 	    MII_WRITE_TS);
4196 	drv_usecwait(MII_DELAY);
4197 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, ETHER_ROM_REG),
4198 	    MII_WRITE_TS | MII_CLOCK);
4199 	drv_usecwait(MII_DELAY);
4200 }
4201 
4202 
4203 static void
4204 set_leaf(SROM_FORMAT *sr, LEAF_FORMAT *leaf)
4205 {
4206 	if (sr->leaf && !sr->leaf->is_static)
4207 		kmem_free(sr->leaf, sr->adapters * sizeof (LEAF_FORMAT));
4208 	sr->leaf = leaf;
4209 }
4210 
4211 /*
4212  * Callback from MII module. Makes sure that the CSR registers are
4213  * configured properly if the PHY changes mode.
4214  */
4215 /* ARGSUSED */
4216 /* dnet_mii_link_cb - called with intrlock held */
4217 static void
4218 dnet_mii_link_cb(dev_info_t *dip, int phy, enum mii_phy_state state)
4219 {
4220 	gld_mac_info_t *macinfo = ddi_get_driver_private(dip);
4221 	struct dnetinstance *dnetp =
4222 	    (struct dnetinstance *)macinfo->gldm_private;
4223 	LEAF_FORMAT *leaf;
4224 
4225 	ASSERT(MUTEX_HELD(&dnetp->intrlock));
4226 	leaf = dnetp->sr.leaf + dnetp->leaf;
4227 	if (state == phy_state_linkup) {
4228 		dnetp->mii_up = 1;
4229 		/* XXX function return value ignored */
4230 		(void) mii_getspeed(dnetp->mii,
4231 		    dnetp->phyaddr, &dnetp->mii_speed,
4232 		    &dnetp->mii_duplex);
4233 		dnetp->selected_media_block = leaf->mii_block;
4234 		setup_block(macinfo);
4235 	} else {
4236 		/* NEEDSWORK: Probably can call find_active_media here */
4237 		dnetp->mii_up = 0;
4238 		dnetp->mii_speed = 0;
4239 		dnetp->mii_duplex = 0;
4240 		if (leaf->default_block->media_code == MEDIA_MII)
4241 			dnetp->selected_media_block = leaf->default_block;
4242 		setup_block(macinfo);
4243 	}
4244 }
4245 
4246 /*
4247  * SROM parsing routines.
4248  * Refer to the Digital 3.03 SROM spec while reading this! (references refer
4249  * to this document)
4250  * Where possible ALL vendor specific changes should be localised here. The
4251  * SROM data should be capable of describing any programmatic irregularities
4252  * of DNET cards (via SIA or GP registers, in particular), so vendor specific
4253  * code elsewhere should not be required
4254  */
4255 static void
4256 dnet_parse_srom(struct dnetinstance *dnetp, SROM_FORMAT *sr, uchar_t *vi)
4257 {
4258 	uint32_t ether_mfg = 0;
4259 	int i;
4260 	uchar_t *p;
4261 
4262 	if (!ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo,
4263 	    DDI_PROP_DONTPASS, "no_sromconfig", 0))
4264 		dnetp->sr.init_from_srom = check_srom_valid(vi);
4265 
4266 	if (dnetp->sr.init_from_srom && dnetp->board_type != DEVICE_ID_21040) {
4267 		/* Section 2/3: General SROM Format/ ID Block */
4268 		p = vi+18;
4269 		sr->version = *p++;
4270 		sr->adapters = *p++;
4271 
4272 		sr->leaf =
4273 		    kmem_zalloc(sr->adapters * sizeof (LEAF_FORMAT), KM_SLEEP);
4274 		for (i = 0; i < 6; i++)
4275 			sr->netaddr[i] = *p++;
4276 
4277 		for (i = 0; i < sr->adapters; i++) {
4278 			uchar_t devno = *p++;
4279 			uint16_t offset = *p++;
4280 			offset |= *p++ << 8;
4281 			sr->leaf[i].device_number = devno;
4282 			parse_controller_leaf(dnetp, sr->leaf+i, vi+offset);
4283 		}
4284 		/*
4285 		 * 'Orrible hack for cogent cards. The 6911A board seems to
4286 		 * have an incorrect SROM. (From the OEMDEMO program
4287 		 * supplied by cogent, it seems that the ROM matches a setup
4288 		 * or a board with a QSI or ICS PHY.
4289 		 */
4290 		for (i = 0; i < 3; i++)
4291 			ether_mfg = (ether_mfg << 8) | sr->netaddr[i];
4292 
4293 		if (ether_mfg == ADAPTEC_ETHER) {
4294 			static uint16_t cogent_gprseq[] = {0x821, 0};
4295 			switch (vi[COGENT_SROM_ID]) {
4296 			case COGENT_ANA6911A_C:
4297 			case COGENT_ANA6911AC_C:
4298 #ifdef DNETDEBUG
4299 				if (dnetdebug & DNETTRACE)
4300 					cmn_err(CE_WARN,
4301 					    "Suspected bad GPR sequence."
4302 					    " Making a guess (821,0)");
4303 #endif
4304 
4305 				/* XXX function return value ignored */
4306 				(void) ddi_prop_update_byte_array(
4307 				    DDI_DEV_T_NONE, dnetp->devinfo,
4308 				    "gpr-sequence", (uchar_t *)cogent_gprseq,
4309 				    sizeof (cogent_gprseq));
4310 				break;
4311 			}
4312 		}
4313 	} else {
4314 		/*
4315 		 * Adhoc SROM, check for some cards which need special handling
4316 		 * Assume vendor info contains ether address in first six bytes
4317 		 */
4318 
4319 		uchar_t *mac = vi + ddi_getprop(DDI_DEV_T_ANY, dnetp->devinfo,
4320 		    DDI_PROP_DONTPASS, macoffset_propname, 0);
4321 
4322 		for (i = 0; i < 6; i++)
4323 			sr->netaddr[i] = mac[i];
4324 
4325 		if (dnetp->board_type == DEVICE_ID_21140) {
4326 			for (i = 0; i < 3; i++)
4327 				ether_mfg = (ether_mfg << 8) | mac[i];
4328 
4329 			switch (ether_mfg) {
4330 			case ASANTE_ETHER:
4331 				dnetp->vendor_21140 = ASANTE_TYPE;
4332 				dnetp->vendor_revision = 0;
4333 				set_leaf(sr, &leaf_asante);
4334 				sr->adapters = 1;
4335 				break;
4336 
4337 			case COGENT_ETHER:
4338 			case ADAPTEC_ETHER:
4339 				dnetp->vendor_21140 = COGENT_EM_TYPE;
4340 				dnetp->vendor_revision =
4341 				    vi[VENDOR_REVISION_OFFSET];
4342 				set_leaf(sr, &leaf_cogent_100);
4343 				sr->adapters = 1;
4344 				break;
4345 
4346 			default:
4347 				dnetp->vendor_21140 = DEFAULT_TYPE;
4348 				dnetp->vendor_revision = 0;
4349 				set_leaf(sr, &leaf_default_100);
4350 				sr->adapters = 1;
4351 				break;
4352 			}
4353 		} else if (dnetp->board_type == DEVICE_ID_21041) {
4354 			set_leaf(sr, &leaf_21041);
4355 		} else if (dnetp->board_type == DEVICE_ID_21040) {
4356 			set_leaf(sr, &leaf_21040);
4357 		}
4358 	}
4359 }
4360 
4361 /* Section 4.2, 4.3, 4.4, 4.5 */
4362 static void
4363 parse_controller_leaf(struct dnetinstance *dnetp, LEAF_FORMAT *leaf,
4364 	uchar_t *vi)
4365 {
4366 	int i;
4367 
4368 	leaf->selected_contype = *vi++;
4369 	leaf->selected_contype |= *vi++ << 8;
4370 
4371 	if (dnetp->board_type == DEVICE_ID_21140) /* Sect. 4.3 */
4372 		leaf->gpr = *vi++;
4373 
4374 	leaf->block_count = *vi++;
4375 
4376 	if (leaf->block_count > MAX_MEDIA) {
4377 		cmn_err(CE_WARN, "dnet: Too many media in SROM!");
4378 		leaf->block_count = 1;
4379 	}
4380 	for (i = 0; i <= leaf->block_count; i++) {
4381 		vi = parse_media_block(dnetp, leaf->block + i, vi);
4382 		if (leaf->block[i].command & CMD_DEFAULT_MEDIUM)
4383 			leaf->default_block = leaf->block+i;
4384 	}
4385 	/* No explicit default block: use last in the ROM */
4386 	if (leaf->default_block == NULL)
4387 		leaf->default_block = leaf->block + leaf->block_count -1;
4388 
4389 }
4390 
4391 static uchar_t *
4392 parse_media_block(struct dnetinstance *dnetp, media_block_t *block, uchar_t *vi)
4393 {
4394 	int i;
4395 
4396 	/*
4397 	 * There are three kinds of media block we need to worry about:
4398 	 * The 21041 blocks.
4399 	 * 21140 blocks from a version 1 SROM
4400 	 * 2114[023] block from a version 3 SROM
4401 	 */
4402 
4403 	if (dnetp->board_type == DEVICE_ID_21041) {
4404 		/* Section 4.2 */
4405 		block->media_code = *vi & 0x3f;
4406 		block->type = 2;
4407 		if (*vi++ & 0x40) {
4408 			block->un.sia.csr13 = *vi++;
4409 			block->un.sia.csr13 |= *vi++ << 8;
4410 			block->un.sia.csr14 = *vi++;
4411 			block->un.sia.csr14 |= *vi++ << 8;
4412 			block->un.sia.csr15 = *vi++;
4413 			block->un.sia.csr15 |= *vi++ << 8;
4414 		} else {
4415 			/* No media data (csrs 13,14,15). Insert defaults */
4416 			switch (block->media_code) {
4417 			case MEDIA_TP:
4418 				block->un.sia.csr13 = 0xef01;
4419 				block->un.sia.csr14 = 0x7f3f;
4420 				block->un.sia.csr15 = 0x0008;
4421 				break;
4422 			case MEDIA_TP_FD:
4423 				block->un.sia.csr13 = 0xef01;
4424 				block->un.sia.csr14 = 0x7f3d;
4425 				block->un.sia.csr15 = 0x0008;
4426 				break;
4427 			case MEDIA_BNC:
4428 				block->un.sia.csr13 = 0xef09;
4429 				block->un.sia.csr14 = 0x0705;
4430 				block->un.sia.csr15 = 0x0006;
4431 				break;
4432 			case MEDIA_AUI:
4433 				block->un.sia.csr13 = 0xef09;
4434 				block->un.sia.csr14 = 0x0705;
4435 				block->un.sia.csr15 = 0x000e;
4436 				break;
4437 			}
4438 		}
4439 	} else  if (*vi & 0x80) {  /* Extended format: Section 4.3.2.2 */
4440 		int blocklen = *vi++ & 0x7f;
4441 		block->type = *vi++;
4442 		switch (block->type) {
4443 		case 0: /* "non-MII": Section 4.3.2.2.1 */
4444 			block->media_code = (*vi++) & 0x3f;
4445 			block->gprseqlen = 1;
4446 			block->gprseq[0] = *vi++;
4447 			block->command = *vi++;
4448 			block->command |= *vi++ << 8;
4449 			break;
4450 
4451 		case 1: /* MII/PHY: Section 4.3.2.2.2 */
4452 			block->command = CMD_PS;
4453 			block->media_code = MEDIA_MII;
4454 				/* This is whats needed in CSR6 */
4455 
4456 			block->un.mii.phy_num = *vi++;
4457 			block->gprseqlen = *vi++;
4458 
4459 			for (i = 0; i < block->gprseqlen; i++)
4460 				block->gprseq[i] = *vi++;
4461 			block->rstseqlen = *vi++;
4462 			for (i = 0; i < block->rstseqlen; i++)
4463 				block->rstseq[i] = *vi++;
4464 
4465 			block->un.mii.mediacaps = *vi++;
4466 			block->un.mii.mediacaps |= *vi++ << 8;
4467 			block->un.mii.nwayadvert = *vi++;
4468 			block->un.mii.nwayadvert |= *vi++ << 8;
4469 			block->un.mii.fdxmask = *vi++;
4470 			block->un.mii.fdxmask |= *vi++ << 8;
4471 			block->un.mii.ttmmask = *vi++;
4472 			block->un.mii.ttmmask |= *vi++ << 8;
4473 			break;
4474 
4475 		case 2: /* SIA Media: Section 4.4.2.1.1 */
4476 			block->media_code = *vi & 0x3f;
4477 			if (*vi++ & 0x40) {
4478 				block->un.sia.csr13 = *vi++;
4479 				block->un.sia.csr13 |= *vi++ << 8;
4480 				block->un.sia.csr14 = *vi++;
4481 				block->un.sia.csr14 |= *vi++ << 8;
4482 				block->un.sia.csr15 = *vi++;
4483 				block->un.sia.csr15 |= *vi++ << 8;
4484 			} else {
4485 				/*
4486 				 * SIA values not provided by SROM; provide
4487 				 * defaults. See appendix D of 2114[23] manuals.
4488 				 */
4489 				switch (block->media_code) {
4490 				case MEDIA_BNC:
4491 					block->un.sia.csr13 = 0x0009;
4492 					block->un.sia.csr14 = 0x0705;
4493 					block->un.sia.csr15 = 0x0000;
4494 					break;
4495 				case MEDIA_AUI:
4496 					block->un.sia.csr13 = 0x0009;
4497 					block->un.sia.csr14 = 0x0705;
4498 					block->un.sia.csr15 = 0x0008;
4499 					break;
4500 				case MEDIA_TP:
4501 					block->un.sia.csr13 = 0x0001;
4502 					block->un.sia.csr14 = 0x7f3f;
4503 					block->un.sia.csr15 = 0x0000;
4504 					break;
4505 				case MEDIA_TP_FD:
4506 					block->un.sia.csr13 = 0x0001;
4507 					block->un.sia.csr14 = 0x7f3d;
4508 					block->un.sia.csr15 = 0x0000;
4509 					break;
4510 				default:
4511 					block->un.sia.csr13 = 0x0000;
4512 					block->un.sia.csr14 = 0x0000;
4513 					block->un.sia.csr15 = 0x0000;
4514 				}
4515 			}
4516 
4517 			/* Treat GP control/data as a GPR sequence */
4518 			block->gprseqlen = 2;
4519 			block->gprseq[0] = *vi++;
4520 			block->gprseq[0] |= *vi++ << 8;
4521 			block->gprseq[0] |= GPR_CONTROL_WRITE;
4522 			block->gprseq[1] = *vi++;
4523 			block->gprseq[1] |= *vi++ << 8;
4524 			break;
4525 
4526 		case 3: /* MII/PHY : Section 4.4.2.1.2 */
4527 			block->command = CMD_PS;
4528 			block->media_code = MEDIA_MII;
4529 			block->un.mii.phy_num = *vi++;
4530 
4531 			block->gprseqlen = *vi++;
4532 			for (i = 0; i < block->gprseqlen; i++) {
4533 				block->gprseq[i] = *vi++;
4534 				block->gprseq[i] |= *vi++ << 8;
4535 			}
4536 
4537 			block->rstseqlen = *vi++;
4538 			for (i = 0; i < block->rstseqlen; i++) {
4539 				block->rstseq[i] = *vi++;
4540 				block->rstseq[i] |= *vi++ << 8;
4541 			}
4542 			block->un.mii.mediacaps = *vi++;
4543 			block->un.mii.mediacaps |= *vi++ << 8;
4544 			block->un.mii.nwayadvert = *vi++;
4545 			block->un.mii.nwayadvert |= *vi++ << 8;
4546 			block->un.mii.fdxmask = *vi++;
4547 			block->un.mii.fdxmask |= *vi++ << 8;
4548 			block->un.mii.ttmmask = *vi++;
4549 			block->un.mii.ttmmask |= *vi++ << 8;
4550 			block->un.mii.miiintr |= *vi++;
4551 			break;
4552 
4553 		case 4: /* SYM Media: 4.5.2.1.3 */
4554 			block->media_code = *vi++ & 0x3f;
4555 			/* Treat GP control and data as a GPR sequence */
4556 			block->gprseqlen = 2;
4557 			block->gprseq[0] = *vi++;
4558 			block->gprseq[0] |= *vi++ << 8;
4559 			block->gprseq[0] |= GPR_CONTROL_WRITE;
4560 			block->gprseq[1]  = *vi++;
4561 			block->gprseq[1] |= *vi++ << 8;
4562 			block->command = *vi++;
4563 			block->command |= *vi++ << 8;
4564 			break;
4565 
4566 		case 5: /* GPR reset sequence:  Section 4.5.2.1.4 */
4567 			block->rstseqlen = *vi++;
4568 			for (i = 0; i < block->rstseqlen; i++)
4569 				block->rstseq[i] = *vi++;
4570 			break;
4571 
4572 		default: /* Unknown media block. Skip it. */
4573 			cmn_err(CE_WARN, "dnet: Unsupported SROM block.");
4574 			vi += blocklen;
4575 			break;
4576 		}
4577 	} else { /* Compact format (or V1 SROM): Section 4.3.2.1 */
4578 		block->type = 0;
4579 		block->media_code = *vi++ & 0x3f;
4580 		block->gprseqlen = 1;
4581 		block->gprseq[0] = *vi++;
4582 		block->command = *vi++;
4583 		block->command |= (*vi++) << 8;
4584 	}
4585 	return (vi);
4586 }
4587 
4588 
4589 /*
4590  * An alternative to doing this would be to store the legacy ROMs in binary
4591  * format in the conf file, and in read_srom, pick out the data. This would
4592  * then allow the parser to continue on as normal. This makes it a little
4593  * easier to read.
4594  */
4595 static void
4596 setup_legacy_blocks()
4597 {
4598 	LEAF_FORMAT *leaf;
4599 	media_block_t *block;
4600 
4601 	/* Default FAKE SROM */
4602 	leaf = &leaf_default_100;
4603 	leaf->is_static = 1;
4604 	leaf->default_block = &leaf->block[3];
4605 	leaf->block_count = 4; /* 100 cards are highly unlikely to have BNC */
4606 	block = leaf->block;
4607 	block->media_code = MEDIA_TP_FD;
4608 	block->type = 0;
4609 	block->command = 0x8e;  /* PCS, PS off, media sense: bit7, pol=1 */
4610 	block++;
4611 	block->media_code = MEDIA_TP;
4612 	block->type = 0;
4613 	block->command = 0x8e;  /* PCS, PS off, media sense: bit7, pol=1 */
4614 	block++;
4615 	block->media_code = MEDIA_SYM_SCR_FD;
4616 	block->type = 0;
4617 	block->command = 0x6d;  /* PCS, PS, SCR on, media sense: bit6, pol=0 */
4618 	block++;
4619 	block->media_code = MEDIA_SYM_SCR;
4620 	block->type = 0;
4621 	block->command = 0x406d; /* PCS, PS, SCR on, media sense: bit6, pol=0 */
4622 
4623 	/* COGENT FAKE SROM */
4624 	leaf = &leaf_cogent_100;
4625 	leaf->is_static = 1;
4626 	leaf->default_block = &leaf->block[4];
4627 	leaf->block_count = 5; /* 100TX, 100TX-FD, 10T 10T-FD, BNC */
4628 	block = leaf->block; /* BNC */
4629 	block->media_code = MEDIA_BNC;
4630 	block->type = 0;
4631 	block->command =  0x8000; /* No media sense, PCS, SCR, PS all off */
4632 	block->gprseqlen = 2;
4633 	block->rstseqlen = 0;
4634 	block->gprseq[0] = 0x13f;
4635 	block->gprseq[1] = 1;
4636 
4637 	block++;
4638 	block->media_code = MEDIA_TP_FD;
4639 	block->type = 0;
4640 	block->command = 0x8e;  /* PCS, PS off, media sense: bit7, pol=1 */
4641 	block->gprseqlen = 2;
4642 	block->rstseqlen = 0;
4643 	block->gprseq[0] = 0x13f;
4644 	block->gprseq[1] = 0x26;
4645 
4646 	block++; /* 10BaseT */
4647 	block->media_code = MEDIA_TP;
4648 	block->type = 0;
4649 	block->command = 0x8e;  /* PCS, PS off, media sense: bit7, pol=1 */
4650 	block->gprseqlen = 2;
4651 	block->rstseqlen = 0;
4652 	block->gprseq[0] = 0x13f;
4653 	block->gprseq[1] = 0x3e;
4654 
4655 	block++; /* 100BaseTX-FD */
4656 	block->media_code = MEDIA_SYM_SCR_FD;
4657 	block->type = 0;
4658 	block->command = 0x6d;  /* PCS, PS, SCR on, media sense: bit6, pol=0 */
4659 	block->gprseqlen = 2;
4660 	block->rstseqlen = 0;
4661 	block->gprseq[0] = 0x13f;
4662 	block->gprseq[1] = 1;
4663 
4664 	block++; /* 100BaseTX */
4665 	block->media_code = MEDIA_SYM_SCR;
4666 	block->type = 0;
4667 	block->command = 0x406d; /* PCS, PS, SCR on, media sense: bit6, pol=0 */
4668 	block->gprseqlen = 2;
4669 	block->rstseqlen = 0;
4670 	block->gprseq[0] = 0x13f;
4671 	block->gprseq[1] = 1;
4672 
4673 	/* Generic legacy card with a PHY. */
4674 	leaf = &leaf_phylegacy;
4675 	leaf->block_count = 1;
4676 	leaf->mii_block = leaf->block;
4677 	leaf->default_block = &leaf->block[0];
4678 	leaf->is_static = 1;
4679 	block = leaf->block;
4680 	block->media_code = MEDIA_MII;
4681 	block->type = 1; /* MII Block type 1 */
4682 	block->command = 1; /* Port select */
4683 	block->gprseqlen = 0;
4684 	block->rstseqlen = 0;
4685 
4686 	/* ASANTE FAKE SROM */
4687 	leaf = &leaf_asante;
4688 	leaf->is_static = 1;
4689 	leaf->default_block = &leaf->block[0];
4690 	leaf->block_count = 1;
4691 	block = leaf->block;
4692 	block->media_code = MEDIA_MII;
4693 	block->type = 1; /* MII Block type 1 */
4694 	block->command = 1; /* Port select */
4695 	block->gprseqlen = 3;
4696 	block->rstseqlen = 0;
4697 	block->gprseq[0] = 0x180;
4698 	block->gprseq[1] = 0x80;
4699 	block->gprseq[2] = 0x0;
4700 
4701 	/* LEGACY 21041 card FAKE SROM */
4702 	leaf = &leaf_21041;
4703 	leaf->is_static = 1;
4704 	leaf->block_count = 4;  /* SIA Blocks for TP, TPfd, BNC, AUI */
4705 	leaf->default_block = &leaf->block[3];
4706 
4707 	block = leaf->block;
4708 	block->media_code = MEDIA_AUI;
4709 	block->type = 2;
4710 	block->un.sia.csr13 = 0xef09;
4711 	block->un.sia.csr14 = 0x0705;
4712 	block->un.sia.csr15 = 0x000e;
4713 
4714 	block++;
4715 	block->media_code = MEDIA_TP_FD;
4716 	block->type = 2;
4717 	block->un.sia.csr13 = 0xef01;
4718 	block->un.sia.csr14 = 0x7f3d;
4719 	block->un.sia.csr15 = 0x0008;
4720 
4721 	block++;
4722 	block->media_code = MEDIA_BNC;
4723 	block->type = 2;
4724 	block->un.sia.csr13 = 0xef09;
4725 	block->un.sia.csr14 = 0x0705;
4726 	block->un.sia.csr15 = 0x0006;
4727 
4728 	block++;
4729 	block->media_code = MEDIA_TP;
4730 	block->type = 2;
4731 	block->un.sia.csr13 = 0xef01;
4732 	block->un.sia.csr14 = 0x7f3f;
4733 	block->un.sia.csr15 = 0x0008;
4734 
4735 	/* LEGACY 21040 card FAKE SROM */
4736 	leaf = &leaf_21040;
4737 	leaf->is_static = 1;
4738 	leaf->block_count = 4;  /* SIA Blocks for TP, TPfd, BNC, AUI */
4739 	block = leaf->block;
4740 	block->media_code = MEDIA_AUI;
4741 	block->type = 2;
4742 	block->un.sia.csr13 = 0x8f09;
4743 	block->un.sia.csr14 = 0x0705;
4744 	block->un.sia.csr15 = 0x000e;
4745 	block++;
4746 	block->media_code = MEDIA_TP_FD;
4747 	block->type = 2;
4748 	block->un.sia.csr13 = 0x0f01;
4749 	block->un.sia.csr14 = 0x7f3d;
4750 	block->un.sia.csr15 = 0x0008;
4751 	block++;
4752 	block->media_code = MEDIA_BNC;
4753 	block->type = 2;
4754 	block->un.sia.csr13 = 0xef09;
4755 	block->un.sia.csr14 = 0x0705;
4756 	block->un.sia.csr15 = 0x0006;
4757 	block++;
4758 	block->media_code = MEDIA_TP;
4759 	block->type = 2;
4760 	block->un.sia.csr13 = 0x8f01;
4761 	block->un.sia.csr14 = 0x7f3f;
4762 	block->un.sia.csr15 = 0x0008;
4763 }
4764 
4765 static void
4766 dnet_print_srom(SROM_FORMAT *sr)
4767 {
4768 	int i;
4769 	uchar_t *a = sr->netaddr;
4770 	cmn_err(CE_NOTE, "SROM Dump: %d. ver %d, Num adapters %d,"
4771 	    "Addr:%x:%x:%x:%x:%x:%x",
4772 	    sr->init_from_srom, sr->version, sr->adapters,
4773 	    a[0], a[1], a[2], a[3], a[4], a[5]);
4774 
4775 	for (i = 0; i < sr->adapters; i++)
4776 		dnet_dump_leaf(sr->leaf+i);
4777 }
4778 
4779 static void
4780 dnet_dump_leaf(LEAF_FORMAT *leaf)
4781 {
4782 	int i;
4783 	cmn_err(CE_NOTE, "Leaf: Device %d, block_count %d, gpr: %x",
4784 	    leaf->device_number, leaf->block_count, leaf->gpr);
4785 	for (i = 0; i < leaf->block_count; i++)
4786 		dnet_dump_block(leaf->block+i);
4787 }
4788 
4789 static void
4790 dnet_dump_block(media_block_t *block)
4791 {
4792 	cmn_err(CE_NOTE, "Block(%p): type %x, media %s, command: %x ",
4793 	    (void *)block,
4794 	    block->type, media_str[block->media_code], block->command);
4795 	dnet_dumpbin("\tGPR Seq", (uchar_t *)block->gprseq, 2,
4796 	    block->gprseqlen *2);
4797 	dnet_dumpbin("\tGPR Reset", (uchar_t *)block->rstseq, 2,
4798 	    block->rstseqlen *2);
4799 	switch (block->type) {
4800 	case 1: case 3:
4801 		cmn_err(CE_NOTE, "\tMII Info: phy %d, nway %x, fdx"
4802 		    "%x, ttm %x, mediacap %x",
4803 		    block->un.mii.phy_num, block->un.mii.nwayadvert,
4804 		    block->un.mii.fdxmask, block->un.mii.ttmmask,
4805 		    block->un.mii.mediacaps);
4806 		break;
4807 	case 2:
4808 		cmn_err(CE_NOTE, "\tSIA Regs: CSR13:%x, CSR14:%x, CSR15:%x",
4809 		    block->un.sia.csr13, block->un.sia.csr14,
4810 		    block->un.sia.csr15);
4811 		break;
4812 	}
4813 }
4814 
4815 
4816 /* Utility to print out binary info dumps. Handy for SROMs, etc */
4817 
4818 static int
4819 hexcode(unsigned val)
4820 {
4821 	if (val <= 9)
4822 		return (val +'0');
4823 	if (val <= 15)
4824 		return (val + 'a' - 10);
4825 	return (-1);
4826 }
4827 
4828 static void
4829 dnet_dumpbin(char *msg, unsigned char *data, int size, int len)
4830 {
4831 	char hex[128], *p = hex;
4832 	char ascii[128], *q = ascii;
4833 	int i, j;
4834 
4835 	if (!len)
4836 		return;
4837 
4838 	for (i = 0; i < len; i += size) {
4839 		for (j = size - 1; j >= 0; j--) { /* PORTABILITY: byte order */
4840 			*p++ = hexcode(data[i+j] >> 4);
4841 			*p++ = hexcode(data[i+j] & 0xf);
4842 			*q++ = (data[i+j] < 32 || data[i+j] > 127) ?
4843 			    '.' : data[i];
4844 		}
4845 		*p++ = ' ';
4846 		if (q-ascii >= 8) {
4847 			*p = *q = 0;
4848 			cmn_err(CE_NOTE, "%s: %s\t%s", msg, hex, ascii);
4849 			p = hex;
4850 			q = ascii;
4851 		}
4852 	}
4853 	if (p != hex) {
4854 		while ((p - hex) < 8*3)
4855 			*p++ = ' ';
4856 		*p = *q = 0;
4857 		cmn_err(CE_NOTE, "%s: %s\t%s", msg, hex, ascii);
4858 	}
4859 }
4860 
4861 #ifdef DNETDEBUG
4862 void
4863 dnet_usectimeout(struct dnetinstance *dnetp, uint32_t usecs, int contin,
4864     timercb_t cback)
4865 {
4866 	mutex_enter(&dnetp->intrlock);
4867 	dnetp->timer.start_ticks = (usecs * 100) / 8192;
4868 	dnetp->timer.cb = cback;
4869 	ddi_put32(dnetp->io_handle, REG32(dnetp->io_reg, GP_TIMER_REG),
4870 	    dnetp->timer.start_ticks | (contin ? GPTIMER_CONT : 0));
4871 	if (dnetp->timer.cb)
4872 		enable_interrupts(dnetp, 1);
4873 	mutex_exit(&dnetp->intrlock);
4874 }
4875 
4876 uint32_t
4877 dnet_usecelapsed(struct dnetinstance *dnetp)
4878 {
4879 	uint32_t ticks = dnetp->timer.start_ticks -
4880 	    (ddi_get32(dnetp->io_handle, REG32(dnetp->io_reg, GP_TIMER_REG)) &
4881 	    0xffff);
4882 	return ((ticks * 8192) / 100);
4883 }
4884 
4885 /* ARGSUSED */
4886 void
4887 dnet_timestamp(struct dnetinstance *dnetp,  char *buf)
4888 {
4889 	uint32_t elapsed = dnet_usecelapsed(dnetp);
4890 	char loc[32], *p = loc;
4891 	int firstdigit = 1;
4892 	uint32_t divisor;
4893 
4894 	while (*p++ = *buf++)
4895 		;
4896 	p--;
4897 
4898 	for (divisor = 1000000000; divisor /= 10; ) {
4899 		int digit = (elapsed / divisor);
4900 		elapsed -= digit * divisor;
4901 		if (!firstdigit || digit) {
4902 			*p++ = digit + '0';
4903 			firstdigit = 0;
4904 		}
4905 
4906 	}
4907 
4908 	/* Actual zero, output it */
4909 	if (firstdigit)
4910 		*p++ = '0';
4911 
4912 	*p++ = '-';
4913 	*p++ = '>';
4914 	*p++ = 0;
4915 
4916 	printf(loc);
4917 	dnet_usectimeout(dnetp, 1000000, 0, 0);
4918 }
4919 
4920 #endif
4921