xref: /illumos-gate/usr/src/uts/common/io/iprb/iprb.c (revision 598f4ceed9327d2d6c2325dd67cae3aa06f7fea6)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
14  */
15 
16 /*
17  * Intel Pro/100B Ethernet Driver
18  */
19 
20 #include <sys/types.h>
21 #include <sys/modctl.h>
22 #include <sys/conf.h>
23 #include <sys/kmem.h>
24 #include <sys/ksynch.h>
25 #include <sys/cmn_err.h>
26 #include <sys/note.h>
27 #include <sys/pci.h>
28 #include <sys/pci_cap.h>
29 #include <sys/ethernet.h>
30 #include <sys/mii.h>
31 #include <sys/miiregs.h>
32 #include <sys/mac.h>
33 #include <sys/mac_ether.h>
34 #include <sys/ethernet.h>
35 #include <sys/vlan.h>
36 #include <sys/list.h>
37 #include <sys/sysmacros.h>
38 #include <sys/varargs.h>
39 #include <sys/stream.h>
40 #include <sys/strsun.h>
41 #include <sys/ddi.h>
42 #include <sys/sunddi.h>
43 
44 #include "iprb.h"
45 #include "rcvbundl.h"
46 
47 /*
48  * Intel has openly documented the programming interface for these
49  * parts in the "Intel 8255x 10/100 Mbps Ethernet Controller Family
50  * Open Source Software Developer Manual".
51  *
52  * While some open source systems have utilized many of the features
53  * of some models in this family (especially scatter gather and IP
54  * checksum support), we have elected to offer only the basic
55  * functionality.  These are only 10/100 parts, and the additional
56  * complexity is not justified by the minimal performance benefit.
57  * KISS.  So, we are only supporting the simple 82557 features.
58  */
59 
60 static uint16_t	iprb_mii_read(void *, uint8_t, uint8_t);
61 static void	iprb_mii_write(void *, uint8_t, uint8_t, uint16_t);
62 static void	iprb_mii_notify(void *, link_state_t);
63 static int	iprb_attach(dev_info_t *);
64 static int	iprb_detach(dev_info_t *);
65 static int	iprb_quiesce(dev_info_t *);
66 static int	iprb_suspend(dev_info_t *);
67 static int	iprb_resume(dev_info_t *);
68 static int	iprb_m_stat(void *, uint_t, uint64_t *);
69 static int	iprb_m_start(void *);
70 static void	iprb_m_stop(void *);
71 static int	iprb_m_promisc(void *, boolean_t);
72 static int	iprb_m_multicst(void *, boolean_t, const uint8_t *);
73 static int	iprb_m_unicst(void *, const uint8_t *);
74 static mblk_t	*iprb_m_tx(void *, mblk_t *);
75 static void	iprb_m_ioctl(void *, queue_t *, mblk_t *);
76 static int	iprb_m_setprop(void *, const char *, mac_prop_id_t, uint_t,
77     const void *);
78 static int	iprb_m_getprop(void *, const char *, mac_prop_id_t, uint_t,
79     void *);
80 static void	iprb_m_propinfo(void *, const char *, mac_prop_id_t,
81     mac_prop_info_handle_t);
82 static void	iprb_destroy(iprb_t *);
83 static int	iprb_configure(iprb_t *);
84 static void	iprb_eeprom_sendbits(iprb_t *, uint32_t, uint8_t);
85 static uint16_t	iprb_eeprom_read(iprb_t *, uint16_t);
86 static void	iprb_identify(iprb_t *);
87 static int	iprb_cmd_submit(iprb_t *, uint16_t);
88 static void	iprb_cmd_reclaim(iprb_t *);
89 static int	iprb_cmd_ready(iprb_t *);
90 static int	iprb_cmd_drain(iprb_t *);
91 static void	iprb_rx_add(iprb_t *);
92 static void	iprb_rx_init(iprb_t *);
93 static mblk_t	*iprb_rx(iprb_t *);
94 static mblk_t	*iprb_send(iprb_t *, mblk_t *);
95 static uint_t	iprb_intr(caddr_t, caddr_t);
96 static void	iprb_periodic(void *);
97 static int	iprb_add_intr(iprb_t *);
98 static int	iprb_dma_alloc(iprb_t *, iprb_dma_t *, size_t);
99 static void	iprb_dma_free(iprb_dma_t *);
100 static iprb_dma_t *iprb_cmd_next(iprb_t *);
101 static int	iprb_set_config(iprb_t *);
102 static int	iprb_set_unicast(iprb_t *);
103 static int	iprb_set_multicast(iprb_t *);
104 static int	iprb_set_ucode(iprb_t *);
105 static void	iprb_update_stats(iprb_t *);
106 static int	iprb_start(iprb_t *);
107 static void	iprb_stop(iprb_t *);
108 static int	iprb_ddi_attach(dev_info_t *, ddi_attach_cmd_t);
109 static int	iprb_ddi_detach(dev_info_t *, ddi_detach_cmd_t);
110 static void	iprb_error(iprb_t *, const char *, ...);
111 
112 static mii_ops_t iprb_mii_ops = {
113 	MII_OPS_VERSION,
114 	iprb_mii_read,
115 	iprb_mii_write,
116 	iprb_mii_notify,
117 	NULL,		/* reset */
118 };
119 
120 static mac_callbacks_t iprb_m_callbacks = {
121 	MC_IOCTL | MC_SETPROP | MC_GETPROP | MC_PROPINFO,
122 	iprb_m_stat,
123 	iprb_m_start,
124 	iprb_m_stop,
125 	iprb_m_promisc,
126 	iprb_m_multicst,
127 	iprb_m_unicst,
128 	iprb_m_tx,
129 	NULL,
130 	iprb_m_ioctl,	/* mc_ioctl */
131 	NULL,		/* mc_getcapab */
132 	NULL,		/* mc_open */
133 	NULL,		/* mc_close */
134 	iprb_m_setprop,
135 	iprb_m_getprop,
136 	iprb_m_propinfo
137 };
138 
139 
140 /*
141  * Stream information
142  */
143 DDI_DEFINE_STREAM_OPS(iprb_devops, nulldev, nulldev,
144     iprb_ddi_attach, iprb_ddi_detach, nodev, NULL, D_MP, NULL, iprb_quiesce);
145 
146 static struct modldrv iprb_modldrv = {
147 	&mod_driverops,			/* drv_modops */
148 	"Intel 8255x Ethernet",		/* drv_linkinfo */
149 	&iprb_devops			/* drv_dev_ops */
150 };
151 
152 static struct modlinkage iprb_modlinkage = {
153 	MODREV_1,		/* ml_rev */
154 	{ &iprb_modldrv, NULL }	/* ml_linkage */
155 };
156 
157 
158 static ddi_device_acc_attr_t acc_attr = {
159 	DDI_DEVICE_ATTR_V0,
160 	DDI_STRUCTURE_LE_ACC,
161 	DDI_STRICTORDER_ACC
162 };
163 
164 static ddi_device_acc_attr_t buf_attr = {
165 	DDI_DEVICE_ATTR_V0,
166 	DDI_NEVERSWAP_ACC,
167 	DDI_STORECACHING_OK_ACC
168 };
169 
170 /*
171  * The 8225x is a 32-bit addressing engine, but it can only address up
172  * to 31 bits on a single transaction.  (Far less in reality it turns
173  * out.)  Statistics buffers have to be 16-byte aligned, and as we
174  * allocate individual data pieces for other things, there is no
175  * compelling reason to use another attribute with support for less
176  * strict alignment.
177  */
178 static ddi_dma_attr_t dma_attr = {
179 	DMA_ATTR_V0,		/* dma_attr_version */
180 	0,			/* dma_attr_addr_lo */
181 	0xFFFFFFFFU,		/* dma_attr_addr_hi */
182 	0x7FFFFFFFU,		/* dma_attr_count_max */
183 	16,			/* dma_attr_align */
184 	0x100,			/* dma_attr_burstsizes */
185 	1,			/* dma_attr_minxfer */
186 	0xFFFFFFFFU,		/* dma_attr_maxxfer */
187 	0xFFFFFFFFU,		/* dma_attr_seg */
188 	1,			/* dma_attr_sgllen */
189 	1,			/* dma_attr_granular */
190 	0			/* dma_attr_flags */
191 };
192 
193 #define	DECL_UCODE(x)						\
194 	static const uint32_t x ## _WORDS[] = x ## _RCVBUNDLE_UCODE
195 DECL_UCODE(D101_A);
196 DECL_UCODE(D101_B0);
197 DECL_UCODE(D101M_B);
198 DECL_UCODE(D101S);
199 DECL_UCODE(D102_B);
200 DECL_UCODE(D102_C);
201 DECL_UCODE(D102_E);
202 
203 static uint8_t iprb_bcast[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
204 
205 /*
206  * We don't bother allowing for tuning of the CPU saver algorithm.
207  * The ucode has reasonable defaults built-in.  However, some variants
208  * apparently have bug fixes delivered via this ucode, so we still
209  * need to support the ucode upload.
210  */
211 typedef struct {
212 	uint8_t		rev;
213 	uint8_t		length;
214 	const uint32_t	*ucode;
215 } iprb_ucode_t;
216 
217 #define	UCODE(x)						\
218 	sizeof (x ## _WORDS) / sizeof (uint32_t), x ## _WORDS
219 
220 static const iprb_ucode_t iprb_ucode[] = {
221 	{ REV_82558_A4,	UCODE(D101_A) },
222 	{ REV_82558_B0,	UCODE(D101_B0) },
223 	{ REV_82559_A0,	UCODE(D101M_B) },
224 	{ REV_82559S_A,	UCODE(D101S) },
225 	{ REV_82550,	UCODE(D102_B) },
226 	{ REV_82550_C,	UCODE(D102_C) },
227 	{ REV_82551_F,	UCODE(D102_E) },
228 	{ 0 },
229 };
230 
231 int
232 _init(void)
233 {
234 	int	rv;
235 	mac_init_ops(&iprb_devops, "iprb");
236 	if ((rv = mod_install(&iprb_modlinkage)) != DDI_SUCCESS) {
237 		mac_fini_ops(&iprb_devops);
238 	}
239 	return (rv);
240 }
241 
242 int
243 _fini(void)
244 {
245 	int	rv;
246 	if ((rv = mod_remove(&iprb_modlinkage)) == DDI_SUCCESS) {
247 		mac_fini_ops(&iprb_devops);
248 	}
249 	return (rv);
250 }
251 
252 int
253 _info(struct modinfo *modinfop)
254 {
255 	return (mod_info(&iprb_modlinkage, modinfop));
256 }
257 
258 int
259 iprb_attach(dev_info_t *dip)
260 {
261 	iprb_t		*ip;
262 	uint16_t	w;
263 	int		i;
264 	mac_register_t	*macp;
265 
266 	ip = kmem_zalloc(sizeof (*ip), KM_SLEEP);
267 	ddi_set_driver_private(dip, ip);
268 	ip->dip = dip;
269 
270 	list_create(&ip->mcast, sizeof (struct iprb_mcast),
271 	    offsetof(struct iprb_mcast, node));
272 
273 	/* we don't support high level interrupts, so we don't need cookies */
274 	mutex_init(&ip->culock, NULL, MUTEX_DRIVER, NULL);
275 	mutex_init(&ip->rulock, NULL, MUTEX_DRIVER, NULL);
276 
277 	if (pci_config_setup(dip, &ip->pcih) != DDI_SUCCESS) {
278 		iprb_error(ip, "unable to map configuration space");
279 		iprb_destroy(ip);
280 		return (DDI_FAILURE);
281 	}
282 
283 	if (ddi_regs_map_setup(dip, 1, &ip->regs, 0, 0, &acc_attr,
284 	    &ip->regsh) != DDI_SUCCESS) {
285 		iprb_error(ip, "unable to map device registers");
286 		iprb_destroy(ip);
287 		return (DDI_FAILURE);
288 	}
289 
290 	/* Reset, but first go into idle state */
291 	PUT32(ip, CSR_PORT, PORT_SEL_RESET);
292 	drv_usecwait(10);
293 	PUT32(ip, CSR_PORT, PORT_SW_RESET);
294 	drv_usecwait(10);
295 	PUT8(ip, CSR_INTCTL, INTCTL_MASK);
296 	(void) GET8(ip, CSR_INTCTL);
297 
298 	/*
299 	 * Precalculate watchdog times.
300 	 */
301 	ip->tx_timeout = drv_usectohz(TX_WATCHDOG * 1000000);
302 	ip->rx_timeout = drv_usectohz(RX_WATCHDOG * 1000000);
303 
304 	iprb_identify(ip);
305 
306 	/* Obtain our factory MAC address */
307 	w = iprb_eeprom_read(ip, 0);
308 	ip->factaddr[0] = w & 0xff;
309 	ip->factaddr[1] = w >> 8;
310 	w = iprb_eeprom_read(ip, 1);
311 	ip->factaddr[2] = w & 0xff;
312 	ip->factaddr[3] = w >> 8;
313 	w = iprb_eeprom_read(ip, 2);
314 	ip->factaddr[4] = w & 0xff;
315 	ip->factaddr[5] = w >> 8;
316 	bcopy(ip->factaddr, ip->curraddr, 6);
317 
318 	if (ip->resumebug) {
319 		/*
320 		 * Generally, most devices we will ever see will
321 		 * already have fixed firmware.  Since I can't verify
322 		 * the validity of the fix (no suitably downrev
323 		 * hardware), we'll just do our best to avoid it for
324 		 * devices that exhibit this behavior.
325 		 */
326 		if ((iprb_eeprom_read(ip, 10) & 0x02) == 0) {
327 			/* EEPROM fix was already applied, assume safe. */
328 			ip->resumebug = B_FALSE;
329 		}
330 	}
331 
332 	if ((iprb_eeprom_read(ip, 3) & 0x3) != 0x3) {
333 		cmn_err(CE_CONT, "?Enabling RX errata workaround.\n");
334 		ip->rxhangbug = B_TRUE;
335 	}
336 
337 	/* Determine whether we have an MII or a legacy 80c24 */
338 	w = iprb_eeprom_read(ip, 6);
339 	if ((w & 0x3f00) != 0x0600) {
340 		if ((ip->miih = mii_alloc(ip, dip, &iprb_mii_ops)) == NULL) {
341 			iprb_error(ip, "unable to allocate MII ops vector");
342 			iprb_destroy(ip);
343 			return (DDI_FAILURE);
344 		}
345 		if (ip->canpause) {
346 			mii_set_pauseable(ip->miih, B_TRUE, B_FALSE);
347 		}
348 	}
349 
350 	/* Allocate cmds and tx region */
351 	for (i = 0; i < NUM_TX; i++) {
352 		/* Command blocks */
353 		if (iprb_dma_alloc(ip, &ip->cmds[i], CB_SIZE) != DDI_SUCCESS) {
354 			iprb_destroy(ip);
355 			return (DDI_FAILURE);
356 		}
357 	}
358 
359 	for (i = 0; i < NUM_TX; i++) {
360 		iprb_dma_t *cb = &ip->cmds[i];
361 		/* Link the command blocks into a ring */
362 		PUTCB32(cb, CB_LNK_OFFSET, (ip->cmds[(i + 1) % NUM_TX].paddr));
363 	}
364 
365 	for (i = 0; i < NUM_RX; i++) {
366 		/* Rx packet buffers */
367 		if (iprb_dma_alloc(ip, &ip->rxb[i], RFD_SIZE) != DDI_SUCCESS) {
368 			iprb_destroy(ip);
369 			return (DDI_FAILURE);
370 		}
371 	}
372 	if (iprb_dma_alloc(ip, &ip->stats, STATS_SIZE) != DDI_SUCCESS) {
373 		iprb_destroy(ip);
374 		return (DDI_FAILURE);
375 	}
376 
377 	if (iprb_add_intr(ip) != DDI_SUCCESS) {
378 		iprb_destroy(ip);
379 		return (DDI_FAILURE);
380 	}
381 
382 	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
383 		iprb_error(ip, "unable to allocate mac structure");
384 		iprb_destroy(ip);
385 		return (DDI_FAILURE);
386 	}
387 
388 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
389 	macp->m_driver = ip;
390 	macp->m_dip = dip;
391 	macp->m_src_addr = ip->curraddr;
392 	macp->m_callbacks = &iprb_m_callbacks;
393 	macp->m_min_sdu = 0;
394 	macp->m_max_sdu = ETHERMTU;
395 	macp->m_margin = VLAN_TAGSZ;
396 	if (mac_register(macp, &ip->mach) != 0) {
397 		iprb_error(ip, "unable to register mac with framework");
398 		mac_free(macp);
399 		iprb_destroy(ip);
400 		return (DDI_FAILURE);
401 	}
402 
403 	mac_free(macp);
404 	return (DDI_SUCCESS);
405 }
406 
407 int
408 iprb_detach(dev_info_t *dip)
409 {
410 	iprb_t *ip;
411 
412 	ip = ddi_get_driver_private(dip);
413 	ASSERT(ip != NULL);
414 
415 	if (mac_disable(ip->mach) != 0)
416 		return (DDI_FAILURE);
417 
418 	(void) mac_unregister(ip->mach);
419 	iprb_destroy(ip);
420 	return (DDI_SUCCESS);
421 }
422 
423 int
424 iprb_add_intr(iprb_t *ip)
425 {
426 	int	actual;
427 
428 	if (ddi_intr_alloc(ip->dip, &ip->intrh, DDI_INTR_TYPE_FIXED, 0, 1,
429 	    &actual, DDI_INTR_ALLOC_STRICT) != DDI_SUCCESS) {
430 		iprb_error(ip, "failed allocating interrupt handle");
431 		return (DDI_FAILURE);
432 	}
433 
434 	if (ddi_intr_add_handler(ip->intrh, iprb_intr, ip, NULL) !=
435 	    DDI_SUCCESS) {
436 		(void) ddi_intr_free(ip->intrh);
437 		ip->intrh = NULL;
438 		iprb_error(ip, "failed adding interrupt handler");
439 		return (DDI_FAILURE);
440 	}
441 	if (ddi_intr_enable(ip->intrh) != DDI_SUCCESS) {
442 		(void) ddi_intr_remove_handler(ip->intrh);
443 		(void) ddi_intr_free(ip->intrh);
444 		ip->intrh = NULL;
445 		iprb_error(ip, "failed enabling interrupt");
446 		return (DDI_FAILURE);
447 	}
448 	return (DDI_SUCCESS);
449 }
450 
451 int
452 iprb_dma_alloc(iprb_t *ip, iprb_dma_t *h, size_t size)
453 {
454 	size_t			rlen;
455 	ddi_dma_cookie_t	dmac;
456 	uint_t			ndmac;
457 
458 	if (ddi_dma_alloc_handle(ip->dip, &dma_attr, DDI_DMA_SLEEP, NULL,
459 	    &h->dmah) != DDI_SUCCESS) {
460 		iprb_error(ip, "unable to allocate dma handle");
461 		return (DDI_FAILURE);
462 	}
463 	if (ddi_dma_mem_alloc(h->dmah, size, &buf_attr, DDI_DMA_CONSISTENT,
464 	    DDI_DMA_SLEEP, NULL, &h->vaddr, &rlen, &h->acch) != DDI_SUCCESS) {
465 		iprb_error(ip, "unable to allocate dma memory");
466 		return (DDI_FAILURE);
467 	}
468 	bzero(h->vaddr, size);
469 	if (ddi_dma_addr_bind_handle(h->dmah, NULL, h->vaddr, size,
470 	    DDI_DMA_CONSISTENT | DDI_DMA_RDWR, DDI_DMA_SLEEP, NULL,
471 	    &dmac, &ndmac) != DDI_DMA_MAPPED) {
472 		iprb_error(ip, "unable to map command memory");
473 		return (DDI_FAILURE);
474 	}
475 	h->paddr = dmac.dmac_address;
476 	return (DDI_SUCCESS);
477 }
478 
479 void
480 iprb_dma_free(iprb_dma_t *h)
481 {
482 	if (h->paddr != 0)
483 		(void) ddi_dma_unbind_handle(h->dmah);
484 	h->paddr = 0;
485 	if (h->acch != NULL)
486 		ddi_dma_mem_free(&h->acch);
487 	h->acch = NULL;
488 	if (h->dmah != NULL)
489 		ddi_dma_free_handle(&h->dmah);
490 	h->dmah = NULL;
491 }
492 
493 void
494 iprb_destroy(iprb_t *ip)
495 {
496 	int i;
497 	iprb_mcast_t *mc;
498 
499 	/* shut down interrupts */
500 	if (ip->intrh != NULL) {
501 		(void) ddi_intr_disable(ip->intrh);
502 		(void) ddi_intr_remove_handler(ip->intrh);
503 		(void) ddi_intr_free(ip->intrh);
504 	}
505 	/* release DMA resources */
506 	for (i = 0; i < NUM_TX; i++) {
507 		iprb_dma_free(&ip->cmds[i]);
508 	}
509 	for (i = 0; i < NUM_RX; i++) {
510 		iprb_dma_free(&ip->rxb[i]);
511 	}
512 	iprb_dma_free(&ip->stats);
513 
514 	if (ip->miih)
515 		mii_free(ip->miih);
516 
517 	/* clean up the multicast list */
518 	while ((mc = list_head(&ip->mcast)) != NULL) {
519 		list_remove(&ip->mcast, mc);
520 		kmem_free(mc, sizeof (*mc));
521 	}
522 
523 	/* tear down register mappings */
524 	if (ip->pcih)
525 		pci_config_teardown(&ip->pcih);
526 	if (ip->regsh)
527 		ddi_regs_map_free(&ip->regsh);
528 
529 	/* clean the dip */
530 	ddi_set_driver_private(ip->dip, NULL);
531 
532 	list_destroy(&ip->mcast);
533 	mutex_destroy(&ip->culock);
534 	mutex_destroy(&ip->rulock);
535 
536 	/* and finally toss the structure itself */
537 	kmem_free(ip, sizeof (*ip));
538 }
539 
540 void
541 iprb_identify(iprb_t *ip)
542 {
543 	ip->devid = pci_config_get16(ip->pcih, PCI_CONF_DEVID);
544 	ip->revid = pci_config_get8(ip->pcih, PCI_CONF_REVID);
545 
546 	switch (ip->devid) {
547 	case 0x1229:	/* 8255x family */
548 	case 0x1030:	/* Intel InBusiness */
549 
550 		if (ip->revid >= REV_82558_A4) {
551 			ip->canpause = B_TRUE;
552 			ip->canmwi = B_TRUE;
553 		} else {
554 			ip->is557 = B_TRUE;
555 		}
556 		if (ip->revid >= REV_82559_A0)
557 			ip->resumebug = B_TRUE;
558 		break;
559 
560 	case 0x1209:	/* Embedded 82559ER */
561 		ip->canpause = B_TRUE;
562 		ip->resumebug = B_TRUE;
563 		ip->canmwi = B_TRUE;
564 		break;
565 
566 	case 0x2449:	/* ICH2 */
567 	case 0x1031:	/* Pro/100 VE (ICH3) */
568 	case 0x1032:	/* Pro/100 VE (ICH3) */
569 	case 0x1033:	/* Pro/100 VM (ICH3) */
570 	case 0x1034:	/* Pro/100 VM (ICH3) */
571 	case 0x1038:	/* Pro/100 VM (ICH3) */
572 		ip->resumebug = B_TRUE;
573 		if (ip->revid >= REV_82558_A4)
574 			ip->canpause = B_TRUE;
575 		break;
576 
577 	default:
578 		if (ip->revid >= REV_82558_A4)
579 			ip->canpause = B_TRUE;
580 		break;
581 	}
582 
583 	/* Allow property override MWI support - not normally needed. */
584 	if (ddi_prop_get_int(DDI_DEV_T_ANY, ip->dip, 0, "MWIEnable", 1) == 0) {
585 		ip->canmwi = B_FALSE;
586 	}
587 }
588 
589 void
590 iprb_eeprom_sendbits(iprb_t *ip, uint32_t val, uint8_t nbits)
591 {
592 	uint32_t	mask;
593 	uint16_t	x;
594 
595 	mask = 1U << (nbits - 1);
596 	while (mask) {
597 		x = (mask & val) ? EEPROM_EEDI : 0;
598 		PUT16(ip, CSR_EECTL, x | EEPROM_EECS);
599 		drv_usecwait(100);
600 		PUT16(ip, CSR_EECTL, x | EEPROM_EESK | EEPROM_EECS);
601 		drv_usecwait(100);
602 		PUT16(ip, CSR_EECTL, x | EEPROM_EECS);
603 		drv_usecwait(100);
604 		mask >>= 1;
605 	}
606 }
607 
608 uint16_t
609 iprb_eeprom_read(iprb_t *ip, uint16_t address)
610 {
611 	uint16_t	val;
612 	int		mask;
613 	uint16_t	n;
614 	uint16_t	bits;
615 
616 	/* if we don't know the address size yet call again to determine it */
617 	if ((address != 0) && (ip->eeprom_bits == 0))
618 		(void) iprb_eeprom_read(ip, 0);
619 
620 	if ((bits = ip->eeprom_bits) == 0) {
621 		bits = 8;
622 		ASSERT(address == 0);
623 	}
624 	/* enable the EEPROM chip select */
625 	PUT16(ip, CSR_EECTL, EEPROM_EECS);
626 	drv_usecwait(100);
627 
628 	/* send a read command */
629 	iprb_eeprom_sendbits(ip, 6, 3);
630 	n = 0;
631 	for (mask = (1U << (bits - 1)); mask != 0; mask >>= 1) {
632 		uint16_t x = (mask & address) ? EEPROM_EEDI : 0;
633 		PUT16(ip, CSR_EECTL, x | EEPROM_EECS);
634 		drv_usecwait(100);
635 		PUT16(ip, CSR_EECTL, x | EEPROM_EESK | EEPROM_EECS);
636 		drv_usecwait(100);
637 		PUT16(ip, CSR_EECTL, x | EEPROM_EECS);
638 		drv_usecwait(100);
639 
640 		n++;
641 		/* check the dummy 0 bit */
642 		if ((GET16(ip, CSR_EECTL) & EEPROM_EEDO) == 0) {
643 			if (ip->eeprom_bits == 0) {
644 				ip->eeprom_bits = n;
645 				cmn_err(CE_CONT, "?EEPROM size %d words.\n",
646 				    1U << ip->eeprom_bits);
647 			}
648 			break;
649 		}
650 	}
651 	if (n != ip->eeprom_bits) {
652 		iprb_error(ip, "cannot determine EEPROM size (%d, %d)",
653 		    ip->eeprom_bits, n);
654 	}
655 
656 	/* shift out a 16-bit word */
657 	val = 0;
658 	for (mask = 0x8000; mask; mask >>= 1) {
659 		PUT16(ip, CSR_EECTL, EEPROM_EECS | EEPROM_EESK);
660 		drv_usecwait(100);
661 		if (GET16(ip, CSR_EECTL) & EEPROM_EEDO)
662 			val |= mask;
663 		drv_usecwait(100);
664 		PUT16(ip, CSR_EECTL, EEPROM_EECS);
665 		drv_usecwait(100);
666 	}
667 
668 	/* and disable the eeprom */
669 	PUT16(ip, CSR_EECTL, 0);
670 	drv_usecwait(100);
671 
672 	return (val);
673 }
674 
675 int
676 iprb_cmd_ready(iprb_t *ip)
677 {
678 	/* wait for pending SCB commands to be accepted */
679 	for (int cnt = 1000000; cnt != 0; cnt -= 10) {
680 		if (GET8(ip, CSR_CMD) == 0) {
681 			return (DDI_SUCCESS);
682 		}
683 		drv_usecwait(10);
684 	}
685 	iprb_error(ip, "timeout waiting for chip to become ready");
686 	return (DDI_FAILURE);
687 }
688 
689 void
690 iprb_cmd_reclaim(iprb_t *ip)
691 {
692 	while (ip->cmd_count) {
693 		iprb_dma_t *cb = &ip->cmds[ip->cmd_tail];
694 
695 		SYNCCB(cb, CB_STS_OFFSET, 2, DDI_DMA_SYNC_FORKERNEL);
696 		if ((GETCB16(cb, CB_STS_OFFSET) & CB_STS_C) == 0) {
697 			break;
698 		}
699 
700 		ip->cmd_tail++;
701 		ip->cmd_tail %= NUM_TX;
702 		ip->cmd_count--;
703 		if (ip->cmd_count == 0) {
704 			ip->tx_wdog = 0;
705 		} else {
706 			ip->tx_wdog = ddi_get_time();
707 		}
708 	}
709 }
710 
711 int
712 iprb_cmd_drain(iprb_t *ip)
713 {
714 	for (int i = 1000000; i; i -= 10) {
715 		iprb_cmd_reclaim(ip);
716 		if (ip->cmd_count == 0)
717 			return (DDI_SUCCESS);
718 		drv_usecwait(10);
719 	}
720 	iprb_error(ip, "time out waiting for commands to drain");
721 	return (DDI_FAILURE);
722 }
723 
724 int
725 iprb_cmd_submit(iprb_t *ip, uint16_t cmd)
726 {
727 	iprb_dma_t	*ncb = &ip->cmds[ip->cmd_head];
728 	iprb_dma_t	*lcb = &ip->cmds[ip->cmd_last];
729 
730 	/* If this command will consume the last CB, interrupt when done */
731 	ASSERT((ip->cmd_count) < NUM_TX);
732 	if (ip->cmd_count == (NUM_TX - 1)) {
733 		cmd |= CB_CMD_I;
734 	}
735 
736 	/* clear the status entry */
737 	PUTCB16(ncb, CB_STS_OFFSET, 0);
738 
739 	/* suspend upon completion of this new command */
740 	cmd |= CB_CMD_S;
741 	PUTCB16(ncb, CB_CMD_OFFSET, cmd);
742 	SYNCCB(ncb, 0, 0, DDI_DMA_SYNC_FORDEV);
743 
744 	/* clear the suspend flag from the last submitted command */
745 	SYNCCB(lcb, CB_CMD_OFFSET, 2, DDI_DMA_SYNC_FORKERNEL);
746 	PUTCB16(lcb, CB_CMD_OFFSET, GETCB16(lcb, CB_CMD_OFFSET) & ~CB_CMD_S);
747 	SYNCCB(lcb, CB_CMD_OFFSET, 2, DDI_DMA_SYNC_FORDEV);
748 
749 
750 	/*
751 	 * If the chip has a resume bug, then we need to try this as a work
752 	 * around.  Some anecdotal evidence is that this will help solve
753 	 * the resume bug.  Its a performance hit, but only if the EEPROM
754 	 * is not updated.  (In theory we could do this only for 10Mbps HDX,
755 	 * but since it should just about never get used, we keep it simple.)
756 	 */
757 	if (ip->resumebug) {
758 		if (iprb_cmd_ready(ip) != DDI_SUCCESS)
759 			return (DDI_FAILURE);
760 		PUT8(ip, CSR_CMD, CUC_NOP);
761 		(void) GET8(ip, CSR_CMD);
762 		drv_usecwait(1);
763 	}
764 
765 	/* wait for the SCB to be ready to accept a new command */
766 	if (iprb_cmd_ready(ip) != DDI_SUCCESS)
767 		return (DDI_FAILURE);
768 
769 	/*
770 	 * Finally we can resume the CU.  Note that if this the first
771 	 * command in the sequence (i.e. if the CU is IDLE), or if the
772 	 * CU is already busy working, then this CU resume command
773 	 * will not have any effect.
774 	 */
775 	PUT8(ip, CSR_CMD, CUC_RESUME);
776 	(void) GET8(ip, CSR_CMD);	/* flush CSR */
777 
778 	ip->tx_wdog = ddi_get_time();
779 	ip->cmd_last = ip->cmd_head;
780 	ip->cmd_head++;
781 	ip->cmd_head %= NUM_TX;
782 	ip->cmd_count++;
783 
784 	return (DDI_SUCCESS);
785 }
786 
787 iprb_dma_t *
788 iprb_cmd_next(iprb_t *ip)
789 {
790 	if (ip->cmd_count == NUM_TX) {
791 		return (NULL);
792 	}
793 	ASSERT(ip->cmd_count < NUM_TX);
794 	return (&ip->cmds[ip->cmd_head]);
795 }
796 
797 int
798 iprb_set_unicast(iprb_t *ip)
799 {
800 	iprb_dma_t	*cb;
801 
802 	ASSERT(mutex_owned(&ip->culock));
803 
804 	if ((cb = iprb_cmd_next(ip)) == NULL)
805 		return (DDI_FAILURE);
806 
807 	PUTCBEA(cb, CB_IAS_ADR_OFFSET, ip->curraddr);
808 	return (iprb_cmd_submit(ip, CB_CMD_IAS));
809 }
810 
811 int
812 iprb_set_multicast(iprb_t *ip)
813 {
814 	iprb_dma_t	*cb;
815 	iprb_mcast_t	*mc;
816 	int		i;
817 	list_t		*l;
818 
819 	ASSERT(mutex_owned(&ip->culock));
820 
821 	if ((ip->nmcast <= 0) || (ip->nmcast > CB_MCS_CNT_MAX)) {
822 		/*
823 		 * Only send the list if the total number of multicast
824 		 * address is nonzero and small enough to fit.  We
825 		 * don't error out if it is too big, because in that
826 		 * case we will use the "allmulticast" support
827 		 * via iprb_set_config instead.
828 		 */
829 		return (DDI_SUCCESS);
830 	}
831 
832 	if ((cb = iprb_cmd_next(ip)) == NULL) {
833 		return (DDI_FAILURE);
834 	}
835 
836 	l = &ip->mcast;
837 	for (mc = list_head(l), i = 0; mc; mc = list_next(l, mc), i++) {
838 		PUTCBEA(cb, CB_MCS_ADR_OFFSET + (i * 6), mc->addr);
839 	}
840 	ASSERT(i == ip->nmcast);
841 	PUTCB16(cb, CB_MCS_CNT_OFFSET, i);
842 	return (iprb_cmd_submit(ip, CB_CMD_MCS));
843 }
844 
845 int
846 iprb_set_config(iprb_t *ip)
847 {
848 	iprb_dma_t *cb;
849 
850 	ASSERT(mutex_owned(&ip->culock));
851 	if ((cb = iprb_cmd_next(ip)) == NULL) {
852 		return (DDI_FAILURE);
853 	}
854 	PUTCB8(cb, CB_CONFIG_OFFSET + 0, 0x16);
855 	PUTCB8(cb, CB_CONFIG_OFFSET + 1, 0x8);
856 	PUTCB8(cb, CB_CONFIG_OFFSET + 2, 0);
857 	PUTCB8(cb, CB_CONFIG_OFFSET + 3, (ip->canmwi ? 1 : 0));
858 	PUTCB8(cb, CB_CONFIG_OFFSET + 4, 0);
859 	PUTCB8(cb, CB_CONFIG_OFFSET + 5, 0);
860 	PUTCB8(cb, CB_CONFIG_OFFSET + 6, (ip->promisc ? 0x80 : 0) | 0x3a);
861 	PUTCB8(cb, CB_CONFIG_OFFSET + 7, (ip->promisc ? 0 : 0x1) | 2);
862 	PUTCB8(cb, CB_CONFIG_OFFSET + 8, (ip->miih ? 0x1 : 0));
863 	PUTCB8(cb, CB_CONFIG_OFFSET + 9, 0);
864 	PUTCB8(cb, CB_CONFIG_OFFSET + 10, 0x2e);
865 	PUTCB8(cb, CB_CONFIG_OFFSET + 11, 0);
866 	PUTCB8(cb, CB_CONFIG_OFFSET + 12, (ip->is557 ? 0 : 1) | 0x60);
867 	PUTCB8(cb, CB_CONFIG_OFFSET + 13, 0);
868 	PUTCB8(cb, CB_CONFIG_OFFSET + 14, 0xf2);
869 	PUTCB8(cb, CB_CONFIG_OFFSET + 15,
870 	    (ip->miih ? 0x80 : 0) | (ip->promisc ? 0x1 : 0) | 0x48);
871 	PUTCB8(cb, CB_CONFIG_OFFSET + 16, 0);
872 	PUTCB8(cb, CB_CONFIG_OFFSET + 17, (ip->canpause ? 0x40 : 0));
873 	PUTCB8(cb, CB_CONFIG_OFFSET + 18, (ip->is557 ? 0 : 0x8) | 0xf2);
874 	PUTCB8(cb, CB_CONFIG_OFFSET + 19,
875 	    ((ip->revid < REV_82558_B0) ? 0 : 0x80) |
876 	    (ip->canpause ? 0x18 : 0));
877 	PUTCB8(cb, CB_CONFIG_OFFSET + 20, 0x3f);
878 	PUTCB8(cb, CB_CONFIG_OFFSET + 21,
879 	    ((ip->nmcast >= CB_MCS_CNT_MAX) ? 0x8 : 0) | 0x5);
880 
881 	return (iprb_cmd_submit(ip, CB_CMD_CONFIG));
882 }
883 
884 int
885 iprb_set_ucode(iprb_t *ip)
886 {
887 	iprb_dma_t *cb;
888 	const iprb_ucode_t *uc = NULL;
889 	int i;
890 
891 	for (i = 0; iprb_ucode[i].length; i++) {
892 		if (iprb_ucode[i].rev == ip->revid) {
893 			uc = &iprb_ucode[i];
894 			break;
895 		}
896 	}
897 	if (uc == NULL) {
898 		/* no matching firmware found, assume success */
899 		return (DDI_SUCCESS);
900 	}
901 
902 	ASSERT(mutex_owned(&ip->culock));
903 	if ((cb = iprb_cmd_next(ip)) == NULL) {
904 		return (DDI_FAILURE);
905 	}
906 	for (i = 0; i < uc->length; i++) {
907 		PUTCB32(cb, (CB_UCODE_OFFSET + i * 4), uc->ucode[i]);
908 	}
909 	return (iprb_cmd_submit(ip, CB_CMD_UCODE));
910 }
911 
912 int
913 iprb_configure(iprb_t *ip)
914 {
915 	ASSERT(mutex_owned(&ip->culock));
916 
917 	if (iprb_cmd_drain(ip) != DDI_SUCCESS)
918 		return (DDI_FAILURE);
919 
920 	if (iprb_set_config(ip) != DDI_SUCCESS)
921 		return (DDI_FAILURE);
922 	if (iprb_set_unicast(ip) != DDI_SUCCESS)
923 		return (DDI_FAILURE);
924 	if (iprb_set_multicast(ip) != DDI_SUCCESS)
925 		return (DDI_FAILURE);
926 
927 	return (DDI_SUCCESS);
928 }
929 
930 void
931 iprb_stop(iprb_t *ip)
932 {
933 	/* go idle */
934 	PUT32(ip, CSR_PORT, PORT_SEL_RESET);
935 	(void) GET32(ip, CSR_PORT);
936 	drv_usecwait(50);
937 
938 	/* shut off device interrupts */
939 	PUT8(ip, CSR_INTCTL, INTCTL_MASK);
940 }
941 
942 int
943 iprb_start(iprb_t *ip)
944 {
945 	iprb_dma_t *cb;
946 
947 	ASSERT(mutex_owned(&ip->rulock));
948 	ASSERT(mutex_owned(&ip->culock));
949 
950 	/* Reset, but first go into idle state */
951 	PUT32(ip, CSR_PORT, PORT_SEL_RESET);
952 	(void) GET32(ip, CSR_PORT);
953 	drv_usecwait(50);
954 
955 	PUT32(ip, CSR_PORT, PORT_SW_RESET);
956 	(void) GET32(ip, CSR_PORT);
957 	drv_usecwait(10);
958 	PUT8(ip, CSR_INTCTL, INTCTL_MASK);
959 
960 	/* Reset pointers */
961 	ip->cmd_head = ip->cmd_tail = 0;
962 	ip->cmd_last = NUM_TX - 1;
963 
964 	if (iprb_cmd_ready(ip) != DDI_SUCCESS)
965 		return (DDI_FAILURE);
966 	PUT32(ip, CSR_GEN_PTR, 0);
967 	PUT8(ip, CSR_CMD, CUC_CUBASE);
968 	(void) GET8(ip, CSR_CMD);
969 
970 	if (iprb_cmd_ready(ip) != DDI_SUCCESS)
971 		return (DDI_FAILURE);
972 	PUT32(ip, CSR_GEN_PTR, 0);
973 	PUT8(ip, CSR_CMD, RUC_RUBASE);
974 	(void) GET8(ip, CSR_CMD);
975 
976 	/* Send a NOP.  This will be the first command seen by the device. */
977 	cb = iprb_cmd_next(ip);
978 	ASSERT(cb);
979 	if (iprb_cmd_submit(ip, CB_CMD_NOP) != DDI_SUCCESS)
980 		return (DDI_FAILURE);
981 
982 	/* as that was the first command, go ahead and submit a CU start */
983 	if (iprb_cmd_ready(ip) != DDI_SUCCESS)
984 		return (DDI_FAILURE);
985 	PUT32(ip, CSR_GEN_PTR, cb->paddr);
986 	PUT8(ip, CSR_CMD, CUC_START);
987 	(void) GET8(ip, CSR_CMD);
988 
989 	/* Upload firmware. */
990 	if (iprb_set_ucode(ip) != DDI_SUCCESS)
991 		return (DDI_FAILURE);
992 
993 	/* Set up RFDs */
994 	iprb_rx_init(ip);
995 
996 	PUT32(ip, CSR_GEN_PTR, ip->rxb[0].paddr);
997 	/* wait for the SCB */
998 	(void) iprb_cmd_ready(ip);
999 	PUT8(ip, CSR_CMD, RUC_START);
1000 	(void) GET8(ip, CSR_CMD);	/* flush CSR */
1001 
1002 	/* Enable device interrupts */
1003 	PUT8(ip, CSR_INTCTL, 0);
1004 	(void) GET8(ip, CSR_INTCTL);
1005 
1006 	return (DDI_SUCCESS);
1007 }
1008 
1009 void
1010 iprb_update_stats(iprb_t *ip)
1011 {
1012 	iprb_dma_t	*sp = &ip->stats;
1013 	time_t		tstamp;
1014 	int		i;
1015 
1016 	ASSERT(mutex_owned(&ip->culock));
1017 
1018 	/* Collect the hardware stats, but don't keep redoing it */
1019 	if ((tstamp = ddi_get_time()) == ip->stats_time) {
1020 		return;
1021 	}
1022 
1023 	PUTSTAT(sp, STATS_DONE_OFFSET, 0);
1024 	SYNCSTATS(sp, 0, 0, DDI_DMA_SYNC_FORDEV);
1025 
1026 	if (iprb_cmd_ready(ip) != DDI_SUCCESS)
1027 		return;
1028 	PUT32(ip, CSR_GEN_PTR, sp->paddr);
1029 	PUT8(ip, CSR_CMD, CUC_STATSBASE);
1030 	(void) GET8(ip, CSR_CMD);
1031 
1032 	if (iprb_cmd_ready(ip) != DDI_SUCCESS)
1033 		return;
1034 	PUT8(ip, CSR_CMD, CUC_STATS_RST);
1035 	(void) GET8(ip, CSR_CMD);	/* flush wb */
1036 
1037 	for (i = 10000; i; i -= 10) {
1038 		SYNCSTATS(sp, 0, 0, DDI_DMA_SYNC_FORKERNEL);
1039 		if (GETSTAT(sp, STATS_DONE_OFFSET) == STATS_RST_DONE) {
1040 			/* yay stats are updated */
1041 			break;
1042 		}
1043 		drv_usecwait(10);
1044 	}
1045 	if (i == 0) {
1046 		iprb_error(ip, "time out acquiring hardware statistics");
1047 		return;
1048 	}
1049 
1050 	ip->ex_coll += GETSTAT(sp, STATS_TX_MAXCOL_OFFSET);
1051 	ip->late_coll += GETSTAT(sp, STATS_TX_LATECOL_OFFSET);
1052 	ip->uflo += GETSTAT(sp, STATS_TX_UFLO_OFFSET);
1053 	ip->defer_xmt += GETSTAT(sp, STATS_TX_DEFER_OFFSET);
1054 	ip->one_coll += GETSTAT(sp, STATS_TX_ONECOL_OFFSET);
1055 	ip->multi_coll += GETSTAT(sp, STATS_TX_MULTCOL_OFFSET);
1056 	ip->collisions += GETSTAT(sp, STATS_TX_TOTCOL_OFFSET);
1057 	ip->fcs_errs += GETSTAT(sp, STATS_RX_FCS_OFFSET);
1058 	ip->align_errs += GETSTAT(sp, STATS_RX_ALIGN_OFFSET);
1059 	ip->norcvbuf += GETSTAT(sp, STATS_RX_NOBUF_OFFSET);
1060 	ip->oflo += GETSTAT(sp, STATS_RX_OFLO_OFFSET);
1061 	ip->runt += GETSTAT(sp, STATS_RX_SHORT_OFFSET);
1062 
1063 	ip->stats_time = tstamp;
1064 }
1065 
1066 mblk_t *
1067 iprb_send(iprb_t *ip, mblk_t *mp)
1068 {
1069 	iprb_dma_t	*cb;
1070 	size_t		sz;
1071 
1072 	ASSERT(mutex_owned(&ip->culock));
1073 
1074 	/* possibly reclaim some CBs */
1075 	iprb_cmd_reclaim(ip);
1076 
1077 	cb = iprb_cmd_next(ip);
1078 
1079 	if (cb == NULL) {
1080 		/* flow control */
1081 		ip->wantw = B_TRUE;
1082 		return (mp);
1083 	}
1084 
1085 	if ((sz = msgsize(mp)) > (ETHERMAX + VLAN_TAGSZ)) {
1086 		/* Generally this should never occur */
1087 		ip->macxmt_errs++;
1088 		freemsg(mp);
1089 		return (NULL);
1090 	}
1091 
1092 	ip->opackets++;
1093 	ip->obytes += sz;
1094 
1095 	PUTCB32(cb, CB_TX_TBD_OFFSET, 0xffffffffU);
1096 	PUTCB16(cb, CB_TX_COUNT_OFFSET, (sz & 0x3fff) | CB_TX_EOF);
1097 	PUTCB8(cb, CB_TX_THRESH_OFFSET, (sz / 8) & 0xff);
1098 	PUTCB8(cb, CB_TX_NUMBER_OFFSET, 0);
1099 	mcopymsg(mp, cb->vaddr + CB_TX_DATA_OFFSET);
1100 	if (cb->vaddr[CB_TX_DATA_OFFSET] & 0x1) {
1101 		if (bcmp(cb->vaddr + CB_TX_DATA_OFFSET, &iprb_bcast, 6) != 0) {
1102 			ip->multixmt++;
1103 		} else {
1104 			ip->brdcstxmt++;
1105 		}
1106 	}
1107 	SYNCCB(cb, 0, CB_TX_DATA_OFFSET + sz, DDI_DMA_SYNC_FORDEV);
1108 
1109 	if (iprb_cmd_submit(ip, CB_CMD_TX) != DDI_SUCCESS) {
1110 		ip->macxmt_errs++;
1111 	}
1112 
1113 	return (NULL);
1114 }
1115 
1116 void
1117 iprb_rx_add(iprb_t *ip)
1118 {
1119 	uint16_t	last, curr, next;
1120 	iprb_dma_t	*rfd, *nfd, *lfd;
1121 
1122 	ASSERT(mutex_owned(&ip->rulock));
1123 
1124 	curr = ip->rx_index;
1125 	last = ip->rx_last;
1126 	next = (curr + 1) % NUM_RX;
1127 
1128 	ip->rx_last = curr;
1129 	ip->rx_index = next;
1130 
1131 	lfd = &ip->rxb[last];
1132 	rfd = &ip->rxb[curr];
1133 	nfd = &ip->rxb[next];
1134 
1135 	PUTRFD32(rfd, RFD_LNK_OFFSET, nfd->paddr);
1136 	PUTRFD16(rfd, RFD_CTL_OFFSET, RFD_CTL_EL);
1137 	PUTRFD16(rfd, RFD_SIZ_OFFSET, RFD_SIZE - RFD_PKT_OFFSET);
1138 	PUTRFD16(rfd, RFD_CNT_OFFSET, 0);
1139 	SYNCRFD(rfd, 0, RFD_PKT_OFFSET, DDI_DMA_SYNC_FORDEV);
1140 	/* clear the suspend & EL bits from the previous RFD */
1141 	PUTRFD16(lfd, RFD_CTL_OFFSET, 0);
1142 	SYNCRFD(rfd, RFD_CTL_OFFSET, 2, DDI_DMA_SYNC_FORDEV);
1143 }
1144 
1145 void
1146 iprb_rx_init(iprb_t *ip)
1147 {
1148 	ip->rx_index = 0;
1149 	ip->rx_last = NUM_RX - 1;
1150 	for (int i = 0; i < NUM_RX; i++)
1151 		iprb_rx_add(ip);
1152 	ip->rx_index = 0;
1153 	ip->rx_last = NUM_RX - 1;
1154 }
1155 
1156 mblk_t *
1157 iprb_rx(iprb_t *ip)
1158 {
1159 	iprb_dma_t	*rfd;
1160 	uint16_t	cnt;
1161 	uint16_t	sts;
1162 	int		i;
1163 	mblk_t		*mplist;
1164 	mblk_t		**mpp;
1165 	mblk_t		*mp;
1166 
1167 	mplist = NULL;
1168 	mpp = &mplist;
1169 
1170 	for (i = 0; i < NUM_RX; i++) {
1171 		rfd = &ip->rxb[ip->rx_index];
1172 		SYNCRFD(rfd, RFD_STS_OFFSET, 2, DDI_DMA_SYNC_FORKERNEL);
1173 		if ((GETRFD16(rfd, RFD_STS_OFFSET) & RFD_STS_C) == 0) {
1174 			break;
1175 		}
1176 
1177 		ip->rx_wdog = ddi_get_time();
1178 
1179 		SYNCRFD(rfd, 0, 0, DDI_DMA_SYNC_FORKERNEL);
1180 		cnt = GETRFD16(rfd, RFD_CNT_OFFSET);
1181 		cnt &= ~(RFD_CNT_EOF | RFD_CNT_F);
1182 		sts = GETRFD16(rfd, RFD_STS_OFFSET);
1183 
1184 		if (cnt > (ETHERMAX + VLAN_TAGSZ)) {
1185 			ip->toolong++;
1186 			iprb_rx_add(ip);
1187 			continue;
1188 		}
1189 		if (((sts & RFD_STS_OK) == 0) && (sts & RFD_STS_ERRS)) {
1190 			iprb_rx_add(ip);
1191 			continue;
1192 		}
1193 		if ((mp = allocb(cnt, BPRI_MED)) == NULL) {
1194 			ip->norcvbuf++;
1195 			iprb_rx_add(ip);
1196 			continue;
1197 		}
1198 		bcopy(rfd->vaddr + RFD_PKT_OFFSET, mp->b_wptr, cnt);
1199 
1200 		/* return it to the RFD list */
1201 		iprb_rx_add(ip);
1202 
1203 		mp->b_wptr += cnt;
1204 		ip->ipackets++;
1205 		ip->rbytes += cnt;
1206 		if (mp->b_rptr[0] & 0x1) {
1207 			if (bcmp(mp->b_rptr, &iprb_bcast, 6) != 0) {
1208 				ip->multircv++;
1209 			} else {
1210 				ip->brdcstrcv++;
1211 			}
1212 		}
1213 		*mpp = mp;
1214 		mpp = &mp->b_next;
1215 	}
1216 	return (mplist);
1217 }
1218 
1219 int
1220 iprb_m_promisc(void *arg, boolean_t on)
1221 {
1222 	iprb_t *ip = arg;
1223 
1224 	mutex_enter(&ip->culock);
1225 	ip->promisc = on;
1226 	if (ip->running && !ip->suspended)
1227 		(void) iprb_configure(ip);
1228 	mutex_exit(&ip->culock);
1229 	return (0);
1230 }
1231 
1232 int
1233 iprb_m_unicst(void *arg, const uint8_t *macaddr)
1234 {
1235 	iprb_t *ip = arg;
1236 
1237 	mutex_enter(&ip->culock);
1238 	bcopy(macaddr, ip->curraddr, 6);
1239 	if (ip->running && !ip->suspended)
1240 		(void) iprb_configure(ip);
1241 	mutex_exit(&ip->culock);
1242 	return (0);
1243 }
1244 
1245 int
1246 iprb_m_multicst(void *arg, boolean_t add, const uint8_t *macaddr)
1247 {
1248 	iprb_t		*ip = arg;
1249 	list_t		*l = &ip->mcast;
1250 	iprb_mcast_t	*mc;
1251 
1252 	if (add) {
1253 		mc = kmem_alloc(sizeof (*mc), KM_NOSLEEP);
1254 		if (mc == NULL) {
1255 			return (ENOMEM);
1256 		}
1257 		bcopy(macaddr, mc->addr, 6);
1258 		mutex_enter(&ip->culock);
1259 		list_insert_head(l, mc);
1260 		ip->nmcast++;
1261 		if (ip->running && !ip->suspended)
1262 			(void) iprb_configure(ip);
1263 		mutex_exit(&ip->culock);
1264 	} else {
1265 		mutex_enter(&ip->culock);
1266 		for (mc = list_head(l); mc != NULL; mc = list_next(l, mc)) {
1267 			if (bcmp(macaddr, mc->addr, 6) == 0) {
1268 				list_remove(&ip->mcast, mc);
1269 				ip->nmcast--;
1270 				if (ip->running && !ip->suspended)
1271 					(void) iprb_configure(ip);
1272 				break;
1273 			}
1274 		}
1275 		mutex_exit(&ip->culock);
1276 		if (mc)
1277 			kmem_free(mc, sizeof (*mc));
1278 	}
1279 	return (0);
1280 }
1281 
1282 int
1283 iprb_m_start(void *arg)
1284 {
1285 	int rv;
1286 	iprb_t *ip = arg;
1287 
1288 	mutex_enter(&ip->rulock);
1289 	mutex_enter(&ip->culock);
1290 	rv = ip->suspended ? 0 : iprb_start(ip);
1291 	if (rv == 0)
1292 		ip->running = B_TRUE;
1293 	ip->perh = ddi_periodic_add(iprb_periodic, ip, 5000000000, 0);
1294 	mutex_exit(&ip->culock);
1295 	mutex_exit(&ip->rulock);
1296 	if (rv == 0) {
1297 		if (ip->miih)
1298 			mii_start(ip->miih);
1299 		else
1300 			/* might be a lie. */
1301 			mac_link_update(ip->mach, LINK_STATE_UP);
1302 	}
1303 	return (rv ? EIO : 0);
1304 }
1305 
1306 void
1307 iprb_m_stop(void *arg)
1308 {
1309 	iprb_t *ip = arg;
1310 
1311 	if (ip->miih) {
1312 		mii_stop(ip->miih);
1313 	} else {
1314 		mac_link_update(ip->mach, LINK_STATE_DOWN);
1315 	}
1316 
1317 	ddi_periodic_delete(ip->perh);
1318 	ip->perh = 0;
1319 
1320 	mutex_enter(&ip->rulock);
1321 	mutex_enter(&ip->culock);
1322 
1323 	if (!ip->suspended) {
1324 		iprb_update_stats(ip);
1325 		iprb_stop(ip);
1326 	}
1327 	ip->running = B_FALSE;
1328 	mutex_exit(&ip->culock);
1329 	mutex_exit(&ip->rulock);
1330 }
1331 
1332 int
1333 iprb_m_stat(void *arg, uint_t stat, uint64_t *val)
1334 {
1335 	iprb_t		*ip = arg;
1336 
1337 	if (ip->miih && (mii_m_getstat(ip->miih, stat, val) == 0)) {
1338 		return (0);
1339 	}
1340 
1341 	mutex_enter(&ip->culock);
1342 	if ((!ip->suspended) && (ip->running)) {
1343 		iprb_update_stats(ip);
1344 	}
1345 	mutex_exit(&ip->culock);
1346 
1347 	switch (stat) {
1348 	case MAC_STAT_IFSPEED:
1349 		if (ip->miih == NULL) {
1350 			*val = 10000000;	/* 10 Mbps */
1351 		}
1352 		break;
1353 	case ETHER_STAT_LINK_DUPLEX:
1354 		if (ip->miih == NULL) {
1355 			*val = LINK_DUPLEX_UNKNOWN;
1356 		}
1357 		break;
1358 	case MAC_STAT_MULTIRCV:
1359 		*val = ip->multircv;
1360 		break;
1361 	case MAC_STAT_BRDCSTRCV:
1362 		*val = ip->brdcstrcv;
1363 		break;
1364 	case MAC_STAT_MULTIXMT:
1365 		*val = ip->multixmt;
1366 		break;
1367 	case MAC_STAT_BRDCSTXMT:
1368 		*val = ip->brdcstxmt;
1369 		break;
1370 	case MAC_STAT_IPACKETS:
1371 		* val = ip->ipackets;
1372 		break;
1373 	case MAC_STAT_RBYTES:
1374 		*val = ip->rbytes;
1375 		break;
1376 	case MAC_STAT_OPACKETS:
1377 		*val = ip->opackets;
1378 		break;
1379 	case MAC_STAT_OBYTES:
1380 		*val = ip->obytes;
1381 		break;
1382 	case MAC_STAT_NORCVBUF:
1383 		*val = ip->norcvbuf;
1384 		break;
1385 	case MAC_STAT_COLLISIONS:
1386 		*val = ip->collisions;
1387 		break;
1388 	case MAC_STAT_IERRORS:
1389 		*val = ip->align_errs +
1390 		    ip->fcs_errs +
1391 		    ip->norcvbuf +
1392 		    ip->runt +
1393 		    ip->toolong +
1394 		    ip->macrcv_errs;
1395 		break;
1396 	case MAC_STAT_OERRORS:
1397 		*val = ip->ex_coll +
1398 		    ip->late_coll +
1399 		    ip->uflo +
1400 		    ip->macxmt_errs +
1401 		    ip->nocarrier;
1402 		break;
1403 	case ETHER_STAT_ALIGN_ERRORS:
1404 		*val = ip->align_errs;
1405 		break;
1406 	case ETHER_STAT_FCS_ERRORS:
1407 		*val = ip->fcs_errs;
1408 		break;
1409 	case ETHER_STAT_DEFER_XMTS:
1410 		*val = ip->defer_xmt;
1411 		break;
1412 	case ETHER_STAT_FIRST_COLLISIONS:
1413 		*val = ip->one_coll + ip->multi_coll + ip->ex_coll;
1414 		break;
1415 	case ETHER_STAT_MULTI_COLLISIONS:
1416 		*val = ip->multi_coll;
1417 		break;
1418 	case ETHER_STAT_TX_LATE_COLLISIONS:
1419 		*val = ip->late_coll;
1420 		break;
1421 	case ETHER_STAT_EX_COLLISIONS:
1422 		*val = ip->ex_coll;
1423 		break;
1424 	case MAC_STAT_OVERFLOWS:
1425 		*val = ip->oflo;
1426 		break;
1427 	case MAC_STAT_UNDERFLOWS:
1428 		*val = ip->uflo;
1429 		break;
1430 	case ETHER_STAT_TOOSHORT_ERRORS:
1431 		*val = ip->runt;
1432 		break;
1433 	case ETHER_STAT_TOOLONG_ERRORS:
1434 		*val = ip->toolong;
1435 		break;
1436 	case ETHER_STAT_CARRIER_ERRORS:
1437 		*val = ip->nocarrier;	/* reported only for "suspend" */
1438 		break;
1439 	case ETHER_STAT_MACXMT_ERRORS:
1440 		*val = ip->macxmt_errs;
1441 		break;
1442 	case ETHER_STAT_MACRCV_ERRORS:
1443 		*val = ip->macrcv_errs;
1444 		break;
1445 	default:
1446 		return (ENOTSUP);
1447 	}
1448 	return (0);
1449 }
1450 
1451 void
1452 iprb_m_propinfo(void *arg, const char *name, mac_prop_id_t id,
1453     mac_prop_info_handle_t pih)
1454 {
1455 	iprb_t *ip = arg;
1456 
1457 	if (ip->miih != NULL) {
1458 		mii_m_propinfo(ip->miih, name, id, pih);
1459 		return;
1460 	}
1461 	switch (id) {
1462 	case MAC_PROP_DUPLEX:
1463 	case MAC_PROP_SPEED:
1464 		mac_prop_info_set_perm(pih, MAC_PROP_PERM_READ);
1465 		break;
1466 	}
1467 }
1468 
1469 int
1470 iprb_m_getprop(void *arg, const char *name, mac_prop_id_t id, uint_t sz,
1471     void *val)
1472 {
1473 	iprb_t *ip = arg;
1474 	uint64_t x;
1475 
1476 	if (ip->miih != NULL) {
1477 		return (mii_m_getprop(ip->miih, name, id, sz, val));
1478 	}
1479 	switch (id) {
1480 	case MAC_PROP_SPEED:
1481 		x = 10000000;
1482 		bcopy(&x, val, sizeof (x));
1483 		return (0);
1484 
1485 	case MAC_PROP_DUPLEX:
1486 		x = LINK_DUPLEX_UNKNOWN;
1487 		bcopy(&x, val, sizeof (x));
1488 		return (0);
1489 	}
1490 
1491 	return (ENOTSUP);
1492 }
1493 
1494 int
1495 iprb_m_setprop(void *arg, const char *name, mac_prop_id_t id, uint_t sz,
1496     const void *val)
1497 {
1498 	iprb_t *ip = arg;
1499 
1500 	if (ip->miih != NULL) {
1501 		return (mii_m_setprop(ip->miih, name, id, sz, val));
1502 	}
1503 	return (ENOTSUP);
1504 }
1505 
1506 mblk_t *
1507 iprb_m_tx(void *arg, mblk_t *mp)
1508 {
1509 	iprb_t *ip = arg;
1510 	mblk_t *nmp;
1511 
1512 	mutex_enter(&ip->culock);
1513 
1514 	while (mp != NULL) {
1515 		nmp = mp->b_next;
1516 		mp->b_next = NULL;
1517 		if (ip->suspended) {
1518 			freemsg(mp);
1519 			ip->nocarrier++;
1520 			mp = nmp;
1521 			continue;
1522 		}
1523 		if ((mp = iprb_send(ip, mp)) != NULL) {
1524 			mp->b_next = nmp;
1525 			break;
1526 		}
1527 		mp = nmp;
1528 	}
1529 	mutex_exit(&ip->culock);
1530 	return (mp);
1531 }
1532 
1533 void
1534 iprb_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
1535 {
1536 	iprb_t	*ip = arg;
1537 
1538 	if ((ip->miih != NULL) && (mii_m_loop_ioctl(ip->miih, wq, mp)))
1539 		return;
1540 
1541 	miocnak(wq, mp, 0, EINVAL);
1542 }
1543 
1544 uint16_t
1545 iprb_mii_read(void *arg, uint8_t phy, uint8_t reg)
1546 {
1547 	iprb_t	*ip = arg;
1548 	uint32_t mdi;
1549 
1550 	/*
1551 	 * NB: we are guaranteed by the MII layer not to be suspended.
1552 	 * Furthermore, we have an independent MII register.
1553 	 */
1554 
1555 	mdi = MDI_OP_RD |
1556 	    ((uint32_t)phy << MDI_PHYAD_SHIFT) |
1557 	    ((uint32_t)reg << MDI_REGAD_SHIFT);
1558 
1559 	PUT32(ip, CSR_MDICTL, mdi);
1560 	for (int i = 0; i < 100; i++) {
1561 		mdi = GET32(ip, CSR_MDICTL);
1562 		if (mdi & MDI_R) {
1563 			return (mdi & 0xffff);
1564 		}
1565 		drv_usecwait(1);
1566 	}
1567 	return (0xffff);
1568 }
1569 
1570 void
1571 iprb_mii_write(void *arg, uint8_t phy, uint8_t reg, uint16_t data)
1572 {
1573 	iprb_t	*ip = arg;
1574 	uint32_t mdi;
1575 
1576 	mdi = MDI_OP_WR |
1577 	    ((uint32_t)phy << MDI_PHYAD_SHIFT) |
1578 	    ((uint32_t)reg << MDI_REGAD_SHIFT) |
1579 	    (data);
1580 
1581 	PUT32(ip, CSR_MDICTL, mdi);
1582 	for (int i = 0; i < 100; i++) {
1583 		if (GET32(ip, CSR_MDICTL) & MDI_R)
1584 			break;
1585 	}
1586 }
1587 
1588 void
1589 iprb_mii_notify(void *arg, link_state_t link)
1590 {
1591 	iprb_t *ip = arg;
1592 
1593 	mac_link_update(ip->mach, link);
1594 }
1595 
1596 uint_t
1597 iprb_intr(caddr_t arg1, caddr_t arg2)
1598 {
1599 	iprb_t *ip = (void *)arg1;
1600 	uint8_t	sts;
1601 	mblk_t	*mp = NULL;
1602 
1603 	_NOTE(ARGUNUSED(arg2));
1604 
1605 	mutex_enter(&ip->rulock);
1606 	if (ip->suspended) {
1607 		mutex_exit(&ip->rulock);
1608 		return (DDI_INTR_UNCLAIMED);
1609 	}
1610 	sts = GET8(ip, CSR_STS);
1611 	if (sts == 0) {
1612 		/* No interrupt status! */
1613 		mutex_exit(&ip->rulock);
1614 		return (DDI_INTR_UNCLAIMED);
1615 	}
1616 	/* acknowledge the interrupts */
1617 	PUT8(ip, CSR_STS, sts);
1618 
1619 	if (sts & (STS_RNR | STS_FR)) {
1620 		mp = iprb_rx(ip);
1621 
1622 		if ((sts & STS_RNR) &&
1623 		    ((GET8(ip, CSR_STATE) & STATE_RUS) == STATE_RUS_NORES)) {
1624 			iprb_rx_init(ip);
1625 
1626 			mutex_enter(&ip->culock);
1627 			PUT32(ip, CSR_GEN_PTR, ip->rxb[0].paddr);
1628 			/* wait for the SCB */
1629 			(void) iprb_cmd_ready(ip);
1630 			PUT8(ip, CSR_CMD, RUC_START);
1631 			(void) GET8(ip, CSR_CMD);	/* flush CSR */
1632 			mutex_exit(&ip->culock);
1633 		}
1634 	}
1635 	mutex_exit(&ip->rulock);
1636 
1637 	if (mp) {
1638 		mac_rx(ip->mach, NULL, mp);
1639 	}
1640 	if ((sts & (STS_CNA | STS_CX)) && ip->wantw)  {
1641 		ip->wantw = B_FALSE;
1642 		mac_tx_update(ip->mach);
1643 	}
1644 	return (DDI_INTR_CLAIMED);
1645 }
1646 
1647 void
1648 iprb_periodic(void *arg)
1649 {
1650 	iprb_t *ip = arg;
1651 	boolean_t reset = B_FALSE;
1652 
1653 	mutex_enter(&ip->rulock);
1654 	if (ip->suspended || !ip->running) {
1655 		mutex_exit(&ip->rulock);
1656 		return;
1657 	}
1658 
1659 	/*
1660 	 * If we haven't received a packet in a while, and if the link
1661 	 * is up, then it might be a hung chip.  This problem
1662 	 * reportedly only occurs at 10 Mbps.
1663 	 */
1664 	if (ip->rxhangbug &&
1665 	    ((ip->miih == NULL) || (mii_get_speed(ip->miih) == 10000000)) &&
1666 	    ((ddi_get_time() - ip->rx_wdog) > ip->rx_timeout)) {
1667 		cmn_err(CE_CONT, "?Possible RU hang, resetting.\n");
1668 		reset = B_TRUE;
1669 	}
1670 
1671 	/* update the statistics */
1672 	mutex_enter(&ip->culock);
1673 
1674 	if (ip->tx_wdog && ((ddi_get_time() - ip->tx_wdog) > ip->tx_timeout)) {
1675 		/* transmit/CU hang? */
1676 		cmn_err(CE_CONT, "?CU stalled, resetting.\n");
1677 		reset = B_TRUE;
1678 	}
1679 
1680 	if (reset) {
1681 		/* We want to reconfigure */
1682 		iprb_stop(ip);
1683 		if (iprb_start(ip) != DDI_SUCCESS) {
1684 			iprb_error(ip, "unable to restart chip");
1685 		}
1686 	}
1687 
1688 	iprb_update_stats(ip);
1689 
1690 	mutex_exit(&ip->culock);
1691 	mutex_exit(&ip->rulock);
1692 }
1693 
1694 int
1695 iprb_quiesce(dev_info_t *dip)
1696 {
1697 	iprb_t *ip = ddi_get_driver_private(dip);
1698 
1699 	/* Reset, but first go into idle state */
1700 	PUT32(ip, CSR_PORT, PORT_SEL_RESET);
1701 	drv_usecwait(50);
1702 	PUT32(ip, CSR_PORT, PORT_SW_RESET);
1703 	drv_usecwait(10);
1704 	PUT8(ip, CSR_INTCTL, INTCTL_MASK);
1705 
1706 	return (DDI_SUCCESS);
1707 }
1708 
1709 int
1710 iprb_suspend(dev_info_t *dip)
1711 {
1712 	iprb_t *ip = ddi_get_driver_private(dip);
1713 
1714 	if (ip->miih)
1715 		mii_suspend(ip->miih);
1716 
1717 	mutex_enter(&ip->rulock);
1718 	mutex_enter(&ip->culock);
1719 	if (!ip->suspended) {
1720 		ip->suspended = B_TRUE;
1721 		if (ip->running) {
1722 			iprb_update_stats(ip);
1723 			iprb_stop(ip);
1724 		}
1725 	}
1726 	mutex_exit(&ip->culock);
1727 	mutex_exit(&ip->rulock);
1728 	return (DDI_SUCCESS);
1729 }
1730 
1731 int
1732 iprb_resume(dev_info_t *dip)
1733 {
1734 	iprb_t *ip = ddi_get_driver_private(dip);
1735 
1736 	mutex_enter(&ip->rulock);
1737 	mutex_enter(&ip->culock);
1738 
1739 	ip->suspended = B_FALSE;
1740 	if (ip->running) {
1741 		if (iprb_start(ip) != DDI_SUCCESS) {
1742 			iprb_error(ip, "unable to restart chip!");
1743 			ip->suspended = B_TRUE;
1744 			mutex_exit(&ip->culock);
1745 			mutex_exit(&ip->rulock);
1746 			return (DDI_FAILURE);
1747 		}
1748 	}
1749 
1750 	mutex_exit(&ip->culock);
1751 	mutex_exit(&ip->rulock);
1752 	if (ip->miih)
1753 		mii_resume(ip->miih);
1754 	return (DDI_SUCCESS);
1755 }
1756 
1757 int
1758 iprb_ddi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
1759 {
1760 	switch (cmd) {
1761 	case DDI_ATTACH:
1762 		return (iprb_attach(dip));
1763 
1764 	case DDI_RESUME:
1765 		return (iprb_resume(dip));
1766 
1767 	default:
1768 		return (DDI_FAILURE);
1769 	}
1770 }
1771 
1772 int
1773 iprb_ddi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
1774 {
1775 	switch (cmd) {
1776 	case DDI_DETACH:
1777 		return (iprb_detach(dip));
1778 
1779 	case DDI_SUSPEND:
1780 		return (iprb_suspend(dip));
1781 
1782 	default:
1783 		return (DDI_FAILURE);
1784 	}
1785 }
1786 
1787 void
1788 iprb_error(iprb_t *ip, const char *fmt, ...)
1789 {
1790 	va_list ap;
1791 	char buf[256];
1792 
1793 	va_start(ap, fmt);
1794 	(void) vsnprintf(buf, sizeof (buf), fmt, ap);
1795 	va_end(ap);
1796 
1797 	cmn_err(CE_WARN, "%s%d: %s",
1798 	    ddi_driver_name(ip->dip), ddi_get_instance(ip->dip), buf);
1799 }
1800