xref: /illumos-gate/usr/src/uts/common/io/afe/afeimpl.h (revision bdb9230a)
11959748cSgd /*
21959748cSgd  * Solaris driver for ethernet cards based on the ADMtek Centaur
31959748cSgd  *
41959748cSgd  * Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>.
51959748cSgd  * All rights reserved.
61959748cSgd  *
71959748cSgd  * Redistribution and use in source and binary forms, with or without
81959748cSgd  * modification, are permitted provided that the following conditions
91959748cSgd  * are met:
101959748cSgd  * 1. Redistributions of source code must retain the above copyright
111959748cSgd  *    notice, this list of conditions and the following disclaimer.
121959748cSgd  * 2. Redistributions in binary form must reproduce the above copyright
131959748cSgd  *    notice, this list of conditions and the following disclaimer in the
141959748cSgd  *    documentation and/or other materials provided with the distribution.
151959748cSgd  * 3. Neither the name of the author nor the names of any co-contributors
161959748cSgd  *    may be used to endorse or promote products derived from this software
171959748cSgd  *    without specific prior written permission.
181959748cSgd  *
191959748cSgd  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
201959748cSgd  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
211959748cSgd  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
221959748cSgd  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
231959748cSgd  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241959748cSgd  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251959748cSgd  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261959748cSgd  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271959748cSgd  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281959748cSgd  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291959748cSgd  * POSSIBILITY OF SUCH DAMAGE.
301959748cSgd  */
3196fb08b9Sgd /*
32*bdb9230aSGarrett D'Amore  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
3396fb08b9Sgd  * Use is subject to license terms.
3496fb08b9Sgd  */
351959748cSgd 
361959748cSgd #ifndef	_AFEIMPL_H
371959748cSgd #define	_AFEIMPL_H
381959748cSgd 
391959748cSgd #ifdef	_KERNEL
401959748cSgd 
41da14cebeSEric Cheng #include	<sys/mac_provider.h>
42da14cebeSEric Cheng 
431959748cSgd /*
441959748cSgd  * Compile time tunables.
451959748cSgd  */
461959748cSgd #define	AFE_RXRING	128	/* number of rcv buffers */
471959748cSgd #define	AFE_TXRING	128	/* number of xmt buffers */
481959748cSgd #define	AFE_TXRECLAIM	8	/* when to reclaim tx buffers (txavail) */
491959748cSgd #define	AFE_TXRESCHED	120	/* when to resched (txavail) */
50*bdb9230aSGarrett D'Amore #define	AFE_WDOGTIMER	5000	/* how often we check for tx hang (in msec) */
511959748cSgd #define	AFE_HEADROOM	34	/* headroom in packet (should be 2 modulo 4) */
521959748cSgd 
531959748cSgd /*
541959748cSgd  * Constants, do not change.
551959748cSgd  */
561959748cSgd #define	AFE_BUFSZ	(1664)	/* big enough for a vlan frame */
571959748cSgd #define	AFE_MCHASH	(64)
581959748cSgd 
591959748cSgd typedef struct afe afe_t;
601959748cSgd typedef struct afe_card afe_card_t;
611959748cSgd typedef struct afe_rxbuf afe_rxbuf_t;
621959748cSgd typedef struct afe_txbuf afe_txbuf_t;
631959748cSgd typedef struct afe_desc afe_desc_t;
641959748cSgd 
651959748cSgd /*
661959748cSgd  * Card models.
671959748cSgd  */
681959748cSgd typedef enum {
691959748cSgd 	MODEL_CENTAUR = 1,
701959748cSgd 	MODEL_COMET,
711959748cSgd } afe_model_t;
721959748cSgd 
731959748cSgd struct afe_card {
741959748cSgd 	uint16_t	card_venid;	/* PCI vendor id */
751959748cSgd 	uint16_t	card_devid;	/* PCI device id */
761959748cSgd 	char		*card_cardname;	/* Description of the card */
771959748cSgd 	afe_model_t	card_model;	/* Card specific flags */
781959748cSgd };
791959748cSgd 
801959748cSgd /*
811959748cSgd  * Device instance structure, one per PCI card.
821959748cSgd  */
831959748cSgd struct afe {
841959748cSgd 	dev_info_t		*afe_dip;
851959748cSgd 	mac_handle_t		afe_mh;
86*bdb9230aSGarrett D'Amore 	mii_handle_t		afe_mii;
871959748cSgd 	afe_card_t		*afe_cardp;
881959748cSgd 	uint16_t		afe_cachesize;
891959748cSgd 	uint8_t			afe_sromwidth;
901959748cSgd 	int			afe_flags;
911959748cSgd 	kmutex_t		afe_xmtlock;
921959748cSgd 	kmutex_t		afe_intrlock;
931959748cSgd 	ddi_iblock_cookie_t	afe_icookie;
941959748cSgd 
951959748cSgd 	/*
961959748cSgd 	 * Register and DMA access.
971959748cSgd 	 */
981959748cSgd 	uintptr_t		afe_regs;
991959748cSgd 	ddi_acc_handle_t	afe_regshandle;
1001959748cSgd 
1011959748cSgd 	/*
1021959748cSgd 	 * Receive descriptors.
1031959748cSgd 	 */
1041959748cSgd 	int			afe_rxhead;
1051959748cSgd 	struct afe_desc		*afe_rxdescp;
1061959748cSgd 	ddi_dma_handle_t	afe_rxdesc_dmah;
1071959748cSgd 	ddi_acc_handle_t	afe_rxdesc_acch;
1081959748cSgd 	uint32_t		afe_rxdesc_paddr;
1091959748cSgd 	struct afe_rxbuf	**afe_rxbufs;
1101959748cSgd 
1111959748cSgd 	/*
1121959748cSgd 	 * Transmit descriptors.
1131959748cSgd 	 */
1141959748cSgd 	int			afe_txreclaim;
1151959748cSgd 	int			afe_txsend;
1161959748cSgd 	int			afe_txavail;
1171959748cSgd 	struct afe_desc		*afe_txdescp;
1181959748cSgd 	ddi_dma_handle_t	afe_txdesc_dmah;
1191959748cSgd 	ddi_acc_handle_t	afe_txdesc_acch;
1201959748cSgd 	uint32_t		afe_txdesc_paddr;
1211959748cSgd 	struct afe_txbuf	**afe_txbufs;
1221959748cSgd 	hrtime_t		afe_txstall_time;
1231959748cSgd 	boolean_t		afe_wantw;
1241959748cSgd 
1251959748cSgd 	/*
1261959748cSgd 	 * Transceiver stuff.
1271959748cSgd 	 */
1281959748cSgd 	int			afe_phyaddr;
1291959748cSgd 	int			afe_phyid;
1301959748cSgd 	int			afe_phyinuse;
13196fb08b9Sgd 
1321959748cSgd 	int			afe_forcefiber;
1331959748cSgd 
1341959748cSgd 	/*
1351959748cSgd 	 * Address management.
1361959748cSgd 	 */
1371959748cSgd 	uchar_t			afe_curraddr[ETHERADDRL];
1381959748cSgd 	boolean_t		afe_promisc;
1391959748cSgd 	uint16_t		afe_mccount[AFE_MCHASH];
1401959748cSgd 	uint32_t		afe_mctab[AFE_MCHASH / 32];	/* Centaur */
1411959748cSgd 
1421959748cSgd 	/*
1431959748cSgd 	 * Kstats.
1441959748cSgd 	 */
1451959748cSgd 	kstat_t			*afe_intrstat;
1461959748cSgd 	uint64_t		afe_ipackets;
1471959748cSgd 	uint64_t		afe_opackets;
1481959748cSgd 	uint64_t		afe_rbytes;
1491959748cSgd 	uint64_t		afe_obytes;
1501959748cSgd 	uint64_t		afe_brdcstxmt;
1511959748cSgd 	uint64_t		afe_multixmt;
1521959748cSgd 	uint64_t		afe_brdcstrcv;
1531959748cSgd 	uint64_t		afe_multircv;
1541959748cSgd 	unsigned		afe_norcvbuf;
1551959748cSgd 	unsigned		afe_errrcv;
1561959748cSgd 	unsigned		afe_errxmt;
1571959748cSgd 	unsigned		afe_missed;
1581959748cSgd 	unsigned		afe_underflow;
1591959748cSgd 	unsigned		afe_overflow;
1601959748cSgd 	unsigned		afe_align_errors;
1611959748cSgd 	unsigned		afe_fcs_errors;
1621959748cSgd 	unsigned		afe_carrier_errors;
1631959748cSgd 	unsigned		afe_collisions;
1641959748cSgd 	unsigned		afe_ex_collisions;
1651959748cSgd 	unsigned		afe_tx_late_collisions;
1661959748cSgd 	unsigned		afe_defer_xmts;
1671959748cSgd 	unsigned		afe_first_collisions;
1681959748cSgd 	unsigned		afe_multi_collisions;
1691959748cSgd 	unsigned		afe_sqe_errors;
1701959748cSgd 	unsigned		afe_macxmt_errors;
1711959748cSgd 	unsigned		afe_macrcv_errors;
1721959748cSgd 	unsigned		afe_toolong_errors;
1731959748cSgd 	unsigned		afe_runt;
1741959748cSgd 	unsigned		afe_jabber;
1751959748cSgd };
1761959748cSgd 
1771959748cSgd struct afe_rxbuf {
1781959748cSgd 	caddr_t			rxb_buf;
1791959748cSgd 	ddi_dma_handle_t	rxb_dmah;
1801959748cSgd 	ddi_acc_handle_t	rxb_acch;
1811959748cSgd 	uint32_t		rxb_paddr;
1821959748cSgd };
1831959748cSgd 
1841959748cSgd struct afe_txbuf {
1851959748cSgd 	caddr_t			txb_buf;
1861959748cSgd 	uint32_t		txb_paddr;
1871959748cSgd 	ddi_dma_handle_t	txb_dmah;
1881959748cSgd 	ddi_acc_handle_t	txb_acch;
1891959748cSgd };
1901959748cSgd 
1911959748cSgd /*
1921959748cSgd  * Descriptor.  We use rings rather than chains.
1931959748cSgd  */
1941959748cSgd struct afe_desc {
1951959748cSgd 	unsigned	desc_status;
1961959748cSgd 	unsigned	desc_control;
1971959748cSgd 	unsigned	desc_buffer1;
1981959748cSgd 	unsigned	desc_buffer2;
1991959748cSgd };
2001959748cSgd 
2011959748cSgd #define	PUTTXDESC(afep, member, val)	\
2021959748cSgd 	ddi_put32(afep->afe_txdesc_acch, &member, val)
2031959748cSgd 
2041959748cSgd #define	PUTRXDESC(afep, member, val)	\
2051959748cSgd 	ddi_put32(afep->afe_rxdesc_acch, &member, val)
2061959748cSgd 
2071959748cSgd #define	GETTXDESC(afep, member)	\
2081959748cSgd 	ddi_get32(afep->afe_txdesc_acch, &member)
2091959748cSgd 
2101959748cSgd #define	GETRXDESC(afep, member)	\
2111959748cSgd 	ddi_get32(afep->afe_rxdesc_acch, &member)
2121959748cSgd 
2131959748cSgd /*
2141959748cSgd  * Receive descriptor fields.
2151959748cSgd  */
2161959748cSgd #define	RXSTAT_OWN		0x80000000U	/* ownership */
2171959748cSgd #define	RXSTAT_RXLEN		0x3FFF0000U	/* frame length, incl. crc */
2181959748cSgd #define	RXSTAT_RXERR		0x00008000U	/* error summary */
2191959748cSgd #define	RXSTAT_DESCERR		0x00004000U	/* descriptor error */
2201959748cSgd #define	RXSTAT_RXTYPE		0x00003000U	/* data type */
2211959748cSgd #define	RXSTAT_RUNT		0x00000800U	/* runt frame */
2221959748cSgd #define	RXSTAT_GROUP		0x00000400U	/* multicast/brdcast frame */
2231959748cSgd #define	RXSTAT_FIRST		0x00000200U	/* first descriptor */
2241959748cSgd #define	RXSTAT_LAST		0x00000100U	/* last descriptor */
2251959748cSgd #define	RXSTAT_TOOLONG		0x00000080U	/* frame too long */
2261959748cSgd #define	RXSTAT_COLLSEEN		0x00000040U	/* late collision seen */
2271959748cSgd #define	RXSTAT_FRTYPE		0x00000020U	/* frame type */
2281959748cSgd #define	RXSTAT_WATCHDOG		0x00000010U	/* receive watchdog */
2291959748cSgd #define	RXSTAT_DRIBBLE		0x00000004U	/* dribbling bit */
2301959748cSgd #define	RXSTAT_CRCERR		0x00000002U	/* crc error */
2311959748cSgd #define	RXSTAT_OFLOW		0x00000001U	/* fifo overflow */
2321959748cSgd #define	RXSTAT_ERRS		(RXSTAT_DESCERR | RXSTAT_RUNT | \
2331959748cSgd 				RXSTAT_COLLSEEN | RXSTAT_DRIBBLE | \
2341959748cSgd 				RXSTAT_CRCERR | RXSTAT_OFLOW)
2351959748cSgd #define	RXLENGTH(x)		((x & RXSTAT_RXLEN) >> 16)
2361959748cSgd 
2371959748cSgd #define	RXCTL_ENDRING		0x02000000U	/* end of ring */
2381959748cSgd #define	RXCTL_CHAIN		0x01000000U	/* chained descriptors */
2391959748cSgd #define	RXCTL_BUFLEN2		0x003FF800U	/* buffer 2 length */
2401959748cSgd #define	RXCTL_BUFLEN1		0x000007FFU	/* buffer 1 length */
2411959748cSgd 
2421959748cSgd /*
2431959748cSgd  * Transmit descriptor fields.
2441959748cSgd  */
2451959748cSgd #define	TXSTAT_OWN		0x80000000U	/* ownership */
2461959748cSgd #define	TXSTAT_URCNT		0x00C00000U	/* underrun count */
2471959748cSgd #define	TXSTAT_TXERR		0x00008000U	/* error summary */
2481959748cSgd #define	TXSTAT_JABBER		0x00004000U	/* jabber timeout */
2491959748cSgd #define	TXSTAT_CARRLOST		0x00000800U	/* lost carrier */
2501959748cSgd #define	TXSTAT_NOCARR		0x00000400U	/* no carrier */
2511959748cSgd #define	TXSTAT_LATECOL		0x00000200U	/* late collision */
2521959748cSgd #define	TXSTAT_EXCOLL		0x00000100U	/* excessive collisions */
2531959748cSgd #define	TXSTAT_SQE		0x00000080U	/* heartbeat failure */
2541959748cSgd #define	TXSTAT_COLLCNT		0x00000078U	/* collision count */
2551959748cSgd #define	TXSTAT_UFLOW		0x00000002U	/* underflow */
2561959748cSgd #define	TXSTAT_DEFER		0x00000001U	/* deferred */
2571959748cSgd #define	TXCOLLCNT(x)		((x & TXSTAT_COLLCNT) >> 3)
2581959748cSgd #define	TXUFLOWCNT(x)		((x & TXSTAT_URCNT) >> 22)
2591959748cSgd 
2601959748cSgd #define	TXCTL_INTCMPLTE		0x80000000U	/* interrupt completed */
2611959748cSgd #define	TXCTL_LAST		0x40000000U	/* last descriptor */
2621959748cSgd #define	TXCTL_FIRST		0x20000000U	/* first descriptor */
2631959748cSgd #define	TXCTL_NOCRC		0x04000000U	/* disable crc */
2641959748cSgd #define	TXCTL_ENDRING		0x02000000U	/* end of ring */
2651959748cSgd #define	TXCTL_CHAIN		0x01000000U	/* chained descriptors */
2661959748cSgd #define	TXCTL_NOPAD		0x00800000U	/* disable padding */
2671959748cSgd #define	TXCTL_HASHPERF		0x00400000U	/* hash perfect mode */
2681959748cSgd #define	TXCTL_BUFLEN2		0x003FF800U	/* buffer length 2 */
2691959748cSgd #define	TXCTL_BUFLEN1		0x000007FFU	/* buffer length 1 */
2701959748cSgd 
2711959748cSgd 
2721959748cSgd /*
2731959748cSgd  * Interface flags.
2741959748cSgd  */
2751959748cSgd #define	AFE_RUNNING	0x1	/* chip is initialized */
2761959748cSgd #define	AFE_SUSPENDED	0x2	/* interface is suspended */
2771959748cSgd #define	AFE_HASFIBER	0x4	/* internal phy supports fiber (AFE_PHY_MCR) */
2781959748cSgd 
2791959748cSgd #define	AFE_MODEL(afep)		((afep)->afe_cardp->card_model)
2801959748cSgd 
2811959748cSgd 
2821959748cSgd /*
2831959748cSgd  * Register definitions located in afe.h exported header file.
2841959748cSgd  */
2851959748cSgd 
2861959748cSgd /*
2871959748cSgd  * Macros to simplify hardware access.
2881959748cSgd  */
2891959748cSgd #define	GETCSR(afep, reg)	\
2901959748cSgd 	ddi_get32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg))
2911959748cSgd 
2921959748cSgd #define	GETCSR16(afep, reg)	\
2931959748cSgd 	ddi_get16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg))
2941959748cSgd 
2951959748cSgd #define	PUTCSR(afep, reg, val)	\
2961959748cSgd 	ddi_put32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg), val)
2971959748cSgd 
2981959748cSgd #define	PUTCSR16(afep, reg, val)	\
2991959748cSgd 	ddi_put16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg), val)
3001959748cSgd 
3011959748cSgd #define	SETBIT(afep, reg, val)	PUTCSR(afep, reg, GETCSR(afep, reg) | (val))
3021959748cSgd 
3031959748cSgd #define	CLRBIT(afep, reg, val)	PUTCSR(afep, reg, GETCSR(afep, reg) & ~(val))
3041959748cSgd 
3051959748cSgd #define	SYNCTXDESC(afep, index, who)	\
3061959748cSgd 	(void) ddi_dma_sync(afep->afe_txdesc_dmah, \
3071959748cSgd 	    (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who)
3081959748cSgd 
3091959748cSgd #define	SYNCTXBUF(txb, len, who)	\
3101959748cSgd 	(void) ddi_dma_sync(txb->txb_dmah, 0, len, who)
3111959748cSgd 
3121959748cSgd #define	SYNCRXDESC(afep, index, who)	\
3131959748cSgd 	(void) ddi_dma_sync(afep->afe_rxdesc_dmah, \
3141959748cSgd 	    (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who)
3151959748cSgd 
3161959748cSgd #define	SYNCRXBUF(rxb, len, who)	\
3171959748cSgd 	(void) ddi_dma_sync(rxb->rxb_dmah, 0, len, who)
3181959748cSgd 
3191959748cSgd #endif	/* _KERNEL */
3201959748cSgd 
3211959748cSgd #endif	/* _AFEIMPL_H */
322