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