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