xref: /titanic_44/usr/src/uts/common/io/bfe/bfe.c (revision 5fd03bc0f2e00e7ba02316c2e08f45d52aab15db)
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) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 #include <sys/stream.h>
26 #include <sys/strsun.h>
27 #include <sys/stat.h>
28 #include <sys/pci.h>
29 #include <sys/modctl.h>
30 #include <sys/kstat.h>
31 #include <sys/ethernet.h>
32 #include <sys/devops.h>
33 #include <sys/debug.h>
34 #include <sys/conf.h>
35 #include <sys/sysmacros.h>
36 #include <sys/dditypes.h>
37 #include <sys/ddi.h>
38 #include <sys/sunddi.h>
39 #include <sys/miiregs.h>
40 #include <sys/byteorder.h>
41 #include <sys/cyclic.h>
42 #include <sys/note.h>
43 #include <sys/crc32.h>
44 #include <sys/mac_provider.h>
45 #include <sys/mac_ether.h>
46 #include <sys/vlan.h>
47 #include <sys/errno.h>
48 #include <sys/sdt.h>
49 #include <sys/strsubr.h>
50 
51 #include "bfe.h"
52 #include "bfe_hw.h"
53 
54 
55 /*
56  * Broadcom BCM4401 chipsets use two rings :
57  *
58  * - One TX : For sending packets down the wire.
59  * - One RX : For receving packets.
60  *
61  * Each ring can have any number of descriptors (configured during attach).
62  * As of now we configure only 128 descriptor per ring (TX/RX). Each descriptor
63  * has address (desc_addr) and control (desc_ctl) which holds a DMA buffer for
64  * the packet and control information (like start/end of frame or end of table).
65  * The descriptor table is allocated first and then a DMA buffer (for a packet)
66  * is allocated and linked to each descriptor.
67  *
68  * Each descriptor entry is bfe_desc_t structure in bfe. During TX/RX
69  * interrupt, the stat register will point to current descriptor being
70  * processed.
71  *
72  * Here's an example of TX and RX ring :
73  *
74  * TX:
75  *
76  *   Base of the descriptor table is programmed using BFE_DMATX_CTRL control
77  *   register. Each 'addr' points to DMA buffer (or packet data buffer) to
78  *   be transmitted and 'ctl' has the length of the packet (usually MTU).
79  *
80  *  ----------------------|
81  *  | addr |Descriptor 0  |
82  *  | ctl  |              |
83  *  ----------------------|
84  *  | addr |Descriptor 1  |    SOF (start of the frame)
85  *  | ctl  |              |
86  *  ----------------------|
87  *  | ...  |Descriptor... |    EOF (end of the frame)
88  *  | ...  |              |
89  *  ----------------------|
90  *  | addr |Descritor 127 |
91  *  | ctl  | EOT          |    EOT (End of Table)
92  *  ----------------------|
93  *
94  * 'r_curr_desc'  : pointer to current descriptor which can be used to transmit
95  *                  a packet.
96  * 'r_avail_desc' : decremented whenever a packet is being sent.
97  * 'r_cons_desc'  : incremented whenever a packet is sent down the wire and
98  *                  notified by an interrupt to bfe driver.
99  *
100  * RX:
101  *
102  *   Base of the descriptor table is programmed using BFE_DMARX_CTRL control
103  *   register. Each 'addr' points to DMA buffer (or packet data buffer). 'ctl'
104  *   contains the size of the DMA buffer and all the DMA buffers are
105  *   pre-allocated during attach and hence the maxmium size of the packet is
106  *   also known (r_buf_len from the bfe_rint_t structure). During RX interrupt
107  *   the packet length is embedded in bfe_header_t which is added by the
108  *   chip in the beginning of the packet.
109  *
110  *  ----------------------|
111  *  | addr |Descriptor 0  |
112  *  | ctl  |              |
113  *  ----------------------|
114  *  | addr |Descriptor 1  |
115  *  | ctl  |              |
116  *  ----------------------|
117  *  | ...  |Descriptor... |
118  *  | ...  |              |
119  *  ----------------------|
120  *  | addr |Descriptor 127|
121  *  | ctl  | EOT          |    EOT (End of Table)
122  *  ----------------------|
123  *
124  * 'r_curr_desc'  : pointer to current descriptor while receving a packet.
125  *
126  */
127 
128 #define	MODULE_NAME	"bfe"
129 
130 /*
131  * Used for checking PHY (link state, speed)
132  */
133 #define	BFE_TIMEOUT_INTERVAL	(1000 * 1000 * 1000)
134 
135 
136 /*
137  * Chip restart action and reason for restart
138  */
139 #define	BFE_ACTION_RESTART		0x1	/* For restarting the chip */
140 #define	BFE_ACTION_RESTART_SETPROP	0x2	/* restart due to setprop */
141 #define	BFE_ACTION_RESTART_FAULT	0x4	/* restart due to fault */
142 #define	BFE_ACTION_RESTART_PKT		0x8	/* restart due to pkt timeout */
143 
144 static	char	bfe_ident[] = "bfe driver for Broadcom BCM4401 chipsets";
145 
146 /*
147  * Function Prototypes for bfe driver.
148  */
149 static	int	bfe_check_link(bfe_t *);
150 static	void	bfe_report_link(bfe_t *);
151 static	void	bfe_chip_halt(bfe_t *);
152 static	void	bfe_chip_reset(bfe_t *);
153 static	void	bfe_tx_desc_init(bfe_ring_t *);
154 static	void	bfe_rx_desc_init(bfe_ring_t *);
155 static	void	bfe_set_rx_mode(bfe_t *);
156 static	void	bfe_enable_chip_intrs(bfe_t *);
157 static	void	bfe_chip_restart(bfe_t *);
158 static	void	bfe_init_vars(bfe_t *);
159 static	void	bfe_clear_stats(bfe_t *);
160 static	void	bfe_gather_stats(bfe_t *);
161 static	void	bfe_error(dev_info_t *, char *, ...);
162 static	int	bfe_mac_getprop(void *, const char *, mac_prop_id_t, uint_t,
163     void *);
164 static	int	bfe_mac_setprop(void *, const char *, mac_prop_id_t, uint_t,
165     const void *);
166 static	int	bfe_tx_reclaim(bfe_ring_t *);
167 int	bfe_mac_set_ether_addr(void *, const uint8_t *);
168 
169 
170 /*
171  * Macros for ddi_dma_sync().
172  */
173 #define	SYNC_DESC(r, s, l, d)	\
174 	(void) ddi_dma_sync(r->r_desc_dma_handle, \
175 	    (off_t)(s * sizeof (bfe_desc_t)), \
176 	    (size_t)(l * sizeof (bfe_desc_t)), \
177 	    d)
178 
179 #define	SYNC_BUF(r, s, b, l, d) \
180 	(void) ddi_dma_sync(r->r_buf_dma[s].handle, \
181 	    (off_t)(b), (size_t)(l), d)
182 
183 /*
184  * Supported Broadcom BCM4401 Cards.
185  */
186 static bfe_cards_t bfe_cards[] = {
187 	{ 0x14e4, 0x170c, "BCM4401 100Base-TX"},
188 };
189 
190 
191 /*
192  * DMA attributes for device registers, packet data (buffer) and
193  * descriptor table.
194  */
195 static struct ddi_device_acc_attr bfe_dev_attr = {
196 	DDI_DEVICE_ATTR_V0,
197 	DDI_STRUCTURE_LE_ACC,
198 	DDI_STRICTORDER_ACC
199 };
200 
201 static struct ddi_device_acc_attr bfe_buf_attr = {
202 	DDI_DEVICE_ATTR_V0,
203 	DDI_NEVERSWAP_ACC,	/* native endianness */
204 	DDI_STRICTORDER_ACC
205 };
206 
207 static ddi_dma_attr_t bfe_dma_attr_buf = {
208 	DMA_ATTR_V0,		/* dma_attr_version */
209 	0,			/* dma_attr_addr_lo */
210 	BFE_PCI_DMA - 1,	/* dma_attr_addr_hi */
211 	0x1fff,			/* dma_attr_count_max */
212 	8,			/* dma_attr_align */
213 	0,			/* dma_attr_burstsizes */
214 	1,			/* dma_attr_minxfer */
215 	0x1fff,			/* dma_attr_maxxfer */
216 	BFE_PCI_DMA - 1,	/* dma_attr_seg */
217 	1,			/* dma_attr_sgllen */
218 	1,			/* dma_attr_granular */
219 	0			/* dma_attr_flags */
220 };
221 
222 static ddi_dma_attr_t bfe_dma_attr_desc = {
223 	DMA_ATTR_V0,		/* dma_attr_version */
224 	0,			/* dma_attr_addr_lo */
225 	BFE_PCI_DMA - 1,	/* dma_attr_addr_hi */
226 	BFE_PCI_DMA - 1,	/* dma_attr_count_max */
227 	BFE_DESC_ALIGN,		/* dma_attr_align */
228 	0,			/* dma_attr_burstsizes */
229 	1,			/* dma_attr_minxfer */
230 	BFE_PCI_DMA - 1,	/* dma_attr_maxxfer */
231 	BFE_PCI_DMA - 1,	/* dma_attr_seg */
232 	1,			/* dma_attr_sgllen */
233 	1,			/* dma_attr_granular */
234 	0			/* dma_attr_flags */
235 };
236 
237 /*
238  * Ethernet broadcast addresses.
239  */
240 static uchar_t bfe_broadcast[ETHERADDRL] = {
241 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff
242 };
243 
244 #define	ASSERT_ALL_LOCKS(bfe) {	\
245 	ASSERT(mutex_owned(&bfe->bfe_tx_ring.r_lock));	\
246 	ASSERT(rw_write_held(&bfe->bfe_rwlock));	\
247 }
248 
249 /*
250  * Debugging and error reproting code.
251  */
252 static void
253 bfe_error(dev_info_t *dip, char *fmt, ...)
254 {
255 	va_list ap;
256 	char	buf[256];
257 
258 	va_start(ap, fmt);
259 	(void) vsnprintf(buf, sizeof (buf), fmt, ap);
260 	va_end(ap);
261 
262 	if (dip) {
263 		cmn_err(CE_WARN, "%s%d: %s",
264 		    ddi_driver_name(dip), ddi_get_instance(dip), buf);
265 	} else {
266 		cmn_err(CE_WARN, "bfe: %s", buf);
267 	}
268 }
269 
270 /*
271  * Grabs all necessary locks to block any other operation on the chip.
272  */
273 static void
274 bfe_grab_locks(bfe_t *bfe)
275 {
276 	bfe_ring_t *tx = &bfe->bfe_tx_ring;
277 
278 	/*
279 	 * Grab all the locks.
280 	 * - bfe_rwlock : locks down whole chip including RX.
281 	 * - tx's r_lock : locks down only TX side.
282 	 */
283 	rw_enter(&bfe->bfe_rwlock, RW_WRITER);
284 	mutex_enter(&tx->r_lock);
285 
286 	/*
287 	 * Note that we don't use RX's r_lock.
288 	 */
289 }
290 
291 /*
292  * Release lock on chip/drver.
293  */
294 static void
295 bfe_release_locks(bfe_t *bfe)
296 {
297 	bfe_ring_t *tx = &bfe->bfe_tx_ring;
298 
299 	/*
300 	 * Release all the locks in the order in which they were grabbed.
301 	 */
302 	mutex_exit(&tx->r_lock);
303 	rw_exit(&bfe->bfe_rwlock);
304 }
305 
306 
307 /*
308  * It's used to make sure that the write to device register was successful.
309  */
310 static int
311 bfe_wait_bit(bfe_t *bfe, uint32_t reg, uint32_t bit,
312     ulong_t t, const int clear)
313 {
314 	ulong_t i;
315 	uint32_t v;
316 
317 	for (i = 0; i < t; i++) {
318 		v = INL(bfe, reg);
319 
320 		if (clear && !(v & bit))
321 			break;
322 
323 		if (!clear && (v & bit))
324 			break;
325 
326 		drv_usecwait(10);
327 	}
328 
329 	/* if device still didn't see the value */
330 	if (i == t)
331 		return (-1);
332 
333 	return (0);
334 }
335 
336 /*
337  * PHY functions (read, write, stop, reset and startup)
338  */
339 static int
340 bfe_read_phy(bfe_t *bfe, uint32_t reg)
341 {
342 	OUTL(bfe, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII);
343 	OUTL(bfe, BFE_MDIO_DATA, (BFE_MDIO_SB_START |
344 	    (BFE_MDIO_OP_READ << BFE_MDIO_OP_SHIFT) |
345 	    (bfe->bfe_phy_addr << BFE_MDIO_PMD_SHIFT) |
346 	    (reg << BFE_MDIO_RA_SHIFT) |
347 	    (BFE_MDIO_TA_VALID << BFE_MDIO_TA_SHIFT)));
348 
349 	(void) bfe_wait_bit(bfe, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII, 10, 0);
350 
351 	return ((INL(bfe, BFE_MDIO_DATA) & BFE_MDIO_DATA_DATA));
352 }
353 
354 static void
355 bfe_write_phy(bfe_t *bfe, uint32_t reg, uint32_t val)
356 {
357 	OUTL(bfe, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII);
358 	OUTL(bfe,  BFE_MDIO_DATA, (BFE_MDIO_SB_START |
359 	    (BFE_MDIO_OP_WRITE << BFE_MDIO_OP_SHIFT) |
360 	    (bfe->bfe_phy_addr << BFE_MDIO_PMD_SHIFT) |
361 	    (reg << BFE_MDIO_RA_SHIFT) |
362 	    (BFE_MDIO_TA_VALID << BFE_MDIO_TA_SHIFT) |
363 	    (val & BFE_MDIO_DATA_DATA)));
364 
365 	(void) bfe_wait_bit(bfe, BFE_EMAC_ISTAT, BFE_EMAC_INT_MII, 10, 0);
366 }
367 
368 /*
369  * It resets the PHY layer.
370  */
371 static int
372 bfe_reset_phy(bfe_t *bfe)
373 {
374 	uint32_t i;
375 
376 	bfe_write_phy(bfe, MII_CONTROL, MII_CONTROL_RESET);
377 	drv_usecwait(100);
378 	for (i = 0; i < 10; i++) {
379 		if (bfe_read_phy(bfe, MII_CONTROL) &
380 		    MII_CONTROL_RESET) {
381 			drv_usecwait(500);
382 			continue;
383 		}
384 
385 		break;
386 	}
387 
388 	if (i == 10) {
389 		bfe_error(bfe->bfe_dip, "Timeout waiting for PHY to reset");
390 		bfe->bfe_phy_state = BFE_PHY_RESET_TIMEOUT;
391 		return (BFE_FAILURE);
392 	}
393 
394 	bfe->bfe_phy_state = BFE_PHY_RESET_DONE;
395 
396 	return (BFE_SUCCESS);
397 }
398 
399 /*
400  * Make sure timer function is out of our way and especially during
401  * detach.
402  */
403 static void
404 bfe_stop_timer(bfe_t *bfe)
405 {
406 	if (bfe->bfe_periodic_id) {
407 		ddi_periodic_delete(bfe->bfe_periodic_id);
408 		bfe->bfe_periodic_id = NULL;
409 	}
410 }
411 
412 /*
413  * Stops the PHY
414  */
415 static void
416 bfe_stop_phy(bfe_t *bfe)
417 {
418 	bfe_write_phy(bfe, MII_CONTROL, MII_CONTROL_PWRDN |
419 	    MII_CONTROL_ISOLATE);
420 
421 	bfe->bfe_chip.link = LINK_STATE_UNKNOWN;
422 	bfe->bfe_chip.speed = 0;
423 	bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
424 
425 	bfe->bfe_phy_state = BFE_PHY_STOPPED;
426 
427 	/*
428 	 * Report the link status to MAC layer.
429 	 */
430 	if (bfe->bfe_machdl != NULL)
431 		(void) bfe_report_link(bfe);
432 }
433 
434 static int
435 bfe_probe_phy(bfe_t *bfe)
436 {
437 	int phy;
438 	uint32_t status;
439 
440 	if (bfe->bfe_phy_addr) {
441 		status = bfe_read_phy(bfe, MII_STATUS);
442 		if (status != 0xffff && status != 0) {
443 			bfe_write_phy(bfe, MII_CONTROL, 0);
444 			return (BFE_SUCCESS);
445 		}
446 	}
447 
448 	for (phy = 0; phy < 32; phy++) {
449 		bfe->bfe_phy_addr = phy;
450 		status = bfe_read_phy(bfe, MII_STATUS);
451 		if (status != 0xffff && status != 0) {
452 			bfe_write_phy(bfe, MII_CONTROL, 0);
453 			return (BFE_SUCCESS);
454 		}
455 	}
456 
457 	return (BFE_FAILURE);
458 }
459 
460 /*
461  * This timeout function fires at BFE_TIMEOUT_INTERVAL to check the link
462  * status.
463  */
464 static void
465 bfe_timeout(void *arg)
466 {
467 	bfe_t *bfe = (bfe_t *)arg;
468 	int resched = 0;
469 
470 	/*
471 	 * We don't grab any lock because bfe can't go away.
472 	 * untimeout() will wait for this timeout instance to complete.
473 	 */
474 	if (bfe->bfe_chip_action & BFE_ACTION_RESTART) {
475 		/*
476 		 * Restart the chip.
477 		 */
478 		bfe_grab_locks(bfe);
479 		bfe_chip_restart(bfe);
480 		bfe->bfe_chip_action &= ~BFE_ACTION_RESTART;
481 		bfe->bfe_chip_action &= ~BFE_ACTION_RESTART_FAULT;
482 		bfe->bfe_chip_action &= ~BFE_ACTION_RESTART_PKT;
483 		bfe_release_locks(bfe);
484 		mac_tx_update(bfe->bfe_machdl);
485 		/* Restart will register a new timeout */
486 		return;
487 	}
488 
489 	rw_enter(&bfe->bfe_rwlock, RW_READER);
490 
491 	if (bfe->bfe_chip_state == BFE_CHIP_ACTIVE) {
492 		hrtime_t hr;
493 
494 		hr = gethrtime();
495 		if (bfe->bfe_tx_stall_time != 0 &&
496 		    hr > bfe->bfe_tx_stall_time) {
497 			DTRACE_PROBE2(chip__restart, int, bfe->bfe_unit,
498 			    char *, "pkt timeout");
499 			bfe->bfe_chip_action |=
500 			    (BFE_ACTION_RESTART | BFE_ACTION_RESTART_PKT);
501 			bfe->bfe_tx_stall_time = 0;
502 		}
503 	}
504 
505 	if (bfe->bfe_phy_state == BFE_PHY_STARTED) {
506 		/*
507 		 * Report the link status to MAC layer if link status changed.
508 		 */
509 		if (bfe_check_link(bfe)) {
510 			bfe_report_link(bfe);
511 			if (bfe->bfe_chip.link == LINK_STATE_UP) {
512 				uint32_t val, flow;
513 
514 				val = INL(bfe, BFE_TX_CTRL);
515 				val &= ~BFE_TX_DUPLEX;
516 				if (bfe->bfe_chip.duplex == LINK_DUPLEX_FULL) {
517 					val |= BFE_TX_DUPLEX;
518 					flow = INL(bfe, BFE_RXCONF);
519 					flow &= ~BFE_RXCONF_FLOW;
520 					OUTL(bfe, BFE_RXCONF, flow);
521 
522 					flow = INL(bfe, BFE_MAC_FLOW);
523 					flow &= ~(BFE_FLOW_RX_HIWAT);
524 					OUTL(bfe, BFE_MAC_FLOW, flow);
525 				}
526 
527 				resched = 1;
528 
529 				OUTL(bfe, BFE_TX_CTRL, val);
530 				DTRACE_PROBE1(link__up,
531 				    int, bfe->bfe_unit);
532 			}
533 		}
534 	}
535 
536 	rw_exit(&bfe->bfe_rwlock);
537 
538 	if (resched)
539 		mac_tx_update(bfe->bfe_machdl);
540 }
541 
542 /*
543  * Starts PHY layer.
544  */
545 static int
546 bfe_startup_phy(bfe_t *bfe)
547 {
548 	uint16_t bmsr, bmcr, anar;
549 	int	prog, s;
550 	int phyid1, phyid2;
551 
552 	if (bfe_probe_phy(bfe) == BFE_FAILURE) {
553 		bfe->bfe_phy_state = BFE_PHY_NOTFOUND;
554 		return (BFE_FAILURE);
555 	}
556 
557 	(void) bfe_reset_phy(bfe);
558 
559 	phyid1 = bfe_read_phy(bfe, MII_PHYIDH);
560 	phyid2 = bfe_read_phy(bfe, MII_PHYIDL);
561 	bfe->bfe_phy_id = (phyid1 << 16) | phyid2;
562 
563 	bmsr = bfe_read_phy(bfe, MII_STATUS);
564 	anar = bfe_read_phy(bfe, MII_AN_ADVERT);
565 
566 again:
567 	anar &= ~(MII_ABILITY_100BASE_T4 |
568 	    MII_ABILITY_100BASE_TX_FD | MII_ABILITY_100BASE_TX |
569 	    MII_ABILITY_10BASE_T_FD | MII_ABILITY_10BASE_T);
570 
571 	/*
572 	 * Supported hardware modes are in bmsr.
573 	 */
574 	bfe->bfe_chip.bmsr = bmsr;
575 
576 	/*
577 	 * Assume no capabilities are supported in the hardware.
578 	 */
579 	bfe->bfe_cap_aneg = bfe->bfe_cap_100T4 =
580 	    bfe->bfe_cap_100fdx = bfe->bfe_cap_100hdx =
581 	    bfe->bfe_cap_10fdx = bfe->bfe_cap_10hdx = 0;
582 
583 	/*
584 	 * Assume property is set.
585 	 */
586 	s = 1;
587 	if (!(bfe->bfe_chip_action & BFE_ACTION_RESTART_SETPROP)) {
588 		/*
589 		 * Property is not set which means bfe_mac_setprop()
590 		 * is not called on us.
591 		 */
592 		s = 0;
593 	}
594 
595 	bmcr = prog = 0;
596 
597 	if (bmsr & MII_STATUS_100_BASEX_FD) {
598 		bfe->bfe_cap_100fdx = 1;
599 		if (s == 0) {
600 			anar |= MII_ABILITY_100BASE_TX_FD;
601 			bfe->bfe_adv_100fdx = 1;
602 			prog++;
603 		} else if (bfe->bfe_adv_100fdx) {
604 			anar |= MII_ABILITY_100BASE_TX_FD;
605 			prog++;
606 		}
607 	}
608 
609 	if (bmsr & MII_STATUS_100_BASE_T4) {
610 		bfe->bfe_cap_100T4 = 1;
611 		if (s == 0) {
612 			anar |= MII_ABILITY_100BASE_T4;
613 			bfe->bfe_adv_100T4 = 1;
614 			prog++;
615 		} else if (bfe->bfe_adv_100T4) {
616 			anar |= MII_ABILITY_100BASE_T4;
617 			prog++;
618 		}
619 	}
620 
621 	if (bmsr & MII_STATUS_100_BASEX) {
622 		bfe->bfe_cap_100hdx = 1;
623 		if (s == 0) {
624 			anar |= MII_ABILITY_100BASE_TX;
625 			bfe->bfe_adv_100hdx = 1;
626 			prog++;
627 		} else if (bfe->bfe_adv_100hdx) {
628 			anar |= MII_ABILITY_100BASE_TX;
629 			prog++;
630 		}
631 	}
632 
633 	if (bmsr & MII_STATUS_10_FD) {
634 		bfe->bfe_cap_10fdx = 1;
635 		if (s == 0) {
636 			anar |= MII_ABILITY_10BASE_T_FD;
637 			bfe->bfe_adv_10fdx = 1;
638 			prog++;
639 		} else if (bfe->bfe_adv_10fdx) {
640 			anar |= MII_ABILITY_10BASE_T_FD;
641 			prog++;
642 		}
643 	}
644 
645 	if (bmsr & MII_STATUS_10) {
646 		bfe->bfe_cap_10hdx = 1;
647 		if (s == 0) {
648 			anar |= MII_ABILITY_10BASE_T;
649 			bfe->bfe_adv_10hdx = 1;
650 			prog++;
651 		} else if (bfe->bfe_adv_10hdx) {
652 			anar |= MII_ABILITY_10BASE_T;
653 			prog++;
654 		}
655 	}
656 
657 	if (bmsr & MII_STATUS_CANAUTONEG) {
658 		bfe->bfe_cap_aneg = 1;
659 		if (s == 0) {
660 			bfe->bfe_adv_aneg = 1;
661 		}
662 	}
663 
664 	if (prog == 0) {
665 		if (s == 0) {
666 			bfe_error(bfe->bfe_dip,
667 			    "No valid link mode selected. Powering down PHY");
668 			bfe_stop_phy(bfe);
669 			bfe_report_link(bfe);
670 			return (BFE_FAILURE);
671 		}
672 
673 		/*
674 		 * If property is set then user would have goofed up. So we
675 		 * go back to default properties.
676 		 */
677 		bfe->bfe_chip_action &= ~BFE_ACTION_RESTART_SETPROP;
678 		goto again;
679 	}
680 
681 	if (bfe->bfe_adv_aneg && (bmsr & MII_STATUS_CANAUTONEG)) {
682 		bmcr = (MII_CONTROL_ANE | MII_CONTROL_RSAN);
683 	} else {
684 		if (bfe->bfe_adv_100fdx)
685 			bmcr = (MII_CONTROL_100MB | MII_CONTROL_FDUPLEX);
686 		else if (bfe->bfe_adv_100hdx)
687 			bmcr = MII_CONTROL_100MB;
688 		else if (bfe->bfe_adv_10fdx)
689 			bmcr = MII_CONTROL_FDUPLEX;
690 		else
691 			bmcr = 0;		/* 10HDX */
692 	}
693 
694 	if (prog)
695 		bfe_write_phy(bfe, MII_AN_ADVERT, anar);
696 
697 	if (bmcr)
698 		bfe_write_phy(bfe, MII_CONTROL, bmcr);
699 
700 	bfe->bfe_mii_anar = anar;
701 	bfe->bfe_mii_bmcr = bmcr;
702 	bfe->bfe_phy_state = BFE_PHY_STARTED;
703 
704 	if (bfe->bfe_periodic_id == NULL) {
705 		bfe->bfe_periodic_id = ddi_periodic_add(bfe_timeout,
706 		    (void *)bfe, BFE_TIMEOUT_INTERVAL, DDI_IPL_0);
707 
708 		DTRACE_PROBE1(first__timeout, int, bfe->bfe_unit);
709 	}
710 
711 	DTRACE_PROBE4(phy_started, int, bfe->bfe_unit,
712 	    int, bmsr, int, bmcr, int, anar);
713 
714 	return (BFE_SUCCESS);
715 }
716 
717 /*
718  * Reports link status back to MAC Layer.
719  */
720 static void
721 bfe_report_link(bfe_t *bfe)
722 {
723 	mac_link_update(bfe->bfe_machdl, bfe->bfe_chip.link);
724 }
725 
726 /*
727  * Reads PHY/MII registers and get the link status for us.
728  */
729 static int
730 bfe_check_link(bfe_t *bfe)
731 {
732 	uint16_t bmsr, bmcr, anar, anlpar;
733 	int speed, duplex, link;
734 
735 	speed = bfe->bfe_chip.speed;
736 	duplex = bfe->bfe_chip.duplex;
737 	link = bfe->bfe_chip.link;
738 
739 	bmsr = bfe_read_phy(bfe, MII_STATUS);
740 	bfe->bfe_mii_bmsr = bmsr;
741 
742 	bmcr = bfe_read_phy(bfe, MII_CONTROL);
743 
744 	anar = bfe_read_phy(bfe, MII_AN_ADVERT);
745 	bfe->bfe_mii_anar = anar;
746 
747 	anlpar = bfe_read_phy(bfe, MII_AN_LPABLE);
748 	bfe->bfe_mii_anlpar = anlpar;
749 
750 	bfe->bfe_mii_exp = bfe_read_phy(bfe, MII_AN_EXPANSION);
751 
752 	/*
753 	 * If exp register is not present in PHY.
754 	 */
755 	if (bfe->bfe_mii_exp == 0xffff) {
756 		bfe->bfe_mii_exp = 0;
757 	}
758 
759 	if ((bmsr & MII_STATUS_LINKUP) == 0) {
760 		bfe->bfe_chip.link = LINK_STATE_DOWN;
761 		bfe->bfe_chip.speed = 0;
762 		bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
763 		goto done;
764 	}
765 
766 	bfe->bfe_chip.link = LINK_STATE_UP;
767 
768 	if (!(bmcr & MII_CONTROL_ANE)) {
769 		/* Forced mode */
770 		if (bmcr & MII_CONTROL_100MB)
771 			bfe->bfe_chip.speed = 100000000;
772 		else
773 			bfe->bfe_chip.speed = 10000000;
774 
775 		if (bmcr & MII_CONTROL_FDUPLEX)
776 			bfe->bfe_chip.duplex = LINK_DUPLEX_FULL;
777 		else
778 			bfe->bfe_chip.duplex = LINK_DUPLEX_HALF;
779 
780 	} else if ((!(bmsr & MII_STATUS_CANAUTONEG)) ||
781 	    (!(bmsr & MII_STATUS_ANDONE))) {
782 		bfe->bfe_chip.speed = 0;
783 		bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
784 	} else if (anar & anlpar & MII_ABILITY_100BASE_TX_FD) {
785 		bfe->bfe_chip.speed = 100000000;
786 		bfe->bfe_chip.duplex = LINK_DUPLEX_FULL;
787 	} else if (anar & anlpar & MII_ABILITY_100BASE_T4) {
788 		bfe->bfe_chip.speed = 100000000;
789 		bfe->bfe_chip.duplex = LINK_DUPLEX_HALF;
790 	} else if (anar & anlpar & MII_ABILITY_100BASE_TX) {
791 		bfe->bfe_chip.speed = 100000000;
792 		bfe->bfe_chip.duplex = LINK_DUPLEX_HALF;
793 	} else if (anar & anlpar & MII_ABILITY_10BASE_T_FD) {
794 		bfe->bfe_chip.speed = 10000000;
795 		bfe->bfe_chip.duplex = LINK_DUPLEX_FULL;
796 	} else if (anar & anlpar & MII_ABILITY_10BASE_T) {
797 		bfe->bfe_chip.speed = 10000000;
798 		bfe->bfe_chip.duplex = LINK_DUPLEX_HALF;
799 	} else {
800 		bfe->bfe_chip.speed = 0;
801 		bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
802 	}
803 
804 done:
805 	/*
806 	 * If speed or link status or duplex mode changed then report to
807 	 * MAC layer which is done by the caller.
808 	 */
809 	if (speed != bfe->bfe_chip.speed ||
810 	    duplex != bfe->bfe_chip.duplex ||
811 	    link != bfe->bfe_chip.link) {
812 		return (1);
813 	}
814 
815 	return (0);
816 }
817 
818 static void
819 bfe_cam_write(bfe_t *bfe, uchar_t *d, int index)
820 {
821 	uint32_t v;
822 
823 	v = ((uint32_t)d[2] << 24);
824 	v |= ((uint32_t)d[3] << 16);
825 	v |= ((uint32_t)d[4] << 8);
826 	v |= (uint32_t)d[5];
827 
828 	OUTL(bfe, BFE_CAM_DATA_LO, v);
829 	v = (BFE_CAM_HI_VALID |
830 	    (((uint32_t)d[0]) << 8) |
831 	    (((uint32_t)d[1])));
832 
833 	OUTL(bfe, BFE_CAM_DATA_HI, v);
834 	OUTL(bfe, BFE_CAM_CTRL, (BFE_CAM_WRITE |
835 	    ((uint32_t)index << BFE_CAM_INDEX_SHIFT)));
836 	(void) bfe_wait_bit(bfe, BFE_CAM_CTRL, BFE_CAM_BUSY, 10, 1);
837 }
838 
839 /*
840  * Chip related functions (halt, reset, start).
841  */
842 static void
843 bfe_chip_halt(bfe_t *bfe)
844 {
845 	/*
846 	 * Disables interrupts.
847 	 */
848 	OUTL(bfe, BFE_INTR_MASK, 0);
849 	FLUSH(bfe, BFE_INTR_MASK);
850 
851 	OUTL(bfe,  BFE_ENET_CTRL, BFE_ENET_DISABLE);
852 
853 	/*
854 	 * Wait until TX and RX finish their job.
855 	 */
856 	(void) bfe_wait_bit(bfe, BFE_ENET_CTRL, BFE_ENET_DISABLE, 20, 1);
857 
858 	/*
859 	 * Disables DMA engine.
860 	 */
861 	OUTL(bfe, BFE_DMARX_CTRL, 0);
862 	OUTL(bfe, BFE_DMATX_CTRL, 0);
863 
864 	drv_usecwait(10);
865 
866 	bfe->bfe_chip_state = BFE_CHIP_HALT;
867 }
868 
869 static void
870 bfe_chip_restart(bfe_t *bfe)
871 {
872 	DTRACE_PROBE2(chip__restart, int, bfe->bfe_unit,
873 	    int, bfe->bfe_chip_action);
874 
875 	/*
876 	 * Halt chip and PHY.
877 	 */
878 	bfe_chip_halt(bfe);
879 	bfe_stop_phy(bfe);
880 	bfe->bfe_chip_state = BFE_CHIP_STOPPED;
881 
882 	/*
883 	 * Init variables.
884 	 */
885 	bfe_init_vars(bfe);
886 
887 	/*
888 	 * Reset chip and start PHY.
889 	 */
890 	bfe_chip_reset(bfe);
891 
892 	/*
893 	 * DMA descriptor rings.
894 	 */
895 	bfe_tx_desc_init(&bfe->bfe_tx_ring);
896 	bfe_rx_desc_init(&bfe->bfe_rx_ring);
897 
898 	bfe->bfe_chip_state = BFE_CHIP_ACTIVE;
899 	bfe_set_rx_mode(bfe);
900 	bfe_enable_chip_intrs(bfe);
901 }
902 
903 /*
904  * Disables core by stopping the clock.
905  */
906 static void
907 bfe_core_disable(bfe_t *bfe)
908 {
909 	if ((INL(bfe, BFE_SBTMSLOW) & BFE_RESET))
910 		return;
911 
912 	OUTL(bfe, BFE_SBTMSLOW, (BFE_REJECT | BFE_CLOCK));
913 	(void) bfe_wait_bit(bfe, BFE_SBTMSLOW, BFE_REJECT, 100, 0);
914 	(void) bfe_wait_bit(bfe, BFE_SBTMSHIGH, BFE_BUSY, 100, 1);
915 	OUTL(bfe, BFE_SBTMSLOW, (BFE_FGC | BFE_CLOCK | BFE_REJECT | BFE_RESET));
916 	FLUSH(bfe, BFE_SBTMSLOW);
917 	drv_usecwait(10);
918 	OUTL(bfe, BFE_SBTMSLOW, (BFE_REJECT | BFE_RESET));
919 	drv_usecwait(10);
920 }
921 
922 /*
923  * Resets core.
924  */
925 static void
926 bfe_core_reset(bfe_t *bfe)
927 {
928 	uint32_t val;
929 
930 	/*
931 	 * First disable the core.
932 	 */
933 	bfe_core_disable(bfe);
934 
935 	OUTL(bfe, BFE_SBTMSLOW, (BFE_RESET | BFE_CLOCK | BFE_FGC));
936 	FLUSH(bfe, BFE_SBTMSLOW);
937 	drv_usecwait(1);
938 
939 	if (INL(bfe, BFE_SBTMSHIGH) & BFE_SERR)
940 		OUTL(bfe, BFE_SBTMSHIGH, 0);
941 
942 	val = INL(bfe, BFE_SBIMSTATE);
943 	if (val & (BFE_IBE | BFE_TO))
944 		OUTL(bfe, BFE_SBIMSTATE, val & ~(BFE_IBE | BFE_TO));
945 
946 	OUTL(bfe, BFE_SBTMSLOW, (BFE_CLOCK | BFE_FGC));
947 	FLUSH(bfe, BFE_SBTMSLOW);
948 	drv_usecwait(1);
949 
950 	OUTL(bfe, BFE_SBTMSLOW, BFE_CLOCK);
951 	FLUSH(bfe, BFE_SBTMSLOW);
952 	drv_usecwait(1);
953 }
954 
955 static void
956 bfe_setup_config(bfe_t *bfe, uint32_t cores)
957 {
958 	uint32_t bar_orig, val;
959 
960 	/*
961 	 * Change bar0 window to map sbtopci registers.
962 	 */
963 	bar_orig = pci_config_get32(bfe->bfe_conf_handle, BFE_BAR0_WIN);
964 	pci_config_put32(bfe->bfe_conf_handle, BFE_BAR0_WIN, BFE_REG_PCI);
965 
966 	/* Just read it and don't do anything */
967 	val = INL(bfe, BFE_SBIDHIGH) & BFE_IDH_CORE;
968 
969 	val = INL(bfe, BFE_SBINTVEC);
970 	val |= cores;
971 	OUTL(bfe, BFE_SBINTVEC, val);
972 
973 	val = INL(bfe, BFE_SSB_PCI_TRANS_2);
974 	val |= BFE_SSB_PCI_PREF | BFE_SSB_PCI_BURST;
975 	OUTL(bfe, BFE_SSB_PCI_TRANS_2, val);
976 
977 	/*
978 	 * Restore bar0 window mapping.
979 	 */
980 	pci_config_put32(bfe->bfe_conf_handle, BFE_BAR0_WIN, bar_orig);
981 }
982 
983 /*
984  * Resets chip and starts PHY.
985  */
986 static void
987 bfe_chip_reset(bfe_t *bfe)
988 {
989 	uint32_t val;
990 
991 	/* Set the interrupt vector for the enet core */
992 	bfe_setup_config(bfe, BFE_INTVEC_ENET0);
993 
994 	/* check if core is up */
995 	val = INL(bfe, BFE_SBTMSLOW) &
996 	    (BFE_RESET | BFE_REJECT | BFE_CLOCK);
997 
998 	if (val == BFE_CLOCK) {
999 		OUTL(bfe, BFE_RCV_LAZY, 0);
1000 		OUTL(bfe, BFE_ENET_CTRL, BFE_ENET_DISABLE);
1001 		(void) bfe_wait_bit(bfe, BFE_ENET_CTRL,
1002 		    BFE_ENET_DISABLE, 10, 1);
1003 		OUTL(bfe, BFE_DMATX_CTRL, 0);
1004 		FLUSH(bfe, BFE_DMARX_STAT);
1005 		drv_usecwait(20000);	/* 20 milli seconds */
1006 		if (INL(bfe, BFE_DMARX_STAT) & BFE_STAT_EMASK) {
1007 			(void) bfe_wait_bit(bfe, BFE_DMARX_STAT, BFE_STAT_SIDLE,
1008 			    10, 0);
1009 		}
1010 		OUTL(bfe, BFE_DMARX_CTRL, 0);
1011 	}
1012 
1013 	bfe_core_reset(bfe);
1014 	bfe_clear_stats(bfe);
1015 
1016 	OUTL(bfe, BFE_MDIO_CTRL, 0x8d);
1017 	val = INL(bfe, BFE_DEVCTRL);
1018 	if (!(val & BFE_IPP))
1019 		OUTL(bfe, BFE_ENET_CTRL, BFE_ENET_EPSEL);
1020 	else if (INL(bfe, BFE_DEVCTRL & BFE_EPR)) {
1021 		OUTL_AND(bfe, BFE_DEVCTRL, ~BFE_EPR);
1022 		drv_usecwait(20000);    /* 20 milli seconds */
1023 	}
1024 
1025 	OUTL_OR(bfe, BFE_MAC_CTRL, BFE_CTRL_CRC32_ENAB | BFE_CTRL_LED);
1026 
1027 	OUTL_AND(bfe, BFE_MAC_CTRL, ~BFE_CTRL_PDOWN);
1028 
1029 	OUTL(bfe, BFE_RCV_LAZY, ((1 << BFE_LAZY_FC_SHIFT) &
1030 	    BFE_LAZY_FC_MASK));
1031 
1032 	OUTL_OR(bfe, BFE_RCV_LAZY, 0);
1033 
1034 	OUTL(bfe, BFE_RXMAXLEN, bfe->bfe_rx_ring.r_buf_len);
1035 	OUTL(bfe, BFE_TXMAXLEN, bfe->bfe_tx_ring.r_buf_len);
1036 
1037 	OUTL(bfe, BFE_TX_WMARK, 56);
1038 
1039 	/* Program DMA channels */
1040 	OUTL(bfe, BFE_DMATX_CTRL, BFE_TX_CTRL_ENABLE);
1041 
1042 	/*
1043 	 * DMA addresses need to be added to BFE_PCI_DMA
1044 	 */
1045 	OUTL(bfe, BFE_DMATX_ADDR,
1046 	    bfe->bfe_tx_ring.r_desc_cookie.dmac_laddress + BFE_PCI_DMA);
1047 
1048 	OUTL(bfe, BFE_DMARX_CTRL, (BFE_RX_OFFSET << BFE_RX_CTRL_ROSHIFT)
1049 	    | BFE_RX_CTRL_ENABLE);
1050 
1051 	OUTL(bfe, BFE_DMARX_ADDR,
1052 	    bfe->bfe_rx_ring.r_desc_cookie.dmac_laddress + BFE_PCI_DMA);
1053 
1054 	(void) bfe_startup_phy(bfe);
1055 
1056 	bfe->bfe_chip_state = BFE_CHIP_INITIALIZED;
1057 }
1058 
1059 /*
1060  * It enables interrupts. Should be the last step while starting chip.
1061  */
1062 static void
1063 bfe_enable_chip_intrs(bfe_t *bfe)
1064 {
1065 	/* Enable the chip and core */
1066 	OUTL(bfe, BFE_ENET_CTRL, BFE_ENET_ENABLE);
1067 
1068 	/* Enable interrupts */
1069 	OUTL(bfe, BFE_INTR_MASK, BFE_IMASK_DEF);
1070 }
1071 
1072 /*
1073  * Common code to take care of setting RX side mode (filter).
1074  */
1075 static void
1076 bfe_set_rx_mode(bfe_t *bfe)
1077 {
1078 	uint32_t val;
1079 	int i;
1080 	ether_addr_t mac[ETHERADDRL] = {0, 0, 0, 0, 0, 0};
1081 
1082 	/*
1083 	 * We don't touch RX filter if we were asked to suspend. It's fine
1084 	 * if chip is not active (no interface is plumbed on us).
1085 	 */
1086 	if (bfe->bfe_chip_state == BFE_CHIP_SUSPENDED)
1087 		return;
1088 
1089 	val = INL(bfe, BFE_RXCONF);
1090 
1091 	val &= ~BFE_RXCONF_PROMISC;
1092 	val &= ~BFE_RXCONF_DBCAST;
1093 
1094 	if ((bfe->bfe_chip_mode & BFE_RX_MODE_ENABLE) == 0) {
1095 		OUTL(bfe, BFE_CAM_CTRL, 0);
1096 		FLUSH(bfe, BFE_CAM_CTRL);
1097 	} else if (bfe->bfe_chip_mode & BFE_RX_MODE_PROMISC) {
1098 		val |= BFE_RXCONF_PROMISC;
1099 		val &= ~BFE_RXCONF_DBCAST;
1100 	} else {
1101 		if (bfe->bfe_chip_state == BFE_CHIP_ACTIVE) {
1102 			/* Flush everything */
1103 			OUTL(bfe, BFE_RXCONF, val |
1104 			    BFE_RXCONF_PROMISC | BFE_RXCONF_ALLMULTI);
1105 			FLUSH(bfe, BFE_RXCONF);
1106 		}
1107 
1108 		/* Disable CAM */
1109 		OUTL(bfe, BFE_CAM_CTRL, 0);
1110 		FLUSH(bfe, BFE_CAM_CTRL);
1111 
1112 		/*
1113 		 * We receive all multicast packets.
1114 		 */
1115 		val |= BFE_RXCONF_ALLMULTI;
1116 
1117 		for (i = 0; i < BFE_MAX_MULTICAST_TABLE - 1; i++) {
1118 			bfe_cam_write(bfe, (uchar_t *)mac, i);
1119 		}
1120 
1121 		bfe_cam_write(bfe, bfe->bfe_ether_addr, i);
1122 
1123 		/* Enable CAM */
1124 		OUTL_OR(bfe, BFE_CAM_CTRL, BFE_CAM_ENABLE);
1125 		FLUSH(bfe, BFE_CAM_CTRL);
1126 	}
1127 
1128 	DTRACE_PROBE2(rx__mode__filter, int, bfe->bfe_unit,
1129 	    int, val);
1130 
1131 	OUTL(bfe, BFE_RXCONF, val);
1132 	FLUSH(bfe, BFE_RXCONF);
1133 }
1134 
1135 /*
1136  * Reset various variable values to initial state.
1137  */
1138 static void
1139 bfe_init_vars(bfe_t *bfe)
1140 {
1141 	bfe->bfe_chip_mode = BFE_RX_MODE_ENABLE;
1142 
1143 	/* Initial assumption */
1144 	bfe->bfe_chip.link = LINK_STATE_UNKNOWN;
1145 	bfe->bfe_chip.speed = 0;
1146 	bfe->bfe_chip.duplex = LINK_DUPLEX_UNKNOWN;
1147 
1148 	bfe->bfe_periodic_id = NULL;
1149 	bfe->bfe_chip_state = BFE_CHIP_UNINITIALIZED;
1150 
1151 	bfe->bfe_tx_stall_time = 0;
1152 }
1153 
1154 /*
1155  * Initializes TX side descriptor entries (bfe_desc_t). Each descriptor entry
1156  * has control (desc_ctl) and address (desc_addr) member.
1157  */
1158 static void
1159 bfe_tx_desc_init(bfe_ring_t *r)
1160 {
1161 	int i;
1162 	uint32_t v;
1163 
1164 	for (i = 0; i < r->r_ndesc; i++) {
1165 		PUT_DESC(r, (uint32_t *)&(r->r_desc[i].desc_ctl),
1166 		    (r->r_buf_dma[i].len & BFE_DESC_LEN));
1167 
1168 		/*
1169 		 * DMA addresses need to be added to BFE_PCI_DMA
1170 		 */
1171 		PUT_DESC(r, (uint32_t *)&(r->r_desc[i].desc_addr),
1172 		    (r->r_buf_dma[i].cookie.dmac_laddress + BFE_PCI_DMA));
1173 	}
1174 
1175 	v = GET_DESC(r, (uint32_t *)&(r->r_desc[i - 1].desc_ctl));
1176 	PUT_DESC(r, (uint32_t *)&(r->r_desc[i - 1].desc_ctl),
1177 	    v | BFE_DESC_EOT);
1178 
1179 	(void) SYNC_DESC(r, 0, r->r_ndesc, DDI_DMA_SYNC_FORDEV);
1180 
1181 	r->r_curr_desc = 0;
1182 	r->r_avail_desc = TX_NUM_DESC;
1183 	r->r_cons_desc = 0;
1184 }
1185 
1186 /*
1187  * Initializes RX side descriptor entries (bfe_desc_t). Each descriptor entry
1188  * has control (desc_ctl) and address (desc_addr) member.
1189  */
1190 static void
1191 bfe_rx_desc_init(bfe_ring_t *r)
1192 {
1193 	int i;
1194 	uint32_t v;
1195 
1196 	for (i = 0; i < r->r_ndesc; i++) {
1197 		PUT_DESC(r, (uint32_t *)&(r->r_desc[i].desc_ctl),
1198 		    (r->r_buf_dma[i].len& BFE_DESC_LEN));
1199 
1200 		PUT_DESC(r, (uint32_t *)&(r->r_desc[i].desc_addr),
1201 		    (r->r_buf_dma[i].cookie.dmac_laddress + BFE_PCI_DMA));
1202 
1203 		/* Initialize rx header (len, flags) */
1204 		bzero(r->r_buf_dma[i].addr, sizeof (bfe_rx_header_t));
1205 
1206 		(void) SYNC_BUF(r, i, 0, sizeof (bfe_rx_header_t),
1207 		    DDI_DMA_SYNC_FORDEV);
1208 	}
1209 
1210 	v = GET_DESC(r, (uint32_t *)&(r->r_desc[i - 1].desc_ctl));
1211 	PUT_DESC(r, (uint32_t *)&(r->r_desc[i - 1].desc_ctl),
1212 	    v | BFE_DESC_EOT);
1213 
1214 	(void) SYNC_DESC(r, 0, r->r_ndesc, DDI_DMA_SYNC_FORDEV);
1215 
1216 	/* TAIL of RX Descriptor */
1217 	OUTL(r->r_bfe, BFE_DMARX_PTR, ((i) * sizeof (bfe_desc_t)));
1218 
1219 	r->r_curr_desc = 0;
1220 	r->r_avail_desc = RX_NUM_DESC;
1221 }
1222 
1223 static int
1224 bfe_chip_start(bfe_t *bfe)
1225 {
1226 	ASSERT_ALL_LOCKS(bfe);
1227 
1228 	/*
1229 	 * Stop the chip first & then Reset the chip. At last enable interrupts.
1230 	 */
1231 	bfe_chip_halt(bfe);
1232 	bfe_stop_phy(bfe);
1233 
1234 	/*
1235 	 * Reset chip and start PHY.
1236 	 */
1237 	bfe_chip_reset(bfe);
1238 
1239 	/*
1240 	 * Initailize Descriptor Rings.
1241 	 */
1242 	bfe_tx_desc_init(&bfe->bfe_tx_ring);
1243 	bfe_rx_desc_init(&bfe->bfe_rx_ring);
1244 
1245 	bfe->bfe_chip_state = BFE_CHIP_ACTIVE;
1246 	bfe->bfe_chip_mode |= BFE_RX_MODE_ENABLE;
1247 	bfe_set_rx_mode(bfe);
1248 	bfe_enable_chip_intrs(bfe);
1249 
1250 	/* Check link, speed and duplex mode */
1251 	(void) bfe_check_link(bfe);
1252 
1253 	return (DDI_SUCCESS);
1254 }
1255 
1256 
1257 /*
1258  * Clear chip statistics.
1259  */
1260 static void
1261 bfe_clear_stats(bfe_t *bfe)
1262 {
1263 	ulong_t r;
1264 
1265 	OUTL(bfe, BFE_MIB_CTRL, BFE_MIB_CLR_ON_READ);
1266 
1267 	/*
1268 	 * Stat registers are cleared by reading.
1269 	 */
1270 	for (r = BFE_TX_GOOD_O; r <= BFE_TX_PAUSE; r += 4)
1271 		(void) INL(bfe, r);
1272 
1273 	for (r = BFE_RX_GOOD_O; r <= BFE_RX_NPAUSE; r += 4)
1274 		(void) INL(bfe, r);
1275 }
1276 
1277 /*
1278  * Collect chip statistics.
1279  */
1280 static void
1281 bfe_gather_stats(bfe_t *bfe)
1282 {
1283 	ulong_t r;
1284 	uint32_t *v;
1285 	uint32_t txerr = 0, rxerr = 0, coll = 0;
1286 
1287 	v = &bfe->bfe_hw_stats.tx_good_octets;
1288 	for (r = BFE_TX_GOOD_O; r <= BFE_TX_PAUSE; r += 4) {
1289 		*v += INL(bfe, r);
1290 		v++;
1291 	}
1292 
1293 	v = &bfe->bfe_hw_stats.rx_good_octets;
1294 	for (r = BFE_RX_GOOD_O; r <= BFE_RX_NPAUSE; r += 4) {
1295 		*v += INL(bfe, r);
1296 		v++;
1297 	}
1298 
1299 	/*
1300 	 * TX :
1301 	 * -------
1302 	 * tx_good_octets, tx_good_pkts, tx_octets
1303 	 * tx_pkts, tx_broadcast_pkts, tx_multicast_pkts
1304 	 * tx_len_64, tx_len_65_to_127, tx_len_128_to_255
1305 	 * tx_len_256_to_511, tx_len_512_to_1023, tx_len_1024_to_max
1306 	 * tx_jabber_pkts, tx_oversize_pkts, tx_fragment_pkts
1307 	 * tx_underruns, tx_total_cols, tx_single_cols
1308 	 * tx_multiple_cols, tx_excessive_cols, tx_late_cols
1309 	 * tx_defered, tx_carrier_lost, tx_pause_pkts
1310 	 *
1311 	 * RX :
1312 	 * -------
1313 	 * rx_good_octets, rx_good_pkts, rx_octets
1314 	 * rx_pkts, rx_broadcast_pkts, rx_multicast_pkts
1315 	 * rx_len_64, rx_len_65_to_127, rx_len_128_to_255
1316 	 * rx_len_256_to_511, rx_len_512_to_1023, rx_len_1024_to_max
1317 	 * rx_jabber_pkts, rx_oversize_pkts, rx_fragment_pkts
1318 	 * rx_missed_pkts, rx_crc_align_errs, rx_undersize
1319 	 * rx_crc_errs, rx_align_errs, rx_symbol_errs
1320 	 * rx_pause_pkts, rx_nonpause_pkts
1321 	 */
1322 
1323 	bfe->bfe_stats.ether_stat_carrier_errors =
1324 	    bfe->bfe_hw_stats.tx_carrier_lost;
1325 
1326 	/* txerr += bfe->bfe_hw_stats.tx_carrier_lost; */
1327 
1328 	bfe->bfe_stats.ether_stat_ex_collisions =
1329 	    bfe->bfe_hw_stats.tx_excessive_cols;
1330 	txerr += bfe->bfe_hw_stats.tx_excessive_cols;
1331 	coll += bfe->bfe_hw_stats.tx_excessive_cols;
1332 
1333 	bfe->bfe_stats.ether_stat_fcs_errors =
1334 	    bfe->bfe_hw_stats.rx_crc_errs;
1335 	rxerr += bfe->bfe_hw_stats.rx_crc_errs;
1336 
1337 	bfe->bfe_stats.ether_stat_first_collisions =
1338 	    bfe->bfe_hw_stats.tx_single_cols;
1339 	coll += bfe->bfe_hw_stats.tx_single_cols;
1340 	bfe->bfe_stats.ether_stat_multi_collisions =
1341 	    bfe->bfe_hw_stats.tx_multiple_cols;
1342 	coll += bfe->bfe_hw_stats.tx_multiple_cols;
1343 
1344 	bfe->bfe_stats.ether_stat_toolong_errors =
1345 	    bfe->bfe_hw_stats.rx_oversize_pkts;
1346 	rxerr += bfe->bfe_hw_stats.rx_oversize_pkts;
1347 
1348 	bfe->bfe_stats.ether_stat_tooshort_errors =
1349 	    bfe->bfe_hw_stats.rx_undersize;
1350 	rxerr += bfe->bfe_hw_stats.rx_undersize;
1351 
1352 	bfe->bfe_stats.ether_stat_tx_late_collisions +=
1353 	    bfe->bfe_hw_stats.tx_late_cols;
1354 
1355 	bfe->bfe_stats.ether_stat_defer_xmts +=
1356 	    bfe->bfe_hw_stats.tx_defered;
1357 
1358 	bfe->bfe_stats.ether_stat_macrcv_errors += rxerr;
1359 	bfe->bfe_stats.ether_stat_macxmt_errors += txerr;
1360 
1361 	bfe->bfe_stats.collisions += coll;
1362 }
1363 
1364 /*
1365  * Gets the state for dladm command and all.
1366  */
1367 int
1368 bfe_mac_getstat(void *arg, uint_t stat, uint64_t *val)
1369 {
1370 	bfe_t *bfe = (bfe_t *)arg;
1371 	uint64_t	v;
1372 	int err = 0;
1373 
1374 	rw_enter(&bfe->bfe_rwlock, RW_READER);
1375 
1376 
1377 	switch (stat) {
1378 	default:
1379 		err = ENOTSUP;
1380 		break;
1381 
1382 	case MAC_STAT_IFSPEED:
1383 		/*
1384 		 * MAC layer will ask for IFSPEED first and hence we
1385 		 * collect it only once.
1386 		 */
1387 		if (bfe->bfe_chip_state == BFE_CHIP_ACTIVE) {
1388 			/*
1389 			 * Update stats from the hardware.
1390 			 */
1391 			bfe_gather_stats(bfe);
1392 		}
1393 		v = bfe->bfe_chip.speed;
1394 		break;
1395 
1396 	case ETHER_STAT_ADV_CAP_100T4:
1397 		v = bfe->bfe_adv_100T4;
1398 		break;
1399 
1400 	case ETHER_STAT_ADV_CAP_100FDX:
1401 		v = (bfe->bfe_mii_anar & MII_ABILITY_100BASE_TX_FD) != 0;
1402 		break;
1403 
1404 	case ETHER_STAT_ADV_CAP_100HDX:
1405 		v = (bfe->bfe_mii_anar & MII_ABILITY_100BASE_TX) != 0;
1406 		break;
1407 
1408 	case ETHER_STAT_ADV_CAP_10FDX:
1409 		v = (bfe->bfe_mii_anar & MII_ABILITY_10BASE_T_FD) != 0;
1410 		break;
1411 
1412 	case ETHER_STAT_ADV_CAP_10HDX:
1413 		v = (bfe->bfe_mii_anar & MII_ABILITY_10BASE_T) != 0;
1414 		break;
1415 
1416 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
1417 		v = 0;
1418 		break;
1419 
1420 	case ETHER_STAT_ADV_CAP_AUTONEG:
1421 		v = bfe->bfe_adv_aneg;
1422 		break;
1423 
1424 	case ETHER_STAT_ADV_CAP_PAUSE:
1425 		v = (bfe->bfe_mii_anar & MII_ABILITY_PAUSE) != 0;
1426 		break;
1427 
1428 	case ETHER_STAT_ADV_REMFAULT:
1429 		v = (bfe->bfe_mii_anar & MII_AN_ADVERT_REMFAULT) != 0;
1430 		break;
1431 
1432 	case ETHER_STAT_ALIGN_ERRORS:
1433 		/* MIB */
1434 		v = bfe->bfe_stats.ether_stat_align_errors;
1435 		break;
1436 
1437 	case ETHER_STAT_CAP_100T4:
1438 		v = (bfe->bfe_mii_bmsr & MII_STATUS_100_BASE_T4) != 0;
1439 		break;
1440 
1441 	case ETHER_STAT_CAP_100FDX:
1442 		v = (bfe->bfe_mii_bmsr & MII_STATUS_100_BASEX_FD) != 0;
1443 		break;
1444 
1445 	case ETHER_STAT_CAP_100HDX:
1446 		v = (bfe->bfe_mii_bmsr & MII_STATUS_100_BASEX) != 0;
1447 		break;
1448 
1449 	case ETHER_STAT_CAP_10FDX:
1450 		v = (bfe->bfe_mii_bmsr & MII_STATUS_10_FD) != 0;
1451 		break;
1452 
1453 	case ETHER_STAT_CAP_10HDX:
1454 		v = (bfe->bfe_mii_bmsr & MII_STATUS_10) != 0;
1455 		break;
1456 
1457 	case ETHER_STAT_CAP_ASMPAUSE:
1458 		v = 0;
1459 		break;
1460 
1461 	case ETHER_STAT_CAP_AUTONEG:
1462 		v = ((bfe->bfe_mii_bmsr & MII_STATUS_CANAUTONEG) != 0);
1463 		break;
1464 
1465 	case ETHER_STAT_CAP_PAUSE:
1466 		v = 1;
1467 		break;
1468 
1469 	case ETHER_STAT_CAP_REMFAULT:
1470 		v = (bfe->bfe_mii_bmsr & MII_STATUS_REMFAULT) != 0;
1471 		break;
1472 
1473 	case ETHER_STAT_CARRIER_ERRORS:
1474 		v = bfe->bfe_stats.ether_stat_carrier_errors;
1475 		break;
1476 
1477 	case ETHER_STAT_JABBER_ERRORS:
1478 		err = ENOTSUP;
1479 		break;
1480 
1481 	case ETHER_STAT_DEFER_XMTS:
1482 		v = bfe->bfe_stats.ether_stat_defer_xmts;
1483 		break;
1484 
1485 	case ETHER_STAT_EX_COLLISIONS:
1486 		/* MIB */
1487 		v = bfe->bfe_stats.ether_stat_ex_collisions;
1488 		break;
1489 
1490 	case ETHER_STAT_FCS_ERRORS:
1491 		/* MIB */
1492 		v = bfe->bfe_stats.ether_stat_fcs_errors;
1493 		break;
1494 
1495 	case ETHER_STAT_FIRST_COLLISIONS:
1496 		/* MIB */
1497 		v = bfe->bfe_stats.ether_stat_first_collisions;
1498 		break;
1499 
1500 	case ETHER_STAT_LINK_ASMPAUSE:
1501 		v = 0;
1502 		break;
1503 
1504 	case ETHER_STAT_LINK_AUTONEG:
1505 		v = (bfe->bfe_mii_bmcr & MII_CONTROL_ANE) != 0 &&
1506 		    (bfe->bfe_mii_bmsr & MII_STATUS_ANDONE) != 0;
1507 		break;
1508 
1509 	case ETHER_STAT_LINK_DUPLEX:
1510 		v = bfe->bfe_chip.duplex;
1511 		break;
1512 
1513 	case ETHER_STAT_LP_CAP_100T4:
1514 		v = (bfe->bfe_mii_anlpar & MII_ABILITY_100BASE_T4) != 0;
1515 		break;
1516 
1517 	case ETHER_STAT_LP_CAP_100FDX:
1518 		v = (bfe->bfe_mii_anlpar & MII_ABILITY_100BASE_TX_FD) != 0;
1519 		break;
1520 
1521 	case ETHER_STAT_LP_CAP_100HDX:
1522 		v = (bfe->bfe_mii_anlpar & MII_ABILITY_100BASE_TX) != 0;
1523 		break;
1524 
1525 	case ETHER_STAT_LP_CAP_10FDX:
1526 		v = (bfe->bfe_mii_anlpar & MII_ABILITY_10BASE_T_FD) != 0;
1527 		break;
1528 
1529 	case ETHER_STAT_LP_CAP_10HDX:
1530 		v = (bfe->bfe_mii_anlpar & MII_ABILITY_10BASE_T) != 0;
1531 		break;
1532 
1533 	case ETHER_STAT_LP_CAP_ASMPAUSE:
1534 		v = 0;
1535 		break;
1536 
1537 	case ETHER_STAT_LP_CAP_AUTONEG:
1538 		v = (bfe->bfe_mii_exp & MII_AN_EXP_LPCANAN) != 0;
1539 		break;
1540 
1541 	case ETHER_STAT_LP_CAP_PAUSE:
1542 		v = (bfe->bfe_mii_anlpar & MII_ABILITY_PAUSE) != 0;
1543 		break;
1544 
1545 	case ETHER_STAT_LP_REMFAULT:
1546 		v = (bfe->bfe_mii_anlpar & MII_STATUS_REMFAULT) != 0;
1547 		break;
1548 
1549 	case ETHER_STAT_MACRCV_ERRORS:
1550 		v = bfe->bfe_stats.ether_stat_macrcv_errors;
1551 		break;
1552 
1553 	case ETHER_STAT_MACXMT_ERRORS:
1554 		v = bfe->bfe_stats.ether_stat_macxmt_errors;
1555 		break;
1556 
1557 	case ETHER_STAT_MULTI_COLLISIONS:
1558 		v = bfe->bfe_stats.ether_stat_multi_collisions;
1559 		break;
1560 
1561 	case ETHER_STAT_SQE_ERRORS:
1562 		err = ENOTSUP;
1563 		break;
1564 
1565 	case ETHER_STAT_TOOLONG_ERRORS:
1566 		v = bfe->bfe_stats.ether_stat_toolong_errors;
1567 		break;
1568 
1569 	case ETHER_STAT_TOOSHORT_ERRORS:
1570 		v = bfe->bfe_stats.ether_stat_tooshort_errors;
1571 		break;
1572 
1573 	case ETHER_STAT_TX_LATE_COLLISIONS:
1574 		v = bfe->bfe_stats.ether_stat_tx_late_collisions;
1575 		break;
1576 
1577 	case ETHER_STAT_XCVR_ADDR:
1578 		v = bfe->bfe_phy_addr;
1579 		break;
1580 
1581 	case ETHER_STAT_XCVR_ID:
1582 		v = bfe->bfe_phy_id;
1583 		break;
1584 
1585 	case MAC_STAT_BRDCSTRCV:
1586 		v = bfe->bfe_stats.brdcstrcv;
1587 		break;
1588 
1589 	case MAC_STAT_BRDCSTXMT:
1590 		v = bfe->bfe_stats.brdcstxmt;
1591 		break;
1592 
1593 	case MAC_STAT_MULTIXMT:
1594 		v = bfe->bfe_stats.multixmt;
1595 		break;
1596 
1597 	case MAC_STAT_COLLISIONS:
1598 		v = bfe->bfe_stats.collisions;
1599 		break;
1600 
1601 	case MAC_STAT_IERRORS:
1602 		v = bfe->bfe_stats.ierrors;
1603 		break;
1604 
1605 	case MAC_STAT_IPACKETS:
1606 		v = bfe->bfe_stats.ipackets;
1607 		break;
1608 
1609 	case MAC_STAT_MULTIRCV:
1610 		v = bfe->bfe_stats.multircv;
1611 		break;
1612 
1613 	case MAC_STAT_NORCVBUF:
1614 		v = bfe->bfe_stats.norcvbuf;
1615 		break;
1616 
1617 	case MAC_STAT_NOXMTBUF:
1618 		v = bfe->bfe_stats.noxmtbuf;
1619 		break;
1620 
1621 	case MAC_STAT_OBYTES:
1622 		v = bfe->bfe_stats.obytes;
1623 		break;
1624 
1625 	case MAC_STAT_OERRORS:
1626 		/* MIB */
1627 		v = bfe->bfe_stats.ether_stat_macxmt_errors;
1628 		break;
1629 
1630 	case MAC_STAT_OPACKETS:
1631 		v = bfe->bfe_stats.opackets;
1632 		break;
1633 
1634 	case MAC_STAT_RBYTES:
1635 		v = bfe->bfe_stats.rbytes;
1636 		break;
1637 
1638 	case MAC_STAT_UNDERFLOWS:
1639 		v = bfe->bfe_stats.underflows;
1640 		break;
1641 
1642 	case MAC_STAT_OVERFLOWS:
1643 		v = bfe->bfe_stats.overflows;
1644 		break;
1645 	}
1646 
1647 	rw_exit(&bfe->bfe_rwlock);
1648 
1649 	*val = v;
1650 	return (err);
1651 }
1652 
1653 int
1654 bfe_mac_getprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
1655     void *val)
1656 {
1657 	bfe_t		*bfe = (bfe_t *)arg;
1658 	int		err = 0;
1659 
1660 	switch (num) {
1661 	case MAC_PROP_DUPLEX:
1662 		ASSERT(sz >= sizeof (link_duplex_t));
1663 		bcopy(&bfe->bfe_chip.duplex, val, sizeof (link_duplex_t));
1664 		break;
1665 
1666 	case MAC_PROP_SPEED:
1667 		ASSERT(sz >= sizeof (uint64_t));
1668 		bcopy(&bfe->bfe_chip.speed, val, sizeof (uint64_t));
1669 		break;
1670 
1671 	case MAC_PROP_AUTONEG:
1672 		*(uint8_t *)val = bfe->bfe_adv_aneg;
1673 		break;
1674 
1675 	case MAC_PROP_ADV_100FDX_CAP:
1676 		*(uint8_t *)val = bfe->bfe_adv_100fdx;
1677 		break;
1678 
1679 	case MAC_PROP_EN_100FDX_CAP:
1680 		*(uint8_t *)val = bfe->bfe_adv_100fdx;
1681 		break;
1682 
1683 	case MAC_PROP_ADV_100HDX_CAP:
1684 		*(uint8_t *)val = bfe->bfe_adv_100hdx;
1685 		break;
1686 
1687 	case MAC_PROP_EN_100HDX_CAP:
1688 		*(uint8_t *)val = bfe->bfe_adv_100hdx;
1689 		break;
1690 
1691 	case MAC_PROP_ADV_10FDX_CAP:
1692 		*(uint8_t *)val = bfe->bfe_adv_10fdx;
1693 		break;
1694 
1695 	case MAC_PROP_EN_10FDX_CAP:
1696 		*(uint8_t *)val = bfe->bfe_adv_10fdx;
1697 		break;
1698 
1699 	case MAC_PROP_ADV_10HDX_CAP:
1700 		*(uint8_t *)val = bfe->bfe_adv_10hdx;
1701 		break;
1702 
1703 	case MAC_PROP_EN_10HDX_CAP:
1704 		*(uint8_t *)val = bfe->bfe_adv_10hdx;
1705 		break;
1706 
1707 	case MAC_PROP_ADV_100T4_CAP:
1708 		*(uint8_t *)val = bfe->bfe_adv_100T4;
1709 		break;
1710 
1711 	case MAC_PROP_EN_100T4_CAP:
1712 		*(uint8_t *)val = bfe->bfe_adv_100T4;
1713 		break;
1714 
1715 	default:
1716 		err = ENOTSUP;
1717 	}
1718 
1719 	return (err);
1720 }
1721 
1722 
1723 static void
1724 bfe_mac_propinfo(void *arg, const char *name, mac_prop_id_t num,
1725     mac_prop_info_handle_t prh)
1726 {
1727 	bfe_t		*bfe = (bfe_t *)arg;
1728 
1729 	switch (num) {
1730 	case MAC_PROP_DUPLEX:
1731 	case MAC_PROP_SPEED:
1732 	case MAC_PROP_ADV_100FDX_CAP:
1733 	case MAC_PROP_ADV_100HDX_CAP:
1734 	case MAC_PROP_ADV_10FDX_CAP:
1735 	case MAC_PROP_ADV_10HDX_CAP:
1736 	case MAC_PROP_ADV_100T4_CAP:
1737 	case MAC_PROP_EN_100T4_CAP:
1738 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
1739 		break;
1740 
1741 	case MAC_PROP_AUTONEG:
1742 		mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_aneg);
1743 		break;
1744 
1745 	case MAC_PROP_EN_100FDX_CAP:
1746 		mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_100fdx);
1747 		break;
1748 
1749 	case MAC_PROP_EN_100HDX_CAP:
1750 		mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_100hdx);
1751 		break;
1752 
1753 	case MAC_PROP_EN_10FDX_CAP:
1754 		mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_10fdx);
1755 		break;
1756 
1757 	case MAC_PROP_EN_10HDX_CAP:
1758 		mac_prop_info_set_default_uint8(prh, bfe->bfe_cap_10hdx);
1759 		break;
1760 	}
1761 }
1762 
1763 
1764 /*ARGSUSED*/
1765 int
1766 bfe_mac_setprop(void *arg, const char *name, mac_prop_id_t num, uint_t sz,
1767     const void *val)
1768 {
1769 	bfe_t		*bfe = (bfe_t *)arg;
1770 	uint8_t		*advp;
1771 	uint8_t		*capp;
1772 	int 		r = 0;
1773 
1774 	switch (num) {
1775 	case MAC_PROP_EN_100FDX_CAP:
1776 		advp = &bfe->bfe_adv_100fdx;
1777 		capp = &bfe->bfe_cap_100fdx;
1778 		break;
1779 
1780 	case MAC_PROP_EN_100HDX_CAP:
1781 		advp = &bfe->bfe_adv_100hdx;
1782 		capp = &bfe->bfe_cap_100hdx;
1783 		break;
1784 
1785 	case MAC_PROP_EN_10FDX_CAP:
1786 		advp = &bfe->bfe_adv_10fdx;
1787 		capp = &bfe->bfe_cap_10fdx;
1788 		break;
1789 
1790 	case MAC_PROP_EN_10HDX_CAP:
1791 		advp = &bfe->bfe_adv_10hdx;
1792 		capp = &bfe->bfe_cap_10hdx;
1793 		break;
1794 
1795 	case MAC_PROP_AUTONEG:
1796 		advp = &bfe->bfe_adv_aneg;
1797 		capp = &bfe->bfe_cap_aneg;
1798 		break;
1799 
1800 	default:
1801 		return (ENOTSUP);
1802 	}
1803 
1804 	if (*capp == 0)
1805 		return (ENOTSUP);
1806 
1807 	bfe_grab_locks(bfe);
1808 
1809 	if (*advp != *(const uint8_t *)val) {
1810 		*advp = *(const uint8_t *)val;
1811 
1812 		bfe->bfe_chip_action = BFE_ACTION_RESTART_SETPROP;
1813 		if (bfe->bfe_chip_state == BFE_CHIP_ACTIVE) {
1814 			/*
1815 			 * We need to stop the timer before grabbing locks
1816 			 * otherwise we can land-up in deadlock with untimeout.
1817 			 */
1818 			bfe_stop_timer(bfe);
1819 
1820 			bfe->bfe_chip_action |= BFE_ACTION_RESTART;
1821 
1822 			bfe_chip_restart(bfe);
1823 
1824 			/*
1825 			 * We leave SETPROP because properties can be
1826 			 * temporary.
1827 			 */
1828 			bfe->bfe_chip_action &= ~(BFE_ACTION_RESTART);
1829 			r = 1;
1830 		}
1831 	}
1832 
1833 	bfe_release_locks(bfe);
1834 
1835 	/* kick-off a potential stopped downstream */
1836 	if (r)
1837 		mac_tx_update(bfe->bfe_machdl);
1838 
1839 	return (0);
1840 }
1841 
1842 
1843 int
1844 bfe_mac_set_ether_addr(void *arg, const uint8_t *ea)
1845 {
1846 	bfe_t *bfe = (bfe_t *)arg;
1847 
1848 	bfe_grab_locks(bfe);
1849 	bcopy(ea, bfe->bfe_ether_addr, ETHERADDRL);
1850 	bfe_set_rx_mode(bfe);
1851 	bfe_release_locks(bfe);
1852 	return (0);
1853 }
1854 
1855 int
1856 bfe_mac_start(void *arg)
1857 {
1858 	bfe_t *bfe = (bfe_t *)arg;
1859 
1860 	bfe_grab_locks(bfe);
1861 	if (bfe_chip_start(bfe) == DDI_FAILURE) {
1862 		bfe_release_locks(bfe);
1863 		return (EINVAL);
1864 	}
1865 
1866 	bfe_release_locks(bfe);
1867 
1868 	mac_tx_update(bfe->bfe_machdl);
1869 
1870 	return (0);
1871 }
1872 
1873 void
1874 bfe_mac_stop(void *arg)
1875 {
1876 	bfe_t *bfe = (bfe_t *)arg;
1877 
1878 	/*
1879 	 * We need to stop the timer before grabbing locks otherwise
1880 	 * we can land-up in deadlock with untimeout.
1881 	 */
1882 	bfe_stop_timer(bfe);
1883 
1884 	bfe_grab_locks(bfe);
1885 
1886 	/*
1887 	 * First halt the chip by disabling interrupts.
1888 	 */
1889 	bfe_chip_halt(bfe);
1890 	bfe_stop_phy(bfe);
1891 
1892 	bfe->bfe_chip_state = BFE_CHIP_STOPPED;
1893 
1894 	/*
1895 	 * This will leave the PHY running.
1896 	 */
1897 	bfe_chip_reset(bfe);
1898 
1899 	/*
1900 	 * Disable RX register.
1901 	 */
1902 	bfe->bfe_chip_mode &= ~BFE_RX_MODE_ENABLE;
1903 	bfe_set_rx_mode(bfe);
1904 
1905 	bfe_release_locks(bfe);
1906 }
1907 
1908 /*
1909  * Send a packet down the wire.
1910  */
1911 static int
1912 bfe_send_a_packet(bfe_t *bfe, mblk_t *mp)
1913 {
1914 	bfe_ring_t *r = &bfe->bfe_tx_ring;
1915 	uint32_t cur = r->r_curr_desc;
1916 	uint32_t next;
1917 	size_t	pktlen = msgsize(mp);
1918 	uchar_t *buf;
1919 	uint32_t v;
1920 
1921 	ASSERT(MUTEX_HELD(&r->r_lock));
1922 	ASSERT(mp != NULL);
1923 
1924 	if (pktlen > r->r_buf_len) {
1925 		freemsg(mp);
1926 		return (BFE_SUCCESS);
1927 	}
1928 
1929 	/*
1930 	 * There is a big reason why we don't check for '0'. It becomes easy
1931 	 * for us to not roll over the ring since we are based on producer (tx)
1932 	 * and consumer (reclaim by an interrupt) model. Especially when we
1933 	 * run out of TX descriptor, chip will send a single interrupt and
1934 	 * both producer and consumer counter will be same. So we keep a
1935 	 * difference of 1 always.
1936 	 */
1937 	if (r->r_avail_desc <= 1) {
1938 		bfe->bfe_stats.noxmtbuf++;
1939 		bfe->bfe_tx_resched = 1;
1940 		return (BFE_FAILURE);
1941 	}
1942 
1943 	/*
1944 	 * Get the DMA buffer to hold packet.
1945 	 */
1946 	buf = (uchar_t *)r->r_buf_dma[cur].addr;
1947 
1948 	mcopymsg(mp, buf);	/* it also frees mp */
1949 
1950 	/*
1951 	 * Gather statistics.
1952 	 */
1953 	if (buf[0] & 0x1) {
1954 		if (bcmp(buf, bfe_broadcast, ETHERADDRL) != 0)
1955 			bfe->bfe_stats.multixmt++;
1956 		else
1957 			bfe->bfe_stats.brdcstxmt++;
1958 	}
1959 	bfe->bfe_stats.opackets++;
1960 	bfe->bfe_stats.obytes += pktlen;
1961 
1962 
1963 	/*
1964 	 * Program the DMA descriptor (start and end of frame are same).
1965 	 */
1966 	next = cur;
1967 	v = (pktlen & BFE_DESC_LEN) | BFE_DESC_IOC | BFE_DESC_SOF |
1968 	    BFE_DESC_EOF;
1969 
1970 	if (cur == (TX_NUM_DESC - 1))
1971 		v |= BFE_DESC_EOT;
1972 
1973 	PUT_DESC(r, (uint32_t *)&(r->r_desc[cur].desc_ctl), v);
1974 
1975 	/*
1976 	 * DMA addresses need to be added to BFE_PCI_DMA
1977 	 */
1978 	PUT_DESC(r, (uint32_t *)&(r->r_desc[cur].desc_addr),
1979 	    (r->r_buf_dma[cur].cookie.dmac_laddress + BFE_PCI_DMA));
1980 
1981 	/*
1982 	 * Sync the packet data for the device.
1983 	 */
1984 	(void) SYNC_BUF(r, cur, 0, pktlen, DDI_DMA_SYNC_FORDEV);
1985 
1986 	/* Move to next descriptor slot */
1987 	BFE_INC_SLOT(next, TX_NUM_DESC);
1988 
1989 	(void) SYNC_DESC(r, 0, r->r_ndesc, DDI_DMA_SYNC_FORDEV);
1990 
1991 	r->r_curr_desc = next;
1992 
1993 	/*
1994 	 * The order should be 1,2,3,... for BFE_DMATX_PTR if 0,1,2,3,...
1995 	 * descriptor slot are being programmed.
1996 	 */
1997 	OUTL(bfe, BFE_DMATX_PTR, next * sizeof (bfe_desc_t));
1998 	FLUSH(bfe, BFE_DMATX_PTR);
1999 
2000 	r->r_avail_desc--;
2001 
2002 	/*
2003 	 * Let timeout know that it must reset the chip if a
2004 	 * packet is not sent down the wire for more than 5 seconds.
2005 	 */
2006 	bfe->bfe_tx_stall_time = gethrtime() + (5 * 1000000000ULL);
2007 
2008 	return (BFE_SUCCESS);
2009 }
2010 
2011 mblk_t *
2012 bfe_mac_transmit_packet(void *arg, mblk_t *mp)
2013 {
2014 	bfe_t *bfe = (bfe_t *)arg;
2015 	bfe_ring_t *r = &bfe->bfe_tx_ring;
2016 	mblk_t	*nmp;
2017 
2018 	mutex_enter(&r->r_lock);
2019 
2020 	if (bfe->bfe_chip_state != BFE_CHIP_ACTIVE) {
2021 		DTRACE_PROBE1(tx__chip__not__active, int, bfe->bfe_unit);
2022 
2023 		freemsgchain(mp);
2024 		mutex_exit(&r->r_lock);
2025 		return (NULL);
2026 	}
2027 
2028 
2029 	while (mp != NULL) {
2030 		nmp = mp->b_next;
2031 		mp->b_next = NULL;
2032 
2033 		if (bfe_send_a_packet(bfe, mp) == BFE_FAILURE) {
2034 			mp->b_next = nmp;
2035 			break;
2036 		}
2037 		mp = nmp;
2038 	}
2039 
2040 	mutex_exit(&r->r_lock);
2041 
2042 	return (mp);
2043 }
2044 
2045 int
2046 bfe_mac_set_promisc(void *arg, boolean_t promiscflag)
2047 {
2048 	bfe_t *bfe = (bfe_t *)arg;
2049 
2050 	bfe_grab_locks(bfe);
2051 	if (bfe->bfe_chip_state != BFE_CHIP_ACTIVE) {
2052 		bfe_release_locks(bfe);
2053 		return (EIO);
2054 	}
2055 
2056 	if (promiscflag) {
2057 		/* Set Promiscous on */
2058 		bfe->bfe_chip_mode |= BFE_RX_MODE_PROMISC;
2059 	} else {
2060 		bfe->bfe_chip_mode &= ~BFE_RX_MODE_PROMISC;
2061 	}
2062 
2063 	bfe_set_rx_mode(bfe);
2064 	bfe_release_locks(bfe);
2065 
2066 	return (0);
2067 }
2068 
2069 int
2070 bfe_mac_set_multicast(void *arg, boolean_t add, const uint8_t *macaddr)
2071 {
2072 	/*
2073 	 * It was too much of pain to implement multicast in CAM. Instead
2074 	 * we never disable multicast filter.
2075 	 */
2076 	return (0);
2077 }
2078 
2079 static mac_callbacks_t bfe_mac_callbacks = {
2080 	MC_SETPROP | MC_GETPROP | MC_PROPINFO,
2081 	bfe_mac_getstat,	/* gets stats */
2082 	bfe_mac_start,		/* starts mac */
2083 	bfe_mac_stop,		/* stops mac */
2084 	bfe_mac_set_promisc,	/* sets promisc mode for snoop */
2085 	bfe_mac_set_multicast,	/* multicast implementation */
2086 	bfe_mac_set_ether_addr,	/* sets ethernet address (unicast) */
2087 	bfe_mac_transmit_packet, /* transmits packet */
2088 	NULL,
2089 	NULL,			/* ioctl */
2090 	NULL,			/* getcap */
2091 	NULL,			/* open */
2092 	NULL,			/* close */
2093 	bfe_mac_setprop,
2094 	bfe_mac_getprop,
2095 	bfe_mac_propinfo
2096 };
2097 
2098 static void
2099 bfe_error_handler(bfe_t *bfe, int intr_mask)
2100 {
2101 	uint32_t v;
2102 
2103 	if (intr_mask & BFE_ISTAT_RFO) {
2104 		bfe->bfe_stats.overflows++;
2105 		bfe->bfe_chip_action |=
2106 		    (BFE_ACTION_RESTART | BFE_ACTION_RESTART_FAULT);
2107 		goto action;
2108 	}
2109 
2110 	if (intr_mask & BFE_ISTAT_TFU) {
2111 		bfe->bfe_stats.underflows++;
2112 		return;
2113 	}
2114 
2115 	/* Descriptor Protocol Error */
2116 	if (intr_mask & BFE_ISTAT_DPE) {
2117 		bfe_error(bfe->bfe_dip,
2118 		    "Descriptor Protocol Error. Halting Chip");
2119 		bfe->bfe_chip_action |=
2120 		    (BFE_ACTION_RESTART | BFE_ACTION_RESTART_FAULT);
2121 		goto action;
2122 	}
2123 
2124 	/* Descriptor Error */
2125 	if (intr_mask & BFE_ISTAT_DSCE) {
2126 		bfe_error(bfe->bfe_dip, "Descriptor Error. Restarting Chip");
2127 		goto action;
2128 	}
2129 
2130 	/* Receive Descr. Underflow */
2131 	if (intr_mask & BFE_ISTAT_RDU) {
2132 		bfe_error(bfe->bfe_dip,
2133 		    "Receive Descriptor Underflow. Restarting Chip");
2134 		bfe->bfe_stats.ether_stat_macrcv_errors++;
2135 		bfe->bfe_chip_action |=
2136 		    (BFE_ACTION_RESTART | BFE_ACTION_RESTART_FAULT);
2137 		goto action;
2138 	}
2139 
2140 	v = INL(bfe, BFE_DMATX_STAT);
2141 
2142 	/* Error while sending a packet */
2143 	if (v & BFE_STAT_EMASK) {
2144 		bfe->bfe_stats.ether_stat_macxmt_errors++;
2145 		bfe_error(bfe->bfe_dip,
2146 		    "Error while sending a packet. Restarting Chip");
2147 	}
2148 
2149 	/* Error while receiving a packet */
2150 	v = INL(bfe, BFE_DMARX_STAT);
2151 	if (v & BFE_RX_FLAG_ERRORS) {
2152 		bfe->bfe_stats.ierrors++;
2153 		bfe_error(bfe->bfe_dip,
2154 		    "Error while receiving a packet. Restarting Chip");
2155 	}
2156 
2157 
2158 	bfe->bfe_chip_action |=
2159 	    (BFE_ACTION_RESTART | BFE_ACTION_RESTART_FAULT);
2160 
2161 action:
2162 	bfe_chip_halt(bfe);
2163 }
2164 
2165 /*
2166  * It will recycle a RX descriptor slot.
2167  */
2168 static void
2169 bfe_rx_desc_buf_reinit(bfe_t *bfe, uint_t slot)
2170 {
2171 	bfe_ring_t *r = &bfe->bfe_rx_ring;
2172 	uint32_t v;
2173 
2174 	slot %= RX_NUM_DESC;
2175 
2176 	bzero(r->r_buf_dma[slot].addr, sizeof (bfe_rx_header_t));
2177 
2178 	(void) SYNC_BUF(r, slot, 0, BFE_RX_OFFSET, DDI_DMA_SYNC_FORDEV);
2179 
2180 	v = r->r_buf_dma[slot].len  & BFE_DESC_LEN;
2181 	if (slot == (RX_NUM_DESC - 1))
2182 		v |= BFE_DESC_EOT;
2183 
2184 	PUT_DESC(r, (uint32_t *)&(r->r_desc[slot].desc_ctl), v);
2185 
2186 	/*
2187 	 * DMA addresses need to be added to BFE_PCI_DMA
2188 	 */
2189 	PUT_DESC(r, (uint32_t *)&(r->r_desc[slot].desc_addr),
2190 	    (r->r_buf_dma[slot].cookie.dmac_laddress + BFE_PCI_DMA));
2191 }
2192 
2193 /*
2194  * Gets called from interrupt context to handle RX interrupt.
2195  */
2196 static mblk_t *
2197 bfe_receive(bfe_t *bfe, int intr_mask)
2198 {
2199 	int rxstat, current;
2200 	mblk_t	*mp = NULL, *rx_head, *rx_tail;
2201 	uchar_t	*rx_header;
2202 	uint16_t len;
2203 	uchar_t	*bp;
2204 	bfe_ring_t *r = &bfe->bfe_rx_ring;
2205 	int i;
2206 
2207 	rxstat = INL(bfe, BFE_DMARX_STAT);
2208 	current = (rxstat & BFE_STAT_CDMASK) / sizeof (bfe_desc_t);
2209 	i = r->r_curr_desc;
2210 
2211 	rx_head = rx_tail = NULL;
2212 
2213 	DTRACE_PROBE3(receive, int, bfe->bfe_unit,
2214 	    int, r->r_curr_desc,
2215 	    int, current);
2216 
2217 	for (i = r->r_curr_desc; i != current;
2218 	    BFE_INC_SLOT(i, RX_NUM_DESC)) {
2219 
2220 		/*
2221 		 * Sync the buffer associated with the descriptor table entry.
2222 		 */
2223 		(void) SYNC_BUF(r, i, 0, r->r_buf_dma[i].len,
2224 		    DDI_DMA_SYNC_FORKERNEL);
2225 
2226 		rx_header = (void *)r->r_buf_dma[i].addr;
2227 
2228 		/*
2229 		 * We do this to make sure we are endian neutral. Chip is
2230 		 * big endian.
2231 		 *
2232 		 * The header looks like :-
2233 		 *
2234 		 *  Offset 0  -> uint16_t len
2235 		 *  Offset 2  -> uint16_t flags
2236 		 *  Offset 4  -> uint16_t pad[12]
2237 		 */
2238 		len = (rx_header[1] << 8) | rx_header[0];
2239 		len -= 4;	/* CRC bytes need to be removed */
2240 
2241 		/*
2242 		 * Don't receive this packet if pkt length is greater than
2243 		 * MTU + VLAN_TAGSZ.
2244 		 */
2245 		if (len > r->r_buf_len) {
2246 			/* Recycle slot for later use */
2247 			bfe_rx_desc_buf_reinit(bfe, i);
2248 			continue;
2249 		}
2250 
2251 		if ((mp = allocb(len + VLAN_TAGSZ, BPRI_MED)) != NULL) {
2252 			mp->b_rptr += VLAN_TAGSZ;
2253 			bp = mp->b_rptr;
2254 			mp->b_wptr = bp + len;
2255 
2256 			/* sizeof (bfe_rx_header_t) + 2 */
2257 			bcopy(r->r_buf_dma[i].addr +
2258 			    BFE_RX_OFFSET, bp, len);
2259 
2260 			mp->b_next = NULL;
2261 			if (rx_tail == NULL)
2262 				rx_head = rx_tail = mp;
2263 			else {
2264 				rx_tail->b_next = mp;
2265 				rx_tail = mp;
2266 			}
2267 
2268 			/* Number of packets received so far */
2269 			bfe->bfe_stats.ipackets++;
2270 
2271 			/* Total bytes of packets received so far */
2272 			bfe->bfe_stats.rbytes += len;
2273 
2274 			if (bcmp(mp->b_rptr, bfe_broadcast, ETHERADDRL) == 0)
2275 				bfe->bfe_stats.brdcstrcv++;
2276 			else
2277 				bfe->bfe_stats.multircv++;
2278 		} else {
2279 			bfe->bfe_stats.norcvbuf++;
2280 			/* Recycle the slot for later use */
2281 			bfe_rx_desc_buf_reinit(bfe, i);
2282 			break;
2283 		}
2284 
2285 		/*
2286 		 * Reinitialize the current descriptor slot's buffer so that
2287 		 * it can be reused.
2288 		 */
2289 		bfe_rx_desc_buf_reinit(bfe, i);
2290 	}
2291 
2292 	r->r_curr_desc = i;
2293 
2294 	(void) SYNC_DESC(r, 0, r->r_ndesc, DDI_DMA_SYNC_FORDEV);
2295 
2296 	return (rx_head);
2297 }
2298 
2299 static int
2300 bfe_tx_reclaim(bfe_ring_t *r)
2301 {
2302 	uint32_t cur, start;
2303 	uint32_t v;
2304 
2305 	cur = INL(r->r_bfe, BFE_DMATX_STAT) & BFE_STAT_CDMASK;
2306 	cur = cur / sizeof (bfe_desc_t);
2307 
2308 	/*
2309 	 * Start with the last descriptor consumed by the chip.
2310 	 */
2311 	start = r->r_cons_desc;
2312 
2313 	DTRACE_PROBE3(tx__reclaim, int, r->r_bfe->bfe_unit,
2314 	    int, start,
2315 	    int, cur);
2316 
2317 	/*
2318 	 * There will be at least one descriptor to process.
2319 	 */
2320 	while (start != cur) {
2321 		r->r_avail_desc++;
2322 		v = r->r_buf_dma[start].len  & BFE_DESC_LEN;
2323 		if (start == (TX_NUM_DESC - 1))
2324 			v |= BFE_DESC_EOT;
2325 
2326 		PUT_DESC(r, (uint32_t *)&(r->r_desc[start].desc_ctl), v);
2327 		PUT_DESC(r, (uint32_t *)&(r->r_desc[start].desc_addr),
2328 		    (r->r_buf_dma[start].cookie.dmac_laddress + BFE_PCI_DMA));
2329 
2330 		/* Move to next descriptor in TX ring */
2331 		BFE_INC_SLOT(start, TX_NUM_DESC);
2332 	}
2333 
2334 	(void) ddi_dma_sync(r->r_desc_dma_handle,
2335 	    0, (r->r_ndesc * sizeof (bfe_desc_t)),
2336 	    DDI_DMA_SYNC_FORDEV);
2337 
2338 	r->r_cons_desc = start; 	/* consumed pointer */
2339 	r->r_bfe->bfe_tx_stall_time = 0;
2340 
2341 	return (cur);
2342 }
2343 
2344 static int
2345 bfe_tx_done(bfe_t *bfe, int intr_mask)
2346 {
2347 	bfe_ring_t *r = &bfe->bfe_tx_ring;
2348 	int resched = 0;
2349 
2350 	mutex_enter(&r->r_lock);
2351 	(void) bfe_tx_reclaim(r);
2352 
2353 	if (bfe->bfe_tx_resched) {
2354 		resched = 1;
2355 		bfe->bfe_tx_resched = 0;
2356 	}
2357 	mutex_exit(&r->r_lock);
2358 
2359 	return (resched);
2360 }
2361 
2362 /*
2363  * ISR for interrupt handling
2364  */
2365 static uint_t
2366 bfe_interrupt(caddr_t arg1, caddr_t arg2)
2367 {
2368 	bfe_t *bfe =  (void *)arg1;
2369 	uint32_t	intr_stat;
2370 	mblk_t *rx_head = NULL;
2371 	int resched = 0;
2372 
2373 	/*
2374 	 * Grab the lock to avoid stopping the chip while this interrupt
2375 	 * is handled.
2376 	 */
2377 	rw_enter(&bfe->bfe_rwlock, RW_READER);
2378 
2379 	/*
2380 	 * It's necessary to read intr stat again because masking interrupt
2381 	 * register does not really mask interrupts coming from the chip.
2382 	 */
2383 	intr_stat = INL(bfe, BFE_INTR_STAT);
2384 	intr_stat &= BFE_IMASK_DEF;
2385 	OUTL(bfe, BFE_INTR_STAT, intr_stat);
2386 	(void) INL(bfe, BFE_INTR_STAT);
2387 
2388 	if (intr_stat == 0) {
2389 		rw_exit(&bfe->bfe_rwlock);
2390 		return (DDI_INTR_UNCLAIMED);
2391 	}
2392 
2393 	DTRACE_PROBE2(bfe__interrupt, int, bfe->bfe_unit,
2394 	    int, intr_stat);
2395 
2396 	if (bfe->bfe_chip_state != BFE_CHIP_ACTIVE) {
2397 		/*
2398 		 * If chip is suspended then we just return.
2399 		 */
2400 		if (bfe->bfe_chip_state == BFE_CHIP_SUSPENDED) {
2401 			rw_exit(&bfe->bfe_rwlock);
2402 			DTRACE_PROBE1(interrupt__chip__is__suspend, int,
2403 			    bfe->bfe_unit);
2404 			return (DDI_INTR_CLAIMED);
2405 		}
2406 
2407 		/*
2408 		 * Halt the chip again i.e basically disable interrupts.
2409 		 */
2410 		bfe_chip_halt(bfe);
2411 		rw_exit(&bfe->bfe_rwlock);
2412 		DTRACE_PROBE1(interrupt__chip__not__active, int,
2413 		    bfe->bfe_unit);
2414 		return (DDI_INTR_CLAIMED);
2415 	}
2416 
2417 	/* A packet was received */
2418 	if (intr_stat & BFE_ISTAT_RX) {
2419 		rx_head = bfe_receive(bfe, intr_stat);
2420 	}
2421 
2422 	/* A packet was sent down the wire */
2423 	if (intr_stat & BFE_ISTAT_TX) {
2424 		resched = bfe_tx_done(bfe, intr_stat);
2425 	}
2426 
2427 	/* There was an error */
2428 	if (intr_stat & BFE_ISTAT_ERRORS) {
2429 		bfe_error_handler(bfe, intr_stat);
2430 	}
2431 
2432 	rw_exit(&bfe->bfe_rwlock);
2433 
2434 	/*
2435 	 * Pass the list of packets received from chip to MAC layer.
2436 	 */
2437 	if (rx_head) {
2438 		mac_rx(bfe->bfe_machdl, 0, rx_head);
2439 	}
2440 
2441 	/*
2442 	 * Let the MAC start sending pkts to a potential stopped stream.
2443 	 */
2444 	if (resched)
2445 		mac_tx_update(bfe->bfe_machdl);
2446 
2447 	return (DDI_INTR_CLAIMED);
2448 }
2449 
2450 /*
2451  * Removes registered interrupt handler.
2452  */
2453 static void
2454 bfe_remove_intr(bfe_t *bfe)
2455 {
2456 	(void) ddi_intr_remove_handler(bfe->bfe_intrhdl);
2457 	(void) ddi_intr_free(bfe->bfe_intrhdl);
2458 }
2459 
2460 /*
2461  * Add an interrupt for the driver.
2462  */
2463 static int
2464 bfe_add_intr(bfe_t *bfe)
2465 {
2466 	int	nintrs = 1;
2467 	int ret;
2468 
2469 	ret = ddi_intr_alloc(bfe->bfe_dip, &bfe->bfe_intrhdl,
2470 	    DDI_INTR_TYPE_FIXED,	/* type */
2471 	    0,	/* inumber */
2472 	    1,	/* count */
2473 	    &nintrs,	/* actual nintrs */
2474 	    DDI_INTR_ALLOC_STRICT);
2475 
2476 	if (ret != DDI_SUCCESS) {
2477 		bfe_error(bfe->bfe_dip, "ddi_intr_alloc() failed"
2478 		    " : ret : %d", ret);
2479 		return (DDI_FAILURE);
2480 	}
2481 
2482 	ret = ddi_intr_add_handler(bfe->bfe_intrhdl, bfe_interrupt, bfe, NULL);
2483 	if (ret != DDI_SUCCESS) {
2484 		bfe_error(bfe->bfe_dip, "ddi_intr_add_handler() failed");
2485 		(void) ddi_intr_free(bfe->bfe_intrhdl);
2486 		return (DDI_FAILURE);
2487 	}
2488 
2489 	ret = ddi_intr_get_pri(bfe->bfe_intrhdl, &bfe->bfe_intrpri);
2490 	if (ret != DDI_SUCCESS) {
2491 		bfe_error(bfe->bfe_dip, "ddi_intr_get_pri() failed");
2492 		bfe_remove_intr(bfe);
2493 		return (DDI_FAILURE);
2494 	}
2495 
2496 	return (DDI_SUCCESS);
2497 }
2498 
2499 
2500 /*
2501  * Identify chipset family.
2502  */
2503 static int
2504 bfe_identify_hardware(bfe_t *bfe)
2505 {
2506 	uint16_t	vid, did;
2507 	int i;
2508 
2509 	vid = pci_config_get16(bfe->bfe_conf_handle, PCI_CONF_VENID);
2510 	did = pci_config_get16(bfe->bfe_conf_handle, PCI_CONF_DEVID);
2511 
2512 	for (i = 0; i < (sizeof (bfe_cards) / sizeof (bfe_cards_t)); i++) {
2513 		if (bfe_cards[i].vendor_id == vid &&
2514 		    bfe_cards[i].device_id == did) {
2515 			return (BFE_SUCCESS);
2516 		}
2517 	}
2518 
2519 	bfe_error(bfe->bfe_dip, "bfe driver is attaching to unknown pci%d,%d"
2520 	    " vendor/device-id card", vid, did);
2521 
2522 	return (BFE_SUCCESS);
2523 }
2524 
2525 /*
2526  * Maps device registers.
2527  */
2528 static int
2529 bfe_regs_map(bfe_t *bfe)
2530 {
2531 	dev_info_t *dip = bfe->bfe_dip;
2532 	int ret;
2533 
2534 	ret = ddi_regs_map_setup(dip, 1, &bfe->bfe_mem_regset.addr, 0, 0,
2535 	    &bfe_dev_attr, &bfe->bfe_mem_regset.hdl);
2536 
2537 	if (ret != DDI_SUCCESS) {
2538 		bfe_error(bfe->bfe_dip, "ddi_regs_map_setup failed");
2539 		return (DDI_FAILURE);
2540 	}
2541 
2542 	return (DDI_SUCCESS);
2543 }
2544 
2545 static void
2546 bfe_unmap_regs(bfe_t *bfe)
2547 {
2548 	ddi_regs_map_free(&bfe->bfe_mem_regset.hdl);
2549 }
2550 
2551 static int
2552 bfe_get_chip_config(bfe_t *bfe)
2553 {
2554 	uint32_t	prom[BFE_EEPROM_SIZE];
2555 	int i;
2556 
2557 	/*
2558 	 * Read EEPROM in prom[]
2559 	 */
2560 	for (i = 0; i < BFE_EEPROM_SIZE; i++) {
2561 		prom[i] = INL(bfe, BFE_EEPROM_BASE + i * sizeof (uint32_t));
2562 	}
2563 
2564 	bfe->bfe_dev_addr[0] = bfe->bfe_ether_addr[0] =
2565 	    INB(bfe, BFE_EEPROM_BASE + 79);
2566 
2567 	bfe->bfe_dev_addr[1] = bfe->bfe_ether_addr[1] =
2568 	    INB(bfe, BFE_EEPROM_BASE + 78);
2569 
2570 	bfe->bfe_dev_addr[2] = bfe->bfe_ether_addr[2] =
2571 	    INB(bfe, BFE_EEPROM_BASE + 81);
2572 
2573 	bfe->bfe_dev_addr[3] = bfe->bfe_ether_addr[3] =
2574 	    INB(bfe, BFE_EEPROM_BASE + 80);
2575 
2576 	bfe->bfe_dev_addr[4] = bfe->bfe_ether_addr[4] =
2577 	    INB(bfe, BFE_EEPROM_BASE + 83);
2578 
2579 	bfe->bfe_dev_addr[5] = bfe->bfe_ether_addr[5] =
2580 	    INB(bfe, BFE_EEPROM_BASE + 82);
2581 
2582 	bfe->bfe_phy_addr = -1;
2583 
2584 	return (DDI_SUCCESS);
2585 }
2586 
2587 /*
2588  * Ring Management routines
2589  */
2590 static int
2591 bfe_ring_buf_alloc(bfe_t *bfe, bfe_ring_t *r, int slot, int d)
2592 {
2593 	int err;
2594 	uint_t count = 0;
2595 
2596 	err = ddi_dma_alloc_handle(bfe->bfe_dip,
2597 	    &bfe_dma_attr_buf, DDI_DMA_SLEEP, NULL,
2598 	    &r->r_buf_dma[slot].handle);
2599 
2600 	if (err != DDI_SUCCESS) {
2601 		bfe_error(bfe->bfe_dip, " bfe_ring_buf_alloc() :"
2602 		    " alloc_handle failed");
2603 		goto fail0;
2604 	}
2605 
2606 	err = ddi_dma_mem_alloc(r->r_buf_dma[slot].handle,
2607 	    r->r_buf_len, &bfe_buf_attr, DDI_DMA_STREAMING,
2608 	    DDI_DMA_SLEEP, NULL, &r->r_buf_dma[slot].addr,
2609 	    &r->r_buf_dma[slot].len,
2610 	    &r->r_buf_dma[slot].acchdl);
2611 
2612 	if (err != DDI_SUCCESS) {
2613 		bfe_error(bfe->bfe_dip, " bfe_ring_buf_alloc() :"
2614 		    " mem_alloc failed :%d", err);
2615 		goto fail1;
2616 	}
2617 
2618 	err = ddi_dma_addr_bind_handle(r->r_buf_dma[slot].handle,
2619 	    NULL, r->r_buf_dma[slot].addr,
2620 	    r->r_buf_dma[slot].len,
2621 	    (DDI_DMA_RDWR | DDI_DMA_STREAMING),
2622 	    DDI_DMA_SLEEP, NULL,
2623 	    &r->r_buf_dma[slot].cookie,
2624 	    &count);
2625 
2626 	if (err != DDI_DMA_MAPPED) {
2627 		bfe_error(bfe->bfe_dip, " bfe_ring_buf_alloc() :"
2628 		    " bind_handle failed");
2629 		goto fail2;
2630 	}
2631 
2632 	if (count > 1) {
2633 		bfe_error(bfe->bfe_dip, " bfe_ring_buf_alloc() :"
2634 		    " more than one DMA cookie");
2635 		(void) ddi_dma_unbind_handle(r->r_buf_dma[slot].handle);
2636 		goto fail2;
2637 	}
2638 
2639 	return (DDI_SUCCESS);
2640 fail2:
2641 	ddi_dma_mem_free(&r->r_buf_dma[slot].acchdl);
2642 fail1:
2643 	ddi_dma_free_handle(&r->r_buf_dma[slot].handle);
2644 fail0:
2645 	return (DDI_FAILURE);
2646 }
2647 
2648 static void
2649 bfe_ring_buf_free(bfe_ring_t *r, int slot)
2650 {
2651 	if (r->r_buf_dma == NULL)
2652 		return;
2653 
2654 	(void) ddi_dma_unbind_handle(r->r_buf_dma[slot].handle);
2655 	ddi_dma_mem_free(&r->r_buf_dma[slot].acchdl);
2656 	ddi_dma_free_handle(&r->r_buf_dma[slot].handle);
2657 }
2658 
2659 static void
2660 bfe_buffer_free(bfe_ring_t *r)
2661 {
2662 	int i;
2663 
2664 	for (i = 0; i < r->r_ndesc; i++) {
2665 		bfe_ring_buf_free(r, i);
2666 	}
2667 }
2668 
2669 static void
2670 bfe_ring_desc_free(bfe_ring_t *r)
2671 {
2672 	(void) ddi_dma_unbind_handle(r->r_desc_dma_handle);
2673 	ddi_dma_mem_free(&r->r_desc_acc_handle);
2674 	ddi_dma_free_handle(&r->r_desc_dma_handle);
2675 	kmem_free(r->r_buf_dma, r->r_ndesc * sizeof (bfe_dma_t));
2676 
2677 	r->r_buf_dma = NULL;
2678 	r->r_desc = NULL;
2679 }
2680 
2681 
2682 static int
2683 bfe_ring_desc_alloc(bfe_t *bfe, bfe_ring_t *r, int d)
2684 {
2685 	int err, i, fail = 0;
2686 	caddr_t	ring;
2687 	size_t	size_krnl = 0, size_dma = 0, ring_len = 0;
2688 	ddi_dma_cookie_t cookie;
2689 	uint_t	count = 0;
2690 
2691 	ASSERT(bfe != NULL);
2692 
2693 	size_krnl = r->r_ndesc * sizeof (bfe_dma_t);
2694 	size_dma = r->r_ndesc * sizeof (bfe_desc_t);
2695 	r->r_buf_dma = kmem_zalloc(size_krnl, KM_SLEEP);
2696 
2697 
2698 	err = ddi_dma_alloc_handle(bfe->bfe_dip, &bfe_dma_attr_desc,
2699 	    DDI_DMA_SLEEP, NULL, &r->r_desc_dma_handle);
2700 
2701 	if (err != DDI_SUCCESS) {
2702 		bfe_error(bfe->bfe_dip, "bfe_ring_desc_alloc() failed on"
2703 		    " ddi_dma_alloc_handle()");
2704 		kmem_free(r->r_buf_dma, size_krnl);
2705 		return (DDI_FAILURE);
2706 	}
2707 
2708 
2709 	err = ddi_dma_mem_alloc(r->r_desc_dma_handle,
2710 	    size_dma, &bfe_buf_attr,
2711 	    DDI_DMA_CONSISTENT, DDI_DMA_SLEEP, NULL,
2712 	    &ring, &ring_len, &r->r_desc_acc_handle);
2713 
2714 	if (err != DDI_SUCCESS) {
2715 		bfe_error(bfe->bfe_dip, "bfe_ring_desc_alloc() failed on"
2716 		    " ddi_dma_mem_alloc()");
2717 		ddi_dma_free_handle(&r->r_desc_dma_handle);
2718 		kmem_free(r->r_buf_dma, size_krnl);
2719 		return (DDI_FAILURE);
2720 	}
2721 
2722 	err = ddi_dma_addr_bind_handle(r->r_desc_dma_handle,
2723 	    NULL, ring, ring_len,
2724 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
2725 	    DDI_DMA_SLEEP, NULL,
2726 	    &cookie, &count);
2727 
2728 	if (err != DDI_SUCCESS) {
2729 		bfe_error(bfe->bfe_dip, "bfe_ring_desc_alloc() failed on"
2730 		    " ddi_dma_addr_bind_handle()");
2731 		ddi_dma_mem_free(&r->r_desc_acc_handle);
2732 		ddi_dma_free_handle(&r->r_desc_dma_handle);
2733 		kmem_free(r->r_buf_dma, size_krnl);
2734 		return (DDI_FAILURE);
2735 	}
2736 
2737 	/*
2738 	 * We don't want to have multiple cookies. Descriptor should be
2739 	 * aligned to PAGESIZE boundary.
2740 	 */
2741 	ASSERT(count == 1);
2742 
2743 	/* The actual descriptor for the ring */
2744 	r->r_desc_len = ring_len;
2745 	r->r_desc_cookie = cookie;
2746 
2747 	r->r_desc = (void *)ring;
2748 
2749 	bzero(r->r_desc, size_dma);
2750 	bzero(r->r_desc, ring_len);
2751 
2752 	/* For each descriptor, allocate a DMA buffer */
2753 	fail = 0;
2754 	for (i = 0; i < r->r_ndesc; i++) {
2755 		if (bfe_ring_buf_alloc(bfe, r, i, d) != DDI_SUCCESS) {
2756 			i--;
2757 			fail = 1;
2758 			break;
2759 		}
2760 	}
2761 
2762 	if (fail) {
2763 		while (i-- >= 0) {
2764 			bfe_ring_buf_free(r, i);
2765 		}
2766 
2767 		/* We don't need the descriptor anymore */
2768 		bfe_ring_desc_free(r);
2769 		return (DDI_FAILURE);
2770 	}
2771 
2772 	return (DDI_SUCCESS);
2773 }
2774 
2775 static int
2776 bfe_rings_alloc(bfe_t *bfe)
2777 {
2778 	/* TX */
2779 	mutex_init(&bfe->bfe_tx_ring.r_lock, NULL, MUTEX_DRIVER, NULL);
2780 	bfe->bfe_tx_ring.r_lockp = &bfe->bfe_tx_ring.r_lock;
2781 	bfe->bfe_tx_ring.r_buf_len = BFE_MTU + sizeof (struct ether_header) +
2782 	    VLAN_TAGSZ + ETHERFCSL;
2783 	bfe->bfe_tx_ring.r_ndesc = TX_NUM_DESC;
2784 	bfe->bfe_tx_ring.r_bfe = bfe;
2785 	bfe->bfe_tx_ring.r_avail_desc = TX_NUM_DESC;
2786 
2787 	/* RX */
2788 	mutex_init(&bfe->bfe_rx_ring.r_lock, NULL, MUTEX_DRIVER, NULL);
2789 	bfe->bfe_rx_ring.r_lockp = &bfe->bfe_rx_ring.r_lock;
2790 	bfe->bfe_rx_ring.r_buf_len = BFE_MTU + sizeof (struct ether_header) +
2791 	    VLAN_TAGSZ + ETHERFCSL + RX_HEAD_ROOM;
2792 	bfe->bfe_rx_ring.r_ndesc = RX_NUM_DESC;
2793 	bfe->bfe_rx_ring.r_bfe = bfe;
2794 	bfe->bfe_rx_ring.r_avail_desc = RX_NUM_DESC;
2795 
2796 	/* Allocate TX Ring */
2797 	if (bfe_ring_desc_alloc(bfe, &bfe->bfe_tx_ring,
2798 	    DDI_DMA_WRITE) != DDI_SUCCESS)
2799 		return (DDI_FAILURE);
2800 
2801 	/* Allocate RX Ring */
2802 	if (bfe_ring_desc_alloc(bfe, &bfe->bfe_rx_ring,
2803 	    DDI_DMA_READ) != DDI_SUCCESS) {
2804 		cmn_err(CE_NOTE, "RX ring allocation failed");
2805 		bfe_ring_desc_free(&bfe->bfe_tx_ring);
2806 		return (DDI_FAILURE);
2807 	}
2808 
2809 	bfe->bfe_tx_ring.r_flags = BFE_RING_ALLOCATED;
2810 	bfe->bfe_rx_ring.r_flags = BFE_RING_ALLOCATED;
2811 
2812 	return (DDI_SUCCESS);
2813 }
2814 
2815 static int
2816 bfe_resume(dev_info_t *dip)
2817 {
2818 	bfe_t *bfe;
2819 	int err = DDI_SUCCESS;
2820 
2821 	if ((bfe = ddi_get_driver_private(dip)) == NULL) {
2822 		bfe_error(dip, "Unexpected error (no driver private data)"
2823 		    " while resume");
2824 		return (DDI_FAILURE);
2825 	}
2826 
2827 	/*
2828 	 * Grab all the locks first.
2829 	 */
2830 	bfe_grab_locks(bfe);
2831 	bfe->bfe_chip_state = BFE_CHIP_RESUME;
2832 
2833 	bfe_init_vars(bfe);
2834 	/* PHY will also start running */
2835 	bfe_chip_reset(bfe);
2836 	if (bfe_chip_start(bfe) == DDI_FAILURE) {
2837 		bfe_error(dip, "Could not resume chip");
2838 		err = DDI_FAILURE;
2839 	}
2840 
2841 	bfe_release_locks(bfe);
2842 
2843 	if (err == DDI_SUCCESS)
2844 		mac_tx_update(bfe->bfe_machdl);
2845 
2846 	return (err);
2847 }
2848 
2849 static int
2850 bfe_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
2851 {
2852 	int	unit;
2853 	bfe_t	*bfe;
2854 	mac_register_t	*macreg;
2855 	int	ret;
2856 
2857 	switch (cmd) {
2858 	case DDI_RESUME:
2859 		return (bfe_resume(dip));
2860 
2861 	case DDI_ATTACH:
2862 		break;
2863 
2864 	default:
2865 		return (DDI_FAILURE);
2866 	}
2867 
2868 
2869 	unit = ddi_get_instance(dip);
2870 
2871 	bfe = kmem_zalloc(sizeof (bfe_t), KM_SLEEP);
2872 	bfe->bfe_dip = dip;
2873 	bfe->bfe_unit = unit;
2874 
2875 	if (pci_config_setup(dip, &bfe->bfe_conf_handle) != DDI_SUCCESS) {
2876 		bfe_error(dip, "pci_config_setup failed");
2877 		goto fail0;
2878 	}
2879 
2880 	/*
2881 	 * Enable IO space, Bus Master and Memory Space accessess.
2882 	 */
2883 	ret = pci_config_get16(bfe->bfe_conf_handle, PCI_CONF_COMM);
2884 	pci_config_put16(bfe->bfe_conf_handle, PCI_CONF_COMM,
2885 	    PCI_COMM_IO | PCI_COMM_MAE | PCI_COMM_ME | ret);
2886 
2887 	ddi_set_driver_private(dip, bfe);
2888 
2889 	/* Identify hardware */
2890 	if (bfe_identify_hardware(bfe) == BFE_FAILURE) {
2891 		bfe_error(dip, "Could not identify device");
2892 		goto fail1;
2893 	}
2894 
2895 	if (bfe_regs_map(bfe) != DDI_SUCCESS) {
2896 		bfe_error(dip, "Could not map device registers");
2897 		goto fail1;
2898 	}
2899 
2900 	(void) bfe_get_chip_config(bfe);
2901 
2902 	/*
2903 	 * Register with MAC layer
2904 	 */
2905 	if ((macreg = mac_alloc(MAC_VERSION)) == NULL) {
2906 		bfe_error(dip, "mac_alloc() failed");
2907 		goto fail2;
2908 	}
2909 
2910 	macreg->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
2911 	macreg->m_driver = bfe;
2912 	macreg->m_dip = dip;
2913 	macreg->m_instance = unit;
2914 	macreg->m_src_addr = bfe->bfe_ether_addr;
2915 	macreg->m_callbacks = &bfe_mac_callbacks;
2916 	macreg->m_min_sdu = 0;
2917 	macreg->m_max_sdu = ETHERMTU;
2918 	macreg->m_margin = VLAN_TAGSZ;
2919 
2920 	if ((ret = mac_register(macreg, &bfe->bfe_machdl)) != 0) {
2921 		bfe_error(dip, "mac_register() failed with %d error", ret);
2922 		mac_free(macreg);
2923 		goto fail2;
2924 	}
2925 
2926 	mac_free(macreg);
2927 
2928 	rw_init(&bfe->bfe_rwlock, NULL, RW_DRIVER,
2929 	    DDI_INTR_PRI(bfe->bfe_intrpri));
2930 
2931 	if (bfe_add_intr(bfe) != DDI_SUCCESS) {
2932 		bfe_error(dip, "Could not add interrupt");
2933 		goto fail3;
2934 	}
2935 
2936 	if (bfe_rings_alloc(bfe) != DDI_SUCCESS) {
2937 		bfe_error(dip, "Could not allocate TX/RX Ring");
2938 		goto fail4;
2939 	}
2940 
2941 	/* Init and then reset the chip */
2942 	bfe->bfe_chip_action = 0;
2943 	bfe_init_vars(bfe);
2944 
2945 	/* PHY will also start running */
2946 	bfe_chip_reset(bfe);
2947 
2948 	/*
2949 	 * Even though we enable the interrupts here but chip's interrupt
2950 	 * is not enabled yet. It will be enabled once we plumb the interface.
2951 	 */
2952 	if (ddi_intr_enable(bfe->bfe_intrhdl) != DDI_SUCCESS) {
2953 		bfe_error(dip, "Could not enable interrupt");
2954 		goto fail4;
2955 	}
2956 
2957 	return (DDI_SUCCESS);
2958 
2959 fail4:
2960 	bfe_remove_intr(bfe);
2961 fail3:
2962 	(void) mac_unregister(bfe->bfe_machdl);
2963 fail2:
2964 	bfe_unmap_regs(bfe);
2965 fail1:
2966 	pci_config_teardown(&bfe->bfe_conf_handle);
2967 fail0:
2968 	kmem_free(bfe, sizeof (bfe_t));
2969 	return (DDI_FAILURE);
2970 }
2971 
2972 static int
2973 bfe_detach(dev_info_t *devinfo, ddi_detach_cmd_t cmd)
2974 {
2975 	bfe_t *bfe;
2976 
2977 	bfe = ddi_get_driver_private(devinfo);
2978 
2979 	switch (cmd) {
2980 	case DDI_DETACH:
2981 		/*
2982 		 * We need to stop the timer before grabbing locks otherwise
2983 		 * we can land-up in deadlock with untimeout.
2984 		 */
2985 		bfe_stop_timer(bfe);
2986 
2987 		/*
2988 		 * First unregister with MAC layer before stopping DMA
2989 		 * engine.
2990 		 */
2991 		if (mac_unregister(bfe->bfe_machdl) != DDI_SUCCESS)
2992 			return (DDI_FAILURE);
2993 
2994 		bfe->bfe_machdl = NULL;
2995 
2996 		/*
2997 		 * Quiesce the chip first.
2998 		 */
2999 		bfe_grab_locks(bfe);
3000 		bfe_chip_halt(bfe);
3001 		bfe_stop_phy(bfe);
3002 		bfe_release_locks(bfe);
3003 
3004 		(void) ddi_intr_disable(bfe->bfe_intrhdl);
3005 
3006 		/* Make sure timer is gone. */
3007 		bfe_stop_timer(bfe);
3008 
3009 		/*
3010 		 * Free the DMA resources for buffer and then descriptors
3011 		 */
3012 		if (bfe->bfe_tx_ring.r_flags == BFE_RING_ALLOCATED) {
3013 			/* TX */
3014 			bfe_buffer_free(&bfe->bfe_tx_ring);
3015 			bfe_ring_desc_free(&bfe->bfe_tx_ring);
3016 		}
3017 
3018 		if (bfe->bfe_rx_ring.r_flags == BFE_RING_ALLOCATED) {
3019 			/* RX */
3020 			bfe_buffer_free(&bfe->bfe_rx_ring);
3021 			bfe_ring_desc_free(&bfe->bfe_rx_ring);
3022 		}
3023 
3024 		bfe_remove_intr(bfe);
3025 		bfe_unmap_regs(bfe);
3026 		pci_config_teardown(&bfe->bfe_conf_handle);
3027 
3028 		mutex_destroy(&bfe->bfe_tx_ring.r_lock);
3029 		mutex_destroy(&bfe->bfe_rx_ring.r_lock);
3030 		rw_destroy(&bfe->bfe_rwlock);
3031 
3032 		kmem_free(bfe, sizeof (bfe_t));
3033 
3034 		ddi_set_driver_private(devinfo, NULL);
3035 		return (DDI_SUCCESS);
3036 
3037 	case DDI_SUSPEND:
3038 		/*
3039 		 * We need to stop the timer before grabbing locks otherwise
3040 		 * we can land-up in deadlock with untimeout.
3041 		 */
3042 		bfe_stop_timer(bfe);
3043 
3044 		/*
3045 		 * Grab all the locks first.
3046 		 */
3047 		bfe_grab_locks(bfe);
3048 		bfe_chip_halt(bfe);
3049 		bfe_stop_phy(bfe);
3050 		bfe->bfe_chip_state = BFE_CHIP_SUSPENDED;
3051 		bfe_release_locks(bfe);
3052 
3053 		return (DDI_SUCCESS);
3054 
3055 	default:
3056 		return (DDI_FAILURE);
3057 	}
3058 }
3059 
3060 /*
3061  * Quiesce the card for fast reboot
3062  */
3063 int
3064 bfe_quiesce(dev_info_t *dev_info)
3065 {
3066 	bfe_t *bfe;
3067 
3068 	bfe = ddi_get_driver_private(dev_info);
3069 
3070 	bfe_chip_halt(bfe);
3071 	bfe_stop_phy(bfe);
3072 	bfe->bfe_chip_state = BFE_CHIP_QUIESCED;
3073 
3074 	return (DDI_SUCCESS);
3075 }
3076 
3077 static struct cb_ops bfe_cb_ops = {
3078 	nulldev,		/* cb_open */
3079 	nulldev,		/* cb_close */
3080 	nodev,			/* cb_strategy */
3081 	nodev,			/* cb_print */
3082 	nodev,			/* cb_dump */
3083 	nodev,			/* cb_read */
3084 	nodev,			/* cb_write */
3085 	nodev,			/* cb_ioctl */
3086 	nodev,			/* cb_devmap */
3087 	nodev,			/* cb_mmap */
3088 	nodev,			/* cb_segmap */
3089 	nochpoll,		/* cb_chpoll */
3090 	ddi_prop_op,		/* cb_prop_op */
3091 	NULL,			/* cb_stream */
3092 	D_MP | D_HOTPLUG,	/* cb_flag */
3093 	CB_REV,			/* cb_rev */
3094 	nodev,			/* cb_aread */
3095 	nodev			/* cb_awrite */
3096 };
3097 
3098 static struct dev_ops bfe_dev_ops = {
3099 	DEVO_REV,	/* devo_rev */
3100 	0,		/* devo_refcnt */
3101 	NULL,		/* devo_getinfo */
3102 	nulldev,	/* devo_identify */
3103 	nulldev,	/* devo_probe */
3104 	bfe_attach,	/* devo_attach */
3105 	bfe_detach,	/* devo_detach */
3106 	nodev,		/* devo_reset */
3107 	&bfe_cb_ops,	/* devo_cb_ops */
3108 	NULL,		/* devo_bus_ops */
3109 	ddi_power,	/* devo_power */
3110 	bfe_quiesce	/* devo_quiesce */
3111 };
3112 
3113 static struct modldrv bfe_modldrv = {
3114 	&mod_driverops,
3115 	bfe_ident,
3116 	&bfe_dev_ops
3117 };
3118 
3119 static struct modlinkage modlinkage = {
3120 	MODREV_1, (void *)&bfe_modldrv, NULL
3121 };
3122 
3123 int
3124 _info(struct modinfo *modinfop)
3125 {
3126 	return (mod_info(&modlinkage, modinfop));
3127 }
3128 
3129 int
3130 _init(void)
3131 {
3132 	int	status;
3133 
3134 	mac_init_ops(&bfe_dev_ops, MODULE_NAME);
3135 	status = mod_install(&modlinkage);
3136 	if (status == DDI_FAILURE)
3137 		mac_fini_ops(&bfe_dev_ops);
3138 	return (status);
3139 }
3140 
3141 int
3142 _fini(void)
3143 {
3144 	int status;
3145 
3146 	status = mod_remove(&modlinkage);
3147 	if (status == 0) {
3148 		mac_fini_ops(&bfe_dev_ops);
3149 	}
3150 	return (status);
3151 }
3152