| /* |
| * Solaris driver for ethernet cards based on the ADMtek Centaur |
| * |
| * Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>. |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * 3. Neither the name of the author nor the names of any co-contributors |
| * may be used to endorse or promote products derived from this software |
| * without specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE |
| * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
| * POSSIBILITY OF SUCH DAMAGE. |
| */ |
| /* |
| * Copyright 2009 Sun Microsystems, Inc. All rights reserved. |
| * Use is subject to license terms. |
| */ |
| |
| #ifndef _AFEIMPL_H |
| #define _AFEIMPL_H |
| |
| #ifdef _KERNEL |
| |
| #include <sys/mac_provider.h> |
| |
| /* |
| * Compile time tunables. |
| */ |
| #define AFE_RXRING 128 /* number of rcv buffers */ |
| #define AFE_TXRING 128 /* number of xmt buffers */ |
| #define AFE_TXRECLAIM 8 /* when to reclaim tx buffers (txavail) */ |
| #define AFE_TXRESCHED 120 /* when to resched (txavail) */ |
| #define AFE_WDOGTIMER 5000 /* how often we check for tx hang (in msec) */ |
| #define AFE_HEADROOM 34 /* headroom in packet (should be 2 modulo 4) */ |
| |
| /* |
| * Constants, do not change. |
| */ |
| #define AFE_BUFSZ (1664) /* big enough for a vlan frame */ |
| #define AFE_MCHASH (64) |
| |
| typedef struct afe afe_t; |
| typedef struct afe_card afe_card_t; |
| typedef struct afe_rxbuf afe_rxbuf_t; |
| typedef struct afe_txbuf afe_txbuf_t; |
| typedef struct afe_desc afe_desc_t; |
| |
| /* |
| * Card models. |
| */ |
| typedef enum { |
| MODEL_CENTAUR = 1, |
| MODEL_COMET, |
| } afe_model_t; |
| |
| struct afe_card { |
| uint16_t card_venid; /* PCI vendor id */ |
| uint16_t card_devid; /* PCI device id */ |
| char *card_cardname; /* Description of the card */ |
| afe_model_t card_model; /* Card specific flags */ |
| }; |
| |
| /* |
| * Device instance structure, one per PCI card. |
| */ |
| struct afe { |
| dev_info_t *afe_dip; |
| mac_handle_t afe_mh; |
| mii_handle_t afe_mii; |
| afe_card_t *afe_cardp; |
| uint16_t afe_cachesize; |
| uint8_t afe_sromwidth; |
| int afe_flags; |
| kmutex_t afe_xmtlock; |
| kmutex_t afe_intrlock; |
| ddi_iblock_cookie_t afe_icookie; |
| |
| /* |
| * Register and DMA access. |
| */ |
| uintptr_t afe_regs; |
| ddi_acc_handle_t afe_regshandle; |
| |
| /* |
| * Receive descriptors. |
| */ |
| int afe_rxhead; |
| struct afe_desc *afe_rxdescp; |
| ddi_dma_handle_t afe_rxdesc_dmah; |
| ddi_acc_handle_t afe_rxdesc_acch; |
| uint32_t afe_rxdesc_paddr; |
| struct afe_rxbuf **afe_rxbufs; |
| |
| /* |
| * Transmit descriptors. |
| */ |
| int afe_txreclaim; |
| int afe_txsend; |
| int afe_txavail; |
| struct afe_desc *afe_txdescp; |
| ddi_dma_handle_t afe_txdesc_dmah; |
| ddi_acc_handle_t afe_txdesc_acch; |
| uint32_t afe_txdesc_paddr; |
| struct afe_txbuf **afe_txbufs; |
| hrtime_t afe_txstall_time; |
| boolean_t afe_wantw; |
| |
| /* |
| * Transceiver stuff. |
| */ |
| int afe_phyaddr; |
| int afe_phyid; |
| int afe_phyinuse; |
| |
| int afe_forcefiber; |
| |
| /* |
| * Address management. |
| */ |
| uchar_t afe_curraddr[ETHERADDRL]; |
| boolean_t afe_promisc; |
| uint16_t afe_mccount[AFE_MCHASH]; |
| uint32_t afe_mctab[AFE_MCHASH / 32]; /* Centaur */ |
| |
| /* |
| * Kstats. |
| */ |
| kstat_t *afe_intrstat; |
| uint64_t afe_ipackets; |
| uint64_t afe_opackets; |
| uint64_t afe_rbytes; |
| uint64_t afe_obytes; |
| uint64_t afe_brdcstxmt; |
| uint64_t afe_multixmt; |
| uint64_t afe_brdcstrcv; |
| uint64_t afe_multircv; |
| unsigned afe_norcvbuf; |
| unsigned afe_errrcv; |
| unsigned afe_errxmt; |
| unsigned afe_missed; |
| unsigned afe_underflow; |
| unsigned afe_overflow; |
| unsigned afe_align_errors; |
| unsigned afe_fcs_errors; |
| unsigned afe_carrier_errors; |
| unsigned afe_collisions; |
| unsigned afe_ex_collisions; |
| unsigned afe_tx_late_collisions; |
| unsigned afe_defer_xmts; |
| unsigned afe_first_collisions; |
| unsigned afe_multi_collisions; |
| unsigned afe_sqe_errors; |
| unsigned afe_macxmt_errors; |
| unsigned afe_macrcv_errors; |
| unsigned afe_toolong_errors; |
| unsigned afe_runt; |
| unsigned afe_jabber; |
| }; |
| |
| struct afe_rxbuf { |
| caddr_t rxb_buf; |
| ddi_dma_handle_t rxb_dmah; |
| ddi_acc_handle_t rxb_acch; |
| uint32_t rxb_paddr; |
| }; |
| |
| struct afe_txbuf { |
| caddr_t txb_buf; |
| uint32_t txb_paddr; |
| ddi_dma_handle_t txb_dmah; |
| ddi_acc_handle_t txb_acch; |
| }; |
| |
| /* |
| * Descriptor. We use rings rather than chains. |
| */ |
| struct afe_desc { |
| unsigned desc_status; |
| unsigned desc_control; |
| unsigned desc_buffer1; |
| unsigned desc_buffer2; |
| }; |
| |
| #define PUTTXDESC(afep, member, val) \ |
| ddi_put32(afep->afe_txdesc_acch, &member, val) |
| |
| #define PUTRXDESC(afep, member, val) \ |
| ddi_put32(afep->afe_rxdesc_acch, &member, val) |
| |
| #define GETTXDESC(afep, member) \ |
| ddi_get32(afep->afe_txdesc_acch, &member) |
| |
| #define GETRXDESC(afep, member) \ |
| ddi_get32(afep->afe_rxdesc_acch, &member) |
| |
| /* |
| * Receive descriptor fields. |
| */ |
| #define RXSTAT_OWN 0x80000000U /* ownership */ |
| #define RXSTAT_RXLEN 0x3FFF0000U /* frame length, incl. crc */ |
| #define RXSTAT_RXERR 0x00008000U /* error summary */ |
| #define RXSTAT_DESCERR 0x00004000U /* descriptor error */ |
| #define RXSTAT_RXTYPE 0x00003000U /* data type */ |
| #define RXSTAT_RUNT 0x00000800U /* runt frame */ |
| #define RXSTAT_GROUP 0x00000400U /* multicast/brdcast frame */ |
| #define RXSTAT_FIRST 0x00000200U /* first descriptor */ |
| #define RXSTAT_LAST 0x00000100U /* last descriptor */ |
| #define RXSTAT_TOOLONG 0x00000080U /* frame too long */ |
| #define RXSTAT_COLLSEEN 0x00000040U /* late collision seen */ |
| #define RXSTAT_FRTYPE 0x00000020U /* frame type */ |
| #define RXSTAT_WATCHDOG 0x00000010U /* receive watchdog */ |
| #define RXSTAT_DRIBBLE 0x00000004U /* dribbling bit */ |
| #define RXSTAT_CRCERR 0x00000002U /* crc error */ |
| #define RXSTAT_OFLOW 0x00000001U /* fifo overflow */ |
| #define RXSTAT_ERRS (RXSTAT_DESCERR | RXSTAT_RUNT | \ |
| RXSTAT_COLLSEEN | RXSTAT_DRIBBLE | \ |
| RXSTAT_CRCERR | RXSTAT_OFLOW) |
| #define RXLENGTH(x) ((x & RXSTAT_RXLEN) >> 16) |
| |
| #define RXCTL_ENDRING 0x02000000U /* end of ring */ |
| #define RXCTL_CHAIN 0x01000000U /* chained descriptors */ |
| #define RXCTL_BUFLEN2 0x003FF800U /* buffer 2 length */ |
| #define RXCTL_BUFLEN1 0x000007FFU /* buffer 1 length */ |
| |
| /* |
| * Transmit descriptor fields. |
| */ |
| #define TXSTAT_OWN 0x80000000U /* ownership */ |
| #define TXSTAT_URCNT 0x00C00000U /* underrun count */ |
| #define TXSTAT_TXERR 0x00008000U /* error summary */ |
| #define TXSTAT_JABBER 0x00004000U /* jabber timeout */ |
| #define TXSTAT_CARRLOST 0x00000800U /* lost carrier */ |
| #define TXSTAT_NOCARR 0x00000400U /* no carrier */ |
| #define TXSTAT_LATECOL 0x00000200U /* late collision */ |
| #define TXSTAT_EXCOLL 0x00000100U /* excessive collisions */ |
| #define TXSTAT_SQE 0x00000080U /* heartbeat failure */ |
| #define TXSTAT_COLLCNT 0x00000078U /* collision count */ |
| #define TXSTAT_UFLOW 0x00000002U /* underflow */ |
| #define TXSTAT_DEFER 0x00000001U /* deferred */ |
| #define TXCOLLCNT(x) ((x & TXSTAT_COLLCNT) >> 3) |
| #define TXUFLOWCNT(x) ((x & TXSTAT_URCNT) >> 22) |
| |
| #define TXCTL_INTCMPLTE 0x80000000U /* interrupt completed */ |
| #define TXCTL_LAST 0x40000000U /* last descriptor */ |
| #define TXCTL_FIRST 0x20000000U /* first descriptor */ |
| #define TXCTL_NOCRC 0x04000000U /* disable crc */ |
| #define TXCTL_ENDRING 0x02000000U /* end of ring */ |
| #define TXCTL_CHAIN 0x01000000U /* chained descriptors */ |
| #define TXCTL_NOPAD 0x00800000U /* disable padding */ |
| #define TXCTL_HASHPERF 0x00400000U /* hash perfect mode */ |
| #define TXCTL_BUFLEN2 0x003FF800U /* buffer length 2 */ |
| #define TXCTL_BUFLEN1 0x000007FFU /* buffer length 1 */ |
| |
| |
| /* |
| * Interface flags. |
| */ |
| #define AFE_RUNNING 0x1 /* chip is initialized */ |
| #define AFE_SUSPENDED 0x2 /* interface is suspended */ |
| #define AFE_HASFIBER 0x4 /* internal phy supports fiber (AFE_PHY_MCR) */ |
| |
| #define AFE_MODEL(afep) ((afep)->afe_cardp->card_model) |
| |
| |
| /* |
| * Register definitions located in afe.h exported header file. |
| */ |
| |
| /* |
| * Macros to simplify hardware access. |
| */ |
| #define GETCSR(afep, reg) \ |
| ddi_get32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg)) |
| |
| #define GETCSR16(afep, reg) \ |
| ddi_get16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg)) |
| |
| #define PUTCSR(afep, reg, val) \ |
| ddi_put32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg), val) |
| |
| #define PUTCSR16(afep, reg, val) \ |
| ddi_put16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg), val) |
| |
| #define SETBIT(afep, reg, val) PUTCSR(afep, reg, GETCSR(afep, reg) | (val)) |
| |
| #define CLRBIT(afep, reg, val) PUTCSR(afep, reg, GETCSR(afep, reg) & ~(val)) |
| |
| #define SYNCTXDESC(afep, index, who) \ |
| (void) ddi_dma_sync(afep->afe_txdesc_dmah, \ |
| (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who) |
| |
| #define SYNCTXBUF(txb, len, who) \ |
| (void) ddi_dma_sync(txb->txb_dmah, 0, len, who) |
| |
| #define SYNCRXDESC(afep, index, who) \ |
| (void) ddi_dma_sync(afep->afe_rxdesc_dmah, \ |
| (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who) |
| |
| #define SYNCRXBUF(rxb, len, who) \ |
| (void) ddi_dma_sync(rxb->rxb_dmah, 0, len, who) |
| |
| #endif /* _KERNEL */ |
| |
| #endif /* _AFEIMPL_H */ |