xref: /titanic_50/usr/src/uts/common/io/bge/bge_main2.c (revision a6d42e7d71324c5193c3b94d57d96ba2925d52e1)
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 2008 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include "bge_impl.h"
28 #include <sys/sdt.h>
29 #include <sys/mac.h>
30 
31 /*
32  * This is the string displayed by modinfo, etc.
33  * Make sure you keep the version ID up to date!
34  */
35 static char bge_ident[] = "Broadcom Gb Ethernet v1.0";
36 
37 /*
38  * Property names
39  */
40 static char debug_propname[] = "bge-debug-flags";
41 static char clsize_propname[] = "cache-line-size";
42 static char latency_propname[] = "latency-timer";
43 static char localmac_boolname[] = "local-mac-address?";
44 static char localmac_propname[] = "local-mac-address";
45 static char macaddr_propname[] = "mac-address";
46 static char subdev_propname[] = "subsystem-id";
47 static char subven_propname[] = "subsystem-vendor-id";
48 static char rxrings_propname[] = "bge-rx-rings";
49 static char txrings_propname[] = "bge-tx-rings";
50 static char fm_cap[] = "fm-capable";
51 static char default_mtu[] = "default_mtu";
52 
53 static int bge_add_intrs(bge_t *, int);
54 static void bge_rem_intrs(bge_t *);
55 
56 /*
57  * Describes the chip's DMA engine
58  */
59 static ddi_dma_attr_t dma_attr = {
60 	DMA_ATTR_V0,			/* dma_attr version	*/
61 	0x0000000000000000ull,		/* dma_attr_addr_lo	*/
62 	0xFFFFFFFFFFFFFFFFull,		/* dma_attr_addr_hi	*/
63 	0x00000000FFFFFFFFull,		/* dma_attr_count_max	*/
64 	0x0000000000000001ull,		/* dma_attr_align	*/
65 	0x00000FFF,			/* dma_attr_burstsizes	*/
66 	0x00000001,			/* dma_attr_minxfer	*/
67 	0x000000000000FFFFull,		/* dma_attr_maxxfer	*/
68 	0xFFFFFFFFFFFFFFFFull,		/* dma_attr_seg		*/
69 	1,				/* dma_attr_sgllen 	*/
70 	0x00000001,			/* dma_attr_granular 	*/
71 	DDI_DMA_FLAGERR			/* dma_attr_flags */
72 };
73 
74 /*
75  * PIO access attributes for registers
76  */
77 static ddi_device_acc_attr_t bge_reg_accattr = {
78 	DDI_DEVICE_ATTR_V0,
79 	DDI_NEVERSWAP_ACC,
80 	DDI_STRICTORDER_ACC,
81 	DDI_FLAGERR_ACC
82 };
83 
84 /*
85  * DMA access attributes for descriptors: NOT to be byte swapped.
86  */
87 static ddi_device_acc_attr_t bge_desc_accattr = {
88 	DDI_DEVICE_ATTR_V0,
89 	DDI_NEVERSWAP_ACC,
90 	DDI_STRICTORDER_ACC,
91 	DDI_FLAGERR_ACC
92 };
93 
94 /*
95  * DMA access attributes for data: NOT to be byte swapped.
96  */
97 static ddi_device_acc_attr_t bge_data_accattr = {
98 	DDI_DEVICE_ATTR_V0,
99 	DDI_NEVERSWAP_ACC,
100 	DDI_STRICTORDER_ACC
101 };
102 
103 static int		bge_m_start(void *);
104 static void		bge_m_stop(void *);
105 static int		bge_m_promisc(void *, boolean_t);
106 static int		bge_m_multicst(void *, boolean_t, const uint8_t *);
107 static int		bge_m_unicst(void *, const uint8_t *);
108 static void		bge_m_resources(void *);
109 static void		bge_m_ioctl(void *, queue_t *, mblk_t *);
110 static boolean_t	bge_m_getcapab(void *, mac_capab_t, void *);
111 static int		bge_unicst_set(void *, const uint8_t *,
112     mac_addr_slot_t);
113 static int		bge_m_unicst_add(void *, mac_multi_addr_t *);
114 static int		bge_m_unicst_remove(void *, mac_addr_slot_t);
115 static int		bge_m_unicst_modify(void *, mac_multi_addr_t *);
116 static int		bge_m_unicst_get(void *, mac_multi_addr_t *);
117 static int		bge_m_setprop(void *, const char *, mac_prop_id_t,
118     uint_t, const void *);
119 static int		bge_m_getprop(void *, const char *, mac_prop_id_t,
120     uint_t, uint_t, void *);
121 static int		bge_set_priv_prop(bge_t *, const char *, uint_t,
122     const void *);
123 static int		bge_get_priv_prop(bge_t *, const char *, uint_t,
124     uint_t, void *);
125 
126 #define	BGE_M_CALLBACK_FLAGS\
127 	(MC_RESOURCES | MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP)
128 
129 static mac_callbacks_t bge_m_callbacks = {
130 	BGE_M_CALLBACK_FLAGS,
131 	bge_m_stat,
132 	bge_m_start,
133 	bge_m_stop,
134 	bge_m_promisc,
135 	bge_m_multicst,
136 	bge_m_unicst,
137 	bge_m_tx,
138 	bge_m_resources,
139 	bge_m_ioctl,
140 	bge_m_getcapab,
141 	NULL,
142 	NULL,
143 	bge_m_setprop,
144 	bge_m_getprop
145 };
146 
147 mac_priv_prop_t bge_priv_prop[] = {
148 	{"_adv_asym_pause_cap", MAC_PROP_PERM_RW},
149 	{"_adv_pause_cap", MAC_PROP_PERM_RW}
150 };
151 
152 #define	BGE_MAX_PRIV_PROPS \
153 	(sizeof (bge_priv_prop) / sizeof (mac_priv_prop_t))
154 
155 /*
156  * ========== Transmit and receive ring reinitialisation ==========
157  */
158 
159 /*
160  * These <reinit> routines each reset the specified ring to an initial
161  * state, assuming that the corresponding <init> routine has already
162  * been called exactly once.
163  */
164 
165 static void
166 bge_reinit_send_ring(send_ring_t *srp)
167 {
168 	bge_queue_t *txbuf_queue;
169 	bge_queue_item_t *txbuf_head;
170 	sw_txbuf_t *txbuf;
171 	sw_sbd_t *ssbdp;
172 	uint32_t slot;
173 
174 	/*
175 	 * Reinitialise control variables ...
176 	 */
177 	srp->tx_flow = 0;
178 	srp->tx_next = 0;
179 	srp->txfill_next = 0;
180 	srp->tx_free = srp->desc.nslots;
181 	ASSERT(mutex_owned(srp->tc_lock));
182 	srp->tc_next = 0;
183 	srp->txpkt_next = 0;
184 	srp->tx_block = 0;
185 	srp->tx_nobd = 0;
186 	srp->tx_nobuf = 0;
187 
188 	/*
189 	 * Initialize the tx buffer push queue
190 	 */
191 	mutex_enter(srp->freetxbuf_lock);
192 	mutex_enter(srp->txbuf_lock);
193 	txbuf_queue = &srp->freetxbuf_queue;
194 	txbuf_queue->head = NULL;
195 	txbuf_queue->count = 0;
196 	txbuf_queue->lock = srp->freetxbuf_lock;
197 	srp->txbuf_push_queue = txbuf_queue;
198 
199 	/*
200 	 * Initialize the tx buffer pop queue
201 	 */
202 	txbuf_queue = &srp->txbuf_queue;
203 	txbuf_queue->head = NULL;
204 	txbuf_queue->count = 0;
205 	txbuf_queue->lock = srp->txbuf_lock;
206 	srp->txbuf_pop_queue = txbuf_queue;
207 	txbuf_head = srp->txbuf_head;
208 	txbuf = srp->txbuf;
209 	for (slot = 0; slot < srp->tx_buffers; ++slot) {
210 		txbuf_head->item = txbuf;
211 		txbuf_head->next = txbuf_queue->head;
212 		txbuf_queue->head = txbuf_head;
213 		txbuf_queue->count++;
214 		txbuf++;
215 		txbuf_head++;
216 	}
217 	mutex_exit(srp->txbuf_lock);
218 	mutex_exit(srp->freetxbuf_lock);
219 
220 	/*
221 	 * Zero and sync all the h/w Send Buffer Descriptors
222 	 */
223 	DMA_ZERO(srp->desc);
224 	DMA_SYNC(srp->desc, DDI_DMA_SYNC_FORDEV);
225 	bzero(srp->pktp, BGE_SEND_BUF_MAX * sizeof (*srp->pktp));
226 	ssbdp = srp->sw_sbds;
227 	for (slot = 0; slot < srp->desc.nslots; ++ssbdp, ++slot)
228 		ssbdp->pbuf = NULL;
229 }
230 
231 static void
232 bge_reinit_recv_ring(recv_ring_t *rrp)
233 {
234 	/*
235 	 * Reinitialise control variables ...
236 	 */
237 	rrp->rx_next = 0;
238 }
239 
240 static void
241 bge_reinit_buff_ring(buff_ring_t *brp, uint32_t ring)
242 {
243 	bge_rbd_t *hw_rbd_p;
244 	sw_rbd_t *srbdp;
245 	uint32_t bufsize;
246 	uint32_t nslots;
247 	uint32_t slot;
248 
249 	static uint16_t ring_type_flag[BGE_BUFF_RINGS_MAX] = {
250 		RBD_FLAG_STD_RING,
251 		RBD_FLAG_JUMBO_RING,
252 		RBD_FLAG_MINI_RING
253 	};
254 
255 	/*
256 	 * Zero, initialise and sync all the h/w Receive Buffer Descriptors
257 	 * Note: all the remaining fields (<type>, <flags>, <ip_cksum>,
258 	 * <tcp_udp_cksum>, <error_flag>, <vlan_tag>, and <reserved>)
259 	 * should be zeroed, and so don't need to be set up specifically
260 	 * once the whole area has been cleared.
261 	 */
262 	DMA_ZERO(brp->desc);
263 
264 	hw_rbd_p = DMA_VPTR(brp->desc);
265 	nslots = brp->desc.nslots;
266 	ASSERT(brp->buf[0].nslots == nslots/BGE_SPLIT);
267 	bufsize = brp->buf[0].size;
268 	srbdp = brp->sw_rbds;
269 	for (slot = 0; slot < nslots; ++hw_rbd_p, ++srbdp, ++slot) {
270 		hw_rbd_p->host_buf_addr = srbdp->pbuf.cookie.dmac_laddress;
271 		hw_rbd_p->index = (uint16_t)slot;
272 		hw_rbd_p->len = (uint16_t)bufsize;
273 		hw_rbd_p->opaque = srbdp->pbuf.token;
274 		hw_rbd_p->flags |= ring_type_flag[ring];
275 	}
276 
277 	DMA_SYNC(brp->desc, DDI_DMA_SYNC_FORDEV);
278 
279 	/*
280 	 * Finally, reinitialise the ring control variables ...
281 	 */
282 	brp->rf_next = (nslots != 0) ? (nslots-1) : 0;
283 }
284 
285 /*
286  * Reinitialize all rings
287  */
288 static void
289 bge_reinit_rings(bge_t *bgep)
290 {
291 	uint32_t ring;
292 
293 	ASSERT(mutex_owned(bgep->genlock));
294 
295 	/*
296 	 * Send Rings ...
297 	 */
298 	for (ring = 0; ring < bgep->chipid.tx_rings; ++ring)
299 		bge_reinit_send_ring(&bgep->send[ring]);
300 
301 	/*
302 	 * Receive Return Rings ...
303 	 */
304 	for (ring = 0; ring < bgep->chipid.rx_rings; ++ring)
305 		bge_reinit_recv_ring(&bgep->recv[ring]);
306 
307 	/*
308 	 * Receive Producer Rings ...
309 	 */
310 	for (ring = 0; ring < BGE_BUFF_RINGS_USED; ++ring)
311 		bge_reinit_buff_ring(&bgep->buff[ring], ring);
312 }
313 
314 /*
315  * ========== Internal state management entry points ==========
316  */
317 
318 #undef	BGE_DBG
319 #define	BGE_DBG		BGE_DBG_NEMO	/* debug flag for this code	*/
320 
321 /*
322  * These routines provide all the functionality required by the
323  * corresponding GLD entry points, but don't update the GLD state
324  * so they can be called internally without disturbing our record
325  * of what GLD thinks we should be doing ...
326  */
327 
328 /*
329  *	bge_reset() -- reset h/w & rings to initial state
330  */
331 static int
332 #ifdef BGE_IPMI_ASF
333 bge_reset(bge_t *bgep, uint_t asf_mode)
334 #else
335 bge_reset(bge_t *bgep)
336 #endif
337 {
338 	uint32_t	ring;
339 	int retval;
340 
341 	BGE_TRACE(("bge_reset($%p)", (void *)bgep));
342 
343 	ASSERT(mutex_owned(bgep->genlock));
344 
345 	/*
346 	 * Grab all the other mutexes in the world (this should
347 	 * ensure no other threads are manipulating driver state)
348 	 */
349 	for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring)
350 		mutex_enter(bgep->recv[ring].rx_lock);
351 	for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring)
352 		mutex_enter(bgep->buff[ring].rf_lock);
353 	rw_enter(bgep->errlock, RW_WRITER);
354 	for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
355 		mutex_enter(bgep->send[ring].tx_lock);
356 	for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
357 		mutex_enter(bgep->send[ring].tc_lock);
358 
359 #ifdef BGE_IPMI_ASF
360 	retval = bge_chip_reset(bgep, B_TRUE, asf_mode);
361 #else
362 	retval = bge_chip_reset(bgep, B_TRUE);
363 #endif
364 	bge_reinit_rings(bgep);
365 
366 	/*
367 	 * Free the world ...
368 	 */
369 	for (ring = BGE_SEND_RINGS_MAX; ring-- > 0; )
370 		mutex_exit(bgep->send[ring].tc_lock);
371 	for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
372 		mutex_exit(bgep->send[ring].tx_lock);
373 	rw_exit(bgep->errlock);
374 	for (ring = BGE_BUFF_RINGS_MAX; ring-- > 0; )
375 		mutex_exit(bgep->buff[ring].rf_lock);
376 	for (ring = BGE_RECV_RINGS_MAX; ring-- > 0; )
377 		mutex_exit(bgep->recv[ring].rx_lock);
378 
379 	BGE_DEBUG(("bge_reset($%p) done", (void *)bgep));
380 	return (retval);
381 }
382 
383 /*
384  *	bge_stop() -- stop processing, don't reset h/w or rings
385  */
386 static void
387 bge_stop(bge_t *bgep)
388 {
389 	BGE_TRACE(("bge_stop($%p)", (void *)bgep));
390 
391 	ASSERT(mutex_owned(bgep->genlock));
392 
393 #ifdef BGE_IPMI_ASF
394 	if (bgep->asf_enabled) {
395 		bgep->asf_pseudostop = B_TRUE;
396 	} else {
397 #endif
398 		bge_chip_stop(bgep, B_FALSE);
399 #ifdef BGE_IPMI_ASF
400 	}
401 #endif
402 
403 	BGE_DEBUG(("bge_stop($%p) done", (void *)bgep));
404 }
405 
406 /*
407  *	bge_start() -- start transmitting/receiving
408  */
409 static int
410 bge_start(bge_t *bgep, boolean_t reset_phys)
411 {
412 	int retval;
413 
414 	BGE_TRACE(("bge_start($%p, %d)", (void *)bgep, reset_phys));
415 
416 	ASSERT(mutex_owned(bgep->genlock));
417 
418 	/*
419 	 * Start chip processing, including enabling interrupts
420 	 */
421 	retval = bge_chip_start(bgep, reset_phys);
422 
423 	BGE_DEBUG(("bge_start($%p, %d) done", (void *)bgep, reset_phys));
424 	return (retval);
425 }
426 
427 /*
428  * bge_restart - restart transmitting/receiving after error or suspend
429  */
430 int
431 bge_restart(bge_t *bgep, boolean_t reset_phys)
432 {
433 	int retval = DDI_SUCCESS;
434 	ASSERT(mutex_owned(bgep->genlock));
435 
436 #ifdef BGE_IPMI_ASF
437 	if (bgep->asf_enabled) {
438 		if (bge_reset(bgep, ASF_MODE_POST_INIT) != DDI_SUCCESS)
439 			retval = DDI_FAILURE;
440 	} else
441 		if (bge_reset(bgep, ASF_MODE_NONE) != DDI_SUCCESS)
442 			retval = DDI_FAILURE;
443 #else
444 	if (bge_reset(bgep) != DDI_SUCCESS)
445 		retval = DDI_FAILURE;
446 #endif
447 	if (bgep->bge_mac_state == BGE_MAC_STARTED) {
448 		if (bge_start(bgep, reset_phys) != DDI_SUCCESS)
449 			retval = DDI_FAILURE;
450 		bgep->watchdog = 0;
451 		ddi_trigger_softintr(bgep->drain_id);
452 	}
453 
454 	BGE_DEBUG(("bge_restart($%p, %d) done", (void *)bgep, reset_phys));
455 	return (retval);
456 }
457 
458 
459 /*
460  * ========== Nemo-required management entry points ==========
461  */
462 
463 #undef	BGE_DBG
464 #define	BGE_DBG		BGE_DBG_NEMO	/* debug flag for this code	*/
465 
466 /*
467  *	bge_m_stop() -- stop transmitting/receiving
468  */
469 static void
470 bge_m_stop(void *arg)
471 {
472 	bge_t *bgep = arg;		/* private device info	*/
473 	send_ring_t *srp;
474 	uint32_t ring;
475 
476 	BGE_TRACE(("bge_m_stop($%p)", arg));
477 
478 	/*
479 	 * Just stop processing, then record new GLD state
480 	 */
481 	mutex_enter(bgep->genlock);
482 	if (!(bgep->progress & PROGRESS_INTR)) {
483 		/* can happen during autorecovery */
484 		mutex_exit(bgep->genlock);
485 		return;
486 	}
487 	bge_stop(bgep);
488 
489 	bgep->link_update_timer = 0;
490 	bgep->link_state = LINK_STATE_UNKNOWN;
491 	mac_link_update(bgep->mh, bgep->link_state);
492 
493 	/*
494 	 * Free the possible tx buffers allocated in tx process.
495 	 */
496 #ifdef BGE_IPMI_ASF
497 	if (!bgep->asf_pseudostop)
498 #endif
499 	{
500 		rw_enter(bgep->errlock, RW_WRITER);
501 		for (ring = 0; ring < bgep->chipid.tx_rings; ++ring) {
502 			srp = &bgep->send[ring];
503 			mutex_enter(srp->tx_lock);
504 			if (srp->tx_array > 1)
505 				bge_free_txbuf_arrays(srp);
506 			mutex_exit(srp->tx_lock);
507 		}
508 		rw_exit(bgep->errlock);
509 	}
510 	bgep->bge_mac_state = BGE_MAC_STOPPED;
511 	BGE_DEBUG(("bge_m_stop($%p) done", arg));
512 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
513 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_UNAFFECTED);
514 	mutex_exit(bgep->genlock);
515 }
516 
517 /*
518  *	bge_m_start() -- start transmitting/receiving
519  */
520 static int
521 bge_m_start(void *arg)
522 {
523 	bge_t *bgep = arg;		/* private device info	*/
524 
525 	BGE_TRACE(("bge_m_start($%p)", arg));
526 
527 	/*
528 	 * Start processing and record new GLD state
529 	 */
530 	mutex_enter(bgep->genlock);
531 	if (!(bgep->progress & PROGRESS_INTR)) {
532 		/* can happen during autorecovery */
533 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
534 		mutex_exit(bgep->genlock);
535 		return (EIO);
536 	}
537 #ifdef BGE_IPMI_ASF
538 	if (bgep->asf_enabled) {
539 		if ((bgep->asf_status == ASF_STAT_RUN) &&
540 		    (bgep->asf_pseudostop)) {
541 			bgep->bge_mac_state = BGE_MAC_STARTED;
542 			mutex_exit(bgep->genlock);
543 			return (0);
544 		}
545 	}
546 	if (bge_reset(bgep, ASF_MODE_INIT) != DDI_SUCCESS) {
547 #else
548 	if (bge_reset(bgep) != DDI_SUCCESS) {
549 #endif
550 		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
551 		(void) bge_check_acc_handle(bgep, bgep->io_handle);
552 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
553 		mutex_exit(bgep->genlock);
554 		return (EIO);
555 	}
556 	if (bge_start(bgep, B_TRUE) != DDI_SUCCESS) {
557 		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
558 		(void) bge_check_acc_handle(bgep, bgep->io_handle);
559 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
560 		mutex_exit(bgep->genlock);
561 		return (EIO);
562 	}
563 	bgep->bge_mac_state = BGE_MAC_STARTED;
564 	BGE_DEBUG(("bge_m_start($%p) done", arg));
565 
566 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
567 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
568 		mutex_exit(bgep->genlock);
569 		return (EIO);
570 	}
571 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
572 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
573 		mutex_exit(bgep->genlock);
574 		return (EIO);
575 	}
576 #ifdef BGE_IPMI_ASF
577 	if (bgep->asf_enabled) {
578 		if (bgep->asf_status != ASF_STAT_RUN) {
579 			/* start ASF heart beat */
580 			bgep->asf_timeout_id = timeout(bge_asf_heartbeat,
581 			    (void *)bgep,
582 			    drv_usectohz(BGE_ASF_HEARTBEAT_INTERVAL));
583 			bgep->asf_status = ASF_STAT_RUN;
584 		}
585 	}
586 #endif
587 	mutex_exit(bgep->genlock);
588 
589 	return (0);
590 }
591 
592 /*
593  *	bge_m_unicst() -- set the physical network address
594  */
595 static int
596 bge_m_unicst(void *arg, const uint8_t *macaddr)
597 {
598 	/*
599 	 * Request to set address in
600 	 * address slot 0, i.e., default address
601 	 */
602 	return (bge_unicst_set(arg, macaddr, 0));
603 }
604 
605 /*
606  *	bge_unicst_set() -- set the physical network address
607  */
608 static int
609 bge_unicst_set(void *arg, const uint8_t *macaddr, mac_addr_slot_t slot)
610 {
611 	bge_t *bgep = arg;		/* private device info	*/
612 
613 	BGE_TRACE(("bge_m_unicst_set($%p, %s)", arg,
614 	    ether_sprintf((void *)macaddr)));
615 	/*
616 	 * Remember the new current address in the driver state
617 	 * Sync the chip's idea of the address too ...
618 	 */
619 	mutex_enter(bgep->genlock);
620 	if (!(bgep->progress & PROGRESS_INTR)) {
621 		/* can happen during autorecovery */
622 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
623 		mutex_exit(bgep->genlock);
624 		return (EIO);
625 	}
626 	ethaddr_copy(macaddr, bgep->curr_addr[slot].addr);
627 #ifdef BGE_IPMI_ASF
628 	if (bge_chip_sync(bgep, B_FALSE) == DDI_FAILURE) {
629 #else
630 	if (bge_chip_sync(bgep) == DDI_FAILURE) {
631 #endif
632 		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
633 		(void) bge_check_acc_handle(bgep, bgep->io_handle);
634 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
635 		mutex_exit(bgep->genlock);
636 		return (EIO);
637 	}
638 #ifdef BGE_IPMI_ASF
639 	if (bgep->asf_enabled) {
640 		/*
641 		 * The above bge_chip_sync() function wrote the ethernet MAC
642 		 * addresses registers which destroyed the IPMI/ASF sideband.
643 		 * Here, we have to reset chip to make IPMI/ASF sideband work.
644 		 */
645 		if (bgep->asf_status == ASF_STAT_RUN) {
646 			/*
647 			 * We must stop ASF heart beat before bge_chip_stop(),
648 			 * otherwise some computers (ex. IBM HS20 blade server)
649 			 * may crash.
650 			 */
651 			bge_asf_update_status(bgep);
652 			bge_asf_stop_timer(bgep);
653 			bgep->asf_status = ASF_STAT_STOP;
654 
655 			bge_asf_pre_reset_operations(bgep, BGE_INIT_RESET);
656 		}
657 		bge_chip_stop(bgep, B_FALSE);
658 
659 		if (bge_restart(bgep, B_FALSE) == DDI_FAILURE) {
660 			(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
661 			(void) bge_check_acc_handle(bgep, bgep->io_handle);
662 			ddi_fm_service_impact(bgep->devinfo,
663 			    DDI_SERVICE_DEGRADED);
664 			mutex_exit(bgep->genlock);
665 			return (EIO);
666 		}
667 
668 		/*
669 		 * Start our ASF heartbeat counter as soon as possible.
670 		 */
671 		if (bgep->asf_status != ASF_STAT_RUN) {
672 			/* start ASF heart beat */
673 			bgep->asf_timeout_id = timeout(bge_asf_heartbeat,
674 			    (void *)bgep,
675 			    drv_usectohz(BGE_ASF_HEARTBEAT_INTERVAL));
676 			bgep->asf_status = ASF_STAT_RUN;
677 		}
678 	}
679 #endif
680 	BGE_DEBUG(("bge_m_unicst_set($%p) done", arg));
681 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
682 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
683 		mutex_exit(bgep->genlock);
684 		return (EIO);
685 	}
686 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
687 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
688 		mutex_exit(bgep->genlock);
689 		return (EIO);
690 	}
691 	mutex_exit(bgep->genlock);
692 
693 	return (0);
694 }
695 
696 /*
697  * The following four routines are used as callbacks for multiple MAC
698  * address support:
699  *    -  bge_m_unicst_add(void *, mac_multi_addr_t *);
700  *    -  bge_m_unicst_remove(void *, mac_addr_slot_t);
701  *    -  bge_m_unicst_modify(void *, mac_multi_addr_t *);
702  *    -  bge_m_unicst_get(void *, mac_multi_addr_t *);
703  */
704 
705 /*
706  * bge_m_unicst_add() - will find an unused address slot, set the
707  * address value to the one specified, reserve that slot and enable
708  * the NIC to start filtering on the new MAC address.
709  * address slot. Returns 0 on success.
710  */
711 static int
712 bge_m_unicst_add(void *arg, mac_multi_addr_t *maddr)
713 {
714 	bge_t *bgep = arg;		/* private device info	*/
715 	mac_addr_slot_t slot;
716 	int err;
717 
718 	if (mac_unicst_verify(bgep->mh,
719 	    maddr->mma_addr, maddr->mma_addrlen) == B_FALSE)
720 		return (EINVAL);
721 
722 	mutex_enter(bgep->genlock);
723 	if (bgep->unicst_addr_avail == 0) {
724 		/* no slots available */
725 		mutex_exit(bgep->genlock);
726 		return (ENOSPC);
727 	}
728 
729 	/*
730 	 * Primary/default address is in slot 0. The next three
731 	 * addresses are the multiple MAC addresses. So multiple
732 	 * MAC address 0 is in slot 1, 1 in slot 2, and so on.
733 	 * So the first multiple MAC address resides in slot 1.
734 	 */
735 	for (slot = 1; slot < bgep->unicst_addr_total; slot++) {
736 		if (bgep->curr_addr[slot].set == B_FALSE) {
737 			bgep->curr_addr[slot].set = B_TRUE;
738 			break;
739 		}
740 	}
741 
742 	ASSERT(slot < bgep->unicst_addr_total);
743 	bgep->unicst_addr_avail--;
744 	mutex_exit(bgep->genlock);
745 	maddr->mma_slot = slot;
746 
747 	if ((err = bge_unicst_set(bgep, maddr->mma_addr, slot)) != 0) {
748 		mutex_enter(bgep->genlock);
749 		bgep->curr_addr[slot].set = B_FALSE;
750 		bgep->unicst_addr_avail++;
751 		mutex_exit(bgep->genlock);
752 	}
753 	return (err);
754 }
755 
756 /*
757  * bge_m_unicst_remove() - removes a MAC address that was added by a
758  * call to bge_m_unicst_add(). The slot number that was returned in
759  * add() is passed in the call to remove the address.
760  * Returns 0 on success.
761  */
762 static int
763 bge_m_unicst_remove(void *arg, mac_addr_slot_t slot)
764 {
765 	bge_t *bgep = arg;		/* private device info	*/
766 
767 	if (slot <= 0 || slot >= bgep->unicst_addr_total)
768 		return (EINVAL);
769 
770 	mutex_enter(bgep->genlock);
771 	if (bgep->curr_addr[slot].set == B_TRUE) {
772 		bgep->curr_addr[slot].set = B_FALSE;
773 		bgep->unicst_addr_avail++;
774 		mutex_exit(bgep->genlock);
775 		/*
776 		 * Copy the default address to the passed slot
777 		 */
778 		return (bge_unicst_set(bgep, bgep->curr_addr[0].addr, slot));
779 	}
780 	mutex_exit(bgep->genlock);
781 	return (EINVAL);
782 }
783 
784 /*
785  * bge_m_unicst_modify() - modifies the value of an address that
786  * has been added by bge_m_unicst_add(). The new address, address
787  * length and the slot number that was returned in the call to add
788  * should be passed to bge_m_unicst_modify(). mma_flags should be
789  * set to 0. Returns 0 on success.
790  */
791 static int
792 bge_m_unicst_modify(void *arg, mac_multi_addr_t *maddr)
793 {
794 	bge_t *bgep = arg;		/* private device info	*/
795 	mac_addr_slot_t slot;
796 
797 	if (mac_unicst_verify(bgep->mh,
798 	    maddr->mma_addr, maddr->mma_addrlen) == B_FALSE)
799 		return (EINVAL);
800 
801 	slot = maddr->mma_slot;
802 
803 	if (slot <= 0 || slot >= bgep->unicst_addr_total)
804 		return (EINVAL);
805 
806 	mutex_enter(bgep->genlock);
807 	if (bgep->curr_addr[slot].set == B_TRUE) {
808 		mutex_exit(bgep->genlock);
809 		return (bge_unicst_set(bgep, maddr->mma_addr, slot));
810 	}
811 	mutex_exit(bgep->genlock);
812 
813 	return (EINVAL);
814 }
815 
816 /*
817  * bge_m_unicst_get() - will get the MAC address and all other
818  * information related to the address slot passed in mac_multi_addr_t.
819  * mma_flags should be set to 0 in the call.
820  * On return, mma_flags can take the following values:
821  * 1) MMAC_SLOT_UNUSED
822  * 2) MMAC_SLOT_USED | MMAC_VENDOR_ADDR
823  * 3) MMAC_SLOT_UNUSED | MMAC_VENDOR_ADDR
824  * 4) MMAC_SLOT_USED
825  */
826 static int
827 bge_m_unicst_get(void *arg, mac_multi_addr_t *maddr)
828 {
829 	bge_t *bgep = arg;		/* private device info	*/
830 	mac_addr_slot_t slot;
831 
832 	slot = maddr->mma_slot;
833 
834 	if (slot <= 0 || slot >= bgep->unicst_addr_total)
835 		return (EINVAL);
836 
837 	mutex_enter(bgep->genlock);
838 	if (bgep->curr_addr[slot].set == B_TRUE) {
839 		ethaddr_copy(bgep->curr_addr[slot].addr,
840 		    maddr->mma_addr);
841 		maddr->mma_flags = MMAC_SLOT_USED;
842 	} else {
843 		maddr->mma_flags = MMAC_SLOT_UNUSED;
844 	}
845 	mutex_exit(bgep->genlock);
846 
847 	return (0);
848 }
849 
850 extern void bge_wake_factotum(bge_t *);
851 
852 static boolean_t
853 bge_param_locked(mac_prop_id_t pr_num)
854 {
855 	/*
856 	 * All adv_* parameters are locked (read-only) while
857 	 * the device is in any sort of loopback mode ...
858 	 */
859 	switch (pr_num) {
860 		case MAC_PROP_ADV_1000FDX_CAP:
861 		case MAC_PROP_EN_1000FDX_CAP:
862 		case MAC_PROP_ADV_1000HDX_CAP:
863 		case MAC_PROP_EN_1000HDX_CAP:
864 		case MAC_PROP_ADV_100FDX_CAP:
865 		case MAC_PROP_EN_100FDX_CAP:
866 		case MAC_PROP_ADV_100HDX_CAP:
867 		case MAC_PROP_EN_100HDX_CAP:
868 		case MAC_PROP_ADV_10FDX_CAP:
869 		case MAC_PROP_EN_10FDX_CAP:
870 		case MAC_PROP_ADV_10HDX_CAP:
871 		case MAC_PROP_EN_10HDX_CAP:
872 		case MAC_PROP_AUTONEG:
873 		case MAC_PROP_FLOWCTRL:
874 			return (B_TRUE);
875 	}
876 	return (B_FALSE);
877 }
878 /*
879  * callback functions for set/get of properties
880  */
881 static int
882 bge_m_setprop(void *barg, const char *pr_name, mac_prop_id_t pr_num,
883     uint_t pr_valsize, const void *pr_val)
884 {
885 	bge_t *bgep = barg;
886 	int err = 0;
887 	uint32_t cur_mtu, new_mtu;
888 	uint_t	maxsdu;
889 	link_flowctrl_t fl;
890 
891 	mutex_enter(bgep->genlock);
892 	if (bgep->param_loop_mode != BGE_LOOP_NONE &&
893 	    bge_param_locked(pr_num)) {
894 		/*
895 		 * All adv_* parameters are locked (read-only)
896 		 * while the device is in any sort of loopback mode.
897 		 */
898 		mutex_exit(bgep->genlock);
899 		return (EBUSY);
900 	}
901 	if ((bgep->chipid.flags & CHIP_FLAG_SERDES) &&
902 	    ((pr_num == MAC_PROP_EN_100FDX_CAP) ||
903 	    (pr_num == MAC_PROP_EN_100FDX_CAP) ||
904 	    (pr_num == MAC_PROP_EN_10FDX_CAP) ||
905 	    (pr_num == MAC_PROP_EN_10HDX_CAP))) {
906 		/*
907 		 * these properties are read/write on copper,
908 		 * read-only and 0 on serdes
909 		 */
910 		mutex_exit(bgep->genlock);
911 		return (ENOTSUP);
912 	}
913 	if ((DEVICE_5906_SERIES_CHIPSETS(bgep) &&
914 	    (pr_num == MAC_PROP_EN_1000FDX_CAP) ||
915 	    (pr_num == MAC_PROP_EN_1000HDX_CAP))) {
916 		mutex_exit(bgep->genlock);
917 		return (ENOTSUP);
918 	}
919 
920 	switch (pr_num) {
921 		case MAC_PROP_EN_1000FDX_CAP:
922 			bgep->param_en_1000fdx = *(uint8_t *)pr_val;
923 			bgep->param_adv_1000fdx = *(uint8_t *)pr_val;
924 			goto reprogram;
925 		case MAC_PROP_EN_1000HDX_CAP:
926 			bgep->param_en_1000hdx = *(uint8_t *)pr_val;
927 			bgep->param_adv_1000hdx = *(uint8_t *)pr_val;
928 			goto reprogram;
929 		case MAC_PROP_EN_100FDX_CAP:
930 			bgep->param_en_100fdx = *(uint8_t *)pr_val;
931 			bgep->param_adv_100fdx = *(uint8_t *)pr_val;
932 			goto reprogram;
933 		case MAC_PROP_EN_100HDX_CAP:
934 			bgep->param_en_100hdx = *(uint8_t *)pr_val;
935 			bgep->param_adv_100hdx = *(uint8_t *)pr_val;
936 			goto reprogram;
937 		case MAC_PROP_EN_10FDX_CAP:
938 			bgep->param_en_10fdx = *(uint8_t *)pr_val;
939 			bgep->param_adv_10fdx = *(uint8_t *)pr_val;
940 			goto reprogram;
941 		case MAC_PROP_EN_10HDX_CAP:
942 			bgep->param_en_10hdx = *(uint8_t *)pr_val;
943 			bgep->param_adv_10hdx = *(uint8_t *)pr_val;
944 reprogram:
945 			if (err == 0 && bge_reprogram(bgep) == IOC_INVAL)
946 				err = EINVAL;
947 			break;
948 		case MAC_PROP_ADV_1000FDX_CAP:
949 		case MAC_PROP_ADV_1000HDX_CAP:
950 		case MAC_PROP_ADV_100FDX_CAP:
951 		case MAC_PROP_ADV_100HDX_CAP:
952 		case MAC_PROP_ADV_10FDX_CAP:
953 		case MAC_PROP_ADV_10HDX_CAP:
954 		case MAC_PROP_STATUS:
955 		case MAC_PROP_SPEED:
956 		case MAC_PROP_DUPLEX:
957 			err = ENOTSUP; /* read-only prop. Can't set this */
958 			break;
959 		case MAC_PROP_AUTONEG:
960 			bgep->param_adv_autoneg = *(uint8_t *)pr_val;
961 			if (bge_reprogram(bgep) == IOC_INVAL)
962 				err = EINVAL;
963 			break;
964 		case MAC_PROP_MTU:
965 			cur_mtu = bgep->chipid.default_mtu;
966 			bcopy(pr_val, &new_mtu, sizeof (new_mtu));
967 
968 			if (new_mtu == cur_mtu) {
969 				err = 0;
970 				break;
971 			}
972 			if (new_mtu < BGE_DEFAULT_MTU ||
973 			    new_mtu > BGE_MAXIMUM_MTU) {
974 				err = EINVAL;
975 				break;
976 			}
977 			if ((new_mtu > BGE_DEFAULT_MTU) &&
978 			    (bgep->chipid.flags & CHIP_FLAG_NO_JUMBO)) {
979 				err = EINVAL;
980 				break;
981 			}
982 			if (bgep->bge_mac_state == BGE_MAC_STARTED) {
983 				err = EBUSY;
984 				break;
985 			}
986 			bgep->chipid.default_mtu = new_mtu;
987 			if (bge_chip_id_init(bgep)) {
988 				err = EINVAL;
989 				break;
990 			}
991 			maxsdu = bgep->chipid.ethmax_size -
992 			    sizeof (struct ether_header);
993 			err = mac_maxsdu_update(bgep->mh, maxsdu);
994 			if (err == 0) {
995 				bgep->bge_dma_error = B_TRUE;
996 				bgep->manual_reset = B_TRUE;
997 				bge_chip_stop(bgep, B_TRUE);
998 				bge_wake_factotum(bgep);
999 				err = 0;
1000 			}
1001 			break;
1002 		case MAC_PROP_FLOWCTRL:
1003 			bcopy(pr_val, &fl, sizeof (fl));
1004 			switch (fl) {
1005 			default:
1006 				err = ENOTSUP;
1007 				break;
1008 			case LINK_FLOWCTRL_NONE:
1009 				bgep->param_adv_pause = 0;
1010 				bgep->param_adv_asym_pause = 0;
1011 
1012 				bgep->param_link_rx_pause = B_FALSE;
1013 				bgep->param_link_tx_pause = B_FALSE;
1014 				break;
1015 			case LINK_FLOWCTRL_RX:
1016 				if (!((bgep->param_lp_pause == 0) &&
1017 				    (bgep->param_lp_asym_pause == 1))) {
1018 					err = EINVAL;
1019 					break;
1020 				}
1021 				bgep->param_adv_pause = 1;
1022 				bgep->param_adv_asym_pause = 1;
1023 
1024 				bgep->param_link_rx_pause = B_TRUE;
1025 				bgep->param_link_tx_pause = B_FALSE;
1026 				break;
1027 			case LINK_FLOWCTRL_TX:
1028 				if (!((bgep->param_lp_pause == 1) &&
1029 				    (bgep->param_lp_asym_pause == 1))) {
1030 					err = EINVAL;
1031 					break;
1032 				}
1033 				bgep->param_adv_pause = 0;
1034 				bgep->param_adv_asym_pause = 1;
1035 
1036 				bgep->param_link_rx_pause = B_FALSE;
1037 				bgep->param_link_tx_pause = B_TRUE;
1038 				break;
1039 			case LINK_FLOWCTRL_BI:
1040 				if (bgep->param_lp_pause != 1) {
1041 					err = EINVAL;
1042 					break;
1043 				}
1044 				bgep->param_adv_pause = 1;
1045 
1046 				bgep->param_link_rx_pause = B_TRUE;
1047 				bgep->param_link_tx_pause = B_TRUE;
1048 				break;
1049 			}
1050 
1051 			if (err == 0) {
1052 				if (bge_reprogram(bgep) == IOC_INVAL)
1053 					err = EINVAL;
1054 			}
1055 
1056 			break;
1057 		case MAC_PROP_PRIVATE:
1058 			err = bge_set_priv_prop(bgep, pr_name, pr_valsize,
1059 			    pr_val);
1060 			break;
1061 		default:
1062 			err = ENOTSUP;
1063 			break;
1064 	}
1065 	mutex_exit(bgep->genlock);
1066 	return (err);
1067 }
1068 
1069 static int
1070 bge_m_getprop(void *barg, const char *pr_name, mac_prop_id_t pr_num,
1071     uint_t pr_flags, uint_t pr_valsize, void *pr_val)
1072 {
1073 	bge_t *bgep = barg;
1074 	int err = 0;
1075 	link_flowctrl_t fl;
1076 	uint64_t speed;
1077 	int flags = bgep->chipid.flags;
1078 	boolean_t is_default = (pr_flags & MAC_PROP_DEFAULT);
1079 
1080 	if (pr_valsize == 0)
1081 		return (EINVAL);
1082 	bzero(pr_val, pr_valsize);
1083 	switch (pr_num) {
1084 		case MAC_PROP_DUPLEX:
1085 			if (pr_valsize < sizeof (link_duplex_t))
1086 				return (EINVAL);
1087 			bcopy(&bgep->param_link_duplex, pr_val,
1088 			    sizeof (link_duplex_t));
1089 			break;
1090 		case MAC_PROP_SPEED:
1091 			if (pr_valsize < sizeof (speed))
1092 				return (EINVAL);
1093 			speed = bgep->param_link_speed * 1000000ull;
1094 			bcopy(&speed, pr_val, sizeof (speed));
1095 			break;
1096 		case MAC_PROP_STATUS:
1097 			if (pr_valsize < sizeof (link_state_t))
1098 				return (EINVAL);
1099 			bcopy(&bgep->link_state, pr_val,
1100 			    sizeof (link_state_t));
1101 			break;
1102 		case MAC_PROP_AUTONEG:
1103 			if (is_default)
1104 				*(uint8_t *)pr_val = 1;
1105 			else
1106 				*(uint8_t *)pr_val = bgep->param_adv_autoneg;
1107 			break;
1108 		case MAC_PROP_FLOWCTRL:
1109 			if (pr_valsize < sizeof (fl))
1110 				return (EINVAL);
1111 			if (is_default) {
1112 				fl = LINK_FLOWCTRL_BI;
1113 				bcopy(&fl, pr_val, sizeof (fl));
1114 				break;
1115 			}
1116 
1117 			if (bgep->param_link_rx_pause &&
1118 			    !bgep->param_link_tx_pause)
1119 				fl = LINK_FLOWCTRL_RX;
1120 
1121 			if (!bgep->param_link_rx_pause &&
1122 			    !bgep->param_link_tx_pause)
1123 				fl = LINK_FLOWCTRL_NONE;
1124 
1125 			if (!bgep->param_link_rx_pause &&
1126 			    bgep->param_link_tx_pause)
1127 				fl = LINK_FLOWCTRL_TX;
1128 
1129 			if (bgep->param_link_rx_pause &&
1130 			    bgep->param_link_tx_pause)
1131 				fl = LINK_FLOWCTRL_BI;
1132 			bcopy(&fl, pr_val, sizeof (fl));
1133 			break;
1134 		case MAC_PROP_ADV_1000FDX_CAP:
1135 			if (is_default) {
1136 				if (DEVICE_5906_SERIES_CHIPSETS(bgep))
1137 					*(uint8_t *)pr_val = 0;
1138 				else
1139 					*(uint8_t *)pr_val = 1;
1140 			}
1141 			else
1142 				*(uint8_t *)pr_val = bgep->param_adv_1000fdx;
1143 			break;
1144 		case MAC_PROP_EN_1000FDX_CAP:
1145 			if (is_default) {
1146 				if (DEVICE_5906_SERIES_CHIPSETS(bgep))
1147 					*(uint8_t *)pr_val = 0;
1148 				else
1149 					*(uint8_t *)pr_val = 1;
1150 			}
1151 			else
1152 				*(uint8_t *)pr_val = bgep->param_en_1000fdx;
1153 			break;
1154 		case MAC_PROP_ADV_1000HDX_CAP:
1155 			if (is_default) {
1156 				if (DEVICE_5906_SERIES_CHIPSETS(bgep))
1157 					*(uint8_t *)pr_val = 0;
1158 				else
1159 					*(uint8_t *)pr_val = 1;
1160 			}
1161 			else
1162 				*(uint8_t *)pr_val = bgep->param_adv_1000hdx;
1163 			break;
1164 		case MAC_PROP_EN_1000HDX_CAP:
1165 			if (is_default) {
1166 				if (DEVICE_5906_SERIES_CHIPSETS(bgep))
1167 					*(uint8_t *)pr_val = 0;
1168 				else
1169 					*(uint8_t *)pr_val = 1;
1170 			}
1171 			else
1172 				*(uint8_t *)pr_val = bgep->param_en_1000hdx;
1173 			break;
1174 		case MAC_PROP_ADV_100FDX_CAP:
1175 			if (is_default) {
1176 				*(uint8_t *)pr_val =
1177 				    ((flags & CHIP_FLAG_SERDES) ? 0 : 1);
1178 			} else {
1179 				*(uint8_t *)pr_val = bgep->param_adv_100fdx;
1180 			}
1181 			break;
1182 		case MAC_PROP_EN_100FDX_CAP:
1183 			if (is_default) {
1184 				*(uint8_t *)pr_val =
1185 				    ((flags & CHIP_FLAG_SERDES) ? 0 : 1);
1186 			} else {
1187 				*(uint8_t *)pr_val = bgep->param_en_100fdx;
1188 			}
1189 			break;
1190 		case MAC_PROP_ADV_100HDX_CAP:
1191 			if (is_default) {
1192 				*(uint8_t *)pr_val =
1193 				    ((flags & CHIP_FLAG_SERDES) ? 0 : 1);
1194 			} else {
1195 				*(uint8_t *)pr_val = bgep->param_adv_100hdx;
1196 			}
1197 			break;
1198 		case MAC_PROP_EN_100HDX_CAP:
1199 			if (is_default) {
1200 				*(uint8_t *)pr_val =
1201 				    ((flags & CHIP_FLAG_SERDES) ? 0 : 1);
1202 			} else {
1203 				*(uint8_t *)pr_val = bgep->param_en_100hdx;
1204 			}
1205 			break;
1206 		case MAC_PROP_ADV_10FDX_CAP:
1207 			if (is_default) {
1208 				*(uint8_t *)pr_val =
1209 				    ((flags & CHIP_FLAG_SERDES) ? 0 : 1);
1210 			} else {
1211 				*(uint8_t *)pr_val = bgep->param_adv_10fdx;
1212 			}
1213 			break;
1214 		case MAC_PROP_EN_10FDX_CAP:
1215 			if (is_default) {
1216 				*(uint8_t *)pr_val =
1217 				    ((flags & CHIP_FLAG_SERDES) ? 0 : 1);
1218 			} else {
1219 				*(uint8_t *)pr_val = bgep->param_en_10fdx;
1220 			}
1221 			break;
1222 		case MAC_PROP_ADV_10HDX_CAP:
1223 			if (is_default) {
1224 				*(uint8_t *)pr_val =
1225 				    ((flags & CHIP_FLAG_SERDES) ? 0 : 1);
1226 			} else {
1227 				*(uint8_t *)pr_val = bgep->param_adv_10hdx;
1228 			}
1229 			break;
1230 		case MAC_PROP_EN_10HDX_CAP:
1231 			if (is_default) {
1232 				*(uint8_t *)pr_val =
1233 				    ((flags & CHIP_FLAG_SERDES) ? 0 : 1);
1234 			} else {
1235 				*(uint8_t *)pr_val = bgep->param_en_10hdx;
1236 			}
1237 			break;
1238 		case MAC_PROP_ADV_100T4_CAP:
1239 		case MAC_PROP_EN_100T4_CAP:
1240 			*(uint8_t *)pr_val = 0;
1241 			break;
1242 		case MAC_PROP_PRIVATE:
1243 			err = bge_get_priv_prop(bgep, pr_name, pr_flags,
1244 			    pr_valsize, pr_val);
1245 			return (err);
1246 		default:
1247 			return (ENOTSUP);
1248 	}
1249 	return (0);
1250 }
1251 
1252 /* ARGSUSED */
1253 static int
1254 bge_set_priv_prop(bge_t *bgep, const char *pr_name, uint_t pr_valsize,
1255     const void *pr_val)
1256 {
1257 	int err = 0;
1258 	long result;
1259 
1260 	if (strcmp(pr_name, "_adv_pause_cap") == 0) {
1261 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1262 		if (result > 1 || result < 0) {
1263 			err = EINVAL;
1264 		} else {
1265 			bgep->param_adv_pause = (uint32_t)result;
1266 			if (bge_reprogram(bgep) == IOC_INVAL)
1267 				err = EINVAL;
1268 		}
1269 		return (err);
1270 	}
1271 	if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
1272 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1273 		if (result > 1 || result < 0) {
1274 			err = EINVAL;
1275 		} else {
1276 			bgep->param_adv_asym_pause = (uint32_t)result;
1277 			if (bge_reprogram(bgep) == IOC_INVAL)
1278 				err = EINVAL;
1279 		}
1280 		return (err);
1281 	}
1282 	if (strcmp(pr_name, "_drain_max") == 0) {
1283 
1284 		/*
1285 		 * on the Tx side, we need to update the h/w register for
1286 		 * real packet transmission per packet. The drain_max parameter
1287 		 * is used to reduce the register access. This parameter
1288 		 * controls the max number of packets that we will hold before
1289 		 * updating the bge h/w to trigger h/w transmit. The bge
1290 		 * chipset usually has a max of 512 Tx descriptors, thus
1291 		 * the upper bound on drain_max is 512.
1292 		 */
1293 		if (pr_val == NULL) {
1294 			err = EINVAL;
1295 			return (err);
1296 		}
1297 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1298 		if (result > 512 || result < 1)
1299 			err = EINVAL;
1300 		else {
1301 			bgep->param_drain_max = (uint32_t)result;
1302 			if (bge_reprogram(bgep) == IOC_INVAL)
1303 				err = EINVAL;
1304 		}
1305 		return (err);
1306 	}
1307 	if (strcmp(pr_name, "_msi_cnt") == 0) {
1308 
1309 		if (pr_val == NULL) {
1310 			err = EINVAL;
1311 			return (err);
1312 		}
1313 		(void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
1314 		if (result > 7 || result < 0)
1315 			err = EINVAL;
1316 		else {
1317 			bgep->param_msi_cnt = (uint32_t)result;
1318 			if (bge_reprogram(bgep) == IOC_INVAL)
1319 				err = EINVAL;
1320 		}
1321 		return (err);
1322 	}
1323 	if (strcmp(pr_name, "_intr_coalesce_blank_time") == 0) {
1324 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0)
1325 			return (EINVAL);
1326 
1327 		bgep->chipid.rx_ticks_norm = (uint32_t)result;
1328 		return (0);
1329 	}
1330 
1331 	if (strcmp(pr_name, "_intr_coalesce_pkt_cnt") == 0) {
1332 		if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0)
1333 			return (EINVAL);
1334 
1335 		bgep->chipid.rx_count_norm = (uint32_t)result;
1336 		return (0);
1337 	}
1338 	return (ENOTSUP);
1339 }
1340 
1341 static int
1342 bge_get_priv_prop(bge_t *bge, const char *pr_name, uint_t pr_flags,
1343     uint_t pr_valsize, void *pr_val)
1344 {
1345 	int err = ENOTSUP;
1346 	boolean_t is_default = (pr_flags & MAC_PROP_DEFAULT);
1347 	int value;
1348 
1349 	if (strcmp(pr_name, "_adv_pause_cap") == 0) {
1350 		value = (is_default? 1 : bge->param_adv_pause);
1351 		err = 0;
1352 		goto done;
1353 	}
1354 	if (strcmp(pr_name, "_adv_asym_pause_cap") == 0) {
1355 		value = (is_default? 1 : bge->param_adv_asym_pause);
1356 		err = 0;
1357 		goto done;
1358 	}
1359 	if (strcmp(pr_name, "_drain_max") == 0) {
1360 		value = (is_default? 64 : bge->param_drain_max);
1361 		err = 0;
1362 		goto done;
1363 	}
1364 	if (strcmp(pr_name, "_msi_cnt") == 0) {
1365 		value = (is_default? 0 : bge->param_msi_cnt);
1366 		err = 0;
1367 		goto done;
1368 	}
1369 
1370 	if (strcmp(pr_name, "_intr_coalesce_blank_time") == 0) {
1371 		value = (is_default? bge_rx_ticks_norm :
1372 		    bge->chipid.rx_ticks_norm);
1373 		err = 0;
1374 		goto done;
1375 	}
1376 
1377 	if (strcmp(pr_name, "_intr_coalesce_pkt_cnt") == 0) {
1378 		value = (is_default? bge_rx_count_norm :
1379 		    bge->chipid.rx_count_norm);
1380 		err = 0;
1381 		goto done;
1382 	}
1383 
1384 done:
1385 	if (err == 0) {
1386 		(void) snprintf(pr_val, pr_valsize, "%d", value);
1387 	}
1388 	return (err);
1389 }
1390 
1391 /*
1392  * Compute the index of the required bit in the multicast hash map.
1393  * This must mirror the way the hardware actually does it!
1394  * See Broadcom document 570X-PG102-R page 125.
1395  */
1396 static uint32_t
1397 bge_hash_index(const uint8_t *mca)
1398 {
1399 	uint32_t hash;
1400 
1401 	CRC32(hash, mca, ETHERADDRL, -1U, crc32_table);
1402 
1403 	return (hash);
1404 }
1405 
1406 /*
1407  *	bge_m_multicst_add() -- enable/disable a multicast address
1408  */
1409 static int
1410 bge_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
1411 {
1412 	bge_t *bgep = arg;		/* private device info	*/
1413 	uint32_t hash;
1414 	uint32_t index;
1415 	uint32_t word;
1416 	uint32_t bit;
1417 	uint8_t *refp;
1418 
1419 	BGE_TRACE(("bge_m_multicst($%p, %s, %s)", arg,
1420 	    (add) ? "add" : "remove", ether_sprintf((void *)mca)));
1421 
1422 	/*
1423 	 * Precalculate all required masks, pointers etc ...
1424 	 */
1425 	hash = bge_hash_index(mca);
1426 	index = hash % BGE_HASH_TABLE_SIZE;
1427 	word = index/32u;
1428 	bit = 1 << (index % 32u);
1429 	refp = &bgep->mcast_refs[index];
1430 
1431 	BGE_DEBUG(("bge_m_multicst: hash 0x%x index %d (%d:0x%x) = %d",
1432 	    hash, index, word, bit, *refp));
1433 
1434 	/*
1435 	 * We must set the appropriate bit in the hash map (and the
1436 	 * corresponding h/w register) when the refcount goes from 0
1437 	 * to >0, and clear it when the last ref goes away (refcount
1438 	 * goes from >0 back to 0).  If we change the hash map, we
1439 	 * must also update the chip's hardware map registers.
1440 	 */
1441 	mutex_enter(bgep->genlock);
1442 	if (!(bgep->progress & PROGRESS_INTR)) {
1443 		/* can happen during autorecovery */
1444 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1445 		mutex_exit(bgep->genlock);
1446 		return (EIO);
1447 	}
1448 	if (add) {
1449 		if ((*refp)++ == 0) {
1450 			bgep->mcast_hash[word] |= bit;
1451 #ifdef BGE_IPMI_ASF
1452 			if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
1453 #else
1454 			if (bge_chip_sync(bgep) == DDI_FAILURE) {
1455 #endif
1456 				(void) bge_check_acc_handle(bgep,
1457 				    bgep->cfg_handle);
1458 				(void) bge_check_acc_handle(bgep,
1459 				    bgep->io_handle);
1460 				ddi_fm_service_impact(bgep->devinfo,
1461 				    DDI_SERVICE_DEGRADED);
1462 				mutex_exit(bgep->genlock);
1463 				return (EIO);
1464 			}
1465 		}
1466 	} else {
1467 		if (--(*refp) == 0) {
1468 			bgep->mcast_hash[word] &= ~bit;
1469 #ifdef BGE_IPMI_ASF
1470 			if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
1471 #else
1472 			if (bge_chip_sync(bgep) == DDI_FAILURE) {
1473 #endif
1474 				(void) bge_check_acc_handle(bgep,
1475 				    bgep->cfg_handle);
1476 				(void) bge_check_acc_handle(bgep,
1477 				    bgep->io_handle);
1478 				ddi_fm_service_impact(bgep->devinfo,
1479 				    DDI_SERVICE_DEGRADED);
1480 				mutex_exit(bgep->genlock);
1481 				return (EIO);
1482 			}
1483 		}
1484 	}
1485 	BGE_DEBUG(("bge_m_multicst($%p) done", arg));
1486 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
1487 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1488 		mutex_exit(bgep->genlock);
1489 		return (EIO);
1490 	}
1491 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
1492 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1493 		mutex_exit(bgep->genlock);
1494 		return (EIO);
1495 	}
1496 	mutex_exit(bgep->genlock);
1497 
1498 	return (0);
1499 }
1500 
1501 /*
1502  * bge_m_promisc() -- set or reset promiscuous mode on the board
1503  *
1504  *	Program the hardware to enable/disable promiscuous and/or
1505  *	receive-all-multicast modes.
1506  */
1507 static int
1508 bge_m_promisc(void *arg, boolean_t on)
1509 {
1510 	bge_t *bgep = arg;
1511 
1512 	BGE_TRACE(("bge_m_promisc_set($%p, %d)", arg, on));
1513 
1514 	/*
1515 	 * Store MAC layer specified mode and pass to chip layer to update h/w
1516 	 */
1517 	mutex_enter(bgep->genlock);
1518 	if (!(bgep->progress & PROGRESS_INTR)) {
1519 		/* can happen during autorecovery */
1520 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1521 		mutex_exit(bgep->genlock);
1522 		return (EIO);
1523 	}
1524 	bgep->promisc = on;
1525 #ifdef BGE_IPMI_ASF
1526 	if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
1527 #else
1528 	if (bge_chip_sync(bgep) == DDI_FAILURE) {
1529 #endif
1530 		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
1531 		(void) bge_check_acc_handle(bgep, bgep->io_handle);
1532 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1533 		mutex_exit(bgep->genlock);
1534 		return (EIO);
1535 	}
1536 	BGE_DEBUG(("bge_m_promisc_set($%p) done", arg));
1537 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
1538 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1539 		mutex_exit(bgep->genlock);
1540 		return (EIO);
1541 	}
1542 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
1543 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1544 		mutex_exit(bgep->genlock);
1545 		return (EIO);
1546 	}
1547 	mutex_exit(bgep->genlock);
1548 	return (0);
1549 }
1550 
1551 /*ARGSUSED*/
1552 static boolean_t
1553 bge_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
1554 {
1555 	bge_t *bgep = arg;
1556 
1557 	switch (cap) {
1558 	case MAC_CAPAB_HCKSUM: {
1559 		uint32_t *txflags = cap_data;
1560 
1561 		*txflags = HCKSUM_INET_FULL_V4 | HCKSUM_IPHDRCKSUM;
1562 		break;
1563 	}
1564 
1565 	case MAC_CAPAB_POLL:
1566 		/*
1567 		 * There's nothing for us to fill in, simply returning
1568 		 * B_TRUE stating that we support polling is sufficient.
1569 		 */
1570 		break;
1571 
1572 	case MAC_CAPAB_MULTIADDRESS: {
1573 		multiaddress_capab_t	*mmacp = cap_data;
1574 
1575 		mutex_enter(bgep->genlock);
1576 		/*
1577 		 * The number of MAC addresses made available by
1578 		 * this capability is one less than the total as
1579 		 * the primary address in slot 0 is counted in
1580 		 * the total.
1581 		 */
1582 		mmacp->maddr_naddr = bgep->unicst_addr_total - 1;
1583 		mmacp->maddr_naddrfree = bgep->unicst_addr_avail;
1584 		/* No multiple factory addresses, set mma_flag to 0 */
1585 		mmacp->maddr_flag = 0;
1586 		mmacp->maddr_handle = bgep;
1587 		mmacp->maddr_add = bge_m_unicst_add;
1588 		mmacp->maddr_remove = bge_m_unicst_remove;
1589 		mmacp->maddr_modify = bge_m_unicst_modify;
1590 		mmacp->maddr_get = bge_m_unicst_get;
1591 		mmacp->maddr_reserve = NULL;
1592 		mutex_exit(bgep->genlock);
1593 		break;
1594 	}
1595 
1596 	default:
1597 		return (B_FALSE);
1598 	}
1599 	return (B_TRUE);
1600 }
1601 
1602 /*
1603  * Loopback ioctl code
1604  */
1605 
1606 static lb_property_t loopmodes[] = {
1607 	{ normal,	"normal",	BGE_LOOP_NONE		},
1608 	{ external,	"1000Mbps",	BGE_LOOP_EXTERNAL_1000	},
1609 	{ external,	"100Mbps",	BGE_LOOP_EXTERNAL_100	},
1610 	{ external,	"10Mbps",	BGE_LOOP_EXTERNAL_10	},
1611 	{ internal,	"PHY",		BGE_LOOP_INTERNAL_PHY	},
1612 	{ internal,	"MAC",		BGE_LOOP_INTERNAL_MAC	}
1613 };
1614 
1615 static enum ioc_reply
1616 bge_set_loop_mode(bge_t *bgep, uint32_t mode)
1617 {
1618 	/*
1619 	 * If the mode isn't being changed, there's nothing to do ...
1620 	 */
1621 	if (mode == bgep->param_loop_mode)
1622 		return (IOC_ACK);
1623 
1624 	/*
1625 	 * Validate the requested mode and prepare a suitable message
1626 	 * to explain the link down/up cycle that the change will
1627 	 * probably induce ...
1628 	 */
1629 	switch (mode) {
1630 	default:
1631 		return (IOC_INVAL);
1632 
1633 	case BGE_LOOP_NONE:
1634 	case BGE_LOOP_EXTERNAL_1000:
1635 	case BGE_LOOP_EXTERNAL_100:
1636 	case BGE_LOOP_EXTERNAL_10:
1637 	case BGE_LOOP_INTERNAL_PHY:
1638 	case BGE_LOOP_INTERNAL_MAC:
1639 		break;
1640 	}
1641 
1642 	/*
1643 	 * All OK; tell the caller to reprogram
1644 	 * the PHY and/or MAC for the new mode ...
1645 	 */
1646 	bgep->param_loop_mode = mode;
1647 	return (IOC_RESTART_ACK);
1648 }
1649 
1650 static enum ioc_reply
1651 bge_loop_ioctl(bge_t *bgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
1652 {
1653 	lb_info_sz_t *lbsp;
1654 	lb_property_t *lbpp;
1655 	uint32_t *lbmp;
1656 	int cmd;
1657 
1658 	_NOTE(ARGUNUSED(wq))
1659 
1660 	/*
1661 	 * Validate format of ioctl
1662 	 */
1663 	if (mp->b_cont == NULL)
1664 		return (IOC_INVAL);
1665 
1666 	cmd = iocp->ioc_cmd;
1667 	switch (cmd) {
1668 	default:
1669 		/* NOTREACHED */
1670 		bge_error(bgep, "bge_loop_ioctl: invalid cmd 0x%x", cmd);
1671 		return (IOC_INVAL);
1672 
1673 	case LB_GET_INFO_SIZE:
1674 		if (iocp->ioc_count != sizeof (lb_info_sz_t))
1675 			return (IOC_INVAL);
1676 		lbsp = (void *)mp->b_cont->b_rptr;
1677 		*lbsp = sizeof (loopmodes);
1678 		return (IOC_REPLY);
1679 
1680 	case LB_GET_INFO:
1681 		if (iocp->ioc_count != sizeof (loopmodes))
1682 			return (IOC_INVAL);
1683 		lbpp = (void *)mp->b_cont->b_rptr;
1684 		bcopy(loopmodes, lbpp, sizeof (loopmodes));
1685 		return (IOC_REPLY);
1686 
1687 	case LB_GET_MODE:
1688 		if (iocp->ioc_count != sizeof (uint32_t))
1689 			return (IOC_INVAL);
1690 		lbmp = (void *)mp->b_cont->b_rptr;
1691 		*lbmp = bgep->param_loop_mode;
1692 		return (IOC_REPLY);
1693 
1694 	case LB_SET_MODE:
1695 		if (iocp->ioc_count != sizeof (uint32_t))
1696 			return (IOC_INVAL);
1697 		lbmp = (void *)mp->b_cont->b_rptr;
1698 		return (bge_set_loop_mode(bgep, *lbmp));
1699 	}
1700 }
1701 
1702 /*
1703  * Specific bge IOCTLs, the gld module handles the generic ones.
1704  */
1705 static void
1706 bge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
1707 {
1708 	bge_t *bgep = arg;
1709 	struct iocblk *iocp;
1710 	enum ioc_reply status;
1711 	boolean_t need_privilege;
1712 	int err;
1713 	int cmd;
1714 
1715 	/*
1716 	 * Validate the command before bothering with the mutex ...
1717 	 */
1718 	iocp = (void *)mp->b_rptr;
1719 	iocp->ioc_error = 0;
1720 	need_privilege = B_TRUE;
1721 	cmd = iocp->ioc_cmd;
1722 	switch (cmd) {
1723 	default:
1724 		miocnak(wq, mp, 0, EINVAL);
1725 		return;
1726 
1727 	case BGE_MII_READ:
1728 	case BGE_MII_WRITE:
1729 	case BGE_SEE_READ:
1730 	case BGE_SEE_WRITE:
1731 	case BGE_FLASH_READ:
1732 	case BGE_FLASH_WRITE:
1733 	case BGE_DIAG:
1734 	case BGE_PEEK:
1735 	case BGE_POKE:
1736 	case BGE_PHY_RESET:
1737 	case BGE_SOFT_RESET:
1738 	case BGE_HARD_RESET:
1739 		break;
1740 
1741 	case LB_GET_INFO_SIZE:
1742 	case LB_GET_INFO:
1743 	case LB_GET_MODE:
1744 		need_privilege = B_FALSE;
1745 		/* FALLTHRU */
1746 	case LB_SET_MODE:
1747 		break;
1748 
1749 	}
1750 
1751 	if (need_privilege) {
1752 		/*
1753 		 * Check for specific net_config privilege on Solaris 10+.
1754 		 */
1755 		err = secpolicy_net_config(iocp->ioc_cr, B_FALSE);
1756 		if (err != 0) {
1757 			miocnak(wq, mp, 0, err);
1758 			return;
1759 		}
1760 	}
1761 
1762 	mutex_enter(bgep->genlock);
1763 	if (!(bgep->progress & PROGRESS_INTR)) {
1764 		/* can happen during autorecovery */
1765 		mutex_exit(bgep->genlock);
1766 		miocnak(wq, mp, 0, EIO);
1767 		return;
1768 	}
1769 
1770 	switch (cmd) {
1771 	default:
1772 		_NOTE(NOTREACHED)
1773 		status = IOC_INVAL;
1774 		break;
1775 
1776 	case BGE_MII_READ:
1777 	case BGE_MII_WRITE:
1778 	case BGE_SEE_READ:
1779 	case BGE_SEE_WRITE:
1780 	case BGE_FLASH_READ:
1781 	case BGE_FLASH_WRITE:
1782 	case BGE_DIAG:
1783 	case BGE_PEEK:
1784 	case BGE_POKE:
1785 	case BGE_PHY_RESET:
1786 	case BGE_SOFT_RESET:
1787 	case BGE_HARD_RESET:
1788 		status = bge_chip_ioctl(bgep, wq, mp, iocp);
1789 		break;
1790 
1791 	case LB_GET_INFO_SIZE:
1792 	case LB_GET_INFO:
1793 	case LB_GET_MODE:
1794 	case LB_SET_MODE:
1795 		status = bge_loop_ioctl(bgep, wq, mp, iocp);
1796 		break;
1797 
1798 	}
1799 
1800 	/*
1801 	 * Do we need to reprogram the PHY and/or the MAC?
1802 	 * Do it now, while we still have the mutex.
1803 	 *
1804 	 * Note: update the PHY first, 'cos it controls the
1805 	 * speed/duplex parameters that the MAC code uses.
1806 	 */
1807 	switch (status) {
1808 	case IOC_RESTART_REPLY:
1809 	case IOC_RESTART_ACK:
1810 		if (bge_reprogram(bgep) == IOC_INVAL)
1811 			status = IOC_INVAL;
1812 		break;
1813 	}
1814 
1815 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
1816 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1817 		status = IOC_INVAL;
1818 	}
1819 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
1820 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
1821 		status = IOC_INVAL;
1822 	}
1823 	mutex_exit(bgep->genlock);
1824 
1825 	/*
1826 	 * Finally, decide how to reply
1827 	 */
1828 	switch (status) {
1829 	default:
1830 	case IOC_INVAL:
1831 		/*
1832 		 * Error, reply with a NAK and EINVAL or the specified error
1833 		 */
1834 		miocnak(wq, mp, 0, iocp->ioc_error == 0 ?
1835 		    EINVAL : iocp->ioc_error);
1836 		break;
1837 
1838 	case IOC_DONE:
1839 		/*
1840 		 * OK, reply already sent
1841 		 */
1842 		break;
1843 
1844 	case IOC_RESTART_ACK:
1845 	case IOC_ACK:
1846 		/*
1847 		 * OK, reply with an ACK
1848 		 */
1849 		miocack(wq, mp, 0, 0);
1850 		break;
1851 
1852 	case IOC_RESTART_REPLY:
1853 	case IOC_REPLY:
1854 		/*
1855 		 * OK, send prepared reply as ACK or NAK
1856 		 */
1857 		mp->b_datap->db_type = iocp->ioc_error == 0 ?
1858 		    M_IOCACK : M_IOCNAK;
1859 		qreply(wq, mp);
1860 		break;
1861 	}
1862 }
1863 
1864 static void
1865 bge_resources_add(bge_t *bgep, time_t time, uint_t pkt_cnt)
1866 {
1867 
1868 	recv_ring_t *rrp;
1869 	mac_rx_fifo_t mrf;
1870 	int ring;
1871 
1872 	/*
1873 	 * Register Rx rings as resources and save mac
1874 	 * resource id for future reference
1875 	 */
1876 	mrf.mrf_type = MAC_RX_FIFO;
1877 	mrf.mrf_blank = bge_chip_blank;
1878 	mrf.mrf_arg = (void *)bgep;
1879 	mrf.mrf_normal_blank_time = time;
1880 	mrf.mrf_normal_pkt_count = pkt_cnt;
1881 
1882 	for (ring = 0; ring < bgep->chipid.rx_rings; ring++) {
1883 		rrp = &bgep->recv[ring];
1884 		rrp->handle = mac_resource_add(bgep->mh,
1885 		    (mac_resource_t *)&mrf);
1886 	}
1887 }
1888 
1889 static void
1890 bge_m_resources(void *arg)
1891 {
1892 	bge_t *bgep = arg;
1893 
1894 	mutex_enter(bgep->genlock);
1895 
1896 	bge_resources_add(bgep, bgep->chipid.rx_ticks_norm,
1897 	    bgep->chipid.rx_count_norm);
1898 	mutex_exit(bgep->genlock);
1899 }
1900 
1901 /*
1902  * ========== Per-instance setup/teardown code ==========
1903  */
1904 
1905 #undef	BGE_DBG
1906 #define	BGE_DBG		BGE_DBG_INIT	/* debug flag for this code	*/
1907 /*
1908  * Allocate an area of memory and a DMA handle for accessing it
1909  */
1910 static int
1911 bge_alloc_dma_mem(bge_t *bgep, size_t memsize, ddi_device_acc_attr_t *attr_p,
1912 	uint_t dma_flags, dma_area_t *dma_p)
1913 {
1914 	caddr_t va;
1915 	int err;
1916 
1917 	BGE_TRACE(("bge_alloc_dma_mem($%p, %ld, $%p, 0x%x, $%p)",
1918 	    (void *)bgep, memsize, attr_p, dma_flags, dma_p));
1919 
1920 	/*
1921 	 * Allocate handle
1922 	 */
1923 	err = ddi_dma_alloc_handle(bgep->devinfo, &dma_attr,
1924 	    DDI_DMA_DONTWAIT, NULL, &dma_p->dma_hdl);
1925 	if (err != DDI_SUCCESS)
1926 		return (DDI_FAILURE);
1927 
1928 	/*
1929 	 * Allocate memory
1930 	 */
1931 	err = ddi_dma_mem_alloc(dma_p->dma_hdl, memsize, attr_p,
1932 	    dma_flags, DDI_DMA_DONTWAIT, NULL, &va, &dma_p->alength,
1933 	    &dma_p->acc_hdl);
1934 	if (err != DDI_SUCCESS)
1935 		return (DDI_FAILURE);
1936 
1937 	/*
1938 	 * Bind the two together
1939 	 */
1940 	dma_p->mem_va = va;
1941 	err = ddi_dma_addr_bind_handle(dma_p->dma_hdl, NULL,
1942 	    va, dma_p->alength, dma_flags, DDI_DMA_DONTWAIT, NULL,
1943 	    &dma_p->cookie, &dma_p->ncookies);
1944 
1945 	BGE_DEBUG(("bge_alloc_dma_mem(): bind %d bytes; err %d, %d cookies",
1946 	    dma_p->alength, err, dma_p->ncookies));
1947 
1948 	if (err != DDI_DMA_MAPPED || dma_p->ncookies != 1)
1949 		return (DDI_FAILURE);
1950 
1951 	dma_p->nslots = ~0U;
1952 	dma_p->size = ~0U;
1953 	dma_p->token = ~0U;
1954 	dma_p->offset = 0;
1955 	return (DDI_SUCCESS);
1956 }
1957 
1958 /*
1959  * Free one allocated area of DMAable memory
1960  */
1961 static void
1962 bge_free_dma_mem(dma_area_t *dma_p)
1963 {
1964 	if (dma_p->dma_hdl != NULL) {
1965 		if (dma_p->ncookies) {
1966 			(void) ddi_dma_unbind_handle(dma_p->dma_hdl);
1967 			dma_p->ncookies = 0;
1968 		}
1969 		ddi_dma_free_handle(&dma_p->dma_hdl);
1970 		dma_p->dma_hdl = NULL;
1971 	}
1972 
1973 	if (dma_p->acc_hdl != NULL) {
1974 		ddi_dma_mem_free(&dma_p->acc_hdl);
1975 		dma_p->acc_hdl = NULL;
1976 	}
1977 }
1978 /*
1979  * Utility routine to carve a slice off a chunk of allocated memory,
1980  * updating the chunk descriptor accordingly.  The size of the slice
1981  * is given by the product of the <qty> and <size> parameters.
1982  */
1983 static void
1984 bge_slice_chunk(dma_area_t *slice, dma_area_t *chunk,
1985 	uint32_t qty, uint32_t size)
1986 {
1987 	static uint32_t sequence = 0xbcd5704a;
1988 	size_t totsize;
1989 
1990 	totsize = qty*size;
1991 	ASSERT(totsize <= chunk->alength);
1992 
1993 	*slice = *chunk;
1994 	slice->nslots = qty;
1995 	slice->size = size;
1996 	slice->alength = totsize;
1997 	slice->token = ++sequence;
1998 
1999 	chunk->mem_va = (caddr_t)chunk->mem_va + totsize;
2000 	chunk->alength -= totsize;
2001 	chunk->offset += totsize;
2002 	chunk->cookie.dmac_laddress += totsize;
2003 	chunk->cookie.dmac_size -= totsize;
2004 }
2005 
2006 /*
2007  * Initialise the specified Receive Producer (Buffer) Ring, using
2008  * the information in the <dma_area> descriptors that it contains
2009  * to set up all the other fields. This routine should be called
2010  * only once for each ring.
2011  */
2012 static void
2013 bge_init_buff_ring(bge_t *bgep, uint64_t ring)
2014 {
2015 	buff_ring_t *brp;
2016 	bge_status_t *bsp;
2017 	sw_rbd_t *srbdp;
2018 	dma_area_t pbuf;
2019 	uint32_t bufsize;
2020 	uint32_t nslots;
2021 	uint32_t slot;
2022 	uint32_t split;
2023 
2024 	static bge_regno_t nic_ring_addrs[BGE_BUFF_RINGS_MAX] = {
2025 		NIC_MEM_SHADOW_BUFF_STD,
2026 		NIC_MEM_SHADOW_BUFF_JUMBO,
2027 		NIC_MEM_SHADOW_BUFF_MINI
2028 	};
2029 	static bge_regno_t mailbox_regs[BGE_BUFF_RINGS_MAX] = {
2030 		RECV_STD_PROD_INDEX_REG,
2031 		RECV_JUMBO_PROD_INDEX_REG,
2032 		RECV_MINI_PROD_INDEX_REG
2033 	};
2034 	static bge_regno_t buff_cons_xref[BGE_BUFF_RINGS_MAX] = {
2035 		STATUS_STD_BUFF_CONS_INDEX,
2036 		STATUS_JUMBO_BUFF_CONS_INDEX,
2037 		STATUS_MINI_BUFF_CONS_INDEX
2038 	};
2039 
2040 	BGE_TRACE(("bge_init_buff_ring($%p, %d)",
2041 	    (void *)bgep, ring));
2042 
2043 	brp = &bgep->buff[ring];
2044 	nslots = brp->desc.nslots;
2045 	ASSERT(brp->buf[0].nslots == nslots/BGE_SPLIT);
2046 	bufsize = brp->buf[0].size;
2047 
2048 	/*
2049 	 * Set up the copy of the h/w RCB
2050 	 *
2051 	 * Note: unlike Send & Receive Return Rings, (where the max_len
2052 	 * field holds the number of slots), in a Receive Buffer Ring
2053 	 * this field indicates the size of each buffer in the ring.
2054 	 */
2055 	brp->hw_rcb.host_ring_addr = brp->desc.cookie.dmac_laddress;
2056 	brp->hw_rcb.max_len = (uint16_t)bufsize;
2057 	brp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED;
2058 	brp->hw_rcb.nic_ring_addr = nic_ring_addrs[ring];
2059 
2060 	/*
2061 	 * Other one-off initialisation of per-ring data
2062 	 */
2063 	brp->bgep = bgep;
2064 	bsp = DMA_VPTR(bgep->status_block);
2065 	brp->cons_index_p = &bsp->buff_cons_index[buff_cons_xref[ring]];
2066 	brp->chip_mbx_reg = mailbox_regs[ring];
2067 	mutex_init(brp->rf_lock, NULL, MUTEX_DRIVER,
2068 	    DDI_INTR_PRI(bgep->intr_pri));
2069 
2070 	/*
2071 	 * Allocate the array of s/w Receive Buffer Descriptors
2072 	 */
2073 	srbdp = kmem_zalloc(nslots*sizeof (*srbdp), KM_SLEEP);
2074 	brp->sw_rbds = srbdp;
2075 
2076 	/*
2077 	 * Now initialise each array element once and for all
2078 	 */
2079 	for (split = 0; split < BGE_SPLIT; ++split) {
2080 		pbuf = brp->buf[split];
2081 		for (slot = 0; slot < nslots/BGE_SPLIT; ++srbdp, ++slot)
2082 			bge_slice_chunk(&srbdp->pbuf, &pbuf, 1, bufsize);
2083 		ASSERT(pbuf.alength == 0);
2084 	}
2085 }
2086 
2087 /*
2088  * Clean up initialisation done above before the memory is freed
2089  */
2090 static void
2091 bge_fini_buff_ring(bge_t *bgep, uint64_t ring)
2092 {
2093 	buff_ring_t *brp;
2094 	sw_rbd_t *srbdp;
2095 
2096 	BGE_TRACE(("bge_fini_buff_ring($%p, %d)",
2097 	    (void *)bgep, ring));
2098 
2099 	brp = &bgep->buff[ring];
2100 	srbdp = brp->sw_rbds;
2101 	kmem_free(srbdp, brp->desc.nslots*sizeof (*srbdp));
2102 
2103 	mutex_destroy(brp->rf_lock);
2104 }
2105 
2106 /*
2107  * Initialise the specified Receive (Return) Ring, using the
2108  * information in the <dma_area> descriptors that it contains
2109  * to set up all the other fields. This routine should be called
2110  * only once for each ring.
2111  */
2112 static void
2113 bge_init_recv_ring(bge_t *bgep, uint64_t ring)
2114 {
2115 	recv_ring_t *rrp;
2116 	bge_status_t *bsp;
2117 	uint32_t nslots;
2118 
2119 	BGE_TRACE(("bge_init_recv_ring($%p, %d)",
2120 	    (void *)bgep, ring));
2121 
2122 	/*
2123 	 * The chip architecture requires that receive return rings have
2124 	 * 512 or 1024 or 2048 elements per ring.  See 570X-PG108-R page 103.
2125 	 */
2126 	rrp = &bgep->recv[ring];
2127 	nslots = rrp->desc.nslots;
2128 	ASSERT(nslots == 0 || nslots == 512 ||
2129 	    nslots == 1024 || nslots == 2048);
2130 
2131 	/*
2132 	 * Set up the copy of the h/w RCB
2133 	 */
2134 	rrp->hw_rcb.host_ring_addr = rrp->desc.cookie.dmac_laddress;
2135 	rrp->hw_rcb.max_len = (uint16_t)nslots;
2136 	rrp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED;
2137 	rrp->hw_rcb.nic_ring_addr = 0;
2138 
2139 	/*
2140 	 * Other one-off initialisation of per-ring data
2141 	 */
2142 	rrp->bgep = bgep;
2143 	bsp = DMA_VPTR(bgep->status_block);
2144 	rrp->prod_index_p = RECV_INDEX_P(bsp, ring);
2145 	rrp->chip_mbx_reg = RECV_RING_CONS_INDEX_REG(ring);
2146 	mutex_init(rrp->rx_lock, NULL, MUTEX_DRIVER,
2147 	    DDI_INTR_PRI(bgep->intr_pri));
2148 }
2149 
2150 
2151 /*
2152  * Clean up initialisation done above before the memory is freed
2153  */
2154 static void
2155 bge_fini_recv_ring(bge_t *bgep, uint64_t ring)
2156 {
2157 	recv_ring_t *rrp;
2158 
2159 	BGE_TRACE(("bge_fini_recv_ring($%p, %d)",
2160 	    (void *)bgep, ring));
2161 
2162 	rrp = &bgep->recv[ring];
2163 	if (rrp->rx_softint)
2164 		ddi_remove_softintr(rrp->rx_softint);
2165 	mutex_destroy(rrp->rx_lock);
2166 }
2167 
2168 /*
2169  * Initialise the specified Send Ring, using the information in the
2170  * <dma_area> descriptors that it contains to set up all the other
2171  * fields. This routine should be called only once for each ring.
2172  */
2173 static void
2174 bge_init_send_ring(bge_t *bgep, uint64_t ring)
2175 {
2176 	send_ring_t *srp;
2177 	bge_status_t *bsp;
2178 	sw_sbd_t *ssbdp;
2179 	dma_area_t desc;
2180 	dma_area_t pbuf;
2181 	uint32_t nslots;
2182 	uint32_t slot;
2183 	uint32_t split;
2184 	sw_txbuf_t *txbuf;
2185 
2186 	BGE_TRACE(("bge_init_send_ring($%p, %d)",
2187 	    (void *)bgep, ring));
2188 
2189 	/*
2190 	 * The chip architecture requires that host-based send rings
2191 	 * have 512 elements per ring.  See 570X-PG102-R page 56.
2192 	 */
2193 	srp = &bgep->send[ring];
2194 	nslots = srp->desc.nslots;
2195 	ASSERT(nslots == 0 || nslots == 512);
2196 
2197 	/*
2198 	 * Set up the copy of the h/w RCB
2199 	 */
2200 	srp->hw_rcb.host_ring_addr = srp->desc.cookie.dmac_laddress;
2201 	srp->hw_rcb.max_len = (uint16_t)nslots;
2202 	srp->hw_rcb.flags = nslots > 0 ? 0 : RCB_FLAG_RING_DISABLED;
2203 	srp->hw_rcb.nic_ring_addr = NIC_MEM_SHADOW_SEND_RING(ring, nslots);
2204 
2205 	/*
2206 	 * Other one-off initialisation of per-ring data
2207 	 */
2208 	srp->bgep = bgep;
2209 	bsp = DMA_VPTR(bgep->status_block);
2210 	srp->cons_index_p = SEND_INDEX_P(bsp, ring);
2211 	srp->chip_mbx_reg = SEND_RING_HOST_INDEX_REG(ring);
2212 	mutex_init(srp->tx_lock, NULL, MUTEX_DRIVER,
2213 	    DDI_INTR_PRI(bgep->intr_pri));
2214 	mutex_init(srp->txbuf_lock, NULL, MUTEX_DRIVER,
2215 	    DDI_INTR_PRI(bgep->intr_pri));
2216 	mutex_init(srp->freetxbuf_lock, NULL, MUTEX_DRIVER,
2217 	    DDI_INTR_PRI(bgep->intr_pri));
2218 	mutex_init(srp->tc_lock, NULL, MUTEX_DRIVER,
2219 	    DDI_INTR_PRI(bgep->intr_pri));
2220 	if (nslots == 0)
2221 		return;
2222 
2223 	/*
2224 	 * Allocate the array of s/w Send Buffer Descriptors
2225 	 */
2226 	ssbdp = kmem_zalloc(nslots*sizeof (*ssbdp), KM_SLEEP);
2227 	txbuf = kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (*txbuf), KM_SLEEP);
2228 	srp->txbuf_head =
2229 	    kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (bge_queue_item_t), KM_SLEEP);
2230 	srp->pktp = kmem_zalloc(BGE_SEND_BUF_MAX*sizeof (send_pkt_t), KM_SLEEP);
2231 	srp->sw_sbds = ssbdp;
2232 	srp->txbuf = txbuf;
2233 	srp->tx_buffers = BGE_SEND_BUF_NUM;
2234 	srp->tx_buffers_low = srp->tx_buffers / 4;
2235 	if (bgep->chipid.snd_buff_size > BGE_SEND_BUFF_SIZE_DEFAULT)
2236 		srp->tx_array_max = BGE_SEND_BUF_ARRAY_JUMBO;
2237 	else
2238 		srp->tx_array_max = BGE_SEND_BUF_ARRAY;
2239 	srp->tx_array = 1;
2240 
2241 	/*
2242 	 * Chunk tx desc area
2243 	 */
2244 	desc = srp->desc;
2245 	for (slot = 0; slot < nslots; ++ssbdp, ++slot) {
2246 		bge_slice_chunk(&ssbdp->desc, &desc, 1,
2247 		    sizeof (bge_sbd_t));
2248 	}
2249 	ASSERT(desc.alength == 0);
2250 
2251 	/*
2252 	 * Chunk tx buffer area
2253 	 */
2254 	for (split = 0; split < BGE_SPLIT; ++split) {
2255 		pbuf = srp->buf[0][split];
2256 		for (slot = 0; slot < BGE_SEND_BUF_NUM/BGE_SPLIT; ++slot) {
2257 			bge_slice_chunk(&txbuf->buf, &pbuf, 1,
2258 			    bgep->chipid.snd_buff_size);
2259 			txbuf++;
2260 		}
2261 		ASSERT(pbuf.alength == 0);
2262 	}
2263 }
2264 
2265 /*
2266  * Clean up initialisation done above before the memory is freed
2267  */
2268 static void
2269 bge_fini_send_ring(bge_t *bgep, uint64_t ring)
2270 {
2271 	send_ring_t *srp;
2272 	uint32_t array;
2273 	uint32_t split;
2274 	uint32_t nslots;
2275 
2276 	BGE_TRACE(("bge_fini_send_ring($%p, %d)",
2277 	    (void *)bgep, ring));
2278 
2279 	srp = &bgep->send[ring];
2280 	mutex_destroy(srp->tc_lock);
2281 	mutex_destroy(srp->freetxbuf_lock);
2282 	mutex_destroy(srp->txbuf_lock);
2283 	mutex_destroy(srp->tx_lock);
2284 	nslots = srp->desc.nslots;
2285 	if (nslots == 0)
2286 		return;
2287 
2288 	for (array = 1; array < srp->tx_array; ++array)
2289 		for (split = 0; split < BGE_SPLIT; ++split)
2290 			bge_free_dma_mem(&srp->buf[array][split]);
2291 	kmem_free(srp->sw_sbds, nslots*sizeof (*srp->sw_sbds));
2292 	kmem_free(srp->txbuf_head, BGE_SEND_BUF_MAX*sizeof (*srp->txbuf_head));
2293 	kmem_free(srp->txbuf, BGE_SEND_BUF_MAX*sizeof (*srp->txbuf));
2294 	kmem_free(srp->pktp, BGE_SEND_BUF_MAX*sizeof (*srp->pktp));
2295 	srp->sw_sbds = NULL;
2296 	srp->txbuf_head = NULL;
2297 	srp->txbuf = NULL;
2298 	srp->pktp = NULL;
2299 }
2300 
2301 /*
2302  * Initialise all transmit, receive, and buffer rings.
2303  */
2304 void
2305 bge_init_rings(bge_t *bgep)
2306 {
2307 	uint32_t ring;
2308 
2309 	BGE_TRACE(("bge_init_rings($%p)", (void *)bgep));
2310 
2311 	/*
2312 	 * Perform one-off initialisation of each ring ...
2313 	 */
2314 	for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
2315 		bge_init_send_ring(bgep, ring);
2316 	for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring)
2317 		bge_init_recv_ring(bgep, ring);
2318 	for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring)
2319 		bge_init_buff_ring(bgep, ring);
2320 }
2321 
2322 /*
2323  * Undo the work of bge_init_rings() above before the memory is freed
2324  */
2325 void
2326 bge_fini_rings(bge_t *bgep)
2327 {
2328 	uint32_t ring;
2329 
2330 	BGE_TRACE(("bge_fini_rings($%p)", (void *)bgep));
2331 
2332 	for (ring = 0; ring < BGE_BUFF_RINGS_MAX; ++ring)
2333 		bge_fini_buff_ring(bgep, ring);
2334 	for (ring = 0; ring < BGE_RECV_RINGS_MAX; ++ring)
2335 		bge_fini_recv_ring(bgep, ring);
2336 	for (ring = 0; ring < BGE_SEND_RINGS_MAX; ++ring)
2337 		bge_fini_send_ring(bgep, ring);
2338 }
2339 
2340 /*
2341  * Called from the bge_m_stop() to free the tx buffers which are
2342  * allocated from the tx process.
2343  */
2344 void
2345 bge_free_txbuf_arrays(send_ring_t *srp)
2346 {
2347 	uint32_t array;
2348 	uint32_t split;
2349 
2350 	ASSERT(mutex_owned(srp->tx_lock));
2351 
2352 	/*
2353 	 * Free the extra tx buffer DMA area
2354 	 */
2355 	for (array = 1; array < srp->tx_array; ++array)
2356 		for (split = 0; split < BGE_SPLIT; ++split)
2357 			bge_free_dma_mem(&srp->buf[array][split]);
2358 
2359 	/*
2360 	 * Restore initial tx buffer numbers
2361 	 */
2362 	srp->tx_array = 1;
2363 	srp->tx_buffers = BGE_SEND_BUF_NUM;
2364 	srp->tx_buffers_low = srp->tx_buffers / 4;
2365 	srp->tx_flow = 0;
2366 	bzero(srp->pktp, BGE_SEND_BUF_MAX * sizeof (*srp->pktp));
2367 }
2368 
2369 /*
2370  * Called from tx process to allocate more tx buffers
2371  */
2372 bge_queue_item_t *
2373 bge_alloc_txbuf_array(bge_t *bgep, send_ring_t *srp)
2374 {
2375 	bge_queue_t *txbuf_queue;
2376 	bge_queue_item_t *txbuf_item_last;
2377 	bge_queue_item_t *txbuf_item;
2378 	bge_queue_item_t *txbuf_item_rtn;
2379 	sw_txbuf_t *txbuf;
2380 	dma_area_t area;
2381 	size_t txbuffsize;
2382 	uint32_t slot;
2383 	uint32_t array;
2384 	uint32_t split;
2385 	uint32_t err;
2386 
2387 	ASSERT(mutex_owned(srp->tx_lock));
2388 
2389 	array = srp->tx_array;
2390 	if (array >= srp->tx_array_max)
2391 		return (NULL);
2392 
2393 	/*
2394 	 * Allocate memory & handles for TX buffers
2395 	 */
2396 	txbuffsize = BGE_SEND_BUF_NUM*bgep->chipid.snd_buff_size;
2397 	ASSERT((txbuffsize % BGE_SPLIT) == 0);
2398 	for (split = 0; split < BGE_SPLIT; ++split) {
2399 		err = bge_alloc_dma_mem(bgep, txbuffsize/BGE_SPLIT,
2400 		    &bge_data_accattr, DDI_DMA_WRITE | BGE_DMA_MODE,
2401 		    &srp->buf[array][split]);
2402 		if (err != DDI_SUCCESS) {
2403 			/* Free the last already allocated OK chunks */
2404 			for (slot = 0; slot <= split; ++slot)
2405 				bge_free_dma_mem(&srp->buf[array][slot]);
2406 			srp->tx_alloc_fail++;
2407 			return (NULL);
2408 		}
2409 	}
2410 
2411 	/*
2412 	 * Chunk tx buffer area
2413 	 */
2414 	txbuf = srp->txbuf + array*BGE_SEND_BUF_NUM;
2415 	for (split = 0; split < BGE_SPLIT; ++split) {
2416 		area = srp->buf[array][split];
2417 		for (slot = 0; slot < BGE_SEND_BUF_NUM/BGE_SPLIT; ++slot) {
2418 			bge_slice_chunk(&txbuf->buf, &area, 1,
2419 			    bgep->chipid.snd_buff_size);
2420 			txbuf++;
2421 		}
2422 	}
2423 
2424 	/*
2425 	 * Add above buffers to the tx buffer pop queue
2426 	 */
2427 	txbuf_item = srp->txbuf_head + array*BGE_SEND_BUF_NUM;
2428 	txbuf = srp->txbuf + array*BGE_SEND_BUF_NUM;
2429 	txbuf_item_last = NULL;
2430 	for (slot = 0; slot < BGE_SEND_BUF_NUM; ++slot) {
2431 		txbuf_item->item = txbuf;
2432 		txbuf_item->next = txbuf_item_last;
2433 		txbuf_item_last = txbuf_item;
2434 		txbuf++;
2435 		txbuf_item++;
2436 	}
2437 	txbuf_item = srp->txbuf_head + array*BGE_SEND_BUF_NUM;
2438 	txbuf_item_rtn = txbuf_item;
2439 	txbuf_item++;
2440 	txbuf_queue = srp->txbuf_pop_queue;
2441 	mutex_enter(txbuf_queue->lock);
2442 	txbuf_item->next = txbuf_queue->head;
2443 	txbuf_queue->head = txbuf_item_last;
2444 	txbuf_queue->count += BGE_SEND_BUF_NUM - 1;
2445 	mutex_exit(txbuf_queue->lock);
2446 
2447 	srp->tx_array++;
2448 	srp->tx_buffers += BGE_SEND_BUF_NUM;
2449 	srp->tx_buffers_low = srp->tx_buffers / 4;
2450 
2451 	return (txbuf_item_rtn);
2452 }
2453 
2454 /*
2455  * This function allocates all the transmit and receive buffers
2456  * and descriptors, in four chunks.
2457  */
2458 int
2459 bge_alloc_bufs(bge_t *bgep)
2460 {
2461 	dma_area_t area;
2462 	size_t rxbuffsize;
2463 	size_t txbuffsize;
2464 	size_t rxbuffdescsize;
2465 	size_t rxdescsize;
2466 	size_t txdescsize;
2467 	uint32_t ring;
2468 	uint32_t rx_rings = bgep->chipid.rx_rings;
2469 	uint32_t tx_rings = bgep->chipid.tx_rings;
2470 	int split;
2471 	int err;
2472 
2473 	BGE_TRACE(("bge_alloc_bufs($%p)",
2474 	    (void *)bgep));
2475 
2476 	rxbuffsize = BGE_STD_SLOTS_USED*bgep->chipid.std_buf_size;
2477 	rxbuffsize += bgep->chipid.jumbo_slots*bgep->chipid.recv_jumbo_size;
2478 	rxbuffsize += BGE_MINI_SLOTS_USED*BGE_MINI_BUFF_SIZE;
2479 
2480 	txbuffsize = BGE_SEND_BUF_NUM*bgep->chipid.snd_buff_size;
2481 	txbuffsize *= tx_rings;
2482 
2483 	rxdescsize = rx_rings*bgep->chipid.recv_slots;
2484 	rxdescsize *= sizeof (bge_rbd_t);
2485 
2486 	rxbuffdescsize = BGE_STD_SLOTS_USED;
2487 	rxbuffdescsize += bgep->chipid.jumbo_slots;
2488 	rxbuffdescsize += BGE_MINI_SLOTS_USED;
2489 	rxbuffdescsize *= sizeof (bge_rbd_t);
2490 
2491 	txdescsize = tx_rings*BGE_SEND_SLOTS_USED;
2492 	txdescsize *= sizeof (bge_sbd_t);
2493 	txdescsize += sizeof (bge_statistics_t);
2494 	txdescsize += sizeof (bge_status_t);
2495 	txdescsize += BGE_STATUS_PADDING;
2496 
2497 	/*
2498 	 * Enable PCI relaxed ordering only for RX/TX data buffers
2499 	 */
2500 	if (bge_relaxed_ordering)
2501 		dma_attr.dma_attr_flags |= DDI_DMA_RELAXED_ORDERING;
2502 
2503 	/*
2504 	 * Allocate memory & handles for RX buffers
2505 	 */
2506 	ASSERT((rxbuffsize % BGE_SPLIT) == 0);
2507 	for (split = 0; split < BGE_SPLIT; ++split) {
2508 		err = bge_alloc_dma_mem(bgep, rxbuffsize/BGE_SPLIT,
2509 		    &bge_data_accattr, DDI_DMA_READ | BGE_DMA_MODE,
2510 		    &bgep->rx_buff[split]);
2511 		if (err != DDI_SUCCESS)
2512 			return (DDI_FAILURE);
2513 	}
2514 
2515 	/*
2516 	 * Allocate memory & handles for TX buffers
2517 	 */
2518 	ASSERT((txbuffsize % BGE_SPLIT) == 0);
2519 	for (split = 0; split < BGE_SPLIT; ++split) {
2520 		err = bge_alloc_dma_mem(bgep, txbuffsize/BGE_SPLIT,
2521 		    &bge_data_accattr, DDI_DMA_WRITE | BGE_DMA_MODE,
2522 		    &bgep->tx_buff[split]);
2523 		if (err != DDI_SUCCESS)
2524 			return (DDI_FAILURE);
2525 	}
2526 
2527 	dma_attr.dma_attr_flags &= ~DDI_DMA_RELAXED_ORDERING;
2528 
2529 	/*
2530 	 * Allocate memory & handles for receive return rings
2531 	 */
2532 	ASSERT((rxdescsize % rx_rings) == 0);
2533 	for (split = 0; split < rx_rings; ++split) {
2534 		err = bge_alloc_dma_mem(bgep, rxdescsize/rx_rings,
2535 		    &bge_desc_accattr, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2536 		    &bgep->rx_desc[split]);
2537 		if (err != DDI_SUCCESS)
2538 			return (DDI_FAILURE);
2539 	}
2540 
2541 	/*
2542 	 * Allocate memory & handles for buffer (producer) descriptor rings
2543 	 */
2544 	err = bge_alloc_dma_mem(bgep, rxbuffdescsize, &bge_desc_accattr,
2545 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT, &bgep->rx_desc[split]);
2546 	if (err != DDI_SUCCESS)
2547 		return (DDI_FAILURE);
2548 
2549 	/*
2550 	 * Allocate memory & handles for TX descriptor rings,
2551 	 * status block, and statistics area
2552 	 */
2553 	err = bge_alloc_dma_mem(bgep, txdescsize, &bge_desc_accattr,
2554 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT, &bgep->tx_desc);
2555 	if (err != DDI_SUCCESS)
2556 		return (DDI_FAILURE);
2557 
2558 	/*
2559 	 * Now carve up each of the allocated areas ...
2560 	 */
2561 	for (split = 0; split < BGE_SPLIT; ++split) {
2562 		area = bgep->rx_buff[split];
2563 		bge_slice_chunk(&bgep->buff[BGE_STD_BUFF_RING].buf[split],
2564 		    &area, BGE_STD_SLOTS_USED/BGE_SPLIT,
2565 		    bgep->chipid.std_buf_size);
2566 		bge_slice_chunk(&bgep->buff[BGE_JUMBO_BUFF_RING].buf[split],
2567 		    &area, bgep->chipid.jumbo_slots/BGE_SPLIT,
2568 		    bgep->chipid.recv_jumbo_size);
2569 		bge_slice_chunk(&bgep->buff[BGE_MINI_BUFF_RING].buf[split],
2570 		    &area, BGE_MINI_SLOTS_USED/BGE_SPLIT,
2571 		    BGE_MINI_BUFF_SIZE);
2572 	}
2573 
2574 	for (split = 0; split < BGE_SPLIT; ++split) {
2575 		area = bgep->tx_buff[split];
2576 		for (ring = 0; ring < tx_rings; ++ring)
2577 			bge_slice_chunk(&bgep->send[ring].buf[0][split],
2578 			    &area, BGE_SEND_BUF_NUM/BGE_SPLIT,
2579 			    bgep->chipid.snd_buff_size);
2580 		for (; ring < BGE_SEND_RINGS_MAX; ++ring)
2581 			bge_slice_chunk(&bgep->send[ring].buf[0][split],
2582 			    &area, 0, bgep->chipid.snd_buff_size);
2583 	}
2584 
2585 	for (ring = 0; ring < rx_rings; ++ring)
2586 		bge_slice_chunk(&bgep->recv[ring].desc, &bgep->rx_desc[ring],
2587 		    bgep->chipid.recv_slots, sizeof (bge_rbd_t));
2588 
2589 	area = bgep->rx_desc[rx_rings];
2590 	for (; ring < BGE_RECV_RINGS_MAX; ++ring)
2591 		bge_slice_chunk(&bgep->recv[ring].desc, &area,
2592 		    0, sizeof (bge_rbd_t));
2593 	bge_slice_chunk(&bgep->buff[BGE_STD_BUFF_RING].desc, &area,
2594 	    BGE_STD_SLOTS_USED, sizeof (bge_rbd_t));
2595 	bge_slice_chunk(&bgep->buff[BGE_JUMBO_BUFF_RING].desc, &area,
2596 	    bgep->chipid.jumbo_slots, sizeof (bge_rbd_t));
2597 	bge_slice_chunk(&bgep->buff[BGE_MINI_BUFF_RING].desc, &area,
2598 	    BGE_MINI_SLOTS_USED, sizeof (bge_rbd_t));
2599 	ASSERT(area.alength == 0);
2600 
2601 	area = bgep->tx_desc;
2602 	for (ring = 0; ring < tx_rings; ++ring)
2603 		bge_slice_chunk(&bgep->send[ring].desc, &area,
2604 		    BGE_SEND_SLOTS_USED, sizeof (bge_sbd_t));
2605 	for (; ring < BGE_SEND_RINGS_MAX; ++ring)
2606 		bge_slice_chunk(&bgep->send[ring].desc, &area,
2607 		    0, sizeof (bge_sbd_t));
2608 	bge_slice_chunk(&bgep->statistics, &area, 1, sizeof (bge_statistics_t));
2609 	bge_slice_chunk(&bgep->status_block, &area, 1, sizeof (bge_status_t));
2610 	ASSERT(area.alength == BGE_STATUS_PADDING);
2611 	DMA_ZERO(bgep->status_block);
2612 
2613 	return (DDI_SUCCESS);
2614 }
2615 
2616 /*
2617  * This routine frees the transmit and receive buffers and descriptors.
2618  * Make sure the chip is stopped before calling it!
2619  */
2620 void
2621 bge_free_bufs(bge_t *bgep)
2622 {
2623 	int split;
2624 
2625 	BGE_TRACE(("bge_free_bufs($%p)",
2626 	    (void *)bgep));
2627 
2628 	bge_free_dma_mem(&bgep->tx_desc);
2629 	for (split = 0; split < BGE_RECV_RINGS_SPLIT; ++split)
2630 		bge_free_dma_mem(&bgep->rx_desc[split]);
2631 	for (split = 0; split < BGE_SPLIT; ++split)
2632 		bge_free_dma_mem(&bgep->tx_buff[split]);
2633 	for (split = 0; split < BGE_SPLIT; ++split)
2634 		bge_free_dma_mem(&bgep->rx_buff[split]);
2635 }
2636 
2637 /*
2638  * Determine (initial) MAC address ("BIA") to use for this interface
2639  */
2640 
2641 static void
2642 bge_find_mac_address(bge_t *bgep, chip_id_t *cidp)
2643 {
2644 	struct ether_addr sysaddr;
2645 	char propbuf[8];		/* "true" or "false", plus NUL	*/
2646 	uchar_t *bytes;
2647 	int *ints;
2648 	uint_t nelts;
2649 	int err;
2650 
2651 	BGE_TRACE(("bge_find_mac_address($%p)",
2652 	    (void *)bgep));
2653 
2654 	BGE_DEBUG(("bge_find_mac_address: hw_mac_addr %012llx, => %s (%sset)",
2655 	    cidp->hw_mac_addr,
2656 	    ether_sprintf((void *)cidp->vendor_addr.addr),
2657 	    cidp->vendor_addr.set ? "" : "not "));
2658 
2659 	/*
2660 	 * The "vendor's factory-set address" may already have
2661 	 * been extracted from the chip, but if the property
2662 	 * "local-mac-address" is set we use that instead.  It
2663 	 * will normally be set by OBP, but it could also be
2664 	 * specified in a .conf file(!)
2665 	 *
2666 	 * There doesn't seem to be a way to define byte-array
2667 	 * properties in a .conf, so we check whether it looks
2668 	 * like an array of 6 ints instead.
2669 	 *
2670 	 * Then, we check whether it looks like an array of 6
2671 	 * bytes (which it should, if OBP set it).  If we can't
2672 	 * make sense of it either way, we'll ignore it.
2673 	 */
2674 	err = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, bgep->devinfo,
2675 	    DDI_PROP_DONTPASS, localmac_propname, &ints, &nelts);
2676 	if (err == DDI_PROP_SUCCESS) {
2677 		if (nelts == ETHERADDRL) {
2678 			while (nelts--)
2679 				cidp->vendor_addr.addr[nelts] = ints[nelts];
2680 			cidp->vendor_addr.set = B_TRUE;
2681 		}
2682 		ddi_prop_free(ints);
2683 	}
2684 
2685 	err = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, bgep->devinfo,
2686 	    DDI_PROP_DONTPASS, localmac_propname, &bytes, &nelts);
2687 	if (err == DDI_PROP_SUCCESS) {
2688 		if (nelts == ETHERADDRL) {
2689 			while (nelts--)
2690 				cidp->vendor_addr.addr[nelts] = bytes[nelts];
2691 			cidp->vendor_addr.set = B_TRUE;
2692 		}
2693 		ddi_prop_free(bytes);
2694 	}
2695 
2696 	BGE_DEBUG(("bge_find_mac_address: +local %s (%sset)",
2697 	    ether_sprintf((void *)cidp->vendor_addr.addr),
2698 	    cidp->vendor_addr.set ? "" : "not "));
2699 
2700 	/*
2701 	 * Look up the OBP property "local-mac-address?".  Note that even
2702 	 * though its value is a string (which should be "true" or "false"),
2703 	 * it can't be decoded by ddi_prop_lookup_string(9F).  So, we zero
2704 	 * the buffer first and then fetch the property as an untyped array;
2705 	 * this may or may not include a final NUL, but since there will
2706 	 * always be one left at the end of the buffer we can now treat it
2707 	 * as a string anyway.
2708 	 */
2709 	nelts = sizeof (propbuf);
2710 	bzero(propbuf, nelts--);
2711 	err = ddi_getlongprop_buf(DDI_DEV_T_ANY, bgep->devinfo,
2712 	    DDI_PROP_CANSLEEP, localmac_boolname, propbuf, (int *)&nelts);
2713 
2714 	/*
2715 	 * Now, if the address still isn't set from the hardware (SEEPROM)
2716 	 * or the OBP or .conf property, OR if the user has foolishly set
2717 	 * 'local-mac-address? = false', use "the system address" instead
2718 	 * (but only if it's non-null i.e. has been set from the IDPROM).
2719 	 */
2720 	if (cidp->vendor_addr.set == B_FALSE || strcmp(propbuf, "false") == 0)
2721 		if (localetheraddr(NULL, &sysaddr) != 0) {
2722 			ethaddr_copy(&sysaddr, cidp->vendor_addr.addr);
2723 			cidp->vendor_addr.set = B_TRUE;
2724 		}
2725 
2726 	BGE_DEBUG(("bge_find_mac_address: +system %s (%sset)",
2727 	    ether_sprintf((void *)cidp->vendor_addr.addr),
2728 	    cidp->vendor_addr.set ? "" : "not "));
2729 
2730 	/*
2731 	 * Finally(!), if there's a valid "mac-address" property (created
2732 	 * if we netbooted from this interface), we must use this instead
2733 	 * of any of the above to ensure that the NFS/install server doesn't
2734 	 * get confused by the address changing as Solaris takes over!
2735 	 */
2736 	err = ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, bgep->devinfo,
2737 	    DDI_PROP_DONTPASS, macaddr_propname, &bytes, &nelts);
2738 	if (err == DDI_PROP_SUCCESS) {
2739 		if (nelts == ETHERADDRL) {
2740 			while (nelts--)
2741 				cidp->vendor_addr.addr[nelts] = bytes[nelts];
2742 			cidp->vendor_addr.set = B_TRUE;
2743 		}
2744 		ddi_prop_free(bytes);
2745 	}
2746 
2747 	BGE_DEBUG(("bge_find_mac_address: =final %s (%sset)",
2748 	    ether_sprintf((void *)cidp->vendor_addr.addr),
2749 	    cidp->vendor_addr.set ? "" : "not "));
2750 }
2751 
2752 
2753 /*ARGSUSED*/
2754 int
2755 bge_check_acc_handle(bge_t *bgep, ddi_acc_handle_t handle)
2756 {
2757 	ddi_fm_error_t de;
2758 
2759 	ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
2760 	ddi_fm_acc_err_clear(handle, DDI_FME_VERSION);
2761 	return (de.fme_status);
2762 }
2763 
2764 /*ARGSUSED*/
2765 int
2766 bge_check_dma_handle(bge_t *bgep, ddi_dma_handle_t handle)
2767 {
2768 	ddi_fm_error_t de;
2769 
2770 	ASSERT(bgep->progress & PROGRESS_BUFS);
2771 	ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
2772 	return (de.fme_status);
2773 }
2774 
2775 /*
2776  * The IO fault service error handling callback function
2777  */
2778 /*ARGSUSED*/
2779 static int
2780 bge_fm_error_cb(dev_info_t *dip, ddi_fm_error_t *err, const void *impl_data)
2781 {
2782 	/*
2783 	 * as the driver can always deal with an error in any dma or
2784 	 * access handle, we can just return the fme_status value.
2785 	 */
2786 	pci_ereport_post(dip, err, NULL);
2787 	return (err->fme_status);
2788 }
2789 
2790 static void
2791 bge_fm_init(bge_t *bgep)
2792 {
2793 	ddi_iblock_cookie_t iblk;
2794 
2795 	/* Only register with IO Fault Services if we have some capability */
2796 	if (bgep->fm_capabilities) {
2797 		bge_reg_accattr.devacc_attr_access = DDI_FLAGERR_ACC;
2798 		bge_desc_accattr.devacc_attr_access = DDI_FLAGERR_ACC;
2799 		dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
2800 
2801 		/* Register capabilities with IO Fault Services */
2802 		ddi_fm_init(bgep->devinfo, &bgep->fm_capabilities, &iblk);
2803 
2804 		/*
2805 		 * Initialize pci ereport capabilities if ereport capable
2806 		 */
2807 		if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities) ||
2808 		    DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
2809 			pci_ereport_setup(bgep->devinfo);
2810 
2811 		/*
2812 		 * Register error callback if error callback capable
2813 		 */
2814 		if (DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
2815 			ddi_fm_handler_register(bgep->devinfo,
2816 			    bge_fm_error_cb, (void*) bgep);
2817 	} else {
2818 		/*
2819 		 * These fields have to be cleared of FMA if there are no
2820 		 * FMA capabilities at runtime.
2821 		 */
2822 		bge_reg_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
2823 		bge_desc_accattr.devacc_attr_access = DDI_DEFAULT_ACC;
2824 		dma_attr.dma_attr_flags = 0;
2825 	}
2826 }
2827 
2828 static void
2829 bge_fm_fini(bge_t *bgep)
2830 {
2831 	/* Only unregister FMA capabilities if we registered some */
2832 	if (bgep->fm_capabilities) {
2833 
2834 		/*
2835 		 * Release any resources allocated by pci_ereport_setup()
2836 		 */
2837 		if (DDI_FM_EREPORT_CAP(bgep->fm_capabilities) ||
2838 		    DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
2839 			pci_ereport_teardown(bgep->devinfo);
2840 
2841 		/*
2842 		 * Un-register error callback if error callback capable
2843 		 */
2844 		if (DDI_FM_ERRCB_CAP(bgep->fm_capabilities))
2845 			ddi_fm_handler_unregister(bgep->devinfo);
2846 
2847 		/* Unregister from IO Fault Services */
2848 		ddi_fm_fini(bgep->devinfo);
2849 	}
2850 }
2851 
2852 static void
2853 #ifdef BGE_IPMI_ASF
2854 bge_unattach(bge_t *bgep, uint_t asf_mode)
2855 #else
2856 bge_unattach(bge_t *bgep)
2857 #endif
2858 {
2859 	BGE_TRACE(("bge_unattach($%p)",
2860 		(void *)bgep));
2861 
2862 	/*
2863 	 * Flag that no more activity may be initiated
2864 	 */
2865 	bgep->progress &= ~PROGRESS_READY;
2866 
2867 	/*
2868 	 * Quiesce the PHY and MAC (leave it reset but still powered).
2869 	 * Clean up and free all BGE data structures
2870 	 */
2871 	if (bgep->periodic_id != NULL) {
2872 		ddi_periodic_delete(bgep->periodic_id);
2873 		bgep->periodic_id = NULL;
2874 	}
2875 	if (bgep->progress & PROGRESS_KSTATS)
2876 		bge_fini_kstats(bgep);
2877 	if (bgep->progress & PROGRESS_PHY)
2878 		bge_phys_reset(bgep);
2879 	if (bgep->progress & PROGRESS_HWINT) {
2880 		mutex_enter(bgep->genlock);
2881 #ifdef BGE_IPMI_ASF
2882 		if (bge_chip_reset(bgep, B_FALSE, asf_mode) != DDI_SUCCESS)
2883 #else
2884 		if (bge_chip_reset(bgep, B_FALSE) != DDI_SUCCESS)
2885 #endif
2886 			ddi_fm_service_impact(bgep->devinfo,
2887 			    DDI_SERVICE_UNAFFECTED);
2888 #ifdef BGE_IPMI_ASF
2889 		if (bgep->asf_enabled) {
2890 			/*
2891 			 * This register has been overlaid. We restore its
2892 			 * initial value here.
2893 			 */
2894 			bge_nic_put32(bgep, BGE_NIC_DATA_SIG_ADDR,
2895 			    BGE_NIC_DATA_SIG);
2896 		}
2897 #endif
2898 		if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK)
2899 			ddi_fm_service_impact(bgep->devinfo,
2900 			    DDI_SERVICE_UNAFFECTED);
2901 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
2902 			ddi_fm_service_impact(bgep->devinfo,
2903 			    DDI_SERVICE_UNAFFECTED);
2904 		mutex_exit(bgep->genlock);
2905 	}
2906 	if (bgep->progress & PROGRESS_INTR) {
2907 		bge_intr_disable(bgep);
2908 		bge_fini_rings(bgep);
2909 	}
2910 	if (bgep->progress & PROGRESS_HWINT) {
2911 		bge_rem_intrs(bgep);
2912 		rw_destroy(bgep->errlock);
2913 		mutex_destroy(bgep->softintrlock);
2914 		mutex_destroy(bgep->genlock);
2915 	}
2916 	if (bgep->progress & PROGRESS_FACTOTUM)
2917 		ddi_remove_softintr(bgep->factotum_id);
2918 	if (bgep->progress & PROGRESS_RESCHED)
2919 		ddi_remove_softintr(bgep->drain_id);
2920 	if (bgep->progress & PROGRESS_BUFS)
2921 		bge_free_bufs(bgep);
2922 	if (bgep->progress & PROGRESS_REGS)
2923 		ddi_regs_map_free(&bgep->io_handle);
2924 	if (bgep->progress & PROGRESS_CFG)
2925 		pci_config_teardown(&bgep->cfg_handle);
2926 
2927 	bge_fm_fini(bgep);
2928 
2929 	ddi_remove_minor_node(bgep->devinfo, NULL);
2930 	kmem_free(bgep->pstats, sizeof (bge_statistics_reg_t));
2931 	kmem_free(bgep, sizeof (*bgep));
2932 }
2933 
2934 static int
2935 bge_resume(dev_info_t *devinfo)
2936 {
2937 	bge_t *bgep;				/* Our private data	*/
2938 	chip_id_t *cidp;
2939 	chip_id_t chipid;
2940 
2941 	bgep = ddi_get_driver_private(devinfo);
2942 	if (bgep == NULL)
2943 		return (DDI_FAILURE);
2944 
2945 	/*
2946 	 * Refuse to resume if the data structures aren't consistent
2947 	 */
2948 	if (bgep->devinfo != devinfo)
2949 		return (DDI_FAILURE);
2950 
2951 #ifdef BGE_IPMI_ASF
2952 	/*
2953 	 * Power management hasn't been supported in BGE now. If you
2954 	 * want to implement it, please add the ASF/IPMI related
2955 	 * code here.
2956 	 */
2957 
2958 #endif
2959 
2960 	/*
2961 	 * Read chip ID & set up config space command register(s)
2962 	 * Refuse to resume if the chip has changed its identity!
2963 	 */
2964 	cidp = &bgep->chipid;
2965 	mutex_enter(bgep->genlock);
2966 	bge_chip_cfg_init(bgep, &chipid, B_FALSE);
2967 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
2968 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
2969 		mutex_exit(bgep->genlock);
2970 		return (DDI_FAILURE);
2971 	}
2972 	mutex_exit(bgep->genlock);
2973 	if (chipid.vendor != cidp->vendor)
2974 		return (DDI_FAILURE);
2975 	if (chipid.device != cidp->device)
2976 		return (DDI_FAILURE);
2977 	if (chipid.revision != cidp->revision)
2978 		return (DDI_FAILURE);
2979 	if (chipid.asic_rev != cidp->asic_rev)
2980 		return (DDI_FAILURE);
2981 
2982 	/*
2983 	 * All OK, reinitialise h/w & kick off GLD scheduling
2984 	 */
2985 	mutex_enter(bgep->genlock);
2986 	if (bge_restart(bgep, B_TRUE) != DDI_SUCCESS) {
2987 		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
2988 		(void) bge_check_acc_handle(bgep, bgep->io_handle);
2989 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
2990 		mutex_exit(bgep->genlock);
2991 		return (DDI_FAILURE);
2992 	}
2993 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
2994 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
2995 		mutex_exit(bgep->genlock);
2996 		return (DDI_FAILURE);
2997 	}
2998 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
2999 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3000 		mutex_exit(bgep->genlock);
3001 		return (DDI_FAILURE);
3002 	}
3003 	mutex_exit(bgep->genlock);
3004 	return (DDI_SUCCESS);
3005 }
3006 
3007 /*
3008  * attach(9E) -- Attach a device to the system
3009  *
3010  * Called once for each board successfully probed.
3011  */
3012 static int
3013 bge_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
3014 {
3015 	bge_t *bgep;				/* Our private data	*/
3016 	mac_register_t *macp;
3017 	chip_id_t *cidp;
3018 	caddr_t regs;
3019 	int instance;
3020 	int err;
3021 	int intr_types;
3022 #ifdef BGE_IPMI_ASF
3023 	uint32_t mhcrValue;
3024 #ifdef __sparc
3025 	uint16_t value16;
3026 #endif
3027 #ifdef BGE_NETCONSOLE
3028 	int retval;
3029 #endif
3030 #endif
3031 
3032 	instance = ddi_get_instance(devinfo);
3033 
3034 	BGE_GTRACE(("bge_attach($%p, %d) instance %d",
3035 	    (void *)devinfo, cmd, instance));
3036 	BGE_BRKPT(NULL, "bge_attach");
3037 
3038 	switch (cmd) {
3039 	default:
3040 		return (DDI_FAILURE);
3041 
3042 	case DDI_RESUME:
3043 		return (bge_resume(devinfo));
3044 
3045 	case DDI_ATTACH:
3046 		break;
3047 	}
3048 
3049 	bgep = kmem_zalloc(sizeof (*bgep), KM_SLEEP);
3050 	bgep->pstats = kmem_zalloc(sizeof (bge_statistics_reg_t), KM_SLEEP);
3051 	ddi_set_driver_private(devinfo, bgep);
3052 	bgep->bge_guard = BGE_GUARD;
3053 	bgep->devinfo = devinfo;
3054 	bgep->param_drain_max = 64;
3055 	bgep->param_msi_cnt = 0;
3056 	bgep->param_loop_mode = 0;
3057 
3058 	/*
3059 	 * Initialize more fields in BGE private data
3060 	 */
3061 	bgep->debug = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3062 	    DDI_PROP_DONTPASS, debug_propname, bge_debug);
3063 	(void) snprintf(bgep->ifname, sizeof (bgep->ifname), "%s%d",
3064 	    BGE_DRIVER_NAME, instance);
3065 
3066 	/*
3067 	 * Initialize for fma support
3068 	 */
3069 	bgep->fm_capabilities = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3070 	    DDI_PROP_DONTPASS, fm_cap,
3071 	    DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
3072 	    DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
3073 	BGE_DEBUG(("bgep->fm_capabilities = %d", bgep->fm_capabilities));
3074 	bge_fm_init(bgep);
3075 
3076 	/*
3077 	 * Look up the IOMMU's page size for DVMA mappings (must be
3078 	 * a power of 2) and convert to a mask.  This can be used to
3079 	 * determine whether a message buffer crosses a page boundary.
3080 	 * Note: in 2s complement binary notation, if X is a power of
3081 	 * 2, then -X has the representation "11...1100...00".
3082 	 */
3083 	bgep->pagemask = dvma_pagesize(devinfo);
3084 	ASSERT(ddi_ffs(bgep->pagemask) == ddi_fls(bgep->pagemask));
3085 	bgep->pagemask = -bgep->pagemask;
3086 
3087 	/*
3088 	 * Map config space registers
3089 	 * Read chip ID & set up config space command register(s)
3090 	 *
3091 	 * Note: this leaves the chip accessible by Memory Space
3092 	 * accesses, but with interrupts and Bus Mastering off.
3093 	 * This should ensure that nothing untoward will happen
3094 	 * if it has been left active by the (net-)bootloader.
3095 	 * We'll re-enable Bus Mastering once we've reset the chip,
3096 	 * and allow interrupts only when everything else is set up.
3097 	 */
3098 	err = pci_config_setup(devinfo, &bgep->cfg_handle);
3099 #ifdef BGE_IPMI_ASF
3100 #ifdef __sparc
3101 	value16 = pci_config_get16(bgep->cfg_handle, PCI_CONF_COMM);
3102 	value16 = value16 | (PCI_COMM_MAE | PCI_COMM_ME);
3103 	pci_config_put16(bgep->cfg_handle, PCI_CONF_COMM, value16);
3104 	mhcrValue = MHCR_ENABLE_INDIRECT_ACCESS |
3105 	    MHCR_ENABLE_TAGGED_STATUS_MODE |
3106 	    MHCR_MASK_INTERRUPT_MODE |
3107 	    MHCR_MASK_PCI_INT_OUTPUT |
3108 	    MHCR_CLEAR_INTERRUPT_INTA |
3109 	    MHCR_ENABLE_ENDIAN_WORD_SWAP |
3110 	    MHCR_ENABLE_ENDIAN_BYTE_SWAP;
3111 	pci_config_put32(bgep->cfg_handle, PCI_CONF_BGE_MHCR, mhcrValue);
3112 	bge_ind_put32(bgep, MEMORY_ARBITER_MODE_REG,
3113 	    bge_ind_get32(bgep, MEMORY_ARBITER_MODE_REG) |
3114 	    MEMORY_ARBITER_ENABLE);
3115 #else
3116 	mhcrValue = pci_config_get32(bgep->cfg_handle, PCI_CONF_BGE_MHCR);
3117 #endif
3118 	if (mhcrValue & MHCR_ENABLE_ENDIAN_WORD_SWAP) {
3119 		bgep->asf_wordswapped = B_TRUE;
3120 	} else {
3121 		bgep->asf_wordswapped = B_FALSE;
3122 	}
3123 	bge_asf_get_config(bgep);
3124 #endif
3125 	if (err != DDI_SUCCESS) {
3126 		bge_problem(bgep, "pci_config_setup() failed");
3127 		goto attach_fail;
3128 	}
3129 	bgep->progress |= PROGRESS_CFG;
3130 	cidp = &bgep->chipid;
3131 	bzero(cidp, sizeof (*cidp));
3132 	bge_chip_cfg_init(bgep, cidp, B_FALSE);
3133 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
3134 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3135 		goto attach_fail;
3136 	}
3137 
3138 #ifdef BGE_IPMI_ASF
3139 	if (DEVICE_5721_SERIES_CHIPSETS(bgep) ||
3140 	    DEVICE_5714_SERIES_CHIPSETS(bgep)) {
3141 		bgep->asf_newhandshake = B_TRUE;
3142 	} else {
3143 		bgep->asf_newhandshake = B_FALSE;
3144 	}
3145 #endif
3146 
3147 	/*
3148 	 * Update those parts of the chip ID derived from volatile
3149 	 * registers with the values seen by OBP (in case the chip
3150 	 * has been reset externally and therefore lost them).
3151 	 */
3152 	cidp->subven = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3153 	    DDI_PROP_DONTPASS, subven_propname, cidp->subven);
3154 	cidp->subdev = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3155 	    DDI_PROP_DONTPASS, subdev_propname, cidp->subdev);
3156 	cidp->clsize = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3157 	    DDI_PROP_DONTPASS, clsize_propname, cidp->clsize);
3158 	cidp->latency = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3159 	    DDI_PROP_DONTPASS, latency_propname, cidp->latency);
3160 	cidp->rx_rings = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3161 	    DDI_PROP_DONTPASS, rxrings_propname, cidp->rx_rings);
3162 	cidp->tx_rings = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3163 	    DDI_PROP_DONTPASS, txrings_propname, cidp->tx_rings);
3164 
3165 	if (bge_jumbo_enable == B_TRUE) {
3166 		cidp->default_mtu = ddi_prop_get_int(DDI_DEV_T_ANY, devinfo,
3167 		    DDI_PROP_DONTPASS, default_mtu, BGE_DEFAULT_MTU);
3168 		if ((cidp->default_mtu < BGE_DEFAULT_MTU)||
3169 		    (cidp->default_mtu > BGE_MAXIMUM_MTU)) {
3170 			cidp->default_mtu = BGE_DEFAULT_MTU;
3171 		}
3172 	}
3173 	/*
3174 	 * Map operating registers
3175 	 */
3176 	err = ddi_regs_map_setup(devinfo, BGE_PCI_OPREGS_RNUMBER,
3177 	    &regs, 0, 0, &bge_reg_accattr, &bgep->io_handle);
3178 	if (err != DDI_SUCCESS) {
3179 		bge_problem(bgep, "ddi_regs_map_setup() failed");
3180 		goto attach_fail;
3181 	}
3182 	bgep->io_regs = regs;
3183 	bgep->progress |= PROGRESS_REGS;
3184 
3185 	/*
3186 	 * Characterise the device, so we know its requirements.
3187 	 * Then allocate the appropriate TX and RX descriptors & buffers.
3188 	 */
3189 	if (bge_chip_id_init(bgep) == EIO) {
3190 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3191 		goto attach_fail;
3192 	}
3193 
3194 
3195 	err = bge_alloc_bufs(bgep);
3196 	if (err != DDI_SUCCESS) {
3197 		bge_problem(bgep, "DMA buffer allocation failed");
3198 		goto attach_fail;
3199 	}
3200 	bgep->progress |= PROGRESS_BUFS;
3201 
3202 	/*
3203 	 * Add the softint handlers:
3204 	 *
3205 	 * Both of these handlers are used to avoid restrictions on the
3206 	 * context and/or mutexes required for some operations.  In
3207 	 * particular, the hardware interrupt handler and its subfunctions
3208 	 * can detect a number of conditions that we don't want to handle
3209 	 * in that context or with that set of mutexes held.  So, these
3210 	 * softints are triggered instead:
3211 	 *
3212 	 * the <resched> softint is triggered if we have previously
3213 	 * had to refuse to send a packet because of resource shortage
3214 	 * (we've run out of transmit buffers), but the send completion
3215 	 * interrupt handler has now detected that more buffers have
3216 	 * become available.
3217 	 *
3218 	 * the <factotum> is triggered if the h/w interrupt handler
3219 	 * sees the <link state changed> or <error> bits in the status
3220 	 * block.  It's also triggered periodically to poll the link
3221 	 * state, just in case we aren't getting link status change
3222 	 * interrupts ...
3223 	 */
3224 	err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &bgep->drain_id,
3225 	    NULL, NULL, bge_send_drain, (caddr_t)bgep);
3226 	if (err != DDI_SUCCESS) {
3227 		bge_problem(bgep, "ddi_add_softintr() failed");
3228 		goto attach_fail;
3229 	}
3230 	bgep->progress |= PROGRESS_RESCHED;
3231 	err = ddi_add_softintr(devinfo, DDI_SOFTINT_LOW, &bgep->factotum_id,
3232 	    NULL, NULL, bge_chip_factotum, (caddr_t)bgep);
3233 	if (err != DDI_SUCCESS) {
3234 		bge_problem(bgep, "ddi_add_softintr() failed");
3235 		goto attach_fail;
3236 	}
3237 	bgep->progress |= PROGRESS_FACTOTUM;
3238 
3239 	/* Get supported interrupt types */
3240 	if (ddi_intr_get_supported_types(devinfo, &intr_types) != DDI_SUCCESS) {
3241 		bge_error(bgep, "ddi_intr_get_supported_types failed\n");
3242 
3243 		goto attach_fail;
3244 	}
3245 
3246 	BGE_DEBUG(("%s: ddi_intr_get_supported_types() returned: %x",
3247 	    bgep->ifname, intr_types));
3248 
3249 	if ((intr_types & DDI_INTR_TYPE_MSI) && bgep->chipid.msi_enabled) {
3250 		if (bge_add_intrs(bgep, DDI_INTR_TYPE_MSI) != DDI_SUCCESS) {
3251 			bge_error(bgep, "MSI registration failed, "
3252 			    "trying FIXED interrupt type\n");
3253 		} else {
3254 			BGE_DEBUG(("%s: Using MSI interrupt type",
3255 			    bgep->ifname));
3256 			bgep->intr_type = DDI_INTR_TYPE_MSI;
3257 			bgep->progress |= PROGRESS_HWINT;
3258 		}
3259 	}
3260 
3261 	if (!(bgep->progress & PROGRESS_HWINT) &&
3262 	    (intr_types & DDI_INTR_TYPE_FIXED)) {
3263 		if (bge_add_intrs(bgep, DDI_INTR_TYPE_FIXED) != DDI_SUCCESS) {
3264 			bge_error(bgep, "FIXED interrupt "
3265 			    "registration failed\n");
3266 			goto attach_fail;
3267 		}
3268 
3269 		BGE_DEBUG(("%s: Using FIXED interrupt type", bgep->ifname));
3270 
3271 		bgep->intr_type = DDI_INTR_TYPE_FIXED;
3272 		bgep->progress |= PROGRESS_HWINT;
3273 	}
3274 
3275 	if (!(bgep->progress & PROGRESS_HWINT)) {
3276 		bge_error(bgep, "No interrupts registered\n");
3277 		goto attach_fail;
3278 	}
3279 
3280 	/*
3281 	 * Note that interrupts are not enabled yet as
3282 	 * mutex locks are not initialized. Initialize mutex locks.
3283 	 */
3284 	mutex_init(bgep->genlock, NULL, MUTEX_DRIVER,
3285 	    DDI_INTR_PRI(bgep->intr_pri));
3286 	mutex_init(bgep->softintrlock, NULL, MUTEX_DRIVER,
3287 	    DDI_INTR_PRI(bgep->intr_pri));
3288 	rw_init(bgep->errlock, NULL, RW_DRIVER,
3289 	    DDI_INTR_PRI(bgep->intr_pri));
3290 
3291 	/*
3292 	 * Initialize rings.
3293 	 */
3294 	bge_init_rings(bgep);
3295 
3296 	/*
3297 	 * Now that mutex locks are initialized, enable interrupts.
3298 	 */
3299 	bge_intr_enable(bgep);
3300 	bgep->progress |= PROGRESS_INTR;
3301 
3302 	/*
3303 	 * Initialise link state variables
3304 	 * Stop, reset & reinitialise the chip.
3305 	 * Initialise the (internal) PHY.
3306 	 */
3307 	bgep->link_state = LINK_STATE_UNKNOWN;
3308 
3309 	mutex_enter(bgep->genlock);
3310 
3311 	/*
3312 	 * Reset chip & rings to initial state; also reset address
3313 	 * filtering, promiscuity, loopback mode.
3314 	 */
3315 #ifdef BGE_IPMI_ASF
3316 #ifdef BGE_NETCONSOLE
3317 	if (bge_reset(bgep, ASF_MODE_INIT) != DDI_SUCCESS) {
3318 #else
3319 	if (bge_reset(bgep, ASF_MODE_SHUTDOWN) != DDI_SUCCESS) {
3320 #endif
3321 #else
3322 	if (bge_reset(bgep) != DDI_SUCCESS) {
3323 #endif
3324 		(void) bge_check_acc_handle(bgep, bgep->cfg_handle);
3325 		(void) bge_check_acc_handle(bgep, bgep->io_handle);
3326 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3327 		mutex_exit(bgep->genlock);
3328 		goto attach_fail;
3329 	}
3330 
3331 #ifdef BGE_IPMI_ASF
3332 	if (bgep->asf_enabled) {
3333 		bgep->asf_status = ASF_STAT_RUN_INIT;
3334 	}
3335 #endif
3336 
3337 	bzero(bgep->mcast_hash, sizeof (bgep->mcast_hash));
3338 	bzero(bgep->mcast_refs, sizeof (bgep->mcast_refs));
3339 	bgep->promisc = B_FALSE;
3340 	bgep->param_loop_mode = BGE_LOOP_NONE;
3341 	if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK) {
3342 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3343 		mutex_exit(bgep->genlock);
3344 		goto attach_fail;
3345 	}
3346 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
3347 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3348 		mutex_exit(bgep->genlock);
3349 		goto attach_fail;
3350 	}
3351 
3352 	mutex_exit(bgep->genlock);
3353 
3354 	if (bge_phys_init(bgep) == EIO) {
3355 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
3356 		goto attach_fail;
3357 	}
3358 	bgep->progress |= PROGRESS_PHY;
3359 
3360 	/*
3361 	 * initialize NDD-tweakable parameters
3362 	 */
3363 	if (bge_nd_init(bgep)) {
3364 		bge_problem(bgep, "bge_nd_init() failed");
3365 		goto attach_fail;
3366 	}
3367 	bgep->progress |= PROGRESS_NDD;
3368 
3369 	/*
3370 	 * Create & initialise named kstats
3371 	 */
3372 	bge_init_kstats(bgep, instance);
3373 	bgep->progress |= PROGRESS_KSTATS;
3374 
3375 	/*
3376 	 * Determine whether to override the chip's own MAC address
3377 	 */
3378 	bge_find_mac_address(bgep, cidp);
3379 	ethaddr_copy(cidp->vendor_addr.addr, bgep->curr_addr[0].addr);
3380 	bgep->curr_addr[0].set = B_TRUE;
3381 
3382 	bgep->unicst_addr_total = MAC_ADDRESS_REGS_MAX;
3383 	/*
3384 	 * Address available is one less than MAX
3385 	 * as primary address is not advertised
3386 	 * as a multiple MAC address.
3387 	 */
3388 	bgep->unicst_addr_avail = MAC_ADDRESS_REGS_MAX - 1;
3389 
3390 	if ((macp = mac_alloc(MAC_VERSION)) == NULL)
3391 		goto attach_fail;
3392 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
3393 	macp->m_driver = bgep;
3394 	macp->m_dip = devinfo;
3395 	macp->m_src_addr = bgep->curr_addr[0].addr;
3396 	macp->m_callbacks = &bge_m_callbacks;
3397 	macp->m_min_sdu = 0;
3398 	macp->m_max_sdu = cidp->ethmax_size - sizeof (struct ether_header);
3399 	macp->m_margin = VLAN_TAGSZ;
3400 	macp->m_priv_props = bge_priv_prop;
3401 	macp->m_priv_prop_count = BGE_MAX_PRIV_PROPS;
3402 
3403 	/*
3404 	 * Finally, we're ready to register ourselves with the MAC layer
3405 	 * interface; if this succeeds, we're all ready to start()
3406 	 */
3407 	err = mac_register(macp, &bgep->mh);
3408 	mac_free(macp);
3409 	if (err != 0)
3410 		goto attach_fail;
3411 
3412 	/*
3413 	 * Register a periodical handler.
3414 	 * bge_chip_cyclic() is invoked in kernel context.
3415 	 */
3416 	bgep->periodic_id = ddi_periodic_add(bge_chip_cyclic, bgep,
3417 	    BGE_CYCLIC_PERIOD, DDI_IPL_0);
3418 
3419 	bgep->progress |= PROGRESS_READY;
3420 	ASSERT(bgep->bge_guard == BGE_GUARD);
3421 #ifdef BGE_IPMI_ASF
3422 #ifdef BGE_NETCONSOLE
3423 	if (bgep->asf_enabled) {
3424 		mutex_enter(bgep->genlock);
3425 		retval = bge_chip_start(bgep, B_TRUE);
3426 		mutex_exit(bgep->genlock);
3427 		if (retval != DDI_SUCCESS)
3428 			goto attach_fail;
3429 	}
3430 #endif
3431 #endif
3432 
3433 	ddi_report_dev(devinfo);
3434 	return (DDI_SUCCESS);
3435 
3436 attach_fail:
3437 #ifdef BGE_IPMI_ASF
3438 	bge_unattach(bgep, ASF_MODE_SHUTDOWN);
3439 #else
3440 	bge_unattach(bgep);
3441 #endif
3442 	return (DDI_FAILURE);
3443 }
3444 
3445 /*
3446  *	bge_suspend() -- suspend transmit/receive for powerdown
3447  */
3448 static int
3449 bge_suspend(bge_t *bgep)
3450 {
3451 	/*
3452 	 * Stop processing and idle (powerdown) the PHY ...
3453 	 */
3454 	mutex_enter(bgep->genlock);
3455 #ifdef BGE_IPMI_ASF
3456 	/*
3457 	 * Power management hasn't been supported in BGE now. If you
3458 	 * want to implement it, please add the ASF/IPMI related
3459 	 * code here.
3460 	 */
3461 #endif
3462 	bge_stop(bgep);
3463 	if (bge_phys_idle(bgep) != DDI_SUCCESS) {
3464 		(void) bge_check_acc_handle(bgep, bgep->io_handle);
3465 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
3466 		mutex_exit(bgep->genlock);
3467 		return (DDI_FAILURE);
3468 	}
3469 	if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK) {
3470 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
3471 		mutex_exit(bgep->genlock);
3472 		return (DDI_FAILURE);
3473 	}
3474 	mutex_exit(bgep->genlock);
3475 
3476 	return (DDI_SUCCESS);
3477 }
3478 
3479 /*
3480  * quiesce(9E) entry point.
3481  *
3482  * This function is called when the system is single-threaded at high
3483  * PIL with preemption disabled. Therefore, this function must not be
3484  * blocked.
3485  *
3486  * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
3487  * DDI_FAILURE indicates an error condition and should almost never happen.
3488  */
3489 #ifdef	__sparc
3490 #define	bge_quiesce	ddi_quiesce_not_supported
3491 #else
3492 static int
3493 bge_quiesce(dev_info_t *devinfo)
3494 {
3495 	bge_t *bgep = ddi_get_driver_private(devinfo);
3496 
3497 	if (bgep == NULL)
3498 		return (DDI_FAILURE);
3499 
3500 	if (bgep->intr_type == DDI_INTR_TYPE_FIXED) {
3501 		bge_reg_set32(bgep, PCI_CONF_BGE_MHCR,
3502 		    MHCR_MASK_PCI_INT_OUTPUT);
3503 	} else {
3504 		bge_reg_clr32(bgep, MSI_MODE_REG, MSI_MSI_ENABLE);
3505 	}
3506 
3507 	/* Stop the chip */
3508 	bge_chip_stop_nonblocking(bgep);
3509 
3510 	return (DDI_SUCCESS);
3511 }
3512 #endif
3513 
3514 /*
3515  * detach(9E) -- Detach a device from the system
3516  */
3517 static int
3518 bge_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
3519 {
3520 	bge_t *bgep;
3521 #ifdef BGE_IPMI_ASF
3522 	uint_t asf_mode;
3523 	asf_mode = ASF_MODE_NONE;
3524 #endif
3525 
3526 	BGE_GTRACE(("bge_detach($%p, %d)", (void *)devinfo, cmd));
3527 
3528 	bgep = ddi_get_driver_private(devinfo);
3529 
3530 	switch (cmd) {
3531 	default:
3532 		return (DDI_FAILURE);
3533 
3534 	case DDI_SUSPEND:
3535 		return (bge_suspend(bgep));
3536 
3537 	case DDI_DETACH:
3538 		break;
3539 	}
3540 
3541 #ifdef BGE_IPMI_ASF
3542 	mutex_enter(bgep->genlock);
3543 	if (bgep->asf_enabled && ((bgep->asf_status == ASF_STAT_RUN) ||
3544 	    (bgep->asf_status == ASF_STAT_RUN_INIT))) {
3545 
3546 		bge_asf_update_status(bgep);
3547 		if (bgep->asf_status == ASF_STAT_RUN) {
3548 			bge_asf_stop_timer(bgep);
3549 		}
3550 		bgep->asf_status = ASF_STAT_STOP;
3551 
3552 		bge_asf_pre_reset_operations(bgep, BGE_SHUTDOWN_RESET);
3553 
3554 		if (bgep->asf_pseudostop) {
3555 			bge_chip_stop(bgep, B_FALSE);
3556 			bgep->bge_mac_state = BGE_MAC_STOPPED;
3557 			bgep->asf_pseudostop = B_FALSE;
3558 		}
3559 
3560 		asf_mode = ASF_MODE_POST_SHUTDOWN;
3561 
3562 		if (bge_check_acc_handle(bgep, bgep->cfg_handle) != DDI_FM_OK)
3563 			ddi_fm_service_impact(bgep->devinfo,
3564 			    DDI_SERVICE_UNAFFECTED);
3565 		if (bge_check_acc_handle(bgep, bgep->io_handle) != DDI_FM_OK)
3566 			ddi_fm_service_impact(bgep->devinfo,
3567 			    DDI_SERVICE_UNAFFECTED);
3568 	}
3569 	mutex_exit(bgep->genlock);
3570 #endif
3571 
3572 	/*
3573 	 * Unregister from the GLD subsystem.  This can fail, in
3574 	 * particular if there are DLPI style-2 streams still open -
3575 	 * in which case we just return failure without shutting
3576 	 * down chip operations.
3577 	 */
3578 	if (mac_unregister(bgep->mh) != 0)
3579 		return (DDI_FAILURE);
3580 
3581 	/*
3582 	 * All activity stopped, so we can clean up & exit
3583 	 */
3584 #ifdef BGE_IPMI_ASF
3585 	bge_unattach(bgep, asf_mode);
3586 #else
3587 	bge_unattach(bgep);
3588 #endif
3589 	return (DDI_SUCCESS);
3590 }
3591 
3592 
3593 /*
3594  * ========== Module Loading Data & Entry Points ==========
3595  */
3596 
3597 #undef	BGE_DBG
3598 #define	BGE_DBG		BGE_DBG_INIT	/* debug flag for this code	*/
3599 
3600 DDI_DEFINE_STREAM_OPS(bge_dev_ops,
3601 	nulldev,	/* identify */
3602 	nulldev,	/* probe */
3603 	bge_attach,	/* attach */
3604 	bge_detach,	/* detach */
3605 	nodev,		/* reset */
3606 	NULL,		/* cb_ops */
3607 	D_MP,		/* bus_ops */
3608 	NULL,		/* power */
3609 	bge_quiesce	/* quiesce */
3610 );
3611 
3612 static struct modldrv bge_modldrv = {
3613 	&mod_driverops,		/* Type of module.  This one is a driver */
3614 	bge_ident,		/* short description */
3615 	&bge_dev_ops		/* driver specific ops */
3616 };
3617 
3618 static struct modlinkage modlinkage = {
3619 	MODREV_1, (void *)&bge_modldrv, NULL
3620 };
3621 
3622 
3623 int
3624 _info(struct modinfo *modinfop)
3625 {
3626 	return (mod_info(&modlinkage, modinfop));
3627 }
3628 
3629 int
3630 _init(void)
3631 {
3632 	int status;
3633 
3634 	mac_init_ops(&bge_dev_ops, "bge");
3635 	status = mod_install(&modlinkage);
3636 	if (status == DDI_SUCCESS)
3637 		mutex_init(bge_log_mutex, NULL, MUTEX_DRIVER, NULL);
3638 	else
3639 		mac_fini_ops(&bge_dev_ops);
3640 	return (status);
3641 }
3642 
3643 int
3644 _fini(void)
3645 {
3646 	int status;
3647 
3648 	status = mod_remove(&modlinkage);
3649 	if (status == DDI_SUCCESS) {
3650 		mac_fini_ops(&bge_dev_ops);
3651 		mutex_destroy(bge_log_mutex);
3652 	}
3653 	return (status);
3654 }
3655 
3656 
3657 /*
3658  * bge_add_intrs:
3659  *
3660  * Register FIXED or MSI interrupts.
3661  */
3662 static int
3663 bge_add_intrs(bge_t *bgep, int	intr_type)
3664 {
3665 	dev_info_t	*dip = bgep->devinfo;
3666 	int		avail, actual, intr_size, count = 0;
3667 	int		i, flag, ret;
3668 
3669 	BGE_DEBUG(("bge_add_intrs($%p, 0x%x)", (void *)bgep, intr_type));
3670 
3671 	/* Get number of interrupts */
3672 	ret = ddi_intr_get_nintrs(dip, intr_type, &count);
3673 	if ((ret != DDI_SUCCESS) || (count == 0)) {
3674 		bge_error(bgep, "ddi_intr_get_nintrs() failure, ret: %d, "
3675 		    "count: %d", ret, count);
3676 
3677 		return (DDI_FAILURE);
3678 	}
3679 
3680 	/* Get number of available interrupts */
3681 	ret = ddi_intr_get_navail(dip, intr_type, &avail);
3682 	if ((ret != DDI_SUCCESS) || (avail == 0)) {
3683 		bge_error(bgep, "ddi_intr_get_navail() failure, "
3684 		    "ret: %d, avail: %d\n", ret, avail);
3685 
3686 		return (DDI_FAILURE);
3687 	}
3688 
3689 	if (avail < count) {
3690 		BGE_DEBUG(("%s: nintrs() returned %d, navail returned %d",
3691 		    bgep->ifname, count, avail));
3692 	}
3693 
3694 	/*
3695 	 * BGE hardware generates only single MSI even though it claims
3696 	 * to support multiple MSIs. So, hard code MSI count value to 1.
3697 	 */
3698 	if (intr_type == DDI_INTR_TYPE_MSI) {
3699 		count = 1;
3700 		flag = DDI_INTR_ALLOC_STRICT;
3701 	} else {
3702 		flag = DDI_INTR_ALLOC_NORMAL;
3703 	}
3704 
3705 	/* Allocate an array of interrupt handles */
3706 	intr_size = count * sizeof (ddi_intr_handle_t);
3707 	bgep->htable = kmem_alloc(intr_size, KM_SLEEP);
3708 
3709 	/* Call ddi_intr_alloc() */
3710 	ret = ddi_intr_alloc(dip, bgep->htable, intr_type, 0,
3711 	    count, &actual, flag);
3712 
3713 	if ((ret != DDI_SUCCESS) || (actual == 0)) {
3714 		bge_error(bgep, "ddi_intr_alloc() failed %d\n", ret);
3715 
3716 		kmem_free(bgep->htable, intr_size);
3717 		return (DDI_FAILURE);
3718 	}
3719 
3720 	if (actual < count) {
3721 		BGE_DEBUG(("%s: Requested: %d, Received: %d",
3722 		    bgep->ifname, count, actual));
3723 	}
3724 
3725 	bgep->intr_cnt = actual;
3726 
3727 	/*
3728 	 * Get priority for first msi, assume remaining are all the same
3729 	 */
3730 	if ((ret = ddi_intr_get_pri(bgep->htable[0], &bgep->intr_pri)) !=
3731 	    DDI_SUCCESS) {
3732 		bge_error(bgep, "ddi_intr_get_pri() failed %d\n", ret);
3733 
3734 		/* Free already allocated intr */
3735 		for (i = 0; i < actual; i++) {
3736 			(void) ddi_intr_free(bgep->htable[i]);
3737 		}
3738 
3739 		kmem_free(bgep->htable, intr_size);
3740 		return (DDI_FAILURE);
3741 	}
3742 
3743 	/* Call ddi_intr_add_handler() */
3744 	for (i = 0; i < actual; i++) {
3745 		if ((ret = ddi_intr_add_handler(bgep->htable[i], bge_intr,
3746 		    (caddr_t)bgep, (caddr_t)(uintptr_t)i)) != DDI_SUCCESS) {
3747 			bge_error(bgep, "ddi_intr_add_handler() "
3748 			    "failed %d\n", ret);
3749 
3750 			/* Free already allocated intr */
3751 			for (i = 0; i < actual; i++) {
3752 				(void) ddi_intr_free(bgep->htable[i]);
3753 			}
3754 
3755 			kmem_free(bgep->htable, intr_size);
3756 			return (DDI_FAILURE);
3757 		}
3758 	}
3759 
3760 	if ((ret = ddi_intr_get_cap(bgep->htable[0], &bgep->intr_cap))
3761 	    != DDI_SUCCESS) {
3762 		bge_error(bgep, "ddi_intr_get_cap() failed %d\n", ret);
3763 
3764 		for (i = 0; i < actual; i++) {
3765 			(void) ddi_intr_remove_handler(bgep->htable[i]);
3766 			(void) ddi_intr_free(bgep->htable[i]);
3767 		}
3768 
3769 		kmem_free(bgep->htable, intr_size);
3770 		return (DDI_FAILURE);
3771 	}
3772 
3773 	return (DDI_SUCCESS);
3774 }
3775 
3776 /*
3777  * bge_rem_intrs:
3778  *
3779  * Unregister FIXED or MSI interrupts
3780  */
3781 static void
3782 bge_rem_intrs(bge_t *bgep)
3783 {
3784 	int	i;
3785 
3786 	BGE_DEBUG(("bge_rem_intrs($%p)", (void *)bgep));
3787 
3788 	/* Call ddi_intr_remove_handler() */
3789 	for (i = 0; i < bgep->intr_cnt; i++) {
3790 		(void) ddi_intr_remove_handler(bgep->htable[i]);
3791 		(void) ddi_intr_free(bgep->htable[i]);
3792 	}
3793 
3794 	kmem_free(bgep->htable, bgep->intr_cnt * sizeof (ddi_intr_handle_t));
3795 }
3796 
3797 
3798 void
3799 bge_intr_enable(bge_t *bgep)
3800 {
3801 	int i;
3802 
3803 	if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) {
3804 		/* Call ddi_intr_block_enable() for MSI interrupts */
3805 		(void) ddi_intr_block_enable(bgep->htable, bgep->intr_cnt);
3806 	} else {
3807 		/* Call ddi_intr_enable for MSI or FIXED interrupts */
3808 		for (i = 0; i < bgep->intr_cnt; i++) {
3809 			(void) ddi_intr_enable(bgep->htable[i]);
3810 		}
3811 	}
3812 }
3813 
3814 
3815 void
3816 bge_intr_disable(bge_t *bgep)
3817 {
3818 	int i;
3819 
3820 	if (bgep->intr_cap & DDI_INTR_FLAG_BLOCK) {
3821 		/* Call ddi_intr_block_disable() */
3822 		(void) ddi_intr_block_disable(bgep->htable, bgep->intr_cnt);
3823 	} else {
3824 		for (i = 0; i < bgep->intr_cnt; i++) {
3825 			(void) ddi_intr_disable(bgep->htable[i]);
3826 		}
3827 	}
3828 }
3829 
3830 int
3831 bge_reprogram(bge_t *bgep)
3832 {
3833 	int status = 0;
3834 
3835 	ASSERT(mutex_owned(bgep->genlock));
3836 
3837 	if (bge_phys_update(bgep) != DDI_SUCCESS) {
3838 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
3839 		status = IOC_INVAL;
3840 	}
3841 #ifdef BGE_IPMI_ASF
3842 	if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
3843 #else
3844 	if (bge_chip_sync(bgep) == DDI_FAILURE) {
3845 #endif
3846 		ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
3847 		status = IOC_INVAL;
3848 	}
3849 	if (bgep->intr_type == DDI_INTR_TYPE_MSI)
3850 		bge_chip_msi_trig(bgep);
3851 	return (status);
3852 }
3853