14992Sgd78059 /* 24992Sgd78059 * Solaris driver for ethernet cards based on the ADMtek Centaur 34992Sgd78059 * 44992Sgd78059 * Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>. 54992Sgd78059 * All rights reserved. 64992Sgd78059 * 74992Sgd78059 * Redistribution and use in source and binary forms, with or without 84992Sgd78059 * modification, are permitted provided that the following conditions 94992Sgd78059 * are met: 104992Sgd78059 * 1. Redistributions of source code must retain the above copyright 114992Sgd78059 * notice, this list of conditions and the following disclaimer. 124992Sgd78059 * 2. Redistributions in binary form must reproduce the above copyright 134992Sgd78059 * notice, this list of conditions and the following disclaimer in the 144992Sgd78059 * documentation and/or other materials provided with the distribution. 154992Sgd78059 * 3. Neither the name of the author nor the names of any co-contributors 164992Sgd78059 * may be used to endorse or promote products derived from this software 174992Sgd78059 * without specific prior written permission. 184992Sgd78059 * 194992Sgd78059 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' 204992Sgd78059 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 214992Sgd78059 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 224992Sgd78059 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 234992Sgd78059 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 244992Sgd78059 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 254992Sgd78059 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 264992Sgd78059 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 274992Sgd78059 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 284992Sgd78059 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 294992Sgd78059 * POSSIBILITY OF SUCH DAMAGE. 304992Sgd78059 */ 316684Sgd78059 /* 32*9860Sgdamore@opensolaris.org * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 336684Sgd78059 * Use is subject to license terms. 346684Sgd78059 */ 354992Sgd78059 364992Sgd78059 #ifndef _AFEIMPL_H 374992Sgd78059 #define _AFEIMPL_H 384992Sgd78059 398275SEric Cheng #ifdef _KERNEL 404992Sgd78059 418275SEric Cheng #include <sys/mac_provider.h> 424992Sgd78059 434992Sgd78059 /* 444992Sgd78059 * Compile time tunables. 454992Sgd78059 */ 464992Sgd78059 #define AFE_RXRING 128 /* number of rcv buffers */ 474992Sgd78059 #define AFE_TXRING 128 /* number of xmt buffers */ 484992Sgd78059 #define AFE_TXRECLAIM 8 /* when to reclaim tx buffers (txavail) */ 494992Sgd78059 #define AFE_TXRESCHED 120 /* when to resched (txavail) */ 50*9860Sgdamore@opensolaris.org #define AFE_WDOGTIMER 5000 /* how often we check for tx hang (in msec) */ 514992Sgd78059 #define AFE_HEADROOM 34 /* headroom in packet (should be 2 modulo 4) */ 524992Sgd78059 534992Sgd78059 /* 544992Sgd78059 * Constants, do not change. 554992Sgd78059 */ 564992Sgd78059 #define AFE_BUFSZ (1664) /* big enough for a vlan frame */ 574992Sgd78059 #define AFE_MCHASH (64) 584992Sgd78059 594992Sgd78059 typedef struct afe afe_t; 604992Sgd78059 typedef struct afe_card afe_card_t; 614992Sgd78059 typedef struct afe_rxbuf afe_rxbuf_t; 624992Sgd78059 typedef struct afe_txbuf afe_txbuf_t; 634992Sgd78059 typedef struct afe_desc afe_desc_t; 644992Sgd78059 654992Sgd78059 /* 664992Sgd78059 * Card models. 674992Sgd78059 */ 684992Sgd78059 typedef enum { 694992Sgd78059 MODEL_CENTAUR = 1, 704992Sgd78059 MODEL_COMET, 714992Sgd78059 } afe_model_t; 724992Sgd78059 734992Sgd78059 struct afe_card { 744992Sgd78059 uint16_t card_venid; /* PCI vendor id */ 754992Sgd78059 uint16_t card_devid; /* PCI device id */ 764992Sgd78059 char *card_cardname; /* Description of the card */ 774992Sgd78059 afe_model_t card_model; /* Card specific flags */ 784992Sgd78059 }; 794992Sgd78059 804992Sgd78059 /* 814992Sgd78059 * Device instance structure, one per PCI card. 824992Sgd78059 */ 834992Sgd78059 struct afe { 844992Sgd78059 dev_info_t *afe_dip; 854992Sgd78059 mac_handle_t afe_mh; 86*9860Sgdamore@opensolaris.org mii_handle_t afe_mii; 874992Sgd78059 afe_card_t *afe_cardp; 884992Sgd78059 uint16_t afe_cachesize; 894992Sgd78059 uint8_t afe_sromwidth; 904992Sgd78059 int afe_flags; 914992Sgd78059 kmutex_t afe_xmtlock; 924992Sgd78059 kmutex_t afe_intrlock; 934992Sgd78059 ddi_iblock_cookie_t afe_icookie; 944992Sgd78059 954992Sgd78059 /* 964992Sgd78059 * Register and DMA access. 974992Sgd78059 */ 984992Sgd78059 uintptr_t afe_regs; 994992Sgd78059 ddi_acc_handle_t afe_regshandle; 1004992Sgd78059 1014992Sgd78059 /* 1024992Sgd78059 * Receive descriptors. 1034992Sgd78059 */ 1044992Sgd78059 int afe_rxhead; 1054992Sgd78059 struct afe_desc *afe_rxdescp; 1064992Sgd78059 ddi_dma_handle_t afe_rxdesc_dmah; 1074992Sgd78059 ddi_acc_handle_t afe_rxdesc_acch; 1084992Sgd78059 uint32_t afe_rxdesc_paddr; 1094992Sgd78059 struct afe_rxbuf **afe_rxbufs; 1104992Sgd78059 1114992Sgd78059 /* 1124992Sgd78059 * Transmit descriptors. 1134992Sgd78059 */ 1144992Sgd78059 int afe_txreclaim; 1154992Sgd78059 int afe_txsend; 1164992Sgd78059 int afe_txavail; 1174992Sgd78059 struct afe_desc *afe_txdescp; 1184992Sgd78059 ddi_dma_handle_t afe_txdesc_dmah; 1194992Sgd78059 ddi_acc_handle_t afe_txdesc_acch; 1204992Sgd78059 uint32_t afe_txdesc_paddr; 1214992Sgd78059 struct afe_txbuf **afe_txbufs; 1224992Sgd78059 hrtime_t afe_txstall_time; 1234992Sgd78059 boolean_t afe_wantw; 1244992Sgd78059 1254992Sgd78059 /* 1264992Sgd78059 * Transceiver stuff. 1274992Sgd78059 */ 1284992Sgd78059 int afe_phyaddr; 1294992Sgd78059 int afe_phyid; 1304992Sgd78059 int afe_phyinuse; 1316684Sgd78059 1324992Sgd78059 int afe_forcefiber; 1334992Sgd78059 1344992Sgd78059 /* 1354992Sgd78059 * Address management. 1364992Sgd78059 */ 1374992Sgd78059 uchar_t afe_curraddr[ETHERADDRL]; 1384992Sgd78059 boolean_t afe_promisc; 1394992Sgd78059 uint16_t afe_mccount[AFE_MCHASH]; 1404992Sgd78059 uint32_t afe_mctab[AFE_MCHASH / 32]; /* Centaur */ 1414992Sgd78059 1424992Sgd78059 /* 1434992Sgd78059 * Kstats. 1444992Sgd78059 */ 1454992Sgd78059 kstat_t *afe_intrstat; 1464992Sgd78059 uint64_t afe_ipackets; 1474992Sgd78059 uint64_t afe_opackets; 1484992Sgd78059 uint64_t afe_rbytes; 1494992Sgd78059 uint64_t afe_obytes; 1504992Sgd78059 uint64_t afe_brdcstxmt; 1514992Sgd78059 uint64_t afe_multixmt; 1524992Sgd78059 uint64_t afe_brdcstrcv; 1534992Sgd78059 uint64_t afe_multircv; 1544992Sgd78059 unsigned afe_norcvbuf; 1554992Sgd78059 unsigned afe_errrcv; 1564992Sgd78059 unsigned afe_errxmt; 1574992Sgd78059 unsigned afe_missed; 1584992Sgd78059 unsigned afe_underflow; 1594992Sgd78059 unsigned afe_overflow; 1604992Sgd78059 unsigned afe_align_errors; 1614992Sgd78059 unsigned afe_fcs_errors; 1624992Sgd78059 unsigned afe_carrier_errors; 1634992Sgd78059 unsigned afe_collisions; 1644992Sgd78059 unsigned afe_ex_collisions; 1654992Sgd78059 unsigned afe_tx_late_collisions; 1664992Sgd78059 unsigned afe_defer_xmts; 1674992Sgd78059 unsigned afe_first_collisions; 1684992Sgd78059 unsigned afe_multi_collisions; 1694992Sgd78059 unsigned afe_sqe_errors; 1704992Sgd78059 unsigned afe_macxmt_errors; 1714992Sgd78059 unsigned afe_macrcv_errors; 1724992Sgd78059 unsigned afe_toolong_errors; 1734992Sgd78059 unsigned afe_runt; 1744992Sgd78059 unsigned afe_jabber; 1754992Sgd78059 }; 1764992Sgd78059 1774992Sgd78059 struct afe_rxbuf { 1784992Sgd78059 caddr_t rxb_buf; 1794992Sgd78059 ddi_dma_handle_t rxb_dmah; 1804992Sgd78059 ddi_acc_handle_t rxb_acch; 1814992Sgd78059 uint32_t rxb_paddr; 1824992Sgd78059 }; 1834992Sgd78059 1844992Sgd78059 struct afe_txbuf { 1854992Sgd78059 caddr_t txb_buf; 1864992Sgd78059 uint32_t txb_paddr; 1874992Sgd78059 ddi_dma_handle_t txb_dmah; 1884992Sgd78059 ddi_acc_handle_t txb_acch; 1894992Sgd78059 }; 1904992Sgd78059 1914992Sgd78059 /* 1924992Sgd78059 * Descriptor. We use rings rather than chains. 1934992Sgd78059 */ 1944992Sgd78059 struct afe_desc { 1954992Sgd78059 unsigned desc_status; 1964992Sgd78059 unsigned desc_control; 1974992Sgd78059 unsigned desc_buffer1; 1984992Sgd78059 unsigned desc_buffer2; 1994992Sgd78059 }; 2004992Sgd78059 2014992Sgd78059 #define PUTTXDESC(afep, member, val) \ 2024992Sgd78059 ddi_put32(afep->afe_txdesc_acch, &member, val) 2034992Sgd78059 2044992Sgd78059 #define PUTRXDESC(afep, member, val) \ 2054992Sgd78059 ddi_put32(afep->afe_rxdesc_acch, &member, val) 2064992Sgd78059 2074992Sgd78059 #define GETTXDESC(afep, member) \ 2084992Sgd78059 ddi_get32(afep->afe_txdesc_acch, &member) 2094992Sgd78059 2104992Sgd78059 #define GETRXDESC(afep, member) \ 2114992Sgd78059 ddi_get32(afep->afe_rxdesc_acch, &member) 2124992Sgd78059 2134992Sgd78059 /* 2144992Sgd78059 * Receive descriptor fields. 2154992Sgd78059 */ 2164992Sgd78059 #define RXSTAT_OWN 0x80000000U /* ownership */ 2174992Sgd78059 #define RXSTAT_RXLEN 0x3FFF0000U /* frame length, incl. crc */ 2184992Sgd78059 #define RXSTAT_RXERR 0x00008000U /* error summary */ 2194992Sgd78059 #define RXSTAT_DESCERR 0x00004000U /* descriptor error */ 2204992Sgd78059 #define RXSTAT_RXTYPE 0x00003000U /* data type */ 2214992Sgd78059 #define RXSTAT_RUNT 0x00000800U /* runt frame */ 2224992Sgd78059 #define RXSTAT_GROUP 0x00000400U /* multicast/brdcast frame */ 2234992Sgd78059 #define RXSTAT_FIRST 0x00000200U /* first descriptor */ 2244992Sgd78059 #define RXSTAT_LAST 0x00000100U /* last descriptor */ 2254992Sgd78059 #define RXSTAT_TOOLONG 0x00000080U /* frame too long */ 2264992Sgd78059 #define RXSTAT_COLLSEEN 0x00000040U /* late collision seen */ 2274992Sgd78059 #define RXSTAT_FRTYPE 0x00000020U /* frame type */ 2284992Sgd78059 #define RXSTAT_WATCHDOG 0x00000010U /* receive watchdog */ 2294992Sgd78059 #define RXSTAT_DRIBBLE 0x00000004U /* dribbling bit */ 2304992Sgd78059 #define RXSTAT_CRCERR 0x00000002U /* crc error */ 2314992Sgd78059 #define RXSTAT_OFLOW 0x00000001U /* fifo overflow */ 2324992Sgd78059 #define RXSTAT_ERRS (RXSTAT_DESCERR | RXSTAT_RUNT | \ 2334992Sgd78059 RXSTAT_COLLSEEN | RXSTAT_DRIBBLE | \ 2344992Sgd78059 RXSTAT_CRCERR | RXSTAT_OFLOW) 2354992Sgd78059 #define RXLENGTH(x) ((x & RXSTAT_RXLEN) >> 16) 2364992Sgd78059 2374992Sgd78059 #define RXCTL_ENDRING 0x02000000U /* end of ring */ 2384992Sgd78059 #define RXCTL_CHAIN 0x01000000U /* chained descriptors */ 2394992Sgd78059 #define RXCTL_BUFLEN2 0x003FF800U /* buffer 2 length */ 2404992Sgd78059 #define RXCTL_BUFLEN1 0x000007FFU /* buffer 1 length */ 2414992Sgd78059 2424992Sgd78059 /* 2434992Sgd78059 * Transmit descriptor fields. 2444992Sgd78059 */ 2454992Sgd78059 #define TXSTAT_OWN 0x80000000U /* ownership */ 2464992Sgd78059 #define TXSTAT_URCNT 0x00C00000U /* underrun count */ 2474992Sgd78059 #define TXSTAT_TXERR 0x00008000U /* error summary */ 2484992Sgd78059 #define TXSTAT_JABBER 0x00004000U /* jabber timeout */ 2494992Sgd78059 #define TXSTAT_CARRLOST 0x00000800U /* lost carrier */ 2504992Sgd78059 #define TXSTAT_NOCARR 0x00000400U /* no carrier */ 2514992Sgd78059 #define TXSTAT_LATECOL 0x00000200U /* late collision */ 2524992Sgd78059 #define TXSTAT_EXCOLL 0x00000100U /* excessive collisions */ 2534992Sgd78059 #define TXSTAT_SQE 0x00000080U /* heartbeat failure */ 2544992Sgd78059 #define TXSTAT_COLLCNT 0x00000078U /* collision count */ 2554992Sgd78059 #define TXSTAT_UFLOW 0x00000002U /* underflow */ 2564992Sgd78059 #define TXSTAT_DEFER 0x00000001U /* deferred */ 2574992Sgd78059 #define TXCOLLCNT(x) ((x & TXSTAT_COLLCNT) >> 3) 2584992Sgd78059 #define TXUFLOWCNT(x) ((x & TXSTAT_URCNT) >> 22) 2594992Sgd78059 2604992Sgd78059 #define TXCTL_INTCMPLTE 0x80000000U /* interrupt completed */ 2614992Sgd78059 #define TXCTL_LAST 0x40000000U /* last descriptor */ 2624992Sgd78059 #define TXCTL_FIRST 0x20000000U /* first descriptor */ 2634992Sgd78059 #define TXCTL_NOCRC 0x04000000U /* disable crc */ 2644992Sgd78059 #define TXCTL_ENDRING 0x02000000U /* end of ring */ 2654992Sgd78059 #define TXCTL_CHAIN 0x01000000U /* chained descriptors */ 2664992Sgd78059 #define TXCTL_NOPAD 0x00800000U /* disable padding */ 2674992Sgd78059 #define TXCTL_HASHPERF 0x00400000U /* hash perfect mode */ 2684992Sgd78059 #define TXCTL_BUFLEN2 0x003FF800U /* buffer length 2 */ 2694992Sgd78059 #define TXCTL_BUFLEN1 0x000007FFU /* buffer length 1 */ 2704992Sgd78059 2714992Sgd78059 2724992Sgd78059 /* 2734992Sgd78059 * Interface flags. 2744992Sgd78059 */ 2754992Sgd78059 #define AFE_RUNNING 0x1 /* chip is initialized */ 2764992Sgd78059 #define AFE_SUSPENDED 0x2 /* interface is suspended */ 2774992Sgd78059 #define AFE_HASFIBER 0x4 /* internal phy supports fiber (AFE_PHY_MCR) */ 2784992Sgd78059 2794992Sgd78059 #define AFE_MODEL(afep) ((afep)->afe_cardp->card_model) 2804992Sgd78059 2814992Sgd78059 2824992Sgd78059 /* 2834992Sgd78059 * Register definitions located in afe.h exported header file. 2844992Sgd78059 */ 2854992Sgd78059 2864992Sgd78059 /* 2874992Sgd78059 * Macros to simplify hardware access. 2884992Sgd78059 */ 2894992Sgd78059 #define GETCSR(afep, reg) \ 2904992Sgd78059 ddi_get32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg)) 2914992Sgd78059 2924992Sgd78059 #define GETCSR16(afep, reg) \ 2934992Sgd78059 ddi_get16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg)) 2944992Sgd78059 2954992Sgd78059 #define PUTCSR(afep, reg, val) \ 2964992Sgd78059 ddi_put32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg), val) 2974992Sgd78059 2984992Sgd78059 #define PUTCSR16(afep, reg, val) \ 2994992Sgd78059 ddi_put16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg), val) 3004992Sgd78059 3014992Sgd78059 #define SETBIT(afep, reg, val) PUTCSR(afep, reg, GETCSR(afep, reg) | (val)) 3024992Sgd78059 3034992Sgd78059 #define CLRBIT(afep, reg, val) PUTCSR(afep, reg, GETCSR(afep, reg) & ~(val)) 3044992Sgd78059 3054992Sgd78059 #define SYNCTXDESC(afep, index, who) \ 3064992Sgd78059 (void) ddi_dma_sync(afep->afe_txdesc_dmah, \ 3074992Sgd78059 (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who) 3084992Sgd78059 3094992Sgd78059 #define SYNCTXBUF(txb, len, who) \ 3104992Sgd78059 (void) ddi_dma_sync(txb->txb_dmah, 0, len, who) 3114992Sgd78059 3124992Sgd78059 #define SYNCRXDESC(afep, index, who) \ 3134992Sgd78059 (void) ddi_dma_sync(afep->afe_rxdesc_dmah, \ 3144992Sgd78059 (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who) 3154992Sgd78059 3164992Sgd78059 #define SYNCRXBUF(rxb, len, who) \ 3174992Sgd78059 (void) ddi_dma_sync(rxb->rxb_dmah, 0, len, who) 3184992Sgd78059 3194992Sgd78059 #endif /* _KERNEL */ 3204992Sgd78059 3214992Sgd78059 #endif /* _AFEIMPL_H */ 322