Home | History | Annotate | Download | only in eri
      1      0     stevel /*
      2      0     stevel  * CDDL HEADER START
      3      0     stevel  *
      4      0     stevel  * The contents of this file are subject to the terms of the
      5   1366     petede  * Common Development and Distribution License (the "License").
      6   1366     petede  * You may not use this file except in compliance with the License.
      7      0     stevel  *
      8      0     stevel  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
      9      0     stevel  * or http://www.opensolaris.org/os/licensing.
     10      0     stevel  * See the License for the specific language governing permissions
     11      0     stevel  * and limitations under the License.
     12      0     stevel  *
     13      0     stevel  * When distributing Covered Code, include this CDDL HEADER in each
     14      0     stevel  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     15      0     stevel  * If applicable, add the following below this CDDL HEADER, with the
     16      0     stevel  * fields enclosed by brackets "[]" replaced with your own identifying
     17      0     stevel  * information: Portions Copyright [yyyy] [name of copyright owner]
     18      0     stevel  *
     19      0     stevel  * CDDL HEADER END
     20      0     stevel  */
     21      0     stevel /*
     22  10306  Vitezslav  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23      0     stevel  * Use is subject to license terms.
     24      0     stevel  */
     25      0     stevel 
     26      0     stevel /*
     27      0     stevel  * SunOS MT STREAMS ERI(PCI) 10/100 Mb Ethernet Device Driver
     28      0     stevel  */
     29      0     stevel 
     30      0     stevel #include	<sys/types.h>
     31      0     stevel #include	<sys/debug.h>
     32      0     stevel #include	<sys/stropts.h>
     33      0     stevel #include	<sys/stream.h>
     34      0     stevel #include	<sys/strsubr.h>
     35      0     stevel #include	<sys/kmem.h>
     36      0     stevel #include	<sys/crc32.h>
     37      0     stevel #include	<sys/ddi.h>
     38      0     stevel #include	<sys/sunddi.h>
     39      0     stevel #include	<sys/strsun.h>
     40      0     stevel #include	<sys/stat.h>
     41      0     stevel #include	<sys/cpu.h>
     42      0     stevel #include	<sys/kstat.h>
     43      0     stevel #include	<inet/common.h>
     44      0     stevel #include	<sys/pattr.h>
     45      0     stevel #include	<inet/mi.h>
     46      0     stevel #include	<inet/nd.h>
     47      0     stevel #include	<sys/ethernet.h>
     48   5895   yz147064 #include	<sys/vlan.h>
     49      0     stevel #include	<sys/policy.h>
     50   8275       Eric #include	<sys/mac_provider.h>
     51   4404    gd78059 #include	<sys/mac_ether.h>
     52   4404    gd78059 #include	<sys/dlpi.h>
     53      0     stevel 
     54      0     stevel #include	<sys/pci.h>
     55      0     stevel 
     56   6833    gd78059 #include	"eri_phy.h"
     57   6833    gd78059 #include	"eri_mac.h"
     58   6833    gd78059 #include	"eri.h"
     59   6833    gd78059 #include	"eri_common.h"
     60   6833    gd78059 
     61   6833    gd78059 #include	"eri_msg.h"
     62   6833    gd78059 
     63      0     stevel /*
     64      0     stevel  *  **** Function Prototypes *****
     65      0     stevel  */
     66      0     stevel /*
     67      0     stevel  * Entry points (man9e)
     68      0     stevel  */
     69      0     stevel static	int	eri_attach(dev_info_t *, ddi_attach_cmd_t);
     70      0     stevel static	int	eri_detach(dev_info_t *, ddi_detach_cmd_t);
     71   4404    gd78059 static	uint_t	eri_intr(caddr_t);
     72      0     stevel 
     73      0     stevel /*
     74      0     stevel  * I/O (Input/Output) Functions
     75      0     stevel  */
     76   4404    gd78059 static	boolean_t	eri_send_msg(struct eri *, mblk_t *);
     77   4404    gd78059 static  mblk_t		*eri_read_dma(struct eri *, volatile struct rmd *,
     78   4404    gd78059 			    volatile int, uint64_t flags);
     79      0     stevel 
     80      0     stevel /*
     81      0     stevel  * Initialization Functions
     82      0     stevel  */
     83   4404    gd78059 static  boolean_t	eri_init(struct eri *);
     84      0     stevel static	int	eri_allocthings(struct eri *);
     85      0     stevel static  int	eri_init_xfer_params(struct eri *);
     86      0     stevel static  void	eri_statinit(struct eri *);
     87      0     stevel static	int	eri_burstsize(struct eri *);
     88      0     stevel 
     89      0     stevel static	void	eri_setup_mac_address(struct eri *, dev_info_t *);
     90      0     stevel 
     91      0     stevel static	uint32_t eri_init_rx_channel(struct eri *);
     92      0     stevel static	void	eri_init_rx(struct eri *);
     93      0     stevel static	void	eri_init_txmac(struct eri *);
     94      0     stevel 
     95      0     stevel /*
     96      0     stevel  * Un-init Functions
     97      0     stevel  */
     98      0     stevel static	uint32_t eri_txmac_disable(struct eri *);
     99      0     stevel static	uint32_t eri_rxmac_disable(struct eri *);
    100      0     stevel static	int	eri_stop(struct eri *);
    101      0     stevel static	void	eri_uninit(struct eri *erip);
    102      0     stevel static	int	eri_freebufs(struct eri *);
    103   4404    gd78059 static	boolean_t	eri_reclaim(struct eri *, uint32_t);
    104      0     stevel 
    105      0     stevel /*
    106      0     stevel  * Transceiver (xcvr) Functions
    107      0     stevel  */
    108      0     stevel static	int	eri_new_xcvr(struct eri *); /* Initializes & detects xcvrs */
    109      0     stevel static	int	eri_reset_xcvr(struct eri *);
    110      0     stevel 
    111      0     stevel #ifdef	ERI_10_10_FORCE_SPEED_WORKAROUND
    112      0     stevel static	void	eri_xcvr_force_mode(struct eri *, uint32_t *);
    113      0     stevel #endif
    114      0     stevel 
    115      0     stevel static	void	eri_mif_poll(struct eri *, soft_mif_enable_t);
    116      0     stevel static	void	eri_check_link(struct eri *);
    117   2534   carlsonj static	uint32_t eri_check_link_noind(struct eri *);
    118   4404    gd78059 static	link_state_t eri_mif_check(struct eri *, uint16_t, uint16_t);
    119      0     stevel static	void    eri_mii_write(struct eri *, uint8_t, uint16_t);
    120      0     stevel static	uint32_t eri_mii_read(struct eri *, uint8_t, uint16_t *);
    121      0     stevel 
    122      0     stevel /*
    123      0     stevel  * Reset Functions
    124      0     stevel  */
    125      0     stevel static	uint32_t eri_etx_reset(struct eri *);
    126      0     stevel static	uint32_t eri_erx_reset(struct eri *);
    127      0     stevel 
    128      0     stevel /*
    129      0     stevel  * Error Functions
    130      0     stevel  */
    131      0     stevel static	void eri_fatal_err(struct eri *, uint32_t);
    132      0     stevel static	void eri_nonfatal_err(struct eri *, uint32_t);
    133      0     stevel 
    134      0     stevel #ifdef	ERI_TX_HUNG
    135      0     stevel static	int eri_check_txhung(struct eri *);
    136      0     stevel #endif
    137      0     stevel 
    138      0     stevel /*
    139      0     stevel  * Hardening Functions
    140      0     stevel  */
    141   4404    gd78059 static void eri_fault_msg(struct eri *, uint_t, msg_t, const char *, ...);
    142      0     stevel 
    143      0     stevel /*
    144      0     stevel  * Misc Functions
    145      0     stevel  */
    146      0     stevel static void	eri_savecntrs(struct eri *);
    147      0     stevel 
    148      0     stevel static	void	eri_stop_timer(struct eri *erip);
    149      0     stevel static	void	eri_start_timer(struct eri *erip, fptrv_t func, clock_t msec);
    150      0     stevel 
    151      0     stevel static	void eri_bb_force_idle(struct eri *);
    152      0     stevel 
    153      0     stevel /*
    154      0     stevel  * Utility Functions
    155      0     stevel  */
    156      0     stevel static	mblk_t *eri_allocb(size_t size);
    157      0     stevel static	mblk_t *eri_allocb_sp(size_t size);
    158      0     stevel static	int	eri_param_get(queue_t *q, mblk_t *mp, caddr_t cp);
    159      0     stevel static	int	eri_param_set(queue_t *, mblk_t *, char *, caddr_t);
    160      0     stevel 
    161      0     stevel /*
    162      0     stevel  * Functions to support ndd
    163      0     stevel  */
    164      0     stevel static	void	eri_nd_free(caddr_t *nd_pparam);
    165      0     stevel 
    166      0     stevel static	boolean_t	eri_nd_load(caddr_t *nd_pparam, char *name,
    167      0     stevel 				pfi_t get_pfi, pfi_t set_pfi, caddr_t data);
    168      0     stevel 
    169      0     stevel static	int	eri_nd_getset(queue_t *q, caddr_t nd_param, MBLKP mp);
    170      0     stevel static	void	eri_param_cleanup(struct eri *);
    171      0     stevel static	int	eri_param_register(struct eri *, param_t *, int);
    172   4404    gd78059 static	void	eri_process_ndd_ioctl(struct eri *, queue_t *, mblk_t *, int);
    173   4404    gd78059 static	int	eri_mk_mblk_tail_space(mblk_t *, mblk_t **, size_t);
    174   4404    gd78059 
    175   4404    gd78059 
    176   4404    gd78059 static	void eri_loopback(struct eri *, queue_t *, mblk_t *);
    177   4404    gd78059 
    178   4404    gd78059 static uint32_t	eri_ladrf_bit(const uint8_t *);
    179   4404    gd78059 
    180   4404    gd78059 
    181   4404    gd78059 /*
    182   4404    gd78059  * Nemo (GLDv3) Functions.
    183   4404    gd78059  */
    184   4404    gd78059 static	int		eri_m_stat(void *, uint_t, uint64_t *);
    185   4404    gd78059 static	int		eri_m_start(void *);
    186   4404    gd78059 static	void		eri_m_stop(void *);
    187   4404    gd78059 static	int		eri_m_promisc(void *, boolean_t);
    188   4404    gd78059 static	int		eri_m_multicst(void *, boolean_t, const uint8_t *);
    189   4404    gd78059 static	int		eri_m_unicst(void *, const uint8_t *);
    190   4404    gd78059 static	void		eri_m_ioctl(void *, queue_t *, mblk_t *);
    191   4404    gd78059 static	boolean_t	eri_m_getcapab(void *, mac_capab_t, void *);
    192   4404    gd78059 static	mblk_t		*eri_m_tx(void *, mblk_t *);
    193   4404    gd78059 
    194   4404    gd78059 static mac_callbacks_t eri_m_callbacks = {
    195   4404    gd78059 	MC_IOCTL | MC_GETCAPAB,
    196   4404    gd78059 	eri_m_stat,
    197   4404    gd78059 	eri_m_start,
    198   4404    gd78059 	eri_m_stop,
    199   4404    gd78059 	eri_m_promisc,
    200   4404    gd78059 	eri_m_multicst,
    201   4404    gd78059 	eri_m_unicst,
    202   4404    gd78059 	eri_m_tx,
    203   4404    gd78059 	eri_m_ioctl,
    204   4404    gd78059 	eri_m_getcapab
    205   4404    gd78059 };
    206      0     stevel 
    207      0     stevel /*
    208      0     stevel  * Define PHY Vendors: Matches to IEEE
    209      0     stevel  * Organizationally Unique Identifier (OUI)
    210      0     stevel  */
    211      0     stevel /*
    212      0     stevel  * The first two are supported as Internal XCVRs
    213      0     stevel  */
    214      0     stevel #define	PHY_VENDOR_LUCENT	0x601d
    215      0     stevel 
    216      0     stevel #define	PHY_LINK_NONE		0	/* Not attempted yet or retry */
    217      0     stevel #define	PHY_LINK_DOWN		1	/* Not being used	*/
    218      0     stevel #define	PHY_LINK_UP		2	/* Not being used	*/
    219      0     stevel 
    220      0     stevel #define	AUTO_SPEED		0
    221      0     stevel #define	FORCE_SPEED		1
    222      0     stevel 
    223      0     stevel /*
    224      0     stevel  * MIB II broadcast/multicast packets
    225      0     stevel  */
    226   4404    gd78059 
    227   4404    gd78059 #define	IS_BROADCAST(pkt) (bcmp(pkt, &etherbroadcastaddr, ETHERADDRL) == 0)
    228   4404    gd78059 #define	IS_MULTICAST(pkt) ((pkt[0] & 01) == 1)
    229   4404    gd78059 
    230   4404    gd78059 #define	BUMP_InNUcast(erip, pkt) \
    231   4404    gd78059 		if (IS_BROADCAST(pkt)) { \
    232      0     stevel 			HSTAT(erip, brdcstrcv); \
    233   4404    gd78059 		} else if (IS_MULTICAST(pkt)) { \
    234      0     stevel 			HSTAT(erip, multircv); \
    235      0     stevel 		}
    236      0     stevel 
    237   4404    gd78059 #define	BUMP_OutNUcast(erip, pkt) \
    238   4404    gd78059 		if (IS_BROADCAST(pkt)) { \
    239      0     stevel 			HSTAT(erip, brdcstxmt); \
    240   4404    gd78059 		} else if (IS_MULTICAST(pkt)) { \
    241      0     stevel 			HSTAT(erip, multixmt); \
    242      0     stevel 		}
    243      0     stevel 
    244      0     stevel #define	NEXTTMDP(tbasep, tmdlimp, tmdp)	(((tmdp) + 1) == tmdlimp	\
    245      0     stevel 	? tbasep : ((tmdp) + 1))
    246      0     stevel 
    247      0     stevel #define	ETHERHEADER_SIZE (sizeof (struct ether_header))
    248      0     stevel 
    249      0     stevel #ifdef	ERI_RCV_CKSUM
    250      0     stevel #define	ERI_PROCESS_READ(erip, bp, sum)				\
    251      0     stevel {								\
    252      0     stevel 	t_uscalar_t	type;					\
    253      0     stevel 	uint_t	start_offset, end_offset;			\
    254      0     stevel 								\
    255      0     stevel 	*(bp->b_wptr) = 0;	/* pad byte */			\
    256      0     stevel 								\
    257      0     stevel 	/*							\
    258      0     stevel 	 * update MIB II statistics				\
    259      0     stevel 	 */							\
    260      0     stevel 	HSTAT(erip, ipackets64);				\
    261      0     stevel 	HSTATN(erip, rbytes64, len);				\
    262   4404    gd78059 	BUMP_InNUcast(erip, bp->b_rptr);			\
    263   4404    gd78059 	type = get_ether_type(bp->b_rptr);			\
    264   4404    gd78059 	if (type == ETHERTYPE_IP || type == ETHERTYPE_IPV6) {	\
    265      0     stevel 		start_offset = 0;				\
    266   6990    gd78059 		end_offset = MBLKL(bp) - ETHERHEADER_SIZE;	\
    267   4404    gd78059 		(void) hcksum_assoc(bp, NULL, NULL,		\
    268   4404    gd78059 			start_offset, 0, end_offset, sum, 	\
    269   4404    gd78059 			HCK_PARTIALCKSUM, 0);			\
    270      0     stevel 	} else {						\
    271      0     stevel 		/*						\
    272      0     stevel 		 * Strip the PADS for 802.3			\
    273      0     stevel 		 */						\
    274      0     stevel 		if (type <= ETHERMTU)				\
    275      0     stevel 			bp->b_wptr = bp->b_rptr +		\
    276      0     stevel 				ETHERHEADER_SIZE + type;	\
    277      0     stevel 	}							\
    278      0     stevel }
    279      0     stevel #else
    280      0     stevel 
    281      0     stevel #define	ERI_PROCESS_READ(erip, bp)				\
    282      0     stevel {								\
    283      0     stevel 	t_uscalar_t	type;					\
    284   4404    gd78059 	type = get_ether_type(bp->b_rptr);			\
    285   4404    gd78059 								\
    286   4404    gd78059 	/*							\
    287   4404    gd78059 	 * update MIB II statistics				\
    288   4404    gd78059 	 */							\
    289   4404    gd78059 	HSTAT(erip, ipackets64);				\
    290   4404    gd78059 	HSTATN(erip, rbytes64, len);				\
    291   4404    gd78059 	BUMP_InNUcast(erip, bp->b_rptr);			\
    292   4404    gd78059 	/*							\
    293   4404    gd78059 	 * Strip the PADS for 802.3				\
    294   4404    gd78059 	 */							\
    295   4404    gd78059 	if (type <= ETHERMTU)					\
    296   4404    gd78059 		bp->b_wptr = bp->b_rptr + ETHERHEADER_SIZE + 	\
    297   4404    gd78059 			type;					\
    298      0     stevel }
    299      0     stevel #endif  /* ERI_RCV_CKSUM */
    300      0     stevel 
    301      0     stevel /*
    302      0     stevel  * TX Interrupt Rate
    303      0     stevel  */
    304      0     stevel static	int	tx_interrupt_rate = 16;
    305      0     stevel 
    306      0     stevel /*
    307      0     stevel  * Ethernet broadcast address definition.
    308      0     stevel  */
    309   4404    gd78059 static uint8_t	etherbroadcastaddr[] = {
    310      0     stevel 	0xff, 0xff, 0xff, 0xff, 0xff, 0xff
    311      0     stevel };
    312      0     stevel 
    313      0     stevel /*
    314      0     stevel  * The following variables are used for configuring various features
    315      0     stevel  */
    316      0     stevel #define	ERI_DESC_HANDLE_ALLOC	0x0001
    317      0     stevel #define	ERI_DESC_MEM_ALLOC	0x0002
    318      0     stevel #define	ERI_DESC_MEM_MAP	0x0004
    319      0     stevel #define	ERI_RCV_HANDLE_ALLOC	0x0020
    320      0     stevel #define	ERI_RCV_HANDLE_BIND	0x0040
    321      0     stevel #define	ERI_XMIT_DVMA_ALLOC	0x0100
    322      0     stevel #define	ERI_RCV_DVMA_ALLOC	0x0200
    323      0     stevel #define	ERI_XBUFS_HANDLE_ALLOC  0x0400
    324      0     stevel #define	ERI_XBUFS_KMEM_ALLOC    0x0800
    325      0     stevel #define	ERI_XBUFS_KMEM_DMABIND  0x1000
    326      0     stevel 
    327      0     stevel 
    328      0     stevel #define	ERI_DONT_STRIP_CRC
    329      0     stevel /*
    330      0     stevel  * Translate a kernel virtual address to i/o address.
    331      0     stevel  */
    332      0     stevel #define	ERI_IOPBIOADDR(erip, a) \
    333      0     stevel 	((erip)->iopbiobase + ((uintptr_t)a - (erip)->iopbkbase))
    334      0     stevel 
    335      0     stevel /*
    336      0     stevel  * ERI Configuration Register Value
    337      0     stevel  * Used to configure parameters that define DMA burst
    338      0     stevel  * and internal arbitration behavior.
    339      0     stevel  * for equal TX and RX bursts, set the following in global
    340      0     stevel  * configuration register.
    341      0     stevel  * static	int	global_config = 0x42;
    342      0     stevel  */
    343      0     stevel 
    344      0     stevel /*
    345      0     stevel  * ERI ERX Interrupt Blanking Time
    346      0     stevel  * Each count is about 16 us (2048 clocks) for 66 MHz PCI.
    347      0     stevel  */
    348      0     stevel static	int	intr_blank_time = 6;	/* for about 96 us */
    349      0     stevel static	int	intr_blank_packets = 8;	/*  */
    350      0     stevel 
    351      0     stevel /*
    352      0     stevel  * ERX PAUSE Threshold Register value
    353      0     stevel  * The following value is for an OFF Threshold of about 15.5 Kbytes
    354      0     stevel  * and an ON Threshold of 4K bytes.
    355      0     stevel  */
    356      0     stevel static	int rx_pause_threshold = 0xf8 | (0x40 << 12);
    357      0     stevel static	int eri_reinit_fatal = 0;
    358      0     stevel #ifdef	DEBUG
    359      0     stevel static	int noteri = 0;
    360      0     stevel #endif
    361      0     stevel 
    362      0     stevel #ifdef	ERI_TX_HUNG
    363      0     stevel static	int eri_reinit_txhung = 0;
    364      0     stevel #endif
    365      0     stevel 
    366      0     stevel #ifdef ERI_HDX_BUG_WORKAROUND
    367      0     stevel /*
    368      0     stevel  * By default enable padding in hdx mode to 97 bytes.
    369      0     stevel  * To disabled, in /etc/system:
    370      0     stevel  * set eri:eri_hdx_pad_enable=0
    371      0     stevel  */
    372      0     stevel static	uchar_t eri_hdx_pad_enable = 1;
    373      0     stevel #endif
    374      0     stevel 
    375      0     stevel /*
    376      0     stevel  * Default values to initialize the cache line size and latency timer
    377      0     stevel  * registers in the PCI configuration space.
    378      0     stevel  * ERI_G_CACHE_LINE_SIZE_16 is defined as 16 since RIO expects in units
    379      0     stevel  * of 4 bytes.
    380      0     stevel  */
    381      0     stevel #ifdef ERI_PM_WORKAROUND_PCI
    382      0     stevel static int eri_pci_cache_line = ERI_G_CACHE_LINE_SIZE_32; /* 128 bytes */
    383      0     stevel static int eri_pci_latency_timer = 0xff;		/* 255 PCI cycles */
    384      0     stevel #else
    385      0     stevel static int eri_pci_cache_line = ERI_G_CACHE_LINE_SIZE_16; /* 64 bytes */
    386      0     stevel static int eri_pci_latency_timer = 0x40;		/* 64 PCI cycles */
    387      0     stevel #endif
    388      0     stevel #define	ERI_CACHE_LINE_SIZE	(eri_pci_cache_line << ERI_G_CACHE_BIT)
    389      0     stevel 
    390      0     stevel /*
    391      0     stevel  * Claim the device is ultra-capable of burst in the beginning.  Use
    392      0     stevel  * the value returned by ddi_dma_burstsizes() to actually set the ERI
    393      0     stevel  * global configuration register later.
    394      0     stevel  *
    395      0     stevel  * PCI_ERI supports Infinite burst or 64-byte-multiple bursts.
    396      0     stevel  */
    397      0     stevel #define	ERI_LIMADDRLO	((uint64_t)0x00000000)
    398      0     stevel #define	ERI_LIMADDRHI	((uint64_t)0xffffffff)
    399      0     stevel 
    400      0     stevel static ddi_dma_attr_t dma_attr = {
    401      0     stevel 	DMA_ATTR_V0,		/* version number. */
    402      0     stevel 	(uint64_t)ERI_LIMADDRLO, /* low address */
    403      0     stevel 	(uint64_t)ERI_LIMADDRHI, /* high address */
    404      0     stevel 	(uint64_t)0x00ffffff,	/* address counter max */
    405      0     stevel 	(uint64_t)1,		/* alignment */
    406      0     stevel 	(uint_t)0xe000e0,	/* dlim_burstsizes for 32 4 bit xfers */
    407      0     stevel 	(uint32_t)0x1,		/* minimum transfer size */
    408      0     stevel 	(uint64_t)0x7fffffff,	/* maximum transfer size */
    409      0     stevel 	(uint64_t)0x00ffffff,	/* maximum segment size */
    410      0     stevel 	1,			/* scatter/gather list length */
    411      0     stevel 	(uint32_t)1,		/* granularity */
    412      0     stevel 	(uint_t)0		/* attribute flags */
    413      0     stevel };
    414      0     stevel 
    415      0     stevel static ddi_dma_attr_t desc_dma_attr = {
    416      0     stevel 	DMA_ATTR_V0,		/* version number. */
    417      0     stevel 	(uint64_t)ERI_LIMADDRLO, /* low address */
    418      0     stevel 	(uint64_t)ERI_LIMADDRHI, /* high address */
    419      0     stevel 	(uint64_t)0x00ffffff,	/* address counter max */
    420      0     stevel 	(uint64_t)8,		/* alignment */
    421      0     stevel 	(uint_t)0xe000e0,	/* dlim_burstsizes for 32 4 bit xfers */
    422      0     stevel 	(uint32_t)0x1,		/* minimum transfer size */
    423      0     stevel 	(uint64_t)0x7fffffff,	/* maximum transfer size */
    424      0     stevel 	(uint64_t)0x00ffffff,	/* maximum segment size */
    425      0     stevel 	1,			/* scatter/gather list length */
    426      0     stevel 	16,			/* granularity */
    427      0     stevel 	0			/* attribute flags */
    428      0     stevel };
    429      0     stevel 
    430   7394    gdamore static ddi_device_acc_attr_t buf_attr = {
    431   7394    gdamore 	DDI_DEVICE_ATTR_V0,	/* devacc_attr_version */
    432   7394    gdamore 	DDI_NEVERSWAP_ACC,	/* devacc_attr_endian_flags */
    433   7394    gdamore 	DDI_STRICTORDER_ACC,	/* devacc_attr_dataorder */
    434   7394    gdamore 	DDI_DEFAULT_ACC,	/* devacc_attr_access */
    435   7394    gdamore };
    436   7394    gdamore 
    437      0     stevel ddi_dma_lim_t eri_dma_limits = {
    438      0     stevel 	(uint64_t)ERI_LIMADDRLO, /* dlim_addr_lo */
    439      0     stevel 	(uint64_t)ERI_LIMADDRHI, /* dlim_addr_hi */
    440      0     stevel 	(uint64_t)ERI_LIMADDRHI, /* dlim_cntr_max */
    441      0     stevel 	(uint_t)0x00e000e0,	/* dlim_burstsizes for 32 and 64 bit xfers */
    442      0     stevel 	(uint32_t)0x1,		/* dlim_minxfer */
    443      0     stevel 	1024			/* dlim_speed */
    444      0     stevel };
    445      0     stevel 
    446      0     stevel /*
    447      0     stevel  * Link Configuration variables
    448      0     stevel  *
    449      0     stevel  * On Motherboard implementations, 10/100 Mbps speeds may be supported
    450      0     stevel  * by using both the Serial Link and the MII on Non-serial-link interface.
    451      0     stevel  * When both links are present, the driver automatically tries to bring up
    452      0     stevel  * both. If both are up, the Gigabit Serial Link is selected for use, by
    453      0     stevel  * default. The following configuration variable is used to force the selection
    454      0     stevel  * of one of the links when both are up.
    455      0     stevel  * To change the default selection to the MII link when both the Serial
    456      0     stevel  * Link and the MII link are up, change eri_default_link to 1.
    457      0     stevel  *
    458      0     stevel  * Once a link is in use, the driver will continue to use that link till it
    459      0     stevel  * goes down. When it goes down, the driver will look at the status of both the
    460      0     stevel  * links again for link selection.
    461      0     stevel  *
    462      0     stevel  * Currently the standard is not stable w.r.t. gigabit link configuration
    463      0     stevel  * using auto-negotiation procedures. Meanwhile, the link may be configured
    464      0     stevel  * in "forced" mode using the "autonegotiation enable" bit (bit-12) in the
    465      0     stevel  * PCS MII Command Register. In this mode the PCS sends "idles" until sees
    466      0     stevel  * "idles" as initialization instead of the Link Configuration protocol
    467      0     stevel  * where a Config register is exchanged. In this mode, the ERI is programmed
    468      0     stevel  * for full-duplex operation with both pauseTX and pauseRX (for flow control)
    469      0     stevel  * enabled.
    470      0     stevel  */
    471      0     stevel 
    472      0     stevel static	int	select_link = 0; /* automatic selection */
    473      0     stevel static	int	default_link = 0; /* Select Serial link if both are up */
    474      0     stevel 
    475      0     stevel /*
    476      0     stevel  * The following variables are used for configuring link-operation
    477      0     stevel  * for all the "eri" interfaces in the system.
    478      0     stevel  * Later these parameters may be changed per interface using "ndd" command
    479      0     stevel  * These parameters may also be specified as properties using the .conf
    480      0     stevel  * file mechanism for each interface.
    481      0     stevel  */
    482      0     stevel 
    483      0     stevel /*
    484      0     stevel  * The following variable value will be overridden by "link-pulse-disabled"
    485      0     stevel  * property which may be created by OBP or eri.conf file. This property is
    486      0     stevel  * applicable only for 10 Mbps links.
    487      0     stevel  */
    488      0     stevel static	int	link_pulse_disabled = 0;	/* link pulse disabled */
    489      0     stevel 
    490      0     stevel /* For MII-based FastEthernet links */
    491      0     stevel static	int	adv_autoneg_cap = 1;
    492      0     stevel static	int	adv_100T4_cap = 0;
    493      0     stevel static	int	adv_100fdx_cap = 1;
    494      0     stevel static	int	adv_100hdx_cap = 1;
    495      0     stevel static	int	adv_10fdx_cap = 1;
    496      0     stevel static	int	adv_10hdx_cap = 1;
    497      0     stevel static	int	adv_pauseTX_cap =  0;
    498      0     stevel static	int	adv_pauseRX_cap =  0;
    499      0     stevel 
    500      0     stevel /*
    501      0     stevel  * The following gap parameters are in terms of byte times.
    502      0     stevel  */
    503      0     stevel static	int	ipg0 = 8;
    504      0     stevel static	int	ipg1 = 8;
    505      0     stevel static	int	ipg2 = 4;
    506      0     stevel 
    507      0     stevel static	int	lance_mode = 1;		/* to enable LANCE mode */
    508      0     stevel static	int	mifpoll_enable = 0;	/* to enable mif poll */
    509      0     stevel static	int	ngu_enable = 0;		/* to enable Never Give Up mode */
    510      0     stevel 
    511      0     stevel static	int	eri_force_mlf = 0; 	/* to enable mif poll */
    512      0     stevel static	int	eri_phy_mintrans = 1;	/* Lu3X31T mintrans algorithm */
    513      0     stevel /*
    514      0     stevel  * For the MII interface, the External Transceiver is selected when present.
    515      0     stevel  * The following variable is used to select the Internal Transceiver even
    516      0     stevel  * when the External Transceiver is present.
    517      0     stevel  */
    518      0     stevel static	int	use_int_xcvr = 0;
    519      0     stevel static	int	pace_size = 0;	/* Do not use pacing for now */
    520      0     stevel 
    521      0     stevel static	int	eri_use_dvma_rx = 0;	/* =1:use dvma */
    522      0     stevel static	int	eri_rx_bcopy_max = RX_BCOPY_MAX;	/* =1:use bcopy() */
    523      0     stevel static	int	eri_overflow_reset = 1;	/* global reset if rx_fifo_overflow */
    524      0     stevel static	int	eri_tx_ring_size = 2048; /* number of entries in tx ring */
    525      0     stevel static	int	eri_rx_ring_size = 1024; /* number of entries in rx ring */
    526      0     stevel /*
    527      0     stevel  * The following parameters may be configured by the user. If they are not
    528      0     stevel  * configured by the user, the values will be based on the capabilities of
    529      0     stevel  * the transceiver.
    530      0     stevel  * The value "ERI_NOTUSR" is ORed with the parameter value to indicate values
    531      0     stevel  * which are NOT configured by the user.
    532      0     stevel  */
    533      0     stevel 
    534      0     stevel #define	ERI_NOTUSR	0x0f000000
    535      0     stevel #define	ERI_MASK_1BIT	0x1
    536      0     stevel #define	ERI_MASK_2BIT	0x3
    537      0     stevel #define	ERI_MASK_8BIT	0xff
    538      0     stevel 
    539      0     stevel 
    540      0     stevel /*
    541      0     stevel  * Note:
    542      0     stevel  * ERI has all of the above capabilities.
    543      0     stevel  * Only when an External Transceiver is selected for MII-based FastEthernet
    544      0     stevel  * link operation, the capabilities depend upon the capabilities of the
    545      0     stevel  * External Transceiver.
    546      0     stevel  */
    547      0     stevel 
    548      0     stevel /* ------------------------------------------------------------------------- */
    549      0     stevel 
    550      0     stevel static  param_t	param_arr[] = {
    551   4404    gd78059 	/* min		max		value	r/w/hidden+name */
    552   4404    gd78059 	{  0,		2,		2,	"-transceiver_inuse"},
    553   4404    gd78059 	{  0,		1,		0,	"-link_status"},
    554   4404    gd78059 	{  0,		1,		0,	"-link_speed"},
    555   4404    gd78059 	{  0,		1,		0,	"-link_mode"},
    556   4404    gd78059 	{  0,		255,		8,	"+ipg1"},
    557   4404    gd78059 	{  0,		255,		4,	"+ipg2"},
    558   4404    gd78059 	{  0,		1,		0,	"+use_int_xcvr"},
    559   4404    gd78059 	{  0,		255,		0,	"+pace_size"},
    560   4404    gd78059 	{  0,		1,		1,	"+adv_autoneg_cap"},
    561   4404    gd78059 	{  0,		1,		1,	"+adv_100T4_cap"},
    562   4404    gd78059 	{  0,		1,		1,	"+adv_100fdx_cap"},
    563   4404    gd78059 	{  0,		1,		1,	"+adv_100hdx_cap"},
    564   4404    gd78059 	{  0,		1,		1,	"+adv_10fdx_cap"},
    565   4404    gd78059 	{  0,		1,		1,	"+adv_10hdx_cap"},
    566   4404    gd78059 	{  0,		1,		1,	"-autoneg_cap"},
    567   4404    gd78059 	{  0,		1,		1,	"-100T4_cap"},
    568   4404    gd78059 	{  0,		1,		1,	"-100fdx_cap"},
    569   4404    gd78059 	{  0,		1,		1,	"-100hdx_cap"},
    570   4404    gd78059 	{  0,		1,		1,	"-10fdx_cap"},
    571   4404    gd78059 	{  0,		1,		1,	"-10hdx_cap"},
    572   4404    gd78059 	{  0,		1,		0,	"-lp_autoneg_cap"},
    573   4404    gd78059 	{  0,		1,		0,	"-lp_100T4_cap"},
    574   4404    gd78059 	{  0,		1,		0,	"-lp_100fdx_cap"},
    575   4404    gd78059 	{  0,		1,		0,	"-lp_100hdx_cap"},
    576   4404    gd78059 	{  0,		1,		0,	"-lp_10fdx_cap"},
    577   4404    gd78059 	{  0,		1,		0,	"-lp_10hdx_cap"},
    578   4404    gd78059 	{  0,		1,		1,	"+lance_mode"},
    579   4404    gd78059 	{  0,		31,		8,	"+ipg0"},
    580   4404    gd78059 	{  0,		127,		6,	"+intr_blank_time"},
    581   4404    gd78059 	{  0,		255,		8,	"+intr_blank_packets"},
    582   4404    gd78059 	{  0,		1,		1,	"!serial-link"},
    583   4404    gd78059 	{  0,		2,		1,	"!non-serial-link"},
    584   4404    gd78059 	{  0,		1,		0,	"%select-link"},
    585   4404    gd78059 	{  0,		1,		0,	"%default-link"},
    586   4404    gd78059 	{  0,		2,		0,	"!link-in-use"},
    587   4404    gd78059 	{  0,		1,		1,	"%adv_asm_dir_cap"},
    588   4404    gd78059 	{  0,		1,		1,	"%adv_pause_cap"},
    589   4404    gd78059 	{  0,		1,		0,	"!asm_dir_cap"},
    590   4404    gd78059 	{  0,		1,		0,	"!pause_cap"},
    591   4404    gd78059 	{  0,		1,		0,	"!lp_asm_dir_cap"},
    592   4404    gd78059 	{  0,		1,		0,	"!lp_pause_cap"},
    593   4404    gd78059 };
    594   4404    gd78059 
    595   4404    gd78059 DDI_DEFINE_STREAM_OPS(eri_dev_ops, nulldev, nulldev, eri_attach, eri_detach,
    596   7656     Sherry 	nodev, NULL, D_MP, NULL, ddi_quiesce_not_supported);
    597      0     stevel 
    598      0     stevel /*
    599      0     stevel  * This is the loadable module wrapper.
    600      0     stevel  */
    601      0     stevel #include <sys/modctl.h>
    602      0     stevel 
    603      0     stevel /*
    604      0     stevel  * Module linkage information for the kernel.
    605      0     stevel  */
    606      0     stevel static struct modldrv modldrv = {
    607      0     stevel 	&mod_driverops,	/* Type of module.  This one is a driver */
    608   4404    gd78059 	"Sun RIO 10/100 Mb Ethernet",
    609   4404    gd78059 	&eri_dev_ops,	/* driver ops */
    610      0     stevel };
    611      0     stevel 
    612      0     stevel static struct modlinkage modlinkage = {
    613      0     stevel 	MODREV_1, &modldrv, NULL
    614      0     stevel };
    615      0     stevel 
    616      0     stevel /*
    617      0     stevel  * Hardware Independent Functions
    618      0     stevel  * New Section
    619      0     stevel  */
    620      0     stevel 
    621      0     stevel int
    622      0     stevel _init(void)
    623      0     stevel {
    624      0     stevel 	int	status;
    625      0     stevel 
    626   4404    gd78059 	mac_init_ops(&eri_dev_ops, "eri");
    627   4404    gd78059 	if ((status = mod_install(&modlinkage)) != 0) {
    628   4404    gd78059 		mac_fini_ops(&eri_dev_ops);
    629   4404    gd78059 	}
    630      0     stevel 	return (status);
    631      0     stevel }
    632      0     stevel 
    633      0     stevel int
    634      0     stevel _fini(void)
    635      0     stevel {
    636   4404    gd78059 	int status;
    637      0     stevel 
    638      0     stevel 	status = mod_remove(&modlinkage);
    639   4404    gd78059 	if (status == 0) {
    640   4404    gd78059 		mac_fini_ops(&eri_dev_ops);
    641   4404    gd78059 	}
    642   4404    gd78059 	return (status);
    643   4404    gd78059 }
    644      0     stevel 
    645      0     stevel int
    646      0     stevel _info(struct modinfo *modinfop)
    647      0     stevel {
    648   4404    gd78059 	return (mod_info(&modlinkage, modinfop));
    649      0     stevel }
    650      0     stevel 
    651      0     stevel 
    652      0     stevel /*
    653      0     stevel  * Interface exists: make available by filling in network interface
    654      0     stevel  * record.  System will initialize the interface when it is ready
    655      0     stevel  * to accept packets.
    656      0     stevel  */
    657      0     stevel static int
    658      0     stevel eri_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
    659      0     stevel {
    660   4404    gd78059 	struct eri *erip = NULL;
    661   4404    gd78059 	mac_register_t *macp = NULL;
    662      0     stevel 	int	regno;
    663   4404    gd78059 	boolean_t	doinit;
    664   4404    gd78059 	boolean_t	mutex_inited = B_FALSE;
    665   4404    gd78059 	boolean_t	intr_add = B_FALSE;
    666      0     stevel 
    667      0     stevel 	switch (cmd) {
    668      0     stevel 	case DDI_ATTACH:
    669      0     stevel 		break;
    670      0     stevel 
    671      0     stevel 	case DDI_RESUME:
    672      0     stevel 		if ((erip = ddi_get_driver_private(dip)) == NULL)
    673      0     stevel 			return (DDI_FAILURE);
    674      0     stevel 
    675   4404    gd78059 		mutex_enter(&erip->intrlock);
    676      0     stevel 		erip->flags &= ~ERI_SUSPENDED;
    677      0     stevel 		erip->init_macregs = 1;
    678      0     stevel 		param_linkup = 0;
    679   4404    gd78059 		erip->stats.link_up = LINK_STATE_DOWN;
    680      0     stevel 		erip->linkcheck = 0;
    681   4404    gd78059 
    682   4404    gd78059 		doinit =  (erip->flags & ERI_STARTED) ? B_TRUE : B_FALSE;
    683   4404    gd78059 		mutex_exit(&erip->intrlock);
    684   4404    gd78059 
    685   4404    gd78059 		if (doinit && !eri_init(erip)) {
    686   4404    gd78059 			return (DDI_FAILURE);
    687      0     stevel 		}
    688      0     stevel 		return (DDI_SUCCESS);
    689      0     stevel 
    690      0     stevel 	default:
    691      0     stevel 		return (DDI_FAILURE);
    692      0     stevel 	}
    693      0     stevel 
    694      0     stevel 	/*
    695      0     stevel 	 * Allocate soft device data structure
    696      0     stevel 	 */
    697   4404    gd78059 	erip = kmem_zalloc(sizeof (struct eri), KM_SLEEP);
    698      0     stevel 
    699      0     stevel 	/*
    700      0     stevel 	 * Initialize as many elements as possible.
    701      0     stevel 	 */
    702      0     stevel 	ddi_set_driver_private(dip, erip);
    703      0     stevel 	erip->dip = dip;			/* dip	*/
    704      0     stevel 	erip->instance = ddi_get_instance(dip);	/* instance */
    705      0     stevel 	erip->flags = 0;
    706   4404    gd78059 	erip->multi_refcnt = 0;
    707   4404    gd78059 	erip->promisc = B_FALSE;
    708   4404    gd78059 
    709   4404    gd78059 	if ((macp = mac_alloc(MAC_VERSION)) == NULL) {
    710   4404    gd78059 		ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG,
    711   4404    gd78059 		    "mac_alloc failed");
    712   4404    gd78059 		goto attach_fail;
    713   4404    gd78059 	}
    714   4404    gd78059 	macp->m_type_ident = MAC_PLUGIN_IDENT_ETHER;
    715   4404    gd78059 	macp->m_driver = erip;
    716   4404    gd78059 	macp->m_dip = dip;
    717   4404    gd78059 	macp->m_src_addr = erip->ouraddr;
    718   4404    gd78059 	macp->m_callbacks = &eri_m_callbacks;
    719   4404    gd78059 	macp->m_min_sdu = 0;
    720   4404    gd78059 	macp->m_max_sdu = ETHERMTU;
    721   5895   yz147064 	macp->m_margin = VLAN_TAGSZ;
    722      0     stevel 
    723      0     stevel 	/*
    724      0     stevel 	 * Map in the device registers.
    725      0     stevel 	 * Separate pointers will be set up for the following
    726      0     stevel 	 * register groups within the GEM Register Space:
    727      0     stevel 	 * 	Global register set
    728      0     stevel 	 * 	ETX register set
    729      0     stevel 	 * 	ERX register set
    730      0     stevel 	 * 	BigMAC register set.
    731      0     stevel 	 * 	MIF register set
    732      0     stevel 	 */
    733      0     stevel 
    734      0     stevel 	if (ddi_dev_nregs(dip, &regno) != (DDI_SUCCESS)) {
    735      0     stevel 		ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG,
    736   4404    gd78059 		    "ddi_dev_nregs failed, returned %d", regno);
    737      0     stevel 		goto attach_fail;
    738      0     stevel 	}
    739      0     stevel 
    740      0     stevel 	/*
    741      0     stevel 	 * Map the PCI config space
    742      0     stevel 	 */
    743   4404    gd78059 	if (pci_config_setup(dip, &erip->pci_config_handle) != DDI_SUCCESS) {
    744      0     stevel 		ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG,
    745   4404    gd78059 		    "%s pci_config_setup()", config_space_fatal_msg);
    746      0     stevel 		goto attach_fail;
    747      0     stevel 	}
    748      0     stevel 
    749      0     stevel 	/*
    750      0     stevel 	 * Initialize device attributes structure
    751      0     stevel 	 */
    752      0     stevel 	erip->dev_attr.devacc_attr_version =	DDI_DEVICE_ATTR_V0;
    753      0     stevel 	erip->dev_attr.devacc_attr_dataorder =	DDI_STRICTORDER_ACC;
    754      0     stevel 	erip->dev_attr.devacc_attr_endian_flags =	DDI_STRUCTURE_LE_ACC;
    755      0     stevel 
    756   4404    gd78059 	if (ddi_regs_map_setup(dip, 1, (caddr_t *)&(erip->globregp), 0, 0,
    757   4404    gd78059 	    &erip->dev_attr, &erip->globregh)) {
    758   4404    gd78059 		goto attach_fail;
    759      0     stevel 	}
    760      0     stevel 	erip->etxregh =		erip->globregh;
    761      0     stevel 	erip->erxregh =		erip->globregh;
    762      0     stevel 	erip->bmacregh =	erip->globregh;
    763      0     stevel 	erip->mifregh =		erip->globregh;
    764      0     stevel 
    765      0     stevel 	erip->etxregp =  (void *)(((caddr_t)erip->globregp) + 0x2000);
    766      0     stevel 	erip->erxregp =  (void *)(((caddr_t)erip->globregp) + 0x4000);
    767      0     stevel 	erip->bmacregp = (void *)(((caddr_t)erip->globregp) + 0x6000);
    768      0     stevel 	erip->mifregp =  (void *)(((caddr_t)erip->globregp) + 0x6200);
    769      0     stevel 
    770      0     stevel 	/*
    771      0     stevel 	 * Map the software reset register.
    772      0     stevel 	 */
    773   4404    gd78059 	if (ddi_regs_map_setup(dip, 1, (caddr_t *)&(erip->sw_reset_reg),
    774   4404    gd78059 	    0x1010, 4, &erip->dev_attr, &erip->sw_reset_regh)) {
    775      0     stevel 		ERI_FAULT_MSG1(erip, SEVERITY_MID, ERI_VERB_MSG,
    776   4404    gd78059 		    mregs_4soft_reset_fail_msg);
    777   4404    gd78059 		goto attach_fail;
    778      0     stevel 	}
    779      0     stevel 
    780      0     stevel 	/*
    781      0     stevel 	 * Try and stop the device.
    782      0     stevel 	 * This is done until we want to handle interrupts.
    783      0     stevel 	 */
    784      0     stevel 	if (eri_stop(erip))
    785      0     stevel 		goto attach_fail;
    786      0     stevel 
    787      0     stevel 	/*
    788      0     stevel 	 * set PCI latency timer register.
    789      0     stevel 	 */
    790      0     stevel 	pci_config_put8(erip->pci_config_handle, PCI_CONF_LATENCY_TIMER,
    791   4404    gd78059 	    (uchar_t)eri_pci_latency_timer);
    792      0     stevel 
    793      0     stevel 	if (ddi_intr_hilevel(dip, 0)) {
    794      0     stevel 		ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG,
    795      0     stevel 		    " high-level interrupts are not supported");
    796      0     stevel 		goto attach_fail;
    797      0     stevel 	}
    798      0     stevel 
    799      0     stevel 	/*
    800      0     stevel 	 * Get the interrupt cookie so the mutexes can be
    801      0     stevel 	 * Initialized.
    802      0     stevel 	 */
    803      0     stevel 	if (ddi_get_iblock_cookie(dip, 0, &erip->cookie) != DDI_SUCCESS)
    804      0     stevel 		goto attach_fail;
    805      0     stevel 
    806      0     stevel 	/*
    807      0     stevel 	 * Initialize mutex's for this device.
    808      0     stevel 	 */
    809      0     stevel 	mutex_init(&erip->xmitlock, NULL, MUTEX_DRIVER, (void *)erip->cookie);
    810      0     stevel 	mutex_init(&erip->intrlock, NULL, MUTEX_DRIVER, (void *)erip->cookie);
    811      0     stevel 	mutex_init(&erip->linklock, NULL, MUTEX_DRIVER, (void *)erip->cookie);
    812      0     stevel 	mutex_init(&erip->xcvrlock, NULL, MUTEX_DRIVER, (void *)erip->cookie);
    813      0     stevel 
    814   4404    gd78059 	mutex_inited = B_TRUE;
    815      0     stevel 
    816      0     stevel 	/*
    817      0     stevel 	 * Add interrupt to system
    818      0     stevel 	 */
    819   4404    gd78059 	if (ddi_add_intr(dip, 0, &erip->cookie, 0, eri_intr, (caddr_t)erip) ==
    820   4404    gd78059 	    DDI_SUCCESS)
    821   4404    gd78059 		intr_add = B_TRUE;
    822      0     stevel 	else {
    823   4404    gd78059 		goto attach_fail;
    824   4404    gd78059 	}
    825   4404    gd78059 
    826      0     stevel 	/*
    827      0     stevel 	 * Set up the ethernet mac address.
    828      0     stevel 	 */
    829      0     stevel 	(void) eri_setup_mac_address(erip, dip);
    830      0     stevel 
    831      0     stevel 	if (eri_init_xfer_params(erip))
    832      0     stevel 		goto attach_fail;
    833      0     stevel 
    834      0     stevel 	if (eri_burstsize(erip) == DDI_FAILURE) {
    835      0     stevel 		goto attach_fail;
    836      0     stevel 	}
    837      0     stevel 
    838      0     stevel 	/*
    839      0     stevel 	 * Setup fewer receive bufers.
    840      0     stevel 	 */
    841      0     stevel 	ERI_RPENDING = eri_rx_ring_size;
    842      0     stevel 	ERI_TPENDING = eri_tx_ring_size;
    843      0     stevel 
    844      0     stevel 	erip->rpending_mask = ERI_RPENDING - 1;
    845      0     stevel 	erip->rmdmax_mask = ERI_RPENDING - 1;
    846      0     stevel 	erip->mif_config = (ERI_PHY_BMSR << ERI_MIF_CFGPR_SHIFT);
    847      0     stevel 
    848      0     stevel 	erip->stats.pmcap = ERI_PMCAP_NONE;
    849      0     stevel 	if (pci_report_pmcap(dip, PCI_PM_IDLESPEED, (void *)4000) ==
    850   4404    gd78059 	    DDI_SUCCESS)
    851      0     stevel 		erip->stats.pmcap = ERI_PMCAP_4MHZ;
    852      0     stevel 
    853   4404    gd78059 	if (mac_register(macp, &erip->mh) != 0)
    854   4404    gd78059 		goto attach_fail;
    855   4404    gd78059 
    856   4404    gd78059 	mac_free(macp);
    857   4404    gd78059 
    858      0     stevel 	return (DDI_SUCCESS);
    859      0     stevel 
    860      0     stevel attach_fail:
    861      0     stevel 	if (erip->pci_config_handle)
    862      0     stevel 		(void) pci_config_teardown(&erip->pci_config_handle);
    863      0     stevel 
    864      0     stevel 	if (mutex_inited) {
    865      0     stevel 		mutex_destroy(&erip->xmitlock);
    866      0     stevel 		mutex_destroy(&erip->intrlock);
    867      0     stevel 		mutex_destroy(&erip->linklock);
    868      0     stevel 		mutex_destroy(&erip->xcvrlock);
    869   4404    gd78059 	}
    870   4404    gd78059 
    871   4404    gd78059 	ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, attach_fail_msg);
    872      0     stevel 
    873      0     stevel 	if (intr_add)
    874      0     stevel 		ddi_remove_intr(dip, 0, erip->cookie);
    875      0     stevel 
    876      0     stevel 	if (erip->globregh)
    877      0     stevel 		ddi_regs_map_free(&erip->globregh);
    878      0     stevel 
    879   4404    gd78059 	if (macp != NULL)
    880   4404    gd78059 		mac_free(macp);
    881   4404    gd78059 	if (erip != NULL)
    882   4404    gd78059 		kmem_free(erip, sizeof (*erip));
    883   4404    gd78059 
    884      0     stevel 	return (DDI_FAILURE);
    885      0     stevel }
    886      0     stevel 
    887      0     stevel static int
    888      0     stevel eri_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
    889      0     stevel {
    890   4404    gd78059 	struct eri 	*erip;
    891      0     stevel 	int i;
    892      0     stevel 
    893      0     stevel 	if ((erip = ddi_get_driver_private(dip)) == NULL) {
    894      0     stevel 		/*
    895      0     stevel 		 * No resources allocated.
    896      0     stevel 		 */
    897      0     stevel 		return (DDI_FAILURE);
    898      0     stevel 	}
    899      0     stevel 
    900      0     stevel 	switch (cmd) {
    901      0     stevel 	case DDI_DETACH:
    902      0     stevel 		break;
    903      0     stevel 
    904      0     stevel 	case DDI_SUSPEND:
    905      0     stevel 		erip->flags |= ERI_SUSPENDED;
    906      0     stevel 		eri_uninit(erip);
    907      0     stevel 		return (DDI_SUCCESS);
    908      0     stevel 
    909      0     stevel 	default:
    910      0     stevel 		return (DDI_FAILURE);
    911      0     stevel 	}
    912      0     stevel 
    913      0     stevel 	if (erip->flags & (ERI_RUNNING | ERI_SUSPENDED)) {
    914      0     stevel 		ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG, busy_msg);
    915      0     stevel 		return (DDI_FAILURE);
    916      0     stevel 	}
    917      0     stevel 
    918   4404    gd78059 	if (mac_unregister(erip->mh) != 0) {
    919   4404    gd78059 		return (DDI_FAILURE);
    920   4404    gd78059 	}
    921   4404    gd78059 
    922      0     stevel 	/*
    923      0     stevel 	 * Make the device quiescent
    924      0     stevel 	 */
    925      0     stevel 	(void) eri_stop(erip);
    926      0     stevel 
    927      0     stevel 	/*
    928      0     stevel 	 * Remove instance of the intr
    929      0     stevel 	 */
    930      0     stevel 	ddi_remove_intr(dip, 0, erip->cookie);
    931      0     stevel 
    932      0     stevel 	if (erip->pci_config_handle)
    933      0     stevel 		(void) pci_config_teardown(&erip->pci_config_handle);
    934      0     stevel 
    935      0     stevel 	/*
    936      0     stevel 	 * Destroy all mutexes and data structures allocated during
    937      0     stevel 	 * attach time.
    938      0     stevel 	 */
    939      0     stevel 
    940      0     stevel 	if (erip->globregh)
    941      0     stevel 		ddi_regs_map_free(&erip->globregh);
    942      0     stevel 
    943      0     stevel 	erip->etxregh =		NULL;
    944      0     stevel 	erip->erxregh =		NULL;
    945      0     stevel 	erip->bmacregh =	NULL;
    946      0     stevel 	erip->mifregh =		NULL;
    947      0     stevel 	erip->globregh =	NULL;
    948      0     stevel 
    949      0     stevel 	if (erip->sw_reset_regh)
    950      0     stevel 		ddi_regs_map_free(&erip->sw_reset_regh);
    951      0     stevel 
    952      0     stevel 	if (erip->ksp)
    953      0     stevel 		kstat_delete(erip->ksp);
    954      0     stevel 
    955      0     stevel 	eri_stop_timer(erip); /* acquire linklock */
    956      0     stevel 	eri_start_timer(erip, eri_check_link, 0);
    957      0     stevel 	mutex_destroy(&erip->xmitlock);
    958      0     stevel 	mutex_destroy(&erip->intrlock);
    959      0     stevel 	mutex_destroy(&erip->linklock);
    960      0     stevel 	mutex_destroy(&erip->xcvrlock);
    961      0     stevel 
    962      0     stevel 	if (erip->md_h) {
    963      0     stevel 		if (ddi_dma_unbind_handle(erip->md_h) ==
    964      0     stevel 		    DDI_FAILURE)
    965      0     stevel 			return (DDI_FAILURE);
    966      0     stevel 		ddi_dma_mem_free(&erip->mdm_h);
    967      0     stevel 		ddi_dma_free_handle(&erip->md_h);
    968      0     stevel 	}
    969      0     stevel 
    970      0     stevel 	if (eri_freebufs(erip))
    971      0     stevel 		return (DDI_FAILURE);
    972      0     stevel 
    973      0     stevel 	/* dvma handle case */
    974      0     stevel 
    975      0     stevel 	if (erip->eri_dvmarh) {
    976      0     stevel 		(void) dvma_release(erip->eri_dvmarh);
    977      0     stevel 		erip->eri_dvmarh = NULL;
    978      0     stevel 	}
    979      0     stevel /*
    980      0     stevel  *	xmit_dma_mode, erip->ndmaxh[i]=NULL for dvma
    981      0     stevel  */
    982      0     stevel 	else {
    983      0     stevel 		for (i = 0; i < ERI_RPENDING; i++)
    984      0     stevel 			if (erip->ndmarh[i])
    985      0     stevel 				ddi_dma_free_handle(&erip->ndmarh[i]);
    986      0     stevel 	}
    987      0     stevel /*
    988   7394    gdamore  *	Release TX buffer
    989      0     stevel  */
    990      0     stevel 	if (erip->tbuf_ioaddr != 0) {
    991      0     stevel 		(void) ddi_dma_unbind_handle(erip->tbuf_handle);
    992      0     stevel 		erip->tbuf_ioaddr = 0;
    993      0     stevel 	}
    994      0     stevel 	if (erip->tbuf_kaddr != NULL) {
    995   7394    gdamore 		ddi_dma_mem_free(&erip->tbuf_acch);
    996      0     stevel 		erip->tbuf_kaddr = NULL;
    997      0     stevel 	}
    998      0     stevel 	if (erip->tbuf_handle != NULL) {
    999      0     stevel 		ddi_dma_free_handle(&erip->tbuf_handle);
   1000      0     stevel 		erip->tbuf_handle = NULL;
   1001      0     stevel 	}
   1002      0     stevel 
   1003      0     stevel 	eri_param_cleanup(erip);
   1004      0     stevel 
   1005      0     stevel 	ddi_set_driver_private(dip, NULL);
   1006      0     stevel 	kmem_free((caddr_t)erip, sizeof (struct eri));
   1007      0     stevel 
   1008      0     stevel 	return (DDI_SUCCESS);
   1009      0     stevel }
   1010      0     stevel 
   1011      0     stevel /*
   1012      0     stevel  * To set up the mac address for the network interface:
   1013      0     stevel  * The adapter card may support a local mac address which is published
   1014      0     stevel  * in a device node property "local-mac-address". This mac address is
   1015      0     stevel  * treated as the factory-installed mac address for DLPI interface.
   1016      0     stevel  * If the adapter firmware has used the device for diskless boot
   1017      0     stevel  * operation it publishes a property called "mac-address" for use by
   1018      0     stevel  * inetboot and the device driver.
   1019      0     stevel  * If "mac-address" is not found, the system options property
   1020      0     stevel  * "local-mac-address" is used to select the mac-address. If this option
   1021      0     stevel  * is set to "true", and "local-mac-address" has been found, then
   1022      0     stevel  * local-mac-address is used; otherwise the system mac address is used
   1023      0     stevel  * by calling the "localetheraddr()" function.
   1024      0     stevel  */
   1025      0     stevel 
   1026      0     stevel static void
   1027      0     stevel eri_setup_mac_address(struct eri *erip, dev_info_t *dip)
   1028      0     stevel {
   1029   4404    gd78059 	uchar_t			*prop;
   1030   4404    gd78059 	char			*uselocal;
   1031   4404    gd78059 	unsigned		prop_len;
   1032   4404    gd78059 	uint32_t		addrflags = 0;
   1033   4404    gd78059 	struct ether_addr	factaddr;
   1034      0     stevel 
   1035      0     stevel 	/*
   1036      0     stevel 	 * Check if it is an adapter with its own local mac address
   1037      0     stevel 	 * If it is present, save it as the "factory-address"
   1038      0     stevel 	 * for this adapter.
   1039      0     stevel 	 */
   1040   4404    gd78059 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
   1041   4404    gd78059 	    "local-mac-address", &prop, &prop_len) == DDI_PROP_SUCCESS) {
   1042      0     stevel 		if (prop_len == ETHERADDRL) {
   1043   4404    gd78059 			addrflags = ERI_FACTADDR_PRESENT;
   1044   4404    gd78059 			bcopy(prop, &factaddr, ETHERADDRL);
   1045      0     stevel 			ERI_FAULT_MSG2(erip, SEVERITY_NONE, ERI_VERB_MSG,
   1046   4404    gd78059 			    lether_addr_msg, ether_sprintf(&factaddr));
   1047   4404    gd78059 		}
   1048   4404    gd78059 		ddi_prop_free(prop);
   1049      0     stevel 	}
   1050      0     stevel 	/*
   1051      0     stevel 	 * Check if the adapter has published "mac-address" property.
   1052      0     stevel 	 * If it is present, use it as the mac address for this device.
   1053      0     stevel 	 */
   1054   4404    gd78059 	if (ddi_prop_lookup_byte_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
   1055   4404    gd78059 	    "mac-address", &prop, &prop_len) == DDI_PROP_SUCCESS) {
   1056      0     stevel 		if (prop_len >= ETHERADDRL) {
   1057   4404    gd78059 			bcopy(prop, erip->ouraddr, ETHERADDRL);
   1058   4472    gd78059 			ddi_prop_free(prop);
   1059      0     stevel 			return;
   1060      0     stevel 		}
   1061   4404    gd78059 		ddi_prop_free(prop);
   1062   4404    gd78059 	}
   1063   4404    gd78059 
   1064   4404    gd78059 	if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "local-mac-address?",
   1065   4404    gd78059 	    &uselocal) == DDI_PROP_SUCCESS) {
   1066   4404    gd78059 		if ((strcmp("true", uselocal) == 0) &&
   1067   4404    gd78059 		    (addrflags & ERI_FACTADDR_PRESENT)) {
   1068   4404    gd78059 			addrflags |= ERI_FACTADDR_USE;
   1069   4404    gd78059 			bcopy(&factaddr, erip->ouraddr, ETHERADDRL);
   1070   4404    gd78059 			ddi_prop_free(uselocal);
   1071      0     stevel 			ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG,
   1072   4404    gd78059 			    lmac_addr_msg);
   1073   4404    gd78059 			return;
   1074   4404    gd78059 		}
   1075   4404    gd78059 		ddi_prop_free(uselocal);
   1076      0     stevel 	}
   1077      0     stevel 
   1078      0     stevel 	/*
   1079      0     stevel 	 * Get the system ethernet address.
   1080      0     stevel 	 */
   1081   4404    gd78059 	(void) localetheraddr(NULL, &factaddr);
   1082   4404    gd78059 	bcopy(&factaddr, erip->ouraddr, ETHERADDRL);
   1083   4404    gd78059 }
   1084      0     stevel 
   1085      0     stevel 
   1086      0     stevel /*
   1087      0     stevel  * Calculate the bit in the multicast address filter that selects the given
   1088      0     stevel  * address.
   1089      0     stevel  * Note: For ERI, the last 8-bits are used.
   1090      0     stevel  */
   1091      0     stevel 
   1092      0     stevel static uint32_t
   1093   4404    gd78059 eri_ladrf_bit(const uint8_t *addr)
   1094      0     stevel {
   1095      0     stevel 	uint32_t crc;
   1096      0     stevel 
   1097      0     stevel 	CRC32(crc, addr, ETHERADDRL, -1U, crc32_table);
   1098      0     stevel 
   1099      0     stevel 	/*
   1100      0     stevel 	 * Just want the 8 most significant bits.
   1101      0     stevel 	 */
   1102      0     stevel 	return ((~crc) >> 24);
   1103      0     stevel }
   1104      0     stevel 
   1105   4404    gd78059 static void
   1106   4404    gd78059 eri_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
   1107   4404    gd78059 {
   1108   4404    gd78059 	struct	eri	*erip = arg;
   1109   4404    gd78059 	struct	iocblk	*iocp = (void *)mp->b_rptr;
   1110   4404    gd78059 	int	err;
   1111   4404    gd78059 
   1112   4404    gd78059 	ASSERT(erip != NULL);
   1113   4404    gd78059 
   1114   4404    gd78059 	/*
   1115   4404    gd78059 	 * Privilege checks.
   1116   4404    gd78059 	 */
   1117      0     stevel 	switch (iocp->ioc_cmd) {
   1118   4404    gd78059 	case ERI_SET_LOOP_MODE:
   1119   4404    gd78059 	case ERI_ND_SET:
   1120   4404    gd78059 		err = secpolicy_net_config(iocp->ioc_cr, B_FALSE);
   1121   4404    gd78059 		if (err != 0) {
   1122   4404    gd78059 			miocnak(wq, mp, 0, err);
   1123   4404    gd78059 			return;
   1124   4404    gd78059 		}
   1125   4404    gd78059 		break;
   1126   4404    gd78059 	default:
   1127   4404    gd78059 		break;
   1128   4404    gd78059 	}
   1129   4404    gd78059 
   1130   4404    gd78059 	switch (iocp->ioc_cmd) {
   1131      0     stevel 	case ERI_ND_GET:
   1132      0     stevel 	case ERI_ND_SET:
   1133   4404    gd78059 		eri_process_ndd_ioctl(erip, wq, mp, iocp->ioc_cmd);
   1134      0     stevel 		break;
   1135      0     stevel 
   1136      0     stevel 	case ERI_SET_LOOP_MODE:
   1137      0     stevel 	case ERI_GET_LOOP_MODE:
   1138   4404    gd78059 		/*
   1139   4404    gd78059 		 * XXX: Consider updating this to the new netlb ioctls.
   1140   4404    gd78059 		 */
   1141   4404    gd78059 		eri_loopback(erip, wq, mp);
   1142      0     stevel 		break;
   1143      0     stevel 
   1144      0     stevel 	default:
   1145      0     stevel 		miocnak(wq, mp, 0, EINVAL);
   1146      0     stevel 		break;
   1147      0     stevel 	}
   1148      0     stevel 
   1149   4404    gd78059 	ASSERT(!MUTEX_HELD(&erip->linklock));
   1150   4404    gd78059 }
   1151   4404    gd78059 
   1152   4404    gd78059 static void
   1153   4404    gd78059 eri_loopback(struct eri *erip, queue_t *wq, mblk_t *mp)
   1154   4404    gd78059 {
   1155   4404    gd78059 	struct	iocblk	*iocp = (void *)mp->b_rptr;
   1156      0     stevel 	loopback_t	*al;
   1157      0     stevel 
   1158   4404    gd78059 	if (mp->b_cont == NULL || MBLKL(mp->b_cont) < sizeof (loopback_t)) {
   1159      0     stevel 		miocnak(wq, mp, 0, EINVAL);
   1160      0     stevel 		return;
   1161      0     stevel 	}
   1162      0     stevel 
   1163   4404    gd78059 	al = (void *)mp->b_cont->b_rptr;
   1164      0     stevel 
   1165      0     stevel 	switch (iocp->ioc_cmd) {
   1166      0     stevel 	case ERI_SET_LOOP_MODE:
   1167      0     stevel 		switch (al->loopback) {
   1168      0     stevel 		case ERI_LOOPBACK_OFF:
   1169   4404    gd78059 			erip->flags &= (~ERI_MACLOOPBACK & ~ERI_SERLOOPBACK);
   1170      0     stevel 			/* force link status to go down */
   1171      0     stevel 			param_linkup = 0;
   1172   4404    gd78059 			erip->stats.link_up = LINK_STATE_DOWN;
   1173   4404    gd78059 			erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN;
   1174      0     stevel 			(void) eri_init(erip);
   1175      0     stevel 			break;
   1176      0     stevel 
   1177      0     stevel 		case ERI_MAC_LOOPBACK_ON:
   1178      0     stevel 			erip->flags |= ERI_MACLOOPBACK;
   1179   4404    gd78059 			erip->flags &= ~ERI_SERLOOPBACK;
   1180   4404    gd78059 			param_linkup = 0;
   1181   4404    gd78059 			erip->stats.link_up = LINK_STATE_DOWN;
   1182   4404    gd78059 			erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN;
   1183      0     stevel 			(void) eri_init(erip);
   1184      0     stevel 			break;
   1185      0     stevel 
   1186      0     stevel 		case ERI_PCS_LOOPBACK_ON:
   1187      0     stevel 			break;
   1188      0     stevel 
   1189      0     stevel 		case ERI_SER_LOOPBACK_ON:
   1190      0     stevel 			erip->flags |= ERI_SERLOOPBACK;
   1191   4404    gd78059 			erip->flags &= ~ERI_MACLOOPBACK;
   1192      0     stevel 			/* force link status to go down */
   1193      0     stevel 			param_linkup = 0;
   1194   4404    gd78059 			erip->stats.link_up = LINK_STATE_DOWN;
   1195   4404    gd78059 			erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN;
   1196      0     stevel 			(void) eri_init(erip);
   1197      0     stevel 			break;
   1198      0     stevel 
   1199      0     stevel 		default:
   1200      0     stevel 			ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG,
   1201   4404    gd78059 			    loopback_val_default);
   1202      0     stevel 			miocnak(wq, mp, 0, EINVAL);
   1203      0     stevel 			return;
   1204      0     stevel 		}
   1205      0     stevel 		miocnak(wq, mp, 0, 0);
   1206      0     stevel 		break;
   1207      0     stevel 
   1208      0     stevel 	case ERI_GET_LOOP_MODE:
   1209   4404    gd78059 		al->loopback =	ERI_MAC_LOOPBACK_ON | ERI_PCS_LOOPBACK_ON |
   1210   4404    gd78059 		    ERI_SER_LOOPBACK_ON;
   1211      0     stevel 		miocack(wq, mp, sizeof (loopback_t), 0);
   1212      0     stevel 		break;
   1213      0     stevel 
   1214      0     stevel 	default:
   1215      0     stevel 		ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG,
   1216   4404    gd78059 		    loopback_cmd_default);
   1217   4404    gd78059 	}
   1218   4404    gd78059 }
   1219   4404    gd78059 
   1220   4404    gd78059 static int
   1221   4404    gd78059 eri_m_promisc(void *arg, boolean_t on)
   1222   4404    gd78059 {
   1223   4404    gd78059 	struct	eri	*erip = arg;
   1224   4404    gd78059 
   1225   4404    gd78059 	mutex_enter(&erip->intrlock);
   1226   4404    gd78059 	erip->promisc = on;
   1227   4404    gd78059 	eri_init_rx(erip);
   1228   4404    gd78059 	mutex_exit(&erip->intrlock);
   1229   4404    gd78059 	return (0);
   1230      0     stevel }
   1231      0     stevel 
   1232      0     stevel /*
   1233      0     stevel  * This is to support unlimited number of members
   1234      0     stevel  * in Multicast.
   1235      0     stevel  */
   1236   4404    gd78059 static int
   1237   4404    gd78059 eri_m_multicst(void *arg, boolean_t add, const uint8_t *mca)
   1238   4404    gd78059 {
   1239   4404    gd78059 	struct eri		*erip = arg;
   1240   4404    gd78059 	uint32_t 		ladrf_bit;
   1241      0     stevel 
   1242      0     stevel 	/*
   1243      0     stevel 	 * If this address's bit was not already set in the local address
   1244      0     stevel 	 * filter, add it and re-initialize the Hardware.
   1245      0     stevel 	 */
   1246   4404    gd78059 	ladrf_bit = eri_ladrf_bit(mca);
   1247   4404    gd78059 
   1248   4404    gd78059 	mutex_enter(&erip->intrlock);
   1249   4404    gd78059 	if (add) {
   1250   4404    gd78059 		erip->ladrf_refcnt[ladrf_bit]++;
   1251   4404    gd78059 		if (erip->ladrf_refcnt[ladrf_bit] == 1) {
   1252   4404    gd78059 			LADRF_SET(erip, ladrf_bit);
   1253   4404    gd78059 			erip->multi_refcnt++;
   1254   4404    gd78059 			eri_init_rx(erip);
   1255   4404    gd78059 		}
   1256   4404    gd78059 	} else {
   1257   4404    gd78059 		erip->ladrf_refcnt[ladrf_bit]--;
   1258   4404    gd78059 		if (erip->ladrf_refcnt[ladrf_bit] == 0) {
   1259   4404    gd78059 			LADRF_CLR(erip, ladrf_bit);
   1260   4404    gd78059 			erip->multi_refcnt--;
   1261   4404    gd78059 			eri_init_rx(erip);
   1262   4404    gd78059 		}
   1263   4404    gd78059 	}
   1264   4404    gd78059 	mutex_exit(&erip->intrlock);
   1265   4404    gd78059 	return (0);
   1266   4404    gd78059 }
   1267   4404    gd78059 
   1268   4404    gd78059 static int
   1269   4404    gd78059 eri_m_unicst(void *arg, const uint8_t *macaddr)
   1270   4404    gd78059 {
   1271   4404    gd78059 	struct	eri	*erip = arg;
   1272      0     stevel 
   1273      0     stevel 	/*
   1274      0     stevel 	 * Set new interface local address and re-init device.
   1275      0     stevel 	 * This is destructive to any other streams attached
   1276      0     stevel 	 * to this device.
   1277      0     stevel 	 */
   1278   4404    gd78059 	mutex_enter(&erip->intrlock);
   1279   4404    gd78059 	bcopy(macaddr, &erip->ouraddr, ETHERADDRL);
   1280   4404    gd78059 	eri_init_rx(erip);
   1281   4404    gd78059 	mutex_exit(&erip->intrlock);
   1282   4404    gd78059 	return (0);
   1283   4404    gd78059 }
   1284   4404    gd78059 
   1285   4404    gd78059 /*ARGSUSED*/
   1286   4404    gd78059 static boolean_t
   1287   4404    gd78059 eri_m_getcapab(void *arg, mac_capab_t cap, void *cap_data)
   1288   4404    gd78059 {
   1289   4404    gd78059 	switch (cap) {
   1290   4404    gd78059 	case MAC_CAPAB_HCKSUM: {
   1291   4404    gd78059 		uint32_t *hcksum_txflags = cap_data;
   1292   4404    gd78059 		*hcksum_txflags = HCKSUM_INET_PARTIAL;
   1293   4404    gd78059 		return (B_TRUE);
   1294   4404    gd78059 	}
   1295   4404    gd78059 	default:
   1296   4404    gd78059 		return (B_FALSE);
   1297   4404    gd78059 	}
   1298   4404    gd78059 }
   1299   4404    gd78059 
   1300   4404    gd78059 static int
   1301   4404    gd78059 eri_m_start(void *arg)
   1302   4404    gd78059 {
   1303   4404    gd78059 	struct eri	*erip = arg;
   1304   4404    gd78059 
   1305   4404    gd78059 	mutex_enter(&erip->intrlock);
   1306   4404    gd78059 	erip->flags |= ERI_STARTED;
   1307   4404    gd78059 	mutex_exit(&erip->intrlock);
   1308   4404    gd78059 
   1309   4404    gd78059 	if (!eri_init(erip)) {
   1310   4404    gd78059 		mutex_enter(&erip->intrlock);
   1311   4404    gd78059 		erip->flags &= ~ERI_STARTED;
   1312   4404    gd78059 		mutex_exit(&erip->intrlock);
   1313   4404    gd78059 		return (EIO);
   1314   4404    gd78059 	}
   1315   4404    gd78059 	return (0);
   1316   4404    gd78059 }
   1317   4404    gd78059 
   1318   4404    gd78059 static void
   1319   4404    gd78059 eri_m_stop(void *arg)
   1320   4404    gd78059 {
   1321   4404    gd78059 	struct eri	*erip = arg;
   1322   4404    gd78059 
   1323   4404    gd78059 	mutex_enter(&erip->intrlock);
   1324   4404    gd78059 	erip->flags &= ~ERI_STARTED;
   1325   4404    gd78059 	mutex_exit(&erip->intrlock);
   1326   4404    gd78059 	eri_uninit(erip);
   1327   4404    gd78059 }
   1328   4404    gd78059 
   1329   4404    gd78059 static int
   1330   4404    gd78059 eri_m_stat(void *arg, uint_t stat, uint64_t *val)
   1331   4404    gd78059 {
   1332   4404    gd78059 	struct eri	*erip = arg;
   1333   4404    gd78059 	struct stats	*esp;
   1334   4404    gd78059 	boolean_t	macupdate = B_FALSE;
   1335   4404    gd78059 
   1336   4404    gd78059 	esp = &erip->stats;
   1337   4404    gd78059 
   1338   4404    gd78059 	mutex_enter(&erip->xmitlock);
   1339   4404    gd78059 	if ((erip->flags & ERI_RUNNING) && (erip->flags & ERI_TXINIT)) {
   1340   4404    gd78059 		erip->tx_completion =
   1341   4404    gd78059 		    GET_ETXREG(tx_completion) & ETX_COMPLETION_MASK;
   1342   4404    gd78059 		macupdate |= eri_reclaim(erip, erip->tx_completion);
   1343   4404    gd78059 	}
   1344   4404    gd78059 	mutex_exit(&erip->xmitlock);
   1345   4404    gd78059 	if (macupdate)
   1346   4404    gd78059 		mac_tx_update(erip->mh);
   1347   4404    gd78059 
   1348   4404    gd78059 	eri_savecntrs(erip);
   1349   4404    gd78059 
   1350   4404    gd78059 	switch (stat) {
   1351   4404    gd78059 	case MAC_STAT_IFSPEED:
   1352   4404    gd78059 		*val = esp->ifspeed * 1000000ULL;
   1353   4404    gd78059 		break;
   1354   4404    gd78059 	case MAC_STAT_MULTIRCV:
   1355   4404    gd78059 		*val = esp->multircv;
   1356   4404    gd78059 		break;
   1357   4404    gd78059 	case MAC_STAT_BRDCSTRCV:
   1358   4404    gd78059 		*val = esp->brdcstrcv;
   1359   4404    gd78059 		break;
   1360   4404    gd78059 	case MAC_STAT_IPACKETS:
   1361   4404    gd78059 		*val = esp->ipackets64;
   1362   4404    gd78059 		break;
   1363   4404    gd78059 	case MAC_STAT_RBYTES:
   1364   4404    gd78059 		*val = esp->rbytes64;
   1365   4404    gd78059 		break;
   1366   4404    gd78059 	case MAC_STAT_OBYTES:
   1367   4404    gd78059 		*val = esp->obytes64;
   1368   4404    gd78059 		break;
   1369   4404    gd78059 	case MAC_STAT_OPACKETS:
   1370   4404    gd78059 		*val = esp->opackets64;
   1371   4404    gd78059 		break;
   1372   4404    gd78059 	case MAC_STAT_IERRORS:
   1373   4404    gd78059 		*val = esp->ierrors;
   1374   4404    gd78059 		break;
   1375   4404    gd78059 	case MAC_STAT_OERRORS:
   1376   4404    gd78059 		*val = esp->oerrors;
   1377   4404    gd78059 		break;
   1378   4404    gd78059 	case MAC_STAT_MULTIXMT:
   1379   4404    gd78059 		*val = esp->multixmt;
   1380   4404    gd78059 		break;
   1381   4404    gd78059 	case MAC_STAT_BRDCSTXMT:
   1382   4404    gd78059 		*val = esp->brdcstxmt;
   1383   4404    gd78059 		break;
   1384   4404    gd78059 	case MAC_STAT_NORCVBUF:
   1385   4404    gd78059 		*val = esp->norcvbuf;
   1386   4404    gd78059 		break;
   1387   4404    gd78059 	case MAC_STAT_NOXMTBUF:
   1388   4404    gd78059 		*val = esp->noxmtbuf;
   1389   4404    gd78059 		break;
   1390   4404    gd78059 	case MAC_STAT_UNDERFLOWS:
   1391   4404    gd78059 		*val = esp->txmac_urun;
   1392   4404    gd78059 		break;
   1393   4404    gd78059 	case MAC_STAT_OVERFLOWS:
   1394   4404    gd78059 		*val = esp->rx_overflow;
   1395   4404    gd78059 		break;
   1396   4404    gd78059 	case MAC_STAT_COLLISIONS:
   1397   4404    gd78059 		*val = esp->collisions;
   1398   4404    gd78059 		break;
   1399   4404    gd78059 	case ETHER_STAT_ALIGN_ERRORS:
   1400   4404    gd78059 		*val = esp->rx_align_err;
   1401   4404    gd78059 		break;
   1402   4404    gd78059 	case ETHER_STAT_FCS_ERRORS:
   1403   4404    gd78059 		*val = esp->rx_crc_err;
   1404   4404    gd78059 		break;
   1405   4404    gd78059 	case ETHER_STAT_EX_COLLISIONS:
   1406   4404    gd78059 		*val = esp->excessive_coll;
   1407   4404    gd78059 		break;
   1408   4404    gd78059 	case ETHER_STAT_TX_LATE_COLLISIONS:
   1409   4404    gd78059 		*val = esp->late_coll;
   1410   4404    gd78059 		break;
   1411   4404    gd78059 	case ETHER_STAT_FIRST_COLLISIONS:
   1412   4404    gd78059 		*val = esp->first_coll;
   1413   4404    gd78059 		break;
   1414   4404    gd78059 	case ETHER_STAT_LINK_DUPLEX:
   1415   4404    gd78059 		*val = esp->link_duplex;
   1416   4404    gd78059 		break;
   1417   4404    gd78059 	case ETHER_STAT_TOOLONG_ERRORS:
   1418   4404    gd78059 		*val = esp->rx_toolong_pkts;
   1419   4404    gd78059 		break;
   1420   4404    gd78059 	case ETHER_STAT_TOOSHORT_ERRORS:
   1421   4404    gd78059 		*val = esp->rx_runt;
   1422   4404    gd78059 		break;
   1423   4404    gd78059 
   1424   4404    gd78059 	case ETHER_STAT_XCVR_ADDR:
   1425   4404    gd78059 		*val = erip->phyad;
   1426   4404    gd78059 		break;
   1427   4404    gd78059 
   1428   4404    gd78059 	case ETHER_STAT_XCVR_INUSE:
   1429   4404    gd78059 		*val = XCVR_100X;	/* should always be 100X for now */
   1430   4404    gd78059 		break;
   1431   4404    gd78059 
   1432   4404    gd78059 	case ETHER_STAT_CAP_100FDX:
   1433   4404    gd78059 		*val = param_bmsr_100fdx;
   1434   4404    gd78059 		break;
   1435   4404    gd78059 	case ETHER_STAT_CAP_100HDX:
   1436   4404    gd78059 		*val = param_bmsr_100hdx;
   1437   4404    gd78059 		break;
   1438   4404    gd78059 	case ETHER_STAT_CAP_10FDX:
   1439   4404    gd78059 		*val = param_bmsr_10fdx;
   1440   4404    gd78059 		break;
   1441   4404    gd78059 	case ETHER_STAT_CAP_10HDX:
   1442   4404    gd78059 		*val = param_bmsr_10hdx;
   1443   4404    gd78059 		break;
   1444   4404    gd78059 	case ETHER_STAT_CAP_AUTONEG:
   1445   4404    gd78059 		*val = param_bmsr_ancap;
   1446   4404    gd78059 		break;
   1447   4404    gd78059 	case ETHER_STAT_CAP_ASMPAUSE:
   1448   4404    gd78059 		*val = param_bmsr_asm_dir;
   1449   4404    gd78059 		break;
   1450   4404    gd78059 	case ETHER_STAT_CAP_PAUSE:
   1451   4404    gd78059 		*val = param_bmsr_pause;
   1452   4404    gd78059 		break;
   1453   4404    gd78059 	case ETHER_STAT_ADV_CAP_100FDX:
   1454   4404    gd78059 		*val = param_anar_100fdx;
   1455   4404    gd78059 		break;
   1456   4404    gd78059 	case ETHER_STAT_ADV_CAP_100HDX:
   1457   4404    gd78059 		*val = param_anar_100hdx;
   1458   4404    gd78059 		break;
   1459   4404    gd78059 	case ETHER_STAT_ADV_CAP_10FDX:
   1460   4404    gd78059 		*val = param_anar_10fdx;
   1461   4404    gd78059 		break;
   1462   4404    gd78059 	case ETHER_STAT_ADV_CAP_10HDX:
   1463   4404    gd78059 		*val = param_anar_10hdx;
   1464   4404    gd78059 		break;
   1465   4404    gd78059 	case ETHER_STAT_ADV_CAP_AUTONEG:
   1466   4404    gd78059 		*val = param_autoneg;
   1467   4404    gd78059 		break;
   1468   4404    gd78059 	case ETHER_STAT_ADV_CAP_ASMPAUSE:
   1469   4404    gd78059 		*val = param_anar_asm_dir;
   1470   4404    gd78059 		break;
   1471   4404    gd78059 	case ETHER_STAT_ADV_CAP_PAUSE:
   1472   4404    gd78059 		*val = param_anar_pause;
   1473   4404    gd78059 		break;
   1474   4404    gd78059 	case ETHER_STAT_LP_CAP_100FDX:
   1475   4404    gd78059 		*val = param_anlpar_100fdx;
   1476   4404    gd78059 		break;
   1477   4404    gd78059 	case ETHER_STAT_LP_CAP_100HDX:
   1478   4404    gd78059 		*val = param_anlpar_100hdx;
   1479   4404    gd78059 		break;
   1480   4404    gd78059 	case ETHER_STAT_LP_CAP_10FDX:
   1481   4404    gd78059 		*val = param_anlpar_10fdx;
   1482   4404    gd78059 		break;
   1483   4404    gd78059 	case ETHER_STAT_LP_CAP_10HDX:
   1484   4404    gd78059 		*val = param_anlpar_10hdx;
   1485   4404    gd78059 		break;
   1486   4404    gd78059 	case ETHER_STAT_LP_CAP_AUTONEG:
   1487   4404    gd78059 		*val = param_aner_lpancap;
   1488   4404    gd78059 		break;
   1489   4404    gd78059 	case ETHER_STAT_LP_CAP_ASMPAUSE:
   1490   4404    gd78059 		*val = param_anlpar_pauseTX;
   1491   4404    gd78059 		break;
   1492   4404    gd78059 	case ETHER_STAT_LP_CAP_PAUSE:
   1493   4404    gd78059 		*val = param_anlpar_pauseRX;
   1494   4404    gd78059 		break;
   1495   4404    gd78059 	case ETHER_STAT_LINK_PAUSE:
   1496   4404    gd78059 		*val = esp->pausing;
   1497   4404    gd78059 		break;
   1498   4404    gd78059 	case ETHER_STAT_LINK_ASMPAUSE:
   1499   4404    gd78059 		*val = param_anar_asm_dir &&
   1500   4404    gd78059 		    param_anlpar_pauseTX &&
   1501   4404    gd78059 		    (param_anar_pause != param_anlpar_pauseRX);
   1502   4404    gd78059 		break;
   1503   4404    gd78059 	case ETHER_STAT_LINK_AUTONEG:
   1504   4404    gd78059 		*val = param_autoneg && param_aner_lpancap;
   1505   4404    gd78059 		break;
   1506   4404    gd78059 	}
   1507   4404    gd78059 	return (0);
   1508   4404    gd78059 }
   1509      0     stevel 
   1510      0     stevel /*
   1511      0     stevel  * Hardware Functions
   1512      0     stevel  * New Section
   1513      0     stevel  */
   1514      0     stevel 
   1515      0     stevel /*
   1516      0     stevel  * Initialize the MAC registers. Some of of the MAC  registers are initialized
   1517      0     stevel  * just once since  Global Reset or MAC reset doesn't clear them. Others (like
   1518      0     stevel  * Host MAC Address Registers) are cleared on every reset and have to be
   1519      0     stevel  * reinitialized.
   1520      0     stevel  */
   1521      0     stevel static void
   1522      0     stevel eri_init_macregs_generic(struct eri *erip)
   1523   4404    gd78059 {
   1524      0     stevel 	/*
   1525      0     stevel 	 * set up the MAC parameter registers once
   1526      0     stevel 	 * after power cycle. SUSPEND/RESUME also requires
   1527      0     stevel 	 * setting these registers.
   1528      0     stevel 	 */
   1529      0     stevel 	if ((erip->stats.inits == 1) || (erip->init_macregs)) {
   1530      0     stevel 		erip->init_macregs = 0;
   1531      0     stevel 		PUT_MACREG(ipg0, param_ipg0);
   1532      0     stevel 		PUT_MACREG(ipg1, param_ipg1);
   1533      0     stevel 		PUT_MACREG(ipg2, param_ipg2);
   1534      0     stevel 		PUT_MACREG(macmin, BMAC_MIN_FRAME_SIZE);
   1535      0     stevel #ifdef	ERI_RX_TAG_ERROR_WORKAROUND
   1536      0     stevel 		PUT_MACREG(macmax, BMAC_MAX_FRAME_SIZE_TAG | BMAC_MAX_BURST);
   1537      0     stevel #else
   1538      0     stevel 		PUT_MACREG(macmax, BMAC_MAX_FRAME_SIZE | BMAC_MAX_BURST);
   1539      0     stevel #endif
   1540      0     stevel 		PUT_MACREG(palen, BMAC_PREAMBLE_SIZE);
   1541      0     stevel 		PUT_MACREG(jam, BMAC_JAM_SIZE);
   1542      0     stevel 		PUT_MACREG(alimit, BMAC_ATTEMPT_LIMIT);
   1543      0     stevel 		PUT_MACREG(macctl_type, BMAC_CONTROL_TYPE);
   1544      0     stevel 		PUT_MACREG(rseed,
   1545   4404    gd78059 		    ((erip->ouraddr[0] & 0x3) << 8) | erip->ouraddr[1]);
   1546      0     stevel 
   1547      0     stevel 		PUT_MACREG(madd3, BMAC_ADDRESS_3);
   1548      0     stevel 		PUT_MACREG(madd4, BMAC_ADDRESS_4);
   1549      0     stevel 		PUT_MACREG(madd5, BMAC_ADDRESS_5);
   1550      0     stevel 
   1551      0     stevel 		/* Program MAC Control address */
   1552      0     stevel 		PUT_MACREG(madd6, BMAC_ADDRESS_6);
   1553      0     stevel 		PUT_MACREG(madd7, BMAC_ADDRESS_7);
   1554      0     stevel 		PUT_MACREG(madd8, BMAC_ADDRESS_8);
   1555      0     stevel 
   1556      0     stevel 		PUT_MACREG(afr0, BMAC_AF_0);
   1557      0     stevel 		PUT_MACREG(afr1, BMAC_AF_1);
   1558      0     stevel 		PUT_MACREG(afr2, BMAC_AF_2);
   1559      0     stevel 		PUT_MACREG(afmr1_2, BMAC_AF21_MASK);
   1560      0     stevel 		PUT_MACREG(afmr0, BMAC_AF0_MASK);
   1561      0     stevel 	}
   1562      0     stevel 
   1563      0     stevel 	/* The counters need to be zeroed */
   1564      0     stevel 	PUT_MACREG(nccnt, 0);
   1565      0     stevel 	PUT_MACREG(fccnt, 0);
   1566      0     stevel 	PUT_MACREG(excnt, 0);
   1567      0     stevel 	PUT_MACREG(ltcnt, 0);
   1568      0     stevel 	PUT_MACREG(dcnt,  0);
   1569      0     stevel 	PUT_MACREG(frcnt, 0);
   1570      0     stevel 	PUT_MACREG(lecnt, 0);
   1571      0     stevel 	PUT_MACREG(aecnt, 0);
   1572      0     stevel 	PUT_MACREG(fecnt, 0);
   1573      0     stevel 	PUT_MACREG(rxcv,  0);
   1574      0     stevel 
   1575      0     stevel 	if (erip->pauseTX)
   1576      0     stevel 		PUT_MACREG(spcmd, BMAC_SEND_PAUSE_CMD);
   1577      0     stevel 	else
   1578      0     stevel 		PUT_MACREG(spcmd, 0);
   1579   4728    gd78059 
   1580   4728    gd78059 	/*
   1581   4728    gd78059 	 * Program BigMAC with local individual ethernet address.
   1582   4728    gd78059 	 */
   1583   4728    gd78059 
   1584   4728    gd78059 	PUT_MACREG(madd0, (erip->ouraddr[4] << 8) | erip->ouraddr[5]);
   1585   4728    gd78059 	PUT_MACREG(madd1, (erip->ouraddr[2] << 8) | erip->ouraddr[3]);
   1586   4728    gd78059 	PUT_MACREG(madd2, (erip->ouraddr[0] << 8) | erip->ouraddr[1]);
   1587   4728    gd78059 
   1588   4728    gd78059 	/*
   1589   4728    gd78059 	 * Install multicast address filter.
   1590   4728    gd78059 	 */
   1591   4728    gd78059 
   1592   4728    gd78059 	PUT_MACREG(hash0, erip->ladrf[0]);
   1593   4728    gd78059 	PUT_MACREG(hash1, erip->ladrf[1]);
   1594   4728    gd78059 	PUT_MACREG(hash2, erip->ladrf[2]);
   1595   4728    gd78059 	PUT_MACREG(hash3, erip->ladrf[3]);
   1596   4728    gd78059 	PUT_MACREG(hash4, erip->ladrf[4]);
   1597   4728    gd78059 	PUT_MACREG(hash5, erip->ladrf[5]);
   1598   4728    gd78059 	PUT_MACREG(hash6, erip->ladrf[6]);
   1599   4728    gd78059 	PUT_MACREG(hash7, erip->ladrf[7]);
   1600   4728    gd78059 	PUT_MACREG(hash8, erip->ladrf[8]);
   1601   4728    gd78059 	PUT_MACREG(hash9, erip->ladrf[9]);
   1602   4728    gd78059 	PUT_MACREG(hash10, erip->ladrf[10]);
   1603   4728    gd78059 	PUT_MACREG(hash11, erip->ladrf[11]);
   1604   4728    gd78059 	PUT_MACREG(hash12, erip->ladrf[12]);
   1605   4728    gd78059 	PUT_MACREG(hash13, erip->ladrf[13]);
   1606   4728    gd78059 	PUT_MACREG(hash14, erip->ladrf[14]);
   1607   4404    gd78059 }
   1608   4404    gd78059 
   1609   4404    gd78059 static int
   1610   4404    gd78059 eri_flush_rxbufs(struct eri *erip)
   1611   4404    gd78059 {
   1612   4404    gd78059 	uint_t	i;
   1613   4404    gd78059 	int	status = 0;
   1614   4404    gd78059 	/*
   1615   4404    gd78059 	 * Free and dvma_unload pending recv buffers.
   1616   4404    gd78059 	 * Maintaining the 1-to-1 ordered sequence of
   1617   4404    gd78059 	 * dvma_load() followed by dvma_unload() is critical.
   1618   4404    gd78059 	 * Always unload anything before loading it again.
   1619   4404    gd78059 	 * Never unload anything twice.  Always unload
   1620   4404    gd78059 	 * before freeing the buffer.  We satisfy these
   1621   4404    gd78059 	 * requirements by unloading only those descriptors
   1622   4404    gd78059 	 * which currently have an mblk associated with them.
   1623   4404    gd78059 	 */
   1624   4404    gd78059 	for (i = 0; i < ERI_RPENDING; i++) {
   1625   4404    gd78059 		if (erip->rmblkp[i]) {
   1626   4404    gd78059 			if (erip->eri_dvmarh)
   1627   4404    gd78059 				dvma_unload(erip->eri_dvmarh, 2 * i,
   1628   4404    gd78059 				    DDI_DMA_SYNC_FORCPU);
   1629   4404    gd78059 			else if ((ddi_dma_unbind_handle(erip->ndmarh[i]) ==
   1630   4404    gd78059 			    DDI_FAILURE))
   1631   4404    gd78059 				status = -1;
   1632   4404    gd78059 			freeb(erip->rmblkp[i]);
   1633   4404    gd78059 			erip->rmblkp[i] = NULL;
   1634   4404    gd78059 		}
   1635   4404    gd78059 	}
   1636   4404    gd78059 	return (status);
   1637   4404    gd78059 }
   1638   4404    gd78059 
   1639   4404    gd78059 static void
   1640   4404    gd78059 eri_init_txbufs(struct eri *erip)
   1641   4404    gd78059 {
   1642   4404    gd78059 	/*
   1643   4404    gd78059 	 * Clear TX descriptors.
   1644   4404    gd78059 	 */
   1645   4404    gd78059 	bzero((caddr_t)erip->eri_tmdp, ERI_TPENDING * sizeof (struct eri_tmd));
   1646   4404    gd78059 
   1647   4404    gd78059 	/*
   1648   4404    gd78059 	 * sync TXDMA descriptors.
   1649   4404    gd78059 	 */
   1650   4404    gd78059 	ERI_SYNCIOPB(erip, erip->eri_tmdp,
   1651   4404    gd78059 	    (ERI_TPENDING * sizeof (struct eri_tmd)), DDI_DMA_SYNC_FORDEV);
   1652   4404    gd78059 	/*
   1653   4404    gd78059 	 * Reset TMD 'walking' pointers.
   1654   4404    gd78059 	 */
   1655   4404    gd78059 	erip->tcurp = erip->eri_tmdp;
   1656   4404    gd78059 	erip->tnextp = erip->eri_tmdp;
   1657   4404    gd78059 	erip->tx_cur_cnt = 0;
   1658   4404    gd78059 	erip->tx_kick = 0;
   1659   4404    gd78059 	erip->tx_completion = 0;
   1660   4404    gd78059 }
   1661   4404    gd78059 
   1662   4404    gd78059 static int
   1663   4404    gd78059 eri_init_rxbufs(struct eri *erip)
   1664   4404    gd78059 {
   1665   4404    gd78059 
   1666   4404    gd78059 	ddi_dma_cookie_t	dma_cookie;
   1667   4404    gd78059 	mblk_t			*bp;
   1668   4404    gd78059 	int			i, status = 0;
   1669   4404    gd78059 	uint32_t		ccnt;
   1670   4404    gd78059 
   1671   4404    gd78059 	/*
   1672   4404    gd78059 	 * clear rcv descriptors
   1673   4404    gd78059 	 */
   1674   4404    gd78059 	bzero((caddr_t)erip->rmdp, ERI_RPENDING * sizeof (struct rmd));
   1675   4404    gd78059 
   1676   4404    gd78059 	for (i = 0; i < ERI_RPENDING; i++) {
   1677   4404    gd78059 		if ((bp = eri_allocb(ERI_BUFSIZE)) == NULL) {
   1678   4404    gd78059 			status = -1;
   1679   4404    gd78059 			continue;
   1680   4404    gd78059 		}
   1681   4404    gd78059 		/* Load data buffer to DVMA space */
   1682   4404    gd78059 		if (erip->eri_dvmarh)
   1683   4404    gd78059 			dvma_kaddr_load(erip->eri_dvmarh,
   1684   4404    gd78059 			    (caddr_t)bp->b_rptr, ERI_BUFSIZE,
   1685   4404    gd78059 			    2 * i, &dma_cookie);
   1686   4404    gd78059 /*
   1687   4404    gd78059  *		Bind data buffer to DMA handle
   1688   4404    gd78059  */
   1689   4404    gd78059 		else if (ddi_dma_addr_bind_handle(erip->ndmarh[i], NULL,
   1690   4404    gd78059 		    (caddr_t)bp->b_rptr, ERI_BUFSIZE,
   1691   4404    gd78059 		    DDI_DMA_READ | DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0,
   1692   4404    gd78059 		    &dma_cookie, &ccnt) != DDI_DMA_MAPPED)
   1693   4404    gd78059 			status = -1;
   1694   4404    gd78059 
   1695   4404    gd78059 		PUT_RMD((&erip->rmdp[i]), dma_cookie);
   1696   4404    gd78059 		erip->rmblkp[i] = bp;	/* save for later use */
   1697   4404    gd78059 	}
   1698   4404    gd78059 
   1699   4404    gd78059 	/*
   1700   4404    gd78059 	 * sync RXDMA descriptors.
   1701   4404    gd78059 	 */
   1702   4404    gd78059 	ERI_SYNCIOPB(erip, erip->rmdp, (ERI_RPENDING * sizeof (struct rmd)),
   1703   4404    gd78059 	    DDI_DMA_SYNC_FORDEV);
   1704   4404    gd78059 	/*
   1705   4404    gd78059 	 * Reset RMD 'walking' pointers.
   1706   4404    gd78059 	 */
   1707   4404    gd78059 	erip->rnextp = erip->rmdp;
   1708   4404    gd78059 	erip->rx_completion = 0;
   1709   4404    gd78059 	erip->rx_kick = ERI_RPENDING - 4;
   1710   4404    gd78059 	return (status);
   1711   4404    gd78059 }
   1712   4404    gd78059 
   1713   4404    gd78059 static uint32_t
   1714   4404    gd78059 eri_txmac_disable(struct eri *erip)
   1715   4404    gd78059 {
   1716   4404    gd78059 	int	n;
   1717   4404    gd78059 
   1718   4404    gd78059 	PUT_MACREG(txcfg, GET_MACREG(txcfg) & ~BMAC_TXCFG_ENAB);
   1719   4404    gd78059 	n = (BMACTXRSTDELAY * 10) / ERI_WAITPERIOD;
   1720   4404    gd78059 
   1721   4404    gd78059 	while (--n > 0) {
   1722   4404    gd78059 		drv_usecwait(ERI_WAITPERIOD);
   1723   4404    gd78059 		if ((GET_MACREG(txcfg) & 1) == 0)
   1724   4404    gd78059 			return (0);
   1725   4404    gd78059 	}
   1726   4404    gd78059 	return (1);
   1727   4404    gd78059 }
   1728   4404    gd78059 
   1729   4404    gd78059 static uint32_t
   1730   4404    gd78059 eri_rxmac_disable(struct eri *erip)
   1731   4404    gd78059 {
   1732   4404    gd78059 	int	n;
   1733   4404    gd78059 	PUT_MACREG(rxcfg, GET_MACREG(rxcfg) & ~BMAC_RXCFG_ENAB);
   1734   4404    gd78059 	n = BMACRXRSTDELAY / ERI_WAITPERIOD;
   1735   4404    gd78059 
   1736   4404    gd78059 	while (--n > 0) {
   1737   4404    gd78059 		drv_usecwait(ERI_WAITPERIOD);
   1738   4404    gd78059 		if ((GET_MACREG(rxcfg) & 1) == 0)
   1739   4404    gd78059 			return (0);
   1740   4404    gd78059 	}
   1741   4404    gd78059 	return (1);
   1742   4404    gd78059 }
   1743   4404    gd78059 
   1744   4404    gd78059 /*
   1745   4404    gd78059  * Return 0 upon success, 1 on failure.
   1746   4404    gd78059  */
   1747   4404    gd78059 static int
   1748   4404    gd78059 eri_stop(struct eri *erip)
   1749   4404    gd78059 {
   1750   4404    gd78059 	(void) eri_erx_reset(erip);
   1751   4404    gd78059 	(void) eri_etx_reset(erip);
   1752   4404    gd78059 
   1753   4404    gd78059 	/*
   1754   4404    gd78059 	 * set up cache line to 16 for 64 bytes of pci burst size
   1755   4404    gd78059 	 */
   1756   4404    gd78059 	PUT_SWRSTREG(reset, ERI_G_RESET_GLOBAL | ERI_CACHE_LINE_SIZE);
   1757   4404    gd78059 
   1758   4404    gd78059 	if (erip->linkcheck) {
   1759   4404    gd78059 		erip->linkcheck = 0;
   1760   4404    gd78059 		erip->global_reset_issued = 2;
   1761   4404    gd78059 	} else {
   1762   4404    gd78059 		param_linkup = 0;
   1763   4404    gd78059 		erip->stats.link_up = LINK_STATE_DOWN;
   1764   4404    gd78059 		erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN;
   1765   4404    gd78059 		erip->global_reset_issued = -1;
   1766   4404    gd78059 	}
   1767   4404    gd78059 
   1768   4404    gd78059 	ERI_DELAY((GET_SWRSTREG(reset) == ERI_CACHE_LINE_SIZE),
   1769   4404    gd78059 	    ERI_MAX_RST_DELAY);
   1770   4404    gd78059 	erip->rx_reset_issued = -1;
   1771   4404    gd78059 	erip->tx_reset_issued = -1;
   1772   4404    gd78059 
   1773   4404    gd78059 	/*
   1774   4404    gd78059 	 * workaround for RIO not resetting the interrupt mask
   1775   4404    gd78059 	 * register to default value 0xffffffff.
   1776   4404    gd78059 	 */
   1777   4404    gd78059 	PUT_GLOBREG(intmask, ERI_G_MASK_ALL);
   1778   4404    gd78059 
   1779   4404    gd78059 	if (GET_SWRSTREG(reset) == ERI_CACHE_LINE_SIZE) {
   1780   4404    gd78059 		return (0);
   1781   4404    gd78059 	} else {
   1782   4404    gd78059 		return (1);
   1783   4404    gd78059 	}
   1784   4404    gd78059 }
   1785   4404    gd78059 
   1786   4404    gd78059 /*
   1787   4404    gd78059  * Reset Just the RX Portion
   1788   4404    gd78059  * Return 0 upon success, 1 on failure.
   1789   4404    gd78059  *
   1790   4404    gd78059  * Resetting the rxdma while there is a rx dma transaction going on the
   1791   4404    gd78059  * bus, will cause bus hang or parity errors. To avoid this, we would first
   1792   4404    gd78059  * disable the rxdma by clearing the ENABLE bit (bit 0). To make sure it is
   1793   4404    gd78059  * disabled, we will poll it until it realy clears. Furthermore, to verify
   1794   4404    gd78059  * any RX DMA activity is subsided, we delay for 5 msec.
   1795   4404    gd78059  */
   1796   4404    gd78059 static uint32_t
   1797   4404    gd78059 eri_erx_reset(struct eri *erip)
   1798   4404    gd78059 {
   1799   4404    gd78059 	(void) eri_rxmac_disable(erip); /* Disable the RX MAC */
   1800   4404    gd78059 
   1801   4404    gd78059 	/* Disable the RX DMA */
   1802   4404    gd78059 	PUT_ERXREG(config, GET_ERXREG(config) & ~GET_CONFIG_RXDMA_EN);
   1803   4404    gd78059 	ERI_DELAY(((GET_ERXREG(config) &  1) == 0), ERI_MAX_RST_DELAY);
   1804   4404    gd78059 	if ((GET_ERXREG(config) & 1) != 0)
   1805   4404    gd78059 		ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG,
   1806   4404    gd78059 		    disable_erx_msg);
   1807   4404    gd78059 
   1808   4404    gd78059 	drv_usecwait(5000); /* Delay to insure no RX DMA activity */
   1809   4404    gd78059 
   1810   4404    gd78059 	PUT_SWRSTREG(reset, ERI_G_RESET_ERX | ERI_CACHE_LINE_SIZE);
   1811   4404    gd78059 	/*
   1812   4404    gd78059 	 * Wait until the reset is completed which is indicated by
   1813   4404    gd78059 	 * the reset bit cleared or time out..
   1814   4404    gd78059 	 */
   1815   4404    gd78059 	ERI_DELAY(((GET_SWRSTREG(reset) & (ERI_G_RESET_ERX)) ==
   1816   4404    gd78059 	    ERI_CACHE_LINE_SIZE), ERI_MAX_RST_DELAY);
   1817   4404    gd78059 	erip->rx_reset_issued = -1;
   1818   4404    gd78059 
   1819   4404    gd78059 	return ((GET_SWRSTREG(reset) & (ERI_G_RESET_ERX)) ? 1 : 0);
   1820   4404    gd78059 }
   1821   4404    gd78059 
   1822   4404    gd78059 /*
   1823   4404    gd78059  * Reset Just the TX Portion
   1824   4404    gd78059  * Return 0 upon success, 1 on failure.
   1825   4404    gd78059  * Resetting the txdma while there is a tx dma transaction on the bus, may cause
   1826   4404    gd78059  * bus hang or parity errors. To avoid this we would first disable the txdma by
   1827   4404    gd78059  * clearing the ENABLE bit (bit 0). To make sure it is disabled, we will poll
   1828   4404    gd78059  * it until it realy clears. Furthermore, to any TX DMA activity is subsided,
   1829   4404    gd78059  * we delay for 1 msec.
   1830   4404    gd78059  */
   1831   4404    gd78059 static uint32_t
   1832   4404    gd78059 eri_etx_reset(struct eri *erip)
   1833   4404    gd78059 {
   1834   4404    gd78059 	(void) eri_txmac_disable(erip);
   1835   4404    gd78059 
   1836   4404    gd78059 	/* Disable the TX DMA */
   1837   4404    gd78059 	PUT_ETXREG(config, GET_ETXREG(config) & ~GET_CONFIG_TXDMA_EN);
   1838   4404    gd78059 #ifdef ORIG
   1839   4404    gd78059 	ERI_DELAY(((GET_ETXREG(config) &  1) == 0), ERI_MAX_RST_DELAY);
   1840   4404    gd78059 	if ((GET_ETXREG(config) &  1) != 0)
   1841   4404    gd78059 		ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG,
   1842   4404    gd78059 		    disable_etx_msg);
   1843   4404    gd78059 	drv_usecwait(5000); /* Delay  to ensure DMA completed (if any). */
   1844   4404    gd78059 #endif
   1845   4404    gd78059 	drv_usecwait(5000); /* Delay  to ensure DMA completed (if any). */
   1846   4404    gd78059 	ERI_DELAY(((GET_ETXREG(config) &  1) == 0), ERI_MAX_RST_DELAY);
   1847   4404    gd78059 	if ((GET_ETXREG(config) &  1) != 0)
   1848   4404    gd78059 		ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG,
   1849   4404    gd78059 		    disable_etx_msg);
   1850   4404    gd78059 
   1851   4404    gd78059 	PUT_SWRSTREG(reset, ERI_G_RESET_ETX | ERI_CACHE_LINE_SIZE);
   1852   4404    gd78059 
   1853   4404    gd78059 	/*
   1854   4404    gd78059 	 * Wait until the reset is completed which is indicated by the reset bit
   1855   4404    gd78059 	 * cleared or time out..
   1856   4404    gd78059 	 */
   1857   4404    gd78059 	ERI_DELAY(((GET_SWRSTREG(reset) & (ERI_G_RESET_ETX)) ==
   1858   4404    gd78059 	    ERI_CACHE_LINE_SIZE), ERI_MAX_RST_DELAY);
   1859   4404    gd78059 	erip->tx_reset_issued = -1;
   1860   4404    gd78059 
   1861   4404    gd78059 	if (GET_SWRSTREG(reset) &  (ERI_G_RESET_ETX)) {
   1862   4404    gd78059 		return (1);
   1863   4404    gd78059 	} else
   1864   4404    gd78059 		return (0);
   1865   4404    gd78059 }
   1866   4404    gd78059 
   1867   4404    gd78059 
   1868   4404    gd78059 /*
   1869   4404    gd78059  * Initialize the TX DMA registers and Enable the TX DMA.
   1870   4404    gd78059  */
   1871   4404    gd78059 static uint32_t
   1872   4404    gd78059 eri_init_txregs(struct eri *erip)
   1873   4404    gd78059 {
   1874   4404    gd78059 
   1875   4404    gd78059 	uint32_t	i;
   1876   4404    gd78059 	uint64_t	tx_ring;
   1877   4404    gd78059 
   1878   4404    gd78059 	/*
   1879   4404    gd78059 	 * Initialize ETX Registers:
   1880   4404    gd78059 	 * config, txring_lo, txring_hi
   1881   4404    gd78059 	 */
   1882   4404    gd78059 	tx_ring = ERI_IOPBIOADDR(erip, erip->eri_tmdp);
   1883   4404    gd78059 	PUT_ETXREG(txring_lo, (uint32_t)(tx_ring));
   1884   4404    gd78059 	PUT_ETXREG(txring_hi, (uint32_t)(tx_ring >> 32));
   1885   4404    gd78059 
   1886   4404    gd78059 	/*
   1887   4404    gd78059 	 * Get TX Ring Size Masks.
   1888   4404    gd78059 	 * The ring size ERI_TPENDING is defined in eri_mac.h.
   1889   4404    gd78059 	 */
   1890   4404    gd78059 	switch (ERI_TPENDING) {
   1891   4404    gd78059 	case 32: i = ETX_RINGSZ_32;
   1892   4404    gd78059 		break;
   1893   4404    gd78059 	case 64: i = ETX_RINGSZ_64;
   1894   4404    gd78059 		break;
   1895   4404    gd78059 	case 128: i = ETX_RINGSZ_128;
   1896   4404    gd78059 		break;
   1897   4404    gd78059 	case 256: i = ETX_RINGSZ_256;
   1898   4404    gd78059 		break;
   1899   4404    gd78059 	case 512: i = ETX_RINGSZ_512;
   1900   4404    gd78059 		break;
   1901   4404    gd78059 	case 1024: i = ETX_RINGSZ_1024;
   1902   4404    gd78059 		break;
   1903   4404    gd78059 	case 2048: i = ETX_RINGSZ_2048;
   1904   4404    gd78059 		break;
   1905   4404    gd78059 	case 4096: i = ETX_RINGSZ_4096;
   1906   4404    gd78059 		break;
   1907   4404    gd78059 	default:
   1908   4404    gd78059 		ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG,
   1909   4404    gd78059 		    unk_tx_descr_sze_msg, ERI_TPENDING);
   1910   4404    gd78059 		return (1);
   1911   4404    gd78059 	}
   1912   4404    gd78059 
   1913   4404    gd78059 	i <<= ERI_TX_RINGSZ_SHIFT;
   1914   4404    gd78059 	PUT_ETXREG(config, ETX_CONFIG_THRESHOLD | i);
   1915   4404    gd78059 	ENABLE_TXDMA(erip);
   1916   4404    gd78059 	ENABLE_MAC(erip);
   1917   4404    gd78059 	return (0);
   1918   4404    gd78059 }
   1919   4404    gd78059 
   1920   4404    gd78059 
   1921   4404    gd78059 /*
   1922   4404    gd78059  * Initialize the RX DMA registers and Enable the RX DMA.
   1923   4404    gd78059  */
   1924   4404    gd78059 static uint32_t
   1925   4404    gd78059 eri_init_rxregs(struct eri *erip)
   1926   4404    gd78059 {
   1927   4404    gd78059 	int i;
   1928   4404    gd78059 	uint64_t	rx_ring;
   1929   4404    gd78059 
   1930   4404    gd78059 	/*
   1931   4404    gd78059 	 * Initialize ERX Registers:
   1932   4404    gd78059 	 * rxring_lo, rxring_hi, config, rx_blanking, rx_pause_threshold.
   1933   4404    gd78059 	 * Also, rx_kick
   1934   4404    gd78059 	 * Read and save rxfifo_size.
   1935   4404    gd78059 	 * XXX: Use this to properly configure PAUSE threshold values.
   1936   4404    gd78059 	 */
   1937   4404    gd78059 	rx_ring = ERI_IOPBIOADDR(erip, erip->rmdp);
   1938   4404    gd78059 	PUT_ERXREG(rxring_lo, (uint32_t)(rx_ring));
   1939   4404    gd78059 	PUT_ERXREG(rxring_hi, (uint32_t)(rx_ring >> 32));
   1940   4404    gd78059 	PUT_ERXREG(rx_kick, erip->rx_kick);
   1941   4404    gd78059 
   1942   4404    gd78059 	/*
   1943   4404    gd78059 	 * The Max ring size, ERI_RMDMAX is defined in eri_mac.h.
   1944   4404    gd78059 	 * More ERI_RPENDING will provide better performance but requires more
   1945   4404    gd78059 	 * system DVMA memory.
   1946   4404    gd78059 	 * eri_rx_ring_size can be used to tune this value from /etc/system
   1947   4404    gd78059 	 * eri_rx_ring_size cannot be NDD'able due to non-recoverable errors
   1948   4404    gd78059 	 * which cannot be detected from NDD operations
   1949   4404    gd78059 	 */
   1950   4404    gd78059 
   1951   4404    gd78059 	/*
   1952   4404    gd78059 	 * get the rxring size bits
   1953   4404    gd78059 	 */
   1954   4404    gd78059 	switch (ERI_RPENDING) {
   1955   4404    gd78059 	case 32: i = ERX_RINGSZ_32;
   1956   4404    gd78059 		break;
   1957   4404    gd78059 	case 64: i = ERX_RINGSZ_64;
   1958   4404    gd78059 		break;
   1959   4404    gd78059 	case 128: i = ERX_RINGSZ_128;
   1960   4404    gd78059 		break;
   1961   4404    gd78059 	case 256: i = ERX_RINGSZ_256;
   1962   4404    gd78059 		break;
   1963   4404    gd78059 	case 512: i = ERX_RINGSZ_512;
   1964   4404    gd78059 		break;
   1965   4404    gd78059 	case 1024: i = ERX_RINGSZ_1024;
   1966   4404    gd78059 		break;
   1967   4404    gd78059 	case 2048: i = ERX_RINGSZ_2048;
   1968   4404    gd78059 		break;
   1969   4404    gd78059 	case 4096: i = ERX_RINGSZ_4096;
   1970   4404    gd78059 		break;
   1971   4404    gd78059 	default:
   1972   4404    gd78059 		ERI_FAULT_MSG2(erip, SEVERITY_HIGH, ERI_VERB_MSG,
   1973   4404    gd78059 		    unk_rx_descr_sze_msg, ERI_RPENDING);
   1974   4404    gd78059 		return (1);
   1975   4404    gd78059 	}
   1976   4404    gd78059 
   1977   4404    gd78059 	i <<= ERI_RX_RINGSZ_SHIFT;
   1978   4404    gd78059 	i |=  (ERI_FSTBYTE_OFFSET << ERI_RX_CONFIG_FBO_SHIFT) |
   1979   4404    gd78059 	    (ETHERHEADER_SIZE << ERI_RX_CONFIG_RX_CSSTART_SHIFT) |
   1980   4404    gd78059 	    (ERI_RX_FIFOTH_1024 << ERI_RX_CONFIG_RXFIFOTH_SHIFT);
   1981   4404    gd78059 
   1982   4404    gd78059 	PUT_ERXREG(config, i);
   1983   4404    gd78059 	PUT_ERXREG(rx_blanking,
   1984   4404    gd78059 	    (param_intr_blank_time << ERI_RX_BLNK_INTR_TIME_SHIFT) |
   1985   4404    gd78059 	    param_intr_blank_packets);
   1986   4404    gd78059 
   1987   4404    gd78059 	PUT_ERXREG(rx_pause_threshold, rx_pause_threshold);
   1988   4404    gd78059 	erip->rxfifo_size = GET_ERXREG(rxfifo_size);
   1989   4404    gd78059 	ENABLE_RXDMA(erip);
   1990   4404    gd78059 	return (0);
   1991   4404    gd78059 }
   1992   4404    gd78059 
   1993   4404    gd78059 static int
   1994   4404    gd78059 eri_freebufs(struct eri *erip)
   1995   4404    gd78059 {
   1996   4404    gd78059 	int status = 0;
   1997   4404    gd78059 
   1998   7394    gdamore 	status = eri_flush_rxbufs(erip);
   1999   4404    gd78059 	return (status);
   2000   4404    gd78059 }
   2001   4404    gd78059 
   2002   4404    gd78059 static void
   2003   4404    gd78059 eri_update_rxbufs(struct eri *erip)
   2004   4404    gd78059 {
   2005   4404    gd78059 	int		i;
   2006   4404    gd78059 	volatile struct rmd  *rmdp, *rmdpbase;
   2007   4404    gd78059 
   2008   4404    gd78059 	/*
   2009   4404    gd78059 	 * Hang out receive buffers.
   2010   4404    gd78059 	 */
   2011   4404    gd78059 	rmdpbase = erip->rmdp;
   2012   4404    gd78059 	for (i = 0; i < ERI_RPENDING; i++) {
   2013   4404    gd78059 		rmdp = rmdpbase + i;
   2014   4404    gd78059 		UPDATE_RMD(rmdp);
   2015   4404    gd78059 	}
   2016   4404    gd78059 
   2017   4404    gd78059 	/*
   2018   4404    gd78059 	 * sync RXDMA descriptors.
   2019   4404    gd78059 	 */
   2020   4404    gd78059 	ERI_SYNCIOPB(erip, erip->rmdp, (ERI_RPENDING * sizeof (struct rmd)),
   2021   4404    gd78059 	    DDI_DMA_SYNC_FORDEV);
   2022   4404    gd78059 	/*
   2023   4404    gd78059 	 * Reset RMD 'walking' pointers.
   2024   4404    gd78059 	 */
   2025   4404    gd78059 	erip->rnextp =	erip->rmdp;
   2026   4404    gd78059 	erip->rx_completion = 0;
   2027   4404    gd78059 	erip->rx_kick =	ERI_RPENDING - 4;
   2028   4404    gd78059 }
   2029   4404    gd78059 
   2030   4404    gd78059 /*
   2031   4404    gd78059  * This routine is used to reset the RX DMA only. In the case of RX
   2032   4404    gd78059  * failures such as RX Tag Error, RX hang etc... we don't want to
   2033   4404    gd78059  * do global reset which takes down the link and clears the FIFO's
   2034   4404    gd78059  * By doing RX only reset, we leave the TX and the link intact.
   2035   4404    gd78059  */
   2036   4404    gd78059 static uint32_t
   2037   4404    gd78059 eri_init_rx_channel(struct eri *erip)
   2038   4404    gd78059 {
   2039   4404    gd78059 	erip->flags &= ~ERI_RXINIT;
   2040   4404    gd78059 	(void) eri_erx_reset(erip);
   2041   4404    gd78059 	eri_update_rxbufs(erip);
   2042   4404    gd78059 	if (eri_init_rxregs(erip))
   2043   4404    gd78059 		return (1);
   2044   4404    gd78059 	PUT_MACREG(rxmask, BMAC_RXINTR_MASK);
   2045   4404    gd78059 	PUT_MACREG(rxcfg, GET_MACREG(rxcfg) | BMAC_RXCFG_ENAB);
   2046   4404    gd78059 	erip->rx_reset_issued = 0;
   2047   4404    gd78059 	HSTAT(erip, rx_inits);
   2048   4404    gd78059 	erip->flags |= ERI_RXINIT;
   2049   4404    gd78059 	return (0);
   2050   4404    gd78059 }
   2051   4404    gd78059 
   2052   4404    gd78059 static void
   2053   4404    gd78059 eri_init_rx(struct eri *erip)
   2054   4404    gd78059 {
   2055   4404    gd78059 	uint16_t	*ladrf;
   2056   4404    gd78059 
   2057   4404    gd78059 	/*
   2058   4404    gd78059 	 * First of all make sure the Receive MAC is stop.
   2059   4404    gd78059 	 */
   2060   4404    gd78059 	(void) eri_rxmac_disable(erip); /* Disable the RX MAC */
   2061   4404    gd78059 
   2062      0     stevel 	/*
   2063      0     stevel 	 * Program BigMAC with local individual ethernet address.
   2064      0     stevel 	 */
   2065   4404    gd78059 
   2066   4404    gd78059 	PUT_MACREG(madd0, (erip->ouraddr[4] << 8) | erip->ouraddr[5]);
   2067   4404    gd78059 	PUT_MACREG(madd1, (erip->ouraddr[2] << 8) | erip->ouraddr[3]);
   2068   4404    gd78059 	PUT_MACREG(madd2, (erip->ouraddr[0] << 8) | erip->ouraddr[1]);
   2069      0     stevel 
   2070      0     stevel 	/*
   2071      0     stevel 	 * Set up multicast address filter by passing all multicast
   2072      0     stevel 	 * addresses through a crc generator, and then using the
   2073      0     stevel 	 * low order 8 bits as a index into the 256 bit logical
   2074      0     stevel 	 * address filter. The high order four bits select the word,
   2075      0     stevel 	 * while the rest of the bits select the bit within the word.
   2076      0     stevel 	 */
   2077      0     stevel 
   2078   4404    gd78059 	ladrf = erip->ladrf;
   2079      0     stevel 
   2080      0     stevel 	PUT_MACREG(hash0, ladrf[0]);
   2081      0     stevel 	PUT_MACREG(hash1, ladrf[1]);
   2082      0     stevel 	PUT_MACREG(hash2, ladrf[2]);
   2083      0     stevel 	PUT_MACREG(hash3, ladrf[3]);
   2084      0     stevel 	PUT_MACREG(hash4, ladrf[4]);
   2085      0     stevel 	PUT_MACREG(hash5, ladrf[5]);
   2086      0     stevel 	PUT_MACREG(hash6, ladrf[6]);
   2087      0     stevel 	PUT_MACREG(hash7, ladrf[7]);
   2088      0     stevel 	PUT_MACREG(hash8, ladrf[8]);
   2089      0     stevel 	PUT_MACREG(hash9, ladrf[9]);
   2090      0     stevel 	PUT_MACREG(hash10, ladrf[10]);
   2091      0     stevel 	PUT_MACREG(hash11, ladrf[11]);
   2092      0     stevel 	PUT_MACREG(hash12, ladrf[12]);
   2093      0     stevel 	PUT_MACREG(hash13, ladrf[13]);
   2094      0     stevel 	PUT_MACREG(hash14, ladrf[14]);
   2095      0     stevel 	PUT_MACREG(hash15, ladrf[15]);
   2096      0     stevel 
   2097      0     stevel #ifdef ERI_DONT_STRIP_CRC
   2098      0     stevel 	PUT_MACREG(rxcfg,
   2099   4404    gd78059 	    ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) |
   2100   4404    gd78059 	    (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) |
   2101      0     stevel 	    BMAC_RXCFG_ENAB));
   2102      0     stevel #else
   2103      0     stevel 	PUT_MACREG(rxcfg,
   2104   4404    gd78059 	    ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) |
   2105   4404    gd78059 	    (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) |
   2106      0     stevel 	    BMAC_RXCFG_ENAB | BMAC_RXCFG_STRIP_CRC));
   2107      0     stevel #endif
   2108      0     stevel 	/* wait after setting Hash Enable bit */
   2109      0     stevel 	/* drv_usecwait(10); */
   2110      0     stevel 
   2111      0     stevel 	HSTAT(erip, rx_inits);
   2112   4404    gd78059 }
   2113      0     stevel 
   2114      0     stevel /*
   2115      0     stevel  * This routine is used to init the TX MAC only.
   2116      0     stevel  *	&erip->xmitlock is held before calling this routine.
   2117      0     stevel  */
   2118      0     stevel void
   2119      0     stevel eri_init_txmac(struct eri *erip)
   2120      0     stevel {
   2121      0     stevel 	uint32_t carrier_ext = 0;
   2122      0     stevel 
   2123      0     stevel 	erip->flags &= ~ERI_TXINIT;
   2124      0     stevel 	/*
   2125      0     stevel 	 * Stop the Transmit MAC.
   2126      0     stevel 	 */
   2127      0     stevel 	(void) eri_txmac_disable(erip);
   2128      0     stevel 
   2129      0     stevel 	/*
   2130      0     stevel 	 * Must be Internal Transceiver
   2131      0     stevel 	 */
   2132      0     stevel 	if (param_mode)
   2133      0     stevel 		PUT_MACREG(xifc, ((param_transceiver == EXTERNAL_XCVR ?
   2134      0     stevel 		    BMAC_XIFC_MIIBUF_OE : 0) | BMAC_XIFC_TX_MII_OE));
   2135      0     stevel 	else
   2136      0     stevel 		PUT_MACREG(xifc, ((param_transceiver == EXTERNAL_XCVR ?
   2137      0     stevel 		    BMAC_XIFC_MIIBUF_OE : 0) | BMAC_XIFC_TX_MII_OE |
   2138      0     stevel 		    BMAC_XIFC_DIS_ECHO));
   2139      0     stevel 
   2140      0     stevel 	/*
   2141      0     stevel 	 * Initialize the interpacket gap registers
   2142      0     stevel 	 */
   2143      0     stevel 	PUT_MACREG(ipg1, param_ipg1);
   2144      0     stevel 	PUT_MACREG(ipg2, param_ipg2);
   2145      0     stevel 
   2146      0     stevel 	if (erip->ngu_enable)
   2147   4404    gd78059 		PUT_MACREG(txcfg, ((param_mode ? BMAC_TXCFG_FDX: 0) |
   2148   4404    gd78059 		    ((param_lance_mode && (erip->lance_mode_enable)) ?
   2149   4404    gd78059 		    BMAC_TXCFG_ENIPG0 : 0) |
   2150   4404    gd78059 		    (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0) |
   2151   4404    gd78059 		    BMAC_TXCFG_NGU));
   2152   4404    gd78059 	else
   2153   4404    gd78059 		PUT_MACREG(txcfg, ((param_mode ? BMAC_TXCFG_FDX: 0) |
   2154   4404    gd78059 		    ((param_lance_mode && (erip->lance_mode_enable)) ?
   2155   4404    gd78059 		    BMAC_TXCFG_ENIPG0 : 0) |
   2156   4404    gd78059 		    (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0)));
   2157      0     stevel 
   2158      0     stevel 	ENABLE_TXDMA(erip);
   2159      0     stevel 	ENABLE_TXMAC(erip);
   2160      0     stevel 
   2161      0     stevel 	HSTAT(erip, tx_inits);
   2162      0     stevel 	erip->flags |= ERI_TXINIT;
   2163      0     stevel }
   2164      0     stevel 
   2165      0     stevel static void
   2166      0     stevel eri_unallocthings(struct eri *erip)
   2167      0     stevel {
   2168      0     stevel 	uint32_t	flag;
   2169      0     stevel 	uint32_t	i;
   2170      0     stevel 
   2171      0     stevel 	flag = erip->alloc_flag;
   2172      0     stevel 
   2173      0     stevel 	if (flag & ERI_DESC_MEM_MAP)
   2174      0     stevel 		(void) ddi_dma_unbind_handle(erip->md_h);
   2175      0     stevel 
   2176      0     stevel 	if (flag & ERI_DESC_MEM_ALLOC) {
   2177      0     stevel 		ddi_dma_mem_free(&erip->mdm_h);
   2178      0     stevel 		erip->rmdp = NULL;
   2179      0     stevel 		erip->eri_tmdp = NULL;
   2180      0     stevel 	}
   2181      0     stevel 
   2182      0     stevel 	if (flag & ERI_DESC_HANDLE_ALLOC)
   2183      0     stevel 		ddi_dma_free_handle(&erip->md_h);
   2184      0     stevel 
   2185      0     stevel 	(void) eri_freebufs(erip);
   2186      0     stevel 
   2187      0     stevel 	if (flag & ERI_RCV_HANDLE_ALLOC)
   2188      0     stevel 		for (i = 0; i < erip->rcv_handle_cnt; i++)
   2189      0     stevel 			ddi_dma_free_handle(&erip->ndmarh[i]);
   2190      0     stevel 
   2191      0     stevel 	if (flag & ERI_RCV_DVMA_ALLOC) {
   2192      0     stevel 		(void) dvma_release(erip->eri_dvmarh);
   2193      0     stevel 		erip->eri_dvmarh = NULL;
   2194      0     stevel 	}
   2195      0     stevel 
   2196      0     stevel 	if (flag & ERI_XBUFS_KMEM_DMABIND) {
   2197      0     stevel 		(void) ddi_dma_unbind_handle(erip->tbuf_handle);
   2198      0     stevel 		erip->tbuf_ioaddr = 0;
   2199      0     stevel 	}
   2200      0     stevel 
   2201      0     stevel 	if (flag & ERI_XBUFS_KMEM_ALLOC) {
   2202   7394    gdamore 		ddi_dma_mem_free(&erip->tbuf_acch);
   2203      0     stevel 		erip->tbuf_kaddr = NULL;
   2204      0     stevel 	}
   2205      0     stevel 
   2206      0     stevel 	if (flag & ERI_XBUFS_HANDLE_ALLOC) {
   2207      0     stevel 		ddi_dma_free_handle(&erip->tbuf_handle);
   2208      0     stevel 		erip->tbuf_handle = NULL;
   2209      0     stevel 	}
   2210      0     stevel 
   2211      0     stevel }
   2212      0     stevel 
   2213      0     stevel /*
   2214      0     stevel  * Initialize channel.
   2215   4404    gd78059  * Return true on success, false on error.
   2216      0     stevel  *
   2217      0     stevel  * The recommended sequence for initialization is:
   2218      0     stevel  * 1. Issue a Global Reset command to the Ethernet Channel.
   2219      0     stevel  * 2. Poll the Global_Reset bits until the execution of the reset has been
   2220      0     stevel  *    completed.
   2221      0     stevel  * 2(a). Use the MIF Frame/Output register to reset the transceiver.
   2222      0     stevel  *	 Poll Register 0 to till the Resetbit is 0.
   2223      0     stevel  * 2(b). Use the MIF Frame/Output register to set the PHY in in Normal-Op,
   2224      0     stevel  *	 100Mbps and Non-Isolated mode. The main point here is to bring the
   2225      0     stevel  *	 PHY out of Isolate mode so that it can generate the rx_clk and tx_clk
   2226      0     stevel  *	 to the MII interface so that the Bigmac core can correctly reset
   2227      0     stevel  *	 upon a software reset.
   2228      0     stevel  * 2(c).  Issue another Global Reset command to the Ethernet Channel and poll
   2229      0     stevel  *	  the Global_Reset bits till completion.
   2230      0     stevel  * 3. Set up all the data structures in the host memory.
   2231      0     stevel  * 4. Program the TX_MAC registers/counters (excluding the TX_MAC Configuration
   2232      0     stevel  *    Register).
   2233      0     stevel  * 5. Program the RX_MAC registers/counters (excluding the RX_MAC Configuration
   2234      0     stevel  *    Register).
   2235      0     stevel  * 6. Program the Transmit Descriptor Ring Base Address in the ETX.
   2236      0     stevel  * 7. Program the Receive Descriptor Ring Base Address in the ERX.
   2237      0     stevel  * 8. Program the Global Configuration and the Global Interrupt Mask Registers.
   2238      0     stevel  * 9. Program the ETX Configuration register (enable the Transmit DMA channel).
   2239      0     stevel  * 10. Program the ERX Configuration register (enable the Receive DMA channel).
   2240      0     stevel  * 11. Program the XIF Configuration Register (enable the XIF).
   2241      0     stevel  * 12. Program the RX_MAC Configuration Register (Enable the RX_MAC).
   2242      0     stevel  * 13. Program the TX_MAC Configuration Register (Enable the TX_MAC).
   2243      0     stevel  */
   2244      0     stevel /*
   2245      0     stevel  * lock order:
   2246   4404    gd78059  *	intrlock->linklock->xmitlock->xcvrlock
   2247   4404    gd78059  */
   2248   4404    gd78059 static boolean_t
   2249      0     stevel eri_init(struct eri *erip)
   2250      0     stevel {
   2251      0     stevel 	uint32_t	init_stat = 0;
   2252      0     stevel 	uint32_t	partial_init = 0;
   2253      0     stevel 	uint32_t	carrier_ext = 0;
   2254      0     stevel 	uint32_t	mac_ctl = 0;
   2255   4404    gd78059 	boolean_t	ret;
   2256   4404    gd78059 	uint32_t 	link_timeout = ERI_LINKCHECK_TIMER;
   2257   4404    gd78059 	link_state_t	linkupdate = LINK_STATE_UNKNOWN;
   2258   4404    gd78059 
   2259   4404    gd78059 	/*
   2260   4404    gd78059 	 * Just return successfully if device is suspended.
   2261      0     stevel 	 * eri_init() will be called again from resume.
   2262      0     stevel 	 */
   2263   4404    gd78059 	ASSERT(erip != NULL);
   2264   4404    gd78059 
   2265   4404    gd78059 	if (erip->flags & ERI_SUSPENDED) {
   2266   4404    gd78059 		ret = B_TRUE;
   2267      0     stevel 		goto init_exit;
   2268   4404    gd78059 	}
   2269      0     stevel 
   2270      0     stevel 	mutex_enter(&erip->intrlock);
   2271      0     stevel 	eri_stop_timer(erip);	/* acquire linklock */
   2272   4404    gd78059 	mutex_enter(&erip->xmitlock);
   2273   4404    gd78059 	erip->flags &= (ERI_DLPI_LINKUP | ERI_STARTED);
   2274   4404    gd78059 	erip->wantw = B_FALSE;
   2275      0     stevel 	HSTAT(erip, inits);
   2276      0     stevel 	erip->txhung = 0;
   2277      0     stevel 
   2278   4728    gd78059 	if ((erip->stats.inits > 1) && (erip->init_macregs == 0))
   2279      0     stevel 		eri_savecntrs(erip);
   2280      0     stevel 
   2281      0     stevel 	mutex_enter(&erip->xcvrlock);
   2282      0     stevel 	if (!param_linkup || erip->linkcheck) {
   2283   2534   carlsonj 		if (!erip->linkcheck)
   2284   4404    gd78059 			linkupdate = LINK_STATE_DOWN;
   2285      0     stevel 		(void) eri_stop(erip);
   2286      0     stevel 	}
   2287      0     stevel 	if (!(erip->flags & ERI_DLPI_LINKUP) || !param_linkup) {
   2288      0     stevel 		erip->flags |= ERI_DLPI_LINKUP;
   2289      0     stevel 		eri_mif_poll(erip, MIF_POLL_STOP);
   2290      0     stevel 		(void) eri_new_xcvr(erip);
   2291   4404    gd78059 		ERI_DEBUG_MSG1(erip, XCVR_MSG, "New transceiver detected.");
   2292      0     stevel 		if (param_transceiver != NO_XCVR) {
   2293      0     stevel 			/*
   2294      0     stevel 			 * Reset the new PHY and bring up the
   2295      0     stevel 			 * link
   2296      0     stevel 			 */
   2297      0     stevel 			if (eri_reset_xcvr(erip)) {
   2298      0     stevel 				ERI_FAULT_MSG1(erip, SEVERITY_NONE,
   2299      0     stevel 				    ERI_VERB_MSG, "In Init after reset");
   2300      0     stevel 				mutex_exit(&erip->xcvrlock);
   2301      0     stevel 				link_timeout = 0;
   2302      0     stevel 				goto done;
   2303      0     stevel 			}
   2304   4404    gd78059 			if (erip->stats.link_up == LINK_STATE_UP)
   2305   4404    gd78059 				linkupdate = LINK_STATE_UP;
   2306      0     stevel 		} else {
   2307      0     stevel 			erip->flags |= (ERI_RUNNING | ERI_INITIALIZED);
   2308      0     stevel 			param_linkup = 0;
   2309   4404    gd78059 			erip->stats.link_up = LINK_STATE_DOWN;
   2310   4404    gd78059 			erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN;
   2311   4404    gd78059 			linkupdate = LINK_STATE_DOWN;
   2312      0     stevel 			/*
   2313      0     stevel 			 * Still go on and complete the MAC initialization as
   2314      0     stevel 			 * xcvr might show up later.
   2315      0     stevel 			 * you must return to their mutex ordering.
   2316      0     stevel 			 */
   2317      0     stevel 		}
   2318      0     stevel 		eri_mif_poll(erip, MIF_POLL_START);
   2319      0     stevel 	}
   2320      0     stevel 
   2321      0     stevel 	mutex_exit(&erip->xcvrlock);
   2322      0     stevel 
   2323      0     stevel 	/*
   2324      0     stevel 	 * Allocate data structures.
   2325      0     stevel 	 */
   2326      0     stevel 	if (erip->global_reset_issued) {
   2327      0     stevel 		if (erip->global_reset_issued == 2) { /* fast path */
   2328   7394    gdamore 
   2329      0     stevel 			/*
   2330      0     stevel 			 * Hang out/Initialize descriptors and buffers.
   2331      0     stevel 			 */
   2332      0     stevel 			eri_init_txbufs(erip);
   2333      0     stevel 
   2334      0     stevel 			eri_update_rxbufs(erip);
   2335      0     stevel 		} else {
   2336      0     stevel 			init_stat = eri_allocthings(erip);
   2337      0     stevel 			if (init_stat)
   2338      0     stevel 				goto done;
   2339      0     stevel 
   2340      0     stevel 			if (eri_freebufs(erip))
   2341      0     stevel 				goto done;
   2342      0     stevel 			/*
   2343      0     stevel 			 * Hang out/Initialize descriptors and buffers.
   2344      0     stevel 			 */
   2345      0     stevel 			eri_init_txbufs(erip);
   2346      0     stevel 			if (eri_init_rxbufs(erip))
   2347      0     stevel 				goto done;
   2348      0     stevel 		}
   2349      0     stevel 	}
   2350      0     stevel 
   2351      0     stevel 	/*
   2352      0     stevel 	 * BigMAC requires that we confirm that tx, rx and hash are in
   2353      0     stevel 	 * quiescent state.
   2354      0     stevel 	 * MAC will not reset successfully if the transceiver is not reset and
   2355      0     stevel 	 * brought out of Isolate mode correctly. TXMAC reset may fail if the
   2356      0     stevel 	 * ext. transceiver is just disconnected. If it fails, try again by
   2357      0     stevel 	 * checking the transceiver.
   2358      0     stevel 	 */
   2359      0     stevel 	if (eri_txmac_disable(erip)) {
   2360      0     stevel 		ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG,
   2361   4404    gd78059 		    disable_txmac_msg);
   2362      0     stevel 		param_linkup = 0;	/* force init again */
   2363   4404    gd78059 		erip->stats.link_up = LINK_STATE_DOWN;
   2364   4404    gd78059 		erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN;
   2365   4404    gd78059 		linkupdate = LINK_STATE_DOWN;
   2366      0     stevel 		goto done;
   2367      0     stevel 	}
   2368      0     stevel 
   2369      0     stevel 	if (eri_rxmac_disable(erip)) {
   2370      0     stevel 		ERI_FAULT_MSG1(erip, SEVERITY_LOW, ERI_VERB_MSG,
   2371   4404    gd78059 		    disable_rxmac_msg);
   2372      0     stevel 		param_linkup = 0;	/* force init again */
   2373   4404    gd78059 		erip->stats.link_up = LINK_STATE_DOWN;
   2374   4404    gd78059 		erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN;
   2375   4404    gd78059 		linkupdate = LINK_STATE_DOWN;
   2376      0     stevel 		goto done;
   2377      0     stevel 	}
   2378      0     stevel 
   2379      0     stevel 	eri_init_macregs_generic(erip);
   2380      0     stevel 
   2381      0     stevel 	/*
   2382      0     stevel 	 * Initialize ERI Global registers :
   2383      0     stevel 	 * config
   2384      0     stevel 	 * For PCI :  err_mask, bif_cfg
   2385      0     stevel 	 *
   2386      0     stevel 	 * Use user-configurable parameter for enabling 64-bit transfers.
   2387      0     stevel 	 * Note:For PCI, burst sizes are in multiples of 64-bytes.
   2388      0     stevel 	 */
   2389      0     stevel 
   2390      0     stevel 	/*
   2391      0     stevel 	 * Significant performance improvements can be achieved by
   2392      0     stevel 	 * disabling transmit interrupt. Thus TMD's are reclaimed
   2393      0     stevel 	 * only very infrequently.
   2394      0     stevel 	 * The PCS Interrupt is masked here. It is enabled only when
   2395      0     stevel 	 * a PCS link is brought up because there is no second level
   2396      0     stevel 	 * mask for this interrupt..
   2397      0     stevel 	 * Init GLOBAL, TXMAC, RXMAC and MACCTL interrupt masks here.
   2398      0     stevel 	 */
   2399      0     stevel 	if (! partial_init) {
   2400      0     stevel 		PUT_GLOBREG(intmask, ERI_G_MASK_INTR);
   2401      0     stevel 		erip->tx_int_me = 0;
   2402      0     stevel 		PUT_MACREG(txmask, BMAC_TXINTR_MASK);
   2403      0     stevel 		PUT_MACREG(rxmask, BMAC_RXINTR_MASK);
   2404      0     stevel 		PUT_MACREG(macctl_mask, ERI_MACCTL_INTR_MASK);
   2405      0     stevel 	}
   2406      0     stevel 
   2407      0     stevel 	if (erip->global_reset_issued) {
   2408      0     stevel 		/*
   2409      0     stevel 		 * Initialize ETX Registers:
   2410      0     stevel 		 * config, txring_lo, txring_hi
   2411      0     stevel 		 */
   2412      0     stevel 		if (eri_init_txregs(erip))
   2413   4404    gd78059 			goto done;
   2414      0     stevel 		/*
   2415      0     stevel 		 * Initialize ERX Registers:
   2416      0     stevel 		 * rxring_lo, rxring_hi, config, rx_blanking,
   2417      0     stevel 		 * rx_pause_threshold.  Also, rx_kick
   2418      0     stevel 		 * Read and save rxfifo_size.
   2419      0     stevel 		 */
   2420      0     stevel 		if (eri_init_rxregs(erip))
   2421      0     stevel 			goto done;
   2422      0     stevel 	}
   2423      0     stevel 
   2424      0     stevel 	PUT_MACREG(macctl_mask, ERI_MACCTL_INTR_MASK);
   2425      0     stevel 
   2426      0     stevel 	/*
   2427      0     stevel 	 * Set up the slottime,and  rxconfig, txconfig without enabling
   2428      0     stevel 	 * the latter two at this time
   2429      0     stevel 	 */
   2430      0     stevel 	PUT_MACREG(slot, BMAC_SLOT_TIME);
   2431      0     stevel 	carrier_ext = 0;
   2432      0     stevel 
   2433      0     stevel #ifdef ERI_DONT_STRIP_CRC
   2434      0     stevel 	PUT_MACREG(rxcfg,
   2435   4404    gd78059 	    ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) |
   2436   4404    gd78059 	    (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) |
   2437      0     stevel 	    (carrier_ext ? BMAC_RXCFG_CARR_EXT : 0)));
   2438      0     stevel #else
   2439      0     stevel 	PUT_MACREG(rxcfg,
   2440   4404    gd78059 	    ((erip->promisc ? BMAC_RXCFG_PROMIS : 0) |
   2441   4404    gd78059 	    (erip->multi_refcnt ? BMAC_RXCFG_HASH : 0) |
   2442      0     stevel 	    BMAC_RXCFG_STRIP_CRC |
   2443      0     stevel 	    (carrier_ext ? BMAC_RXCFG_CARR_EXT : 0)));
   2444      0     stevel #endif
   2445      0     stevel 	drv_usecwait(10);	/* wait after setting Hash Enable bit */
   2446      0     stevel 
   2447      0     stevel 	if (erip->ngu_enable)
   2448      0     stevel 		PUT_MACREG(txcfg,
   2449      0     stevel 		    ((param_mode ? BMAC_TXCFG_FDX: 0) |
   2450      0     stevel 		    ((param_lance_mode && (erip->lance_mode_enable)) ?
   2451      0     stevel 		    BMAC_TXCFG_ENIPG0 : 0) |
   2452      0     stevel 		    (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0) |
   2453      0     stevel 		    BMAC_TXCFG_NGU));
   2454      0     stevel 	else
   2455      0     stevel 		PUT_MACREG(txcfg,
   2456      0     stevel 		    ((param_mode ? BMAC_TXCFG_FDX: 0) |
   2457      0     stevel 		    ((param_lance_mode && (erip->lance_mode_enable)) ?
   2458      0     stevel 		    BMAC_TXCFG_ENIPG0 : 0) |
   2459      0     stevel 		    (carrier_ext ? BMAC_TXCFG_CARR_EXT : 0)));
   2460      0     stevel 
   2461      0     stevel 	if (erip->pauseRX)
   2462      0     stevel 		mac_ctl = ERI_MCTLCFG_RXPAUSE;
   2463      0     stevel 	if (erip->pauseTX)
   2464      0     stevel 		mac_ctl |= ERI_MCTLCFG_TXPAUSE;
   2465      0     stevel 
   2466      0     stevel 	PUT_MACREG(macctl_cfg, mac_ctl);
   2467      0     stevel 
   2468      0     stevel 	/*
   2469      0     stevel 	 * Must be Internal Transceiver
   2470      0     stevel 	 */
   2471      0     stevel 	if (param_mode)
   2472      0     stevel 		PUT_MACREG(xifc, ((param_transceiver == EXTERNAL_XCVR ?
   2473      0     stevel 		    BMAC_XIFC_MIIBUF_OE : 0) | BMAC_XIFC_TX_MII_OE));
   2474      0     stevel 	else {
   2475      0     stevel 		PUT_MACREG(xifc, ((param_transceiver == EXTERNAL_XCVR ?
   2476      0     stevel 		    BMAC_XIFC_MIIBUF_OE : 0) | BMAC_XIFC_TX_MII_OE |
   2477      0     stevel 		    BMAC_XIFC_DIS_ECHO));
   2478      0     stevel 
   2479      0     stevel 		link_timeout = ERI_CHECK_HANG_TIMER;
   2480      0     stevel 	}
   2481      0     stevel 
   2482      0     stevel 	/*
   2483      0     stevel 	 * if MAC int loopback flag is set, put xifc reg in mii loopback
   2484      0     stevel 	 * mode {DIAG}
   2485      0     stevel 	 */
   2486      0     stevel 	if (erip->flags & ERI_MACLOOPBACK) {
   2487      0     stevel 		PUT_MACREG(xifc, GET_MACREG(xifc) | BMAC_XIFC_MIILPBK);
   2488      0     stevel 	}
   2489      0     stevel 
   2490      0     stevel 	/*
   2491      0     stevel 	 * Enable TX and RX MACs.
   2492      0     stevel 	 */
   2493      0     stevel 	ENABLE_MAC(erip);
   2494      0     stevel 	erip->flags |= (ERI_RUNNING | ERI_INITIALIZED |
   2495   4404    gd78059 	    ERI_TXINIT | ERI_RXINIT);
   2496   4404    gd78059 	mac_tx_update(erip->mh);
   2497      0     stevel 	erip->global_reset_issued = 0;
   2498      0     stevel 
   2499      0     stevel #ifdef	ERI_10_10_FORCE_SPEED_WORKAROUND
   2500      0     stevel 	eri_xcvr_force_mode(erip, &link_timeout);
   2501      0     stevel #endif
   2502      0     stevel 
   2503      0     stevel done:
   2504      0     stevel 	if (init_stat)
   2505      0     stevel 		eri_unallocthings(erip);
   2506      0     stevel 
   2507      0     stevel 	mutex_exit(&erip->xmitlock);
   2508      0     stevel 	eri_start_timer(erip, eri_check_link, link_timeout);
   2509      0     stevel 	mutex_exit(&erip->intrlock);
   2510      0     stevel 
   2511   4404    gd78059 	if (linkupdate != LINK_STATE_UNKNOWN)
   2512   4404    gd78059 		mac_link_update(erip->mh, linkupdate);
   2513   4404    gd78059 
   2514   4404    gd78059 	ret = (erip->flags & ERI_RUNNING) ? B_TRUE : B_FALSE;
   2515   4404    gd78059 	if (!ret) {
   2516      0     stevel 		ERI_FAULT_MSG1(erip, SEVERITY_NONE, ERI_VERB_MSG,
   2517   4404    gd78059 		    "eri_init failed");
   2518      0     stevel 	}
   2519      0     stevel 
   2520      0     stevel init_exit:
   2521      0     stevel 	ASSERT(!MUTEX_HELD(&erip->linklock));
   2522      0     stevel 	return (ret);
   2523      0     stevel }
   2524      0     stevel 
   2525      0     stevel /*
   2526      0     stevel  * 0 as burstsize upon failure as it signifies no burst size.
   2527      0     stevel  */
   2528      0     stevel static int
   2529      0     stevel eri_burstsize(struct eri *erip)
   2530      0     stevel {
   2531      0     stevel 	ddi_dma_handle_t handle;
   2532      0     stevel 
   2533   4404    gd78059 	if (ddi_dma_alloc_handle(erip->dip, &dma_attr, DDI_DMA_DONTWAIT,
   2534   4404    gd78059 	    NULL, &handle))
   2535      0     stevel 		return (DDI_FAILURE);
   2536      0     stevel 
   2537      0     stevel 	erip->burstsizes = ddi_dma_burstsizes(handle);
   2538      0     stevel 	ddi_dma_free_handle(&handle);
   2539      0     stevel 
   2540      0     stevel 	if (erip->burstsizes)
   2541      0     stevel 		return (DDI_SUCCESS);
   2542      0     stevel 
   2543      0     stevel 	return (DDI_FAILURE);
   2544      0     stevel }
   2545      0     stevel 
   2546      0     stevel /*
   2547      0     stevel  * Un-initialize (STOP) ERI channel.
   2548      0     stevel  */
   2549      0     stevel static void
   2550      0     stevel eri_uninit(struct eri *erip)
   2551      0     stevel {
   2552   2534   carlsonj 	boolean_t needind;
   2553   2534   carlsonj 
   2554      0     stevel 	/*
   2555      0     stevel 	 * Allow up to 'ERI_DRAINTIME' for pending xmit's to complete.
   2556      0     stevel 	 */
   2557      0     stevel 	ERI_DELAY((erip->tcurp == erip->tnextp), ERI_DRAINTIME);
   2558      0     stevel 
   2559      0     stevel 	mutex_enter(&erip->intrlock);
   2560      0     stevel 	eri_stop_timer(erip);   /* acquire linklock */
   2561      0     stevel 	mutex_enter(&erip->xmitlock);
   2562      0     stevel 	mutex_enter(&erip->xcvrlock);
   2563      0     stevel 	eri_mif_poll(erip, MIF_POLL_STOP);
   2564      0     stevel 	erip->flags &= ~ERI_DLPI_LINKUP;
   2565      0     stevel 	mutex_exit(&erip->xcvrlock);
   2566      0     stevel 
   2567   2534   carlsonj 	needind = !erip->linkcheck;
   2568      0     stevel 	(void) eri_stop(erip);
   2569      0     stevel 	erip->flags &= ~ERI_RUNNING;
   2570      0     stevel 
   2571      0     stevel 	mutex_exit(&erip->xmitlock);
   2572      0     stevel 	eri_start_timer(erip, eri_check_link, 0);
   2573      0     stevel 	mutex_exit(&erip->intrlock);
   2574   2534   carlsonj 
   2575   2534   carlsonj 	if (needind)
   2576   4404    gd78059 		mac_link_update(erip->mh, LINK_STATE_DOWN);
   2577      0     stevel }
   2578      0     stevel 
   2579      0     stevel /*
   2580      0     stevel  * Allocate CONSISTENT memory for rmds and tmds with appropriate alignment and
   2581      0     stevel  * map it in IO space.
   2582      0     stevel  *
   2583      0     stevel  * The driver allocates STREAMS buffers which will be mapped in DVMA
   2584      0     stevel  * space using DDI DMA resources.
   2585      0     stevel  *
   2586      0     stevel  */
   2587      0     stevel static int
   2588      0     stevel eri_allocthings(struct eri *erip)
   2589      0     stevel {
   2590      0     stevel 
   2591      0     stevel 	uintptr_t	a;
   2592      0     stevel 	int		size;
   2593      0     stevel 	uint32_t	rval;
   2594      0     stevel 	int		i;
   2595      0     stevel 	size_t		real_len;
   2596      0     stevel 	uint32_t	cookiec;
   2597      0     stevel 	int		alloc_stat = 0;
   2598      0     stevel 	ddi_dma_cookie_t dma_cookie;
   2599      0     stevel 
   2600      0     stevel 	/*
   2601      0     stevel 	 * Return if resources are already allocated.
   2602      0     stevel 	 */
   2603      0     stevel 	if (erip->rmdp)
   2604      0     stevel 		return (alloc_stat);
   2605      0     stevel 
   2606      0     stevel 	erip->alloc_flag = 0;
   2607      0     stevel 
   2608      0     stevel 	/*
   2609      0     stevel 	 * Allocate the TMD and RMD descriptors and extra for alignments.
   2610      0     stevel 	 */
   2611   4404    gd78059 	size = (ERI_RPENDING * sizeof (struct rmd) +
   2612   4404    gd78059 	    ERI_TPENDING * sizeof (struct eri_tmd)) + ERI_GMDALIGN;
   2613      0     stevel 
   2614      0     stevel 	rval = ddi_dma_alloc_handle(erip->dip, &desc_dma_attr,
   2615   4404    gd78059 	    DDI_DMA_DONTWAIT, 0, &erip->md_h);
   2616      0     stevel 	if (rval != DDI_SUCCESS) {
   2617      0     stevel 		return (++alloc_stat);
   2618      0     stevel 	}
   2619      0     stevel 	erip->alloc_flag |= ERI_DESC_HANDLE_ALLOC;
   2620      0     stevel 
   2621      0     stevel 	rval = ddi_dma_mem_alloc(erip->md_h, size, &erip->dev_attr,
   2622   4404    gd78059 	    DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, 0,
   2623   4404    gd78059 	    (caddr_t *)&erip->iopbkbase, &real_len, &erip->mdm_h);
   2624      0     stevel 	if (rval != DDI_SUCCESS) {
   2625      0     stevel 		return (++alloc_stat);
   2626      0     stevel 	}
   2627      0     stevel 	erip->alloc_flag |= ERI_DESC_MEM_ALLOC;
   2628      0     stevel 
   2629      0     stevel 	rval = ddi_dma_addr_bind_handle(erip->md_h, NULL,
   2630   4404    gd78059 	    (caddr_t)erip->iopbkbase, size, DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
   2631   4404    gd78059 	    DDI_DMA_DONTWAIT, 0, &erip->md_c, &cookiec);
   2632      0     stevel 
   2633      0     stevel 	if (rval != DDI_DMA_MAPPED)
   2634      0     stevel 		return (++alloc_stat);
   2635      0     stevel 
   2636      0     stevel 	erip->alloc_flag |= ERI_DESC_MEM_MAP;
   2637      0     stevel 
   2638      0     stevel 	if (cookiec != 1)
   2639      0     stevel 		return (++alloc_stat);
   2640      0     stevel 
   2641      0     stevel 	erip->iopbiobase = erip->md_c.dmac_address;
   2642      0     stevel 
   2643      0     stevel 	a = erip->iopbkbase;
   2644      0     stevel 	a = ROUNDUP(a, ERI_GMDALIGN);
   2645      0     stevel 	erip->rmdp = (struct rmd *)a;
   2646      0     stevel 	a += ERI_RPENDING * sizeof (struct rmd);
   2647      0     stevel 	erip->eri_tmdp = (struct eri_tmd *)a;
   2648      0     stevel /*
   2649      0     stevel  *	Specifically we reserve n (ERI_TPENDING + ERI_RPENDING)
   2650      0     stevel  *	pagetable entries. Therefore we have 2 ptes for each
   2651      0     stevel  *	descriptor. Since the ethernet buffers are 1518 bytes
   2652      0     stevel  *	so they can at most use 2 ptes.
   2653      0     stevel  * 	Will do a ddi_dma_addr_setup for each bufer
   2654      0     stevel  */
   2655      0     stevel 	/*
   2656      0     stevel 	 * In the current implementation, we use the ddi compliant
   2657   7394    gdamore 	 * dma interface. We allocate ERI_RPENDING dma handles for receive
   2658   7394    gdamore 	 * activity. The actual dma mapping is done in the io function
   2659   7394    gdamore 	 * eri_read_dma(), by calling the ddi_dma_addr_bind_handle.
   2660      0     stevel 	 * Dma resources are deallocated by calling ddi_dma_unbind_handle
   2661      0     stevel 	 * in eri_reclaim() for transmit and eri_read_dma(), for receive io.
   2662      0     stevel 	 */
   2663      0     stevel 
   2664      0     stevel 	if (eri_use_dvma_rx &&
   2665      0     stevel 	    (dvma_reserve(erip->dip, &eri_dma_limits, (ERI_RPENDING * 2),
   2666      0     stevel 	    &erip->eri_dvmarh)) == DDI_SUCCESS) {
   2667      0     stevel 		erip->alloc_flag |= ERI_RCV_DVMA_ALLOC;
   2668      0     stevel 	} else {
   2669      0     stevel 		erip->eri_dvmarh = NULL;
   2670      0     stevel 
   2671      0     stevel 		for (i = 0; i < ERI_RPENDING; i++) {
   2672      0     stevel 			rval = ddi_dma_alloc_handle(erip->dip,
   2673      0     stevel 			    &dma_attr, DDI_DMA_DONTWAIT,
   2674      0     stevel 			    0, &erip->ndmarh[i]);
   2675      0     stevel 
   2676      0     stevel 			if (rval != DDI_SUCCESS) {
   2677      0     stevel 				ERI_FAULT_MSG1(erip, SEVERITY_HIGH,
   2678      0     stevel 				    ERI_VERB_MSG, alloc_rx_dmah_msg);
   2679      0     stevel 				alloc_stat++;
   2680      0     stevel 				break;
   2681      0     stevel 			}
   2682      0     stevel 		}
   2683      0     stevel 
   2684      0     stevel 		erip->rcv_handle_cnt = i;
   2685      0     stevel 
   2686      0     stevel 		if (i)
   2687      0     stevel 			erip->alloc_flag |= ERI_RCV_HANDLE_ALLOC;
   2688      0     stevel 
   2689      0     stevel 		if (alloc_stat)
   2690      0     stevel 			return (alloc_stat);
   2691      0     stevel 
   2692      0     stevel 	}
   2693      0     stevel 
   2694      0     stevel /*
   2695   7394    gdamore  *	Allocate TX buffer
   2696   7394    gdamore  *	Note: buffers must always be allocated in the native
   2697      0     stevel  *	ordering of the CPU (always big-endian for Sparc).
   2698      0     stevel  *	ddi_dma_mem_alloc returns memory in the native ordering
   2699      0     stevel  *	of the bus (big endian for SBus, little endian for PCI).
   2700      0     stevel  *	So we cannot use ddi_dma_mem_alloc(, &erip->ge_dev_attr)
   2701      0     stevel  *	because we'll get little endian memory on PCI.
   2702      0     stevel  */
   2703   4404    gd78059 	if (ddi_dma_alloc_handle(erip->dip, &desc_dma_attr, DDI_DMA_DONTWAIT,
   2704   4404    gd78059 	    0, &erip->tbuf_handle) != DDI_SUCCESS) {
   2705   4404    gd78059 		ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG,
   2706   4404    gd78059 		    alloc_tx_dmah_msg);
   2707   4404    gd78059 		return (++alloc_stat);
   2708      0     stevel 	}
   2709      0     stevel 	erip->alloc_flag |= ERI_XBUFS_HANDLE_ALLOC;
   2710   7394    gdamore 	size = ERI_TPENDING * ERI_BUFSIZE;
   2711   7394    gdamore 	if (ddi_dma_mem_alloc(erip->tbuf_handle, size, &buf_attr,
   2712   7394    gdamore 	    DDI_DMA_CONSISTENT, DDI_DMA_DONTWAIT, NULL, &erip->tbuf_kaddr,
   2713   7394    gdamore 	    &real_len, &erip->tbuf_acch) != DDI_SUCCESS) {
   2714      0     stevel 		ERI_FAULT_MSG1(erip, SEVERITY_HIGH, ERI_VERB_MSG,
   2715   4404    gd78059 		    alloc_tx_dmah_msg);
   2716      0     stevel 		return (++alloc_stat);
   2717      0     stevel 	}
   2718      0     stevel 	erip->alloc_flag |= ERI_XBUFS_KMEM_ALLOC;
   2719      0     stevel 	if (ddi_dma_addr_bind_handle(erip->tbuf_handle, NULL,
   2720   4404    gd78059 	    erip->tbuf_kaddr, size, DDI_DMA_WRITE | DDI_DMA_CONSISTENT,
   2721   4404    gd78059 	    DDI_DMA_DONTWAIT, 0, &dma_cookie, &cookiec) != DDI_DMA_MAPPED) {
   2722      0     stevel 			return (++alloc_stat);
   2723      0     stevel 	}
   2724      0     stevel 	erip->tbuf_ioaddr = dma_cookie.dmac_address;
   2725      0     stevel 	erip->alloc_flag |= ERI_XBUFS_KMEM_DMABIND;
   2726      0     stevel 	if (cookiec != 1)
   2727      0     stevel 		return (++alloc_stat);
   2728      0     stevel 
   2729      0     stevel 	/*
   2730      0     stevel 	 * Keep handy limit values for RMD, TMD, and Buffers.
   2731      0     stevel 	 */
   2732      0     stevel 	erip->rmdlimp = &((erip->rmdp)[ERI_RPENDING]);
   2733      0     stevel 	erip->eri_tmdlimp = &((erip->eri_tmdp)[ERI_TPENDING]);
   2734      0     stevel 
   2735      0     stevel 	/*
   2736   7394    gdamore 	 * Zero out RCV holders.
   2737   7394    gdamore 	 */
   2738      0     stevel 	bzero((caddr_t)erip->rmblkp, sizeof (erip->rmblkp));
   2739      0     stevel 	return (alloc_stat);
   2740      0     stevel }
   2741      0     stevel 
   2742      0     stevel /* <<<<<<<<<<<<<<<<<	INTERRUPT HANDLING FUNCTION	>>>>>>>>>>>>>>>>>>>> */
   2743      0     stevel /*
   2744      0     stevel  *	First check to see if it is our device interrupting.
   2745      0     stevel  */
   2746      0     stevel static uint_t
   2747   4404    gd78059 eri_intr(caddr_t arg)
   2748   4404    gd78059 {
   2749   4404    gd78059 	struct eri *erip = (void *)arg;
   2750      0     stevel 	uint32_t erisbits;
   2751      0     stevel 	uint32_t mif_status;
   2752      0     stevel 	uint32_t serviced = DDI_INTR_UNCLAIMED;
   2753   4404    gd78059 	link_state_t linkupdate = LINK_STATE_UNKNOWN;
   2754   4404    gd78059 	boolean_t macupdate = B_FALSE;
   2755   4404    gd78059 	mblk_t *mp;
   2756   4404    gd78059 	mblk_t *head;
   2757   4404    gd78059 	mblk_t **tail;
   2758   4404    gd78059 
   2759   4404    gd78059 	head = NULL;
   2760   4404    gd78059 	tail = &head;
   2761   2534   carlsonj 
   2762      0     stevel 	mutex_enter(&erip->intrlock);
   2763      0     stevel 
   2764      0     stevel 	erisbits = GET_GLOBREG(status);
   2765      0     stevel 
   2766      0     stevel 	/*
   2767      0     stevel 	 * Check if it is only the RX_DONE interrupt, which is
   2768      0     stevel 	 * the most frequent one.
   2769      0     stevel 	 */
   2770      0     stevel 	if (((erisbits & ERI_G_STATUS_RX_INT) == ERI_G_STATUS_RX_DONE) &&
   2771   4404    gd78059 	    (erip->flags & ERI_RUNNING)) {
   2772      0     stevel 		serviced = DDI_INTR_CLAIMED;
   2773      0     stevel 		goto rx_done_int;
   2774      0     stevel 	}
   2775      0     stevel 
   2776      0     stevel 	/* Claim the first interrupt after initialization */
   2777      0     stevel 	if (erip->flags & ERI_INITIALIZED) {
   2778      0     stevel 		erip->flags &= ~ERI_INITIALIZED;
   2779      0     stevel 		serviced = DDI_INTR_CLAIMED;
   2780      0     stevel 	}
   2781      0     stevel 
   2782      0     stevel 	/* Check for interesting events */
   2783      0     stevel 	if ((erisbits & ERI_G_STATUS_INTR) == 0) {
   2784   2534   carlsonj #ifdef	ESTAR_WORKAROUND
   2785   4404    gd78059 		uint32_t linkupdate;
   2786   2534   carlsonj #endif
   2787   2534   carlsonj 
   2788      0     stevel 		ERI_DEBUG_MSG2(erip, DIAG_MSG,
   2789   4404    gd78059 		    "eri_intr: Interrupt Not Claimed gsbits  %X", erisbits);
   2790      0     stevel #ifdef	DEBUG
   2791      0     stevel 		noteri++;
   2792      0     stevel #endif
   2793   4404    gd78059 		ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:MIF Config = 0x%X",
   2794   4404    gd78059 		    GET_MIFREG(mif_cfg));
   2795   4404    gd78059 		ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:MIF imask = 0x%X",
   2796   4404    gd78059 		    GET_MIFREG(mif_imask));
   2797   4404    gd78059 		ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:INT imask = 0x%X",
   2798   4404    gd78059 		    GET_GLOBREG(intmask));
   2799   4404    gd78059 		ERI_DEBUG_MSG2(erip, DIAG_MSG, "eri_intr:alias %X",
   2800   4404    gd78059 		    GET_GLOBREG(status_alias));
   2801      0     stevel #ifdef	ESTAR_WORKAROUND
   2802   4404    gd78059 		linkupdate = eri_check_link_noind(erip);
   2803      0     stevel #endif
   2804      0     stevel 		mutex_exit(&erip->intrlock);
   2805   2534   carlsonj #ifdef	ESTAR_WORKAROUND
   2806   4404    gd78059 		if (linkupdate != LINK_STATE_UNKNOWN)
   2807   4404    gd78059 			mac_link_update(erip->mh, linkupdate);
   2808   2534   carlsonj #endif
   2809      0     stevel 		return (serviced);
   2810      0     stevel 	}
   2811      0     stevel 	serviced = DDI_INTR_CLAIMED;
   2812      0     stevel 
   2813      0     stevel 	if (!(erip->flags & ERI_RUNNING)) {
   2814      0     stevel 		mutex_exit(&erip->intrlock);
   2815      0     stevel 		eri_uninit(erip);
   2816      0     stevel 		return (serviced);
   2817      0     stevel 	}
   2818      0     stevel 
   2819      0     stevel 	if (erisbits & ERI_G_STATUS_FATAL_ERR) {
   2820      0     stevel 		ERI_DEBUG_MSG2(erip, INTR_MSG,
   2821   4404    gd78059 		    "eri_intr: fatal error: erisbits = %X", erisbits);
   2822      0     stevel 		(void) eri_fatal_err(erip, erisbits);
   2823      0     stevel 		eri_reinit_fatal++;
   2824      0     stevel 
   2825      0     stevel 		if (erip->rx_reset_issued) {
   2826      0     stevel 			erip->rx_reset_issued = 0;
   2827      0     stevel 			(void) eri_init_rx_channel(erip);
   2828      0     stevel 			mutex_exit(&erip->intrlock);
   2829      0     stevel 		} else {
   2830      0     stevel 			param_linkup = 0;
   2831   4404    gd78059 			erip->stats.link_up = LINK_STATE_DOWN;
   2832   4404    gd78059 			erip->stats.link_duplex = LINK_DUPLEX_UNKNOWN;
   2833      0     stevel 			DISABLE_MAC(erip);
   2834      0     stevel 			mutex_exit(&erip->intrlock);
   2835      0     stevel 			(void) eri_init(erip);
   2836      0     stevel 		}
   2837      0     stevel 		return (serviced);
   2838      0     stevel 	}
   2839      0     stevel 
   2840      0     stevel 	if (erisbits & ERI_G_STATUS_NONFATAL_ERR) {
   2841      0     stevel 		ERI_DEBUG_MSG2(erip, INTR_MSG,
   2842   4404    gd78059 		    "eri_intr: non-fatal error: erisbits = %X", erisbits);
   2843      0     stevel 		(void) eri_nonfatal_err(erip, erisbits);
   2844      0     stevel 		if (erip->linkcheck) {
   2845      0     stevel 			mutex_exit(&erip->intrlock);
   2846      0     stevel 			(void) eri_init(erip);
   2847      0     stevel 			return (serviced);
   2848      0     stevel 		}
   2849      0     stevel 	}
   2850      0     stevel 
   2851      0     stevel 	if (erisbits & ERI_G_STATUS_MIF_INT) {
   2852      0     stevel 		uint16_t stat;
   2853      0     stevel 		ERI_DEBUG_MSG2(erip, XCVR_MSG,
   2854   4404    gd78059 		    "eri_intr:MIF Interrupt:mii_status %X", erip->mii_status);
   2855      0     stevel 		eri_stop_timer(erip);   /* acquire linklock */
   2856      0     stevel 
   2857      0     stevel 		mutex_enter(&erip->xmitlock);
   2858      0     stevel 		mutex_enter(&erip->xcvrlock);
   2859      0     stevel #ifdef	ERI_MIF_POLL_STATUS_WORKAROUND
   2860      0     stevel 		mif_status = GET_MIFREG(mif_bsts);
   2861      0     stevel 		eri_mif_poll(erip, MIF_POLL_STOP);
   2862      0     stevel 		ERI_DEBUG_MSG3(erip, XCVR_MSG,
   2863   4404    gd78059 		    "eri_intr: new MIF interrupt status %X XCVR status %X",
   2864   4404    gd78059 		    mif_status, erip->mii_status);
   2865      0     stevel 		(void) eri_mii_read(erip, ERI_PHY_BMSR, &stat);
   2866   4404    gd78059 		linkupdate = eri_mif_check(erip, stat, stat);
   2867      0     stevel 
   2868      0     stevel #else
   2869      0     stevel 		mif_status = GET_MIFREG(mif_bsts);
   2870      0     stevel 		eri_mif_poll(erip, MIF_POLL_STOP);
   2871   4404    gd78059 		linkupdate = eri_mif_check(erip, (uint16_t)mif_status,
   2872   4404    gd78059 		    (uint16_t)(mif_status >> 16));
   2873      0     stevel #endif
   2874      0     stevel 		eri_mif_poll(erip, MIF_POLL_START);
   2875      0     stevel 		mutex_exit(&erip->xcvrlock);
   2876      0     stevel 		mutex_exit(&erip->xmitlock);
   2877      0     stevel 
   2878      0     stevel 		if (!erip->openloop_autoneg)
   2879      0     stevel 			eri_start_timer(erip, eri_check_link,
   2880   4404    gd78059 			    ERI_LINKCHECK_TIMER);
   2881      0     stevel 		else
   2882      0     stevel 			eri_start_timer(erip, eri_check_link,
   2883   4404    gd78059 			    ERI_P_FAULT_TIMER);
   2884      0     stevel 	}
   2885      0     stevel 
   2886      0     stevel 	ERI_DEBUG_MSG2(erip, INTR_MSG,
   2887   4404    gd78059 	    "eri_intr:May have Read Interrupt status:status %X", erisbits);
   2888      0     stevel 
   2889      0     stevel rx_done_int:
   2890      0     stevel 	if ((erisbits & (ERI_G_STATUS_TX_INT_ME)) ||
   2891      0     stevel 	    (erip->tx_cur_cnt >= tx_interrupt_rate)) {
   2892      0     stevel 		mutex_enter(&erip->xmitlock);
   2893      0     stevel 		erip->tx_completion = (uint32_t)(GET_ETXREG(tx_completion) &
   2894      0     stevel 		    ETX_COMPLETION_MASK);
   2895      0     stevel 
   2896   4404    gd78059 		macupdate |= eri_reclaim(erip, erip->tx_completion);
   2897  10306  Vitezslav 		if (macupdate)
   2898  10306  Vitezslav 			erip->wantw = B_FALSE;
   2899  10306  Vitezslav 
   2900      0     stevel 		mutex_exit(&erip->xmitlock);
   2901      0     stevel 	}
   2902      0     stevel 
   2903      0     stevel 	if (erisbits & ERI_G_STATUS_RX_DONE) {
   2904      0     stevel 		volatile struct	rmd	*rmdp, *rmdpbase;
   2905      0     stevel 		volatile uint32_t rmdi;
   2906      0     stevel 		uint8_t loop_limit = 0x20;
   2907      0     stevel 		uint64_t flags;
   2908      0     stevel 		uint32_t rmdmax_mask = erip->rmdmax_mask;
   2909      0     stevel 
   2910      0     stevel 		rmdpbase = erip->rmdp;
   2911      0     stevel 		rmdi = erip->rx_completion;
   2912      0     stevel 		rmdp = rmdpbase + rmdi;
   2913      0     stevel 
   2914      0     stevel 		/*
   2915      0     stevel 		 * Sync RMD before looking at it.
   2916      0     stevel 		 */
   2917      0     stevel 		ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd),
   2918   4404    gd78059 		    DDI_DMA_SYNC_FORCPU);
   2919      0     stevel 		/*
   2920      0     stevel 		 * Loop through each RMD.
   2921      0     stevel 		 */
   2922      0     stevel 
   2923      0     stevel 		flags = GET_RMD_FLAGS(rmdp);
   2924      0     stevel 		while (((flags & ERI_RMD_OWN) == 0) && (loop_limit)) {
   2925      0     stevel 			/* process one packet */
   2926   4404    gd78059 			mp = eri_read_dma(erip, rmdp, rmdi, flags);
   2927      0     stevel 			rmdi =  (rmdi + 1) & rmdmax_mask;
   2928      0     stevel 			rmdp = rmdpbase + rmdi;
   2929   4404    gd78059 
   2930   4404    gd78059 			if (mp != NULL) {
   2931   4404    gd78059 				*tail = mp;
   2932   4404    gd78059 				tail = &mp->b_next;
   2933   4404    gd78059 			}
   2934      0     stevel 
   2935      0     stevel 			/*
   2936      0     stevel 			 * ERI RCV DMA fetches or updates four descriptors
   2937      0     stevel 			 * a time. Also we don't want to update the desc.
   2938      0     stevel 			 * batch we just received packet on. So we update
   2939      0     stevel 			 * descriptors for every 4 packets and we update
   2940      0     stevel 			 * the group of 4 after the current batch.
   2941      0     stevel 			 */
   2942      0     stevel 
   2943      0     stevel 			if (!(rmdi % 4)) {
   2944      0     stevel 				if (eri_overflow_reset &&
   2945      0     stevel 				    (GET_GLOBREG(status_alias) &
   2946      0     stevel 				    ERI_G_STATUS_NONFATAL_ERR)) {
   2947      0     stevel 					loop_limit = 1;
   2948      0     stevel 				} else {
   2949      0     stevel 					erip->rx_kick =
   2950   4404    gd78059 					    (rmdi + ERI_RPENDING - 4) &
   2951   4404    gd78059 					    rmdmax_mask;
   2952      0     stevel 					PUT_ERXREG(rx_kick, erip->rx_kick);
   2953      0     stevel 				}
   2954      0     stevel 			}
   2955      0     stevel 
   2956      0     stevel 			/*
   2957      0     stevel 			 * Sync the next RMD before looking at it.
   2958      0     stevel 			 */
   2959      0     stevel 			ERI_SYNCIOPB(erip, rmdp, sizeof (struct rmd),
   2960   4404    gd78059 			    DDI_DMA_SYNC_FORCPU);
   2961      0     stevel 			flags = GET_RMD_FLAGS(rmdp);
   2962      0     stevel 			loop_limit--;
   2963      0     stevel 		}
   2964      0     stevel 		erip->rx_completion = rmdi;
   2965      0     stevel 	}
   2966   4404    gd78059 
   2967   4404    gd78059 	mutex_exit(&erip->intrlock);
   2968   4404    gd78059 
   2969   4404    gd78059 	if (head)
   2970   4404    gd78059 		mac_rx(erip->mh, NULL, head);
   2971   4404    gd78059 
   2972   4404    gd78059 	if (macupdate)
   2973   4404    gd78059 		mac_tx_update(erip->mh);
   2974   4404    gd78059 
   2975   4404    gd78059 	if (linkupdate != LINK_STATE_UNKNOWN)
   2976   4404    gd78059 		mac_link_update(erip->mh, linkupdate);
   2977      0     stevel 
   2978      0     stevel 	return (serviced);
   2979      0     stevel }
   2980      0     stevel 
   2981      0     stevel /*
   2982      0     stevel  * Handle interrupts for fatal errors
   2983      0     stevel  * Need reinitialization.
   2984      0     stevel  */
   2985      0     stevel #define	PCI_DATA_PARITY_REP	(1 << 8)
   2986      0     stevel #define	PCI_SING_TARGET_ABORT	(1 << 11)
   2987      0     stevel #define	PCI_RCV_TARGET_ABORT	(1 << 12)
   2988      0     stevel #define	PCI_RCV_MASTER_ABORT	(1 << 13)
   2989      0     stevel #define	PCI_SING_SYSTEM_ERR	(1 << 14)
   2990      0     stevel #define	PCI_DATA_PARITY_ERR	(1 << 15)
   2991      0     stevel 
   2992      0     stevel /* called with intrlock held */
   2993      0     stevel static void
   2994      0     stevel eri_fatal_err(struct eri *erip, uint32_t erisbits)
   2995      0     stevel {
   2996      0     stevel 	uint16_t	pci_status;
   2997      0     stevel 	uint32_t	pci_error_int = 0;
   2998      0     stevel 
   2999      0     stevel 	if (erisbits & ERI_G_STATUS_RX_TAG_ERR) {
   3000      0     stevel 		erip->rx_reset_issued = 1;
   3001      0     stevel 		HSTAT(erip, rxtag_err);
   3002      0     stevel 	} else {
   3003      0     stevel 		erip->global_reset_issued = 1;
   3004      0     stevel 		if (erisbits & ERI_G_STATUS_BUS_ERR_INT) {
   3005      0     stevel 			pci_error_int = 1;
   3006      0     stevel 			HSTAT(erip, pci_error_int);
   3007      0     stevel 		} else if (erisbits & ERI_G_STATUS_PERR_INT) {
   3008      0     stevel 			HSTAT(erip, parity_error);
   3009      0     stevel 		} else {
   3010      0     stevel 			HSTAT(erip, unknown_fatal);
   3011      0     stevel 		}
   3012      0     stevel 	}
   3013      0     stevel 
   3014      0     stevel 	/*
   3015      0     stevel 	 * PCI bus error
   3016      0     stevel 	 */
   3017      0     stevel 	if (pci_error_int && erip->pci_config_handle) {
   3018      0     stevel 		pci_status = pci_config_get16(erip->pci_config_handle,
   3019   4404    gd78059 		    PCI_CONF_STAT);
   3020   4404    gd78059 		ERI_DEBUG_MSG2(erip, FATAL_ERR_MSG, "Bus Error Status %x",
   3021   4404    gd78059 		    pci_status);
   3022      0     stevel 		if (pci_status & PCI_DATA_PARITY_REP)
   3023      0     stevel 			HSTAT(erip, pci_data_parity_err);
   3024      0     stevel 		if (pci_status & PCI_SING_TARGET_ABORT)
   3025      0     stevel 			HSTAT(erip, pci_signal_target_abort);
   3026      0     stevel 		if (pci_status & PCI_RCV_TARGET_ABORT)
   3027      0     stevel 			HSTAT(erip, pci_rcvd_target_abort);
   3028      0     stevel 		if (pci_status & PCI_RCV_MASTER_ABORT)
   3029      0     stevel 			HSTAT(erip, pci_rcvd_master_abort);
   3030      0     stevel 		if (pci_status & PCI_SING_SYSTEM_ERR)
   3031      0     stevel 			HSTAT(erip, pci_signal_system_err);
   3032      0     stevel 		if (pci_status & PCI_DATA_PARITY_ERR)
   3033      0     stevel 			HSTAT(erip, pci_signal_system_err);
   3034      0     stevel 		/*
   3035      0     stevel 		 * clear it by writing the value that was read back.
   3036      0     stevel 		 */
   3037   4404    gd78059 		pci_config_put16(erip->pci_config_handle, PCI_CONF_STAT,
   3038   4404    gd78059 		    pci_status);
   3039      0     stevel 	}
   3040      0     stevel }
   3041      0     stevel 
   3042      0     stevel /*
   3043      0     stevel  * Handle interrupts regarding non-fatal events.
   3044      0     stevel  * TXMAC, RXMAC and MACCTL events
   3045      0     stevel  */
   3046      0     stevel static void
   3047      0     stevel eri_nonfatal_err(struct eri *erip, uint32_t erisbits)
   3048      0     stevel {
   3049      0     stevel 
   3050      0     stevel 	uint32_t	txmac_sts, rxmac_sts, macctl_sts, pause_time;
   3051      0     stevel 
   3052      0     stevel #ifdef ERI_PM_WORKAROUND
   3053      0     stevel 	if (pci_report_pmcap(erip->dip, PCI_PM_IDLESPEED,
   3054      0     stevel 	    PCI_PM_IDLESPEED_NONE) == DDI_SUCCESS)
   3055      0     stevel 		erip->stats.pmcap = ERI_PMCAP_NONE;
   3056      0     stevel #endif
   3057      0     stevel 
   3058      0     stevel 	if (erisbits & ERI_G_STATUS_TX_MAC_INT) {
   3059      0     stevel 		txmac_sts = GET_MACREG(txsts);
   3060      0     stevel 		if (txmac_sts & BMAC_TXSTS_TX_URUN) {
   3061      0     stevel 			erip->linkcheck = 1;
   3062      0     stevel 			HSTAT(erip, txmac_urun);
   3063      0     stevel 			HSTAT(erip, oerrors);
   3064      0     stevel 		}
   3065      0     stevel 
   3066      0     stevel 		if (txmac_sts & BMAC_TXSTS_MAXPKT_ERR) {
   3067      0     stevel 			erip->linkcheck = 1;
   3068      0     stevel 			HSTAT(erip, txmac_maxpkt_err);
   3069      0     stevel 			HSTAT(erip, oerrors);
   3070      0     stevel 		}
   3071      0     stevel 		if (txmac_sts & BMAC_TXSTS_NCC_EXP) {
   3072      0     stevel 			erip->stats.collisions += 0x10000;
   3073      0     stevel 		}
   3074      0     stevel 
   3075      0     stevel 		if (txmac_sts & BMAC_TXSTS_ECC_EXP) {
   3076      0     stevel 			erip->stats.excessive_coll += 0x10000;
   3077      0     stevel 		}
   3078      0     stevel 
   3079      0     stevel 		if (txmac_sts & BMAC_TXSTS_LCC_EXP) {
   3080      0     stevel 			erip->stats.late_coll += 0x10000;
   3081      0     stevel 		}
   3082      0     stevel 
   3083      0     stevel 		if (txmac_sts & BMAC_TXSTS_FCC_EXP) {
   3084      0     stevel 			erip->stats.first_coll += 0x10000;
   3085      0     stevel 		}
   3086      0     stevel 
   3087      0     stevel 		if (txmac_sts & BMAC_TXSTS_DEFER_EXP) {
   3088      0     stevel 			HSTAT(erip, defer_timer_exp);
   3089      0     stevel 		}
   3090      0     stevel 
   3091      0     stevel 		if (txmac_sts & BMAC_TXSTS_PEAK_EXP) {
   3092      0     stevel 			erip->stats.peak_attempt_cnt += 0x100;
   3093      0     stevel 		}
   3094      0     stevel 	}
   3095      0     stevel 
   3096      0     stevel 	if (erisbits & ERI_G_STATUS_RX_NO_BUF) {
   3097   4404    gd78059 		ERI_DEBUG_MSG1(erip, NONFATAL_MSG, "rx dropped/no free desc");
   3098      0     stevel 
   3099      0     stevel 		if (eri_overflow_reset)
   3100      0     stevel 			erip->linkcheck = 1;
   3101      0     stevel 
   3102      0     stevel 		HSTAT(erip, no_free_rx_desc);
   3103      0     stevel 		HSTAT(erip, ierrors);
   3104      0     stevel 	}
   3105      0     stevel 	if (erisbits & ERI_G_STATUS_RX_MAC_INT) {
   3106      0     stevel 		rxmac_sts = GET_MACREG(rxsts);
   3107      0     stevel 		if (rxmac_sts & BMAC_RXSTS_RX_OVF) {
   3108      0     stevel #ifndef ERI_RMAC_HANG_WORKAROUND
   3109      0     stevel 			eri_stop_timer(erip);   /* acquire linklock */
   3110      0     stevel 			erip->check_rmac_hang ++;
   3111      0     stevel 			erip->check2_rmac_hang = 0;
   3112      0     stevel 			erip->rxfifo_wr_ptr = GET_ERXREG(rxfifo_wr_ptr);
   3113      0     stevel 			erip->rxfifo_rd_ptr = GET_ERXREG(rxfifo_rd_ptr);
   3114      0     stevel 
   3115   4404    gd78059 			ERI_DEBUG_MSG5(erip, NONFATAL_MSG,
   3116      0     stevel 			    "overflow intr %d: %8x wr:%2x rd:%2x",
   3117      0     stevel 			    erip->check_rmac_hang,
   3118      0     stevel 			    GET_MACREG(macsm),
   3119      0     stevel 			    GET_ERXREG(rxfifo_wr_ptr),
   3120      0     stevel 			    GET_ERXREG(rxfifo_rd_ptr));
   3121      0     stevel 
   3122      0     stevel 			eri_start_timer(erip, eri_check_link,
   3123