1*4992Sgd78059 /* 2*4992Sgd78059 * Solaris driver for ethernet cards based on the ADMtek Centaur 3*4992Sgd78059 * 4*4992Sgd78059 * Copyright (c) 2007 by Garrett D'Amore <garrett@damore.org>. 5*4992Sgd78059 * All rights reserved. 6*4992Sgd78059 * 7*4992Sgd78059 * Redistribution and use in source and binary forms, with or without 8*4992Sgd78059 * modification, are permitted provided that the following conditions 9*4992Sgd78059 * are met: 10*4992Sgd78059 * 1. Redistributions of source code must retain the above copyright 11*4992Sgd78059 * notice, this list of conditions and the following disclaimer. 12*4992Sgd78059 * 2. Redistributions in binary form must reproduce the above copyright 13*4992Sgd78059 * notice, this list of conditions and the following disclaimer in the 14*4992Sgd78059 * documentation and/or other materials provided with the distribution. 15*4992Sgd78059 * 3. Neither the name of the author nor the names of any co-contributors 16*4992Sgd78059 * may be used to endorse or promote products derived from this software 17*4992Sgd78059 * without specific prior written permission. 18*4992Sgd78059 * 19*4992Sgd78059 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS'' 20*4992Sgd78059 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21*4992Sgd78059 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22*4992Sgd78059 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23*4992Sgd78059 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*4992Sgd78059 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*4992Sgd78059 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*4992Sgd78059 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*4992Sgd78059 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*4992Sgd78059 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*4992Sgd78059 * POSSIBILITY OF SUCH DAMAGE. 30*4992Sgd78059 */ 31*4992Sgd78059 32*4992Sgd78059 #ifndef _AFEIMPL_H 33*4992Sgd78059 #define _AFEIMPL_H 34*4992Sgd78059 35*4992Sgd78059 #pragma ident "%Z%%M% %I% %E% SMI" 36*4992Sgd78059 37*4992Sgd78059 #ifdef _KERNEL 38*4992Sgd78059 39*4992Sgd78059 /* 40*4992Sgd78059 * Compile time tunables. 41*4992Sgd78059 */ 42*4992Sgd78059 #define AFE_RXRING 128 /* number of rcv buffers */ 43*4992Sgd78059 #define AFE_TXRING 128 /* number of xmt buffers */ 44*4992Sgd78059 #define AFE_TXRECLAIM 8 /* when to reclaim tx buffers (txavail) */ 45*4992Sgd78059 #define AFE_TXRESCHED 120 /* when to resched (txavail) */ 46*4992Sgd78059 #define AFE_LINKTIMER 5000 /* how often we check link state (in msec) */ 47*4992Sgd78059 #define AFE_HEADROOM 34 /* headroom in packet (should be 2 modulo 4) */ 48*4992Sgd78059 49*4992Sgd78059 /* 50*4992Sgd78059 * Constants, do not change. 51*4992Sgd78059 */ 52*4992Sgd78059 #define AFE_BUFSZ (1664) /* big enough for a vlan frame */ 53*4992Sgd78059 #define AFE_MCHASH (64) 54*4992Sgd78059 55*4992Sgd78059 typedef struct afe afe_t; 56*4992Sgd78059 typedef struct afe_card afe_card_t; 57*4992Sgd78059 typedef struct afe_nd afe_nd_t; 58*4992Sgd78059 typedef struct afe_rxbuf afe_rxbuf_t; 59*4992Sgd78059 typedef struct afe_txbuf afe_txbuf_t; 60*4992Sgd78059 typedef struct afe_desc afe_desc_t; 61*4992Sgd78059 typedef int (*afe_nd_pf_t)(afe_t *, mblk_t *, afe_nd_t *); 62*4992Sgd78059 63*4992Sgd78059 /* 64*4992Sgd78059 * Card models. 65*4992Sgd78059 */ 66*4992Sgd78059 typedef enum { 67*4992Sgd78059 MODEL_CENTAUR = 1, 68*4992Sgd78059 MODEL_COMET, 69*4992Sgd78059 } afe_model_t; 70*4992Sgd78059 71*4992Sgd78059 struct afe_card { 72*4992Sgd78059 uint16_t card_venid; /* PCI vendor id */ 73*4992Sgd78059 uint16_t card_devid; /* PCI device id */ 74*4992Sgd78059 char *card_cardname; /* Description of the card */ 75*4992Sgd78059 afe_model_t card_model; /* Card specific flags */ 76*4992Sgd78059 }; 77*4992Sgd78059 78*4992Sgd78059 struct afe_nd { 79*4992Sgd78059 afe_nd_t *nd_next; 80*4992Sgd78059 char *nd_name; 81*4992Sgd78059 afe_nd_pf_t nd_get; 82*4992Sgd78059 afe_nd_pf_t nd_set; 83*4992Sgd78059 intptr_t nd_arg1; 84*4992Sgd78059 intptr_t nd_arg2; 85*4992Sgd78059 }; 86*4992Sgd78059 87*4992Sgd78059 /* 88*4992Sgd78059 * Device instance structure, one per PCI card. 89*4992Sgd78059 */ 90*4992Sgd78059 struct afe { 91*4992Sgd78059 dev_info_t *afe_dip; 92*4992Sgd78059 mac_handle_t afe_mh; 93*4992Sgd78059 afe_card_t *afe_cardp; 94*4992Sgd78059 uint16_t afe_cachesize; 95*4992Sgd78059 uint8_t afe_sromwidth; 96*4992Sgd78059 int afe_flags; 97*4992Sgd78059 kmutex_t afe_xmtlock; 98*4992Sgd78059 kmutex_t afe_intrlock; 99*4992Sgd78059 ddi_iblock_cookie_t afe_icookie; 100*4992Sgd78059 101*4992Sgd78059 /* 102*4992Sgd78059 * Register and DMA access. 103*4992Sgd78059 */ 104*4992Sgd78059 uintptr_t afe_regs; 105*4992Sgd78059 ddi_acc_handle_t afe_regshandle; 106*4992Sgd78059 107*4992Sgd78059 /* 108*4992Sgd78059 * Receive descriptors. 109*4992Sgd78059 */ 110*4992Sgd78059 int afe_rxhead; 111*4992Sgd78059 struct afe_desc *afe_rxdescp; 112*4992Sgd78059 ddi_dma_handle_t afe_rxdesc_dmah; 113*4992Sgd78059 ddi_acc_handle_t afe_rxdesc_acch; 114*4992Sgd78059 uint32_t afe_rxdesc_paddr; 115*4992Sgd78059 struct afe_rxbuf **afe_rxbufs; 116*4992Sgd78059 117*4992Sgd78059 /* 118*4992Sgd78059 * Transmit descriptors. 119*4992Sgd78059 */ 120*4992Sgd78059 int afe_txreclaim; 121*4992Sgd78059 int afe_txsend; 122*4992Sgd78059 int afe_txavail; 123*4992Sgd78059 struct afe_desc *afe_txdescp; 124*4992Sgd78059 ddi_dma_handle_t afe_txdesc_dmah; 125*4992Sgd78059 ddi_acc_handle_t afe_txdesc_acch; 126*4992Sgd78059 uint32_t afe_txdesc_paddr; 127*4992Sgd78059 struct afe_txbuf **afe_txbufs; 128*4992Sgd78059 hrtime_t afe_txstall_time; 129*4992Sgd78059 boolean_t afe_wantw; 130*4992Sgd78059 131*4992Sgd78059 /* 132*4992Sgd78059 * Link state. 133*4992Sgd78059 */ 134*4992Sgd78059 int afe_lastifspeed; 135*4992Sgd78059 int afe_lastduplex; 136*4992Sgd78059 int afe_linkup; 137*4992Sgd78059 int afe_duplex; 138*4992Sgd78059 int afe_ifspeed; 139*4992Sgd78059 boolean_t afe_resetting; /* no link warning */ 140*4992Sgd78059 141*4992Sgd78059 /* 142*4992Sgd78059 * NDD related support. 143*4992Sgd78059 */ 144*4992Sgd78059 afe_nd_t *afe_ndp; 145*4992Sgd78059 146*4992Sgd78059 /* 147*4992Sgd78059 * Transceiver stuff. 148*4992Sgd78059 */ 149*4992Sgd78059 int afe_phyaddr; 150*4992Sgd78059 int afe_phyid; 151*4992Sgd78059 int afe_phyinuse; 152*4992Sgd78059 int afe_adv_aneg; 153*4992Sgd78059 int afe_adv_100T4; 154*4992Sgd78059 int afe_adv_100fdx; 155*4992Sgd78059 int afe_adv_100hdx; 156*4992Sgd78059 int afe_adv_10fdx; 157*4992Sgd78059 int afe_adv_10hdx; 158*4992Sgd78059 int afe_forcephy; 159*4992Sgd78059 int afe_forcefiber; 160*4992Sgd78059 161*4992Sgd78059 /* 162*4992Sgd78059 * Address management. 163*4992Sgd78059 */ 164*4992Sgd78059 uchar_t afe_curraddr[ETHERADDRL]; 165*4992Sgd78059 boolean_t afe_promisc; 166*4992Sgd78059 uint16_t afe_mccount[AFE_MCHASH]; 167*4992Sgd78059 uint32_t afe_mctab[AFE_MCHASH / 32]; /* Centaur */ 168*4992Sgd78059 169*4992Sgd78059 /* 170*4992Sgd78059 * Kstats. 171*4992Sgd78059 */ 172*4992Sgd78059 kstat_t *afe_intrstat; 173*4992Sgd78059 uint64_t afe_ipackets; 174*4992Sgd78059 uint64_t afe_opackets; 175*4992Sgd78059 uint64_t afe_rbytes; 176*4992Sgd78059 uint64_t afe_obytes; 177*4992Sgd78059 uint64_t afe_brdcstxmt; 178*4992Sgd78059 uint64_t afe_multixmt; 179*4992Sgd78059 uint64_t afe_brdcstrcv; 180*4992Sgd78059 uint64_t afe_multircv; 181*4992Sgd78059 unsigned afe_norcvbuf; 182*4992Sgd78059 unsigned afe_errrcv; 183*4992Sgd78059 unsigned afe_errxmt; 184*4992Sgd78059 unsigned afe_missed; 185*4992Sgd78059 unsigned afe_underflow; 186*4992Sgd78059 unsigned afe_overflow; 187*4992Sgd78059 unsigned afe_align_errors; 188*4992Sgd78059 unsigned afe_fcs_errors; 189*4992Sgd78059 unsigned afe_carrier_errors; 190*4992Sgd78059 unsigned afe_collisions; 191*4992Sgd78059 unsigned afe_ex_collisions; 192*4992Sgd78059 unsigned afe_tx_late_collisions; 193*4992Sgd78059 unsigned afe_defer_xmts; 194*4992Sgd78059 unsigned afe_first_collisions; 195*4992Sgd78059 unsigned afe_multi_collisions; 196*4992Sgd78059 unsigned afe_sqe_errors; 197*4992Sgd78059 unsigned afe_macxmt_errors; 198*4992Sgd78059 unsigned afe_macrcv_errors; 199*4992Sgd78059 unsigned afe_toolong_errors; 200*4992Sgd78059 unsigned afe_runt; 201*4992Sgd78059 unsigned afe_jabber; 202*4992Sgd78059 }; 203*4992Sgd78059 204*4992Sgd78059 struct afe_rxbuf { 205*4992Sgd78059 caddr_t rxb_buf; 206*4992Sgd78059 ddi_dma_handle_t rxb_dmah; 207*4992Sgd78059 ddi_acc_handle_t rxb_acch; 208*4992Sgd78059 uint32_t rxb_paddr; 209*4992Sgd78059 }; 210*4992Sgd78059 211*4992Sgd78059 struct afe_txbuf { 212*4992Sgd78059 caddr_t txb_buf; 213*4992Sgd78059 uint32_t txb_paddr; 214*4992Sgd78059 ddi_dma_handle_t txb_dmah; 215*4992Sgd78059 ddi_acc_handle_t txb_acch; 216*4992Sgd78059 }; 217*4992Sgd78059 218*4992Sgd78059 /* 219*4992Sgd78059 * Descriptor. We use rings rather than chains. 220*4992Sgd78059 */ 221*4992Sgd78059 struct afe_desc { 222*4992Sgd78059 unsigned desc_status; 223*4992Sgd78059 unsigned desc_control; 224*4992Sgd78059 unsigned desc_buffer1; 225*4992Sgd78059 unsigned desc_buffer2; 226*4992Sgd78059 }; 227*4992Sgd78059 228*4992Sgd78059 #define PUTTXDESC(afep, member, val) \ 229*4992Sgd78059 ddi_put32(afep->afe_txdesc_acch, &member, val) 230*4992Sgd78059 231*4992Sgd78059 #define PUTRXDESC(afep, member, val) \ 232*4992Sgd78059 ddi_put32(afep->afe_rxdesc_acch, &member, val) 233*4992Sgd78059 234*4992Sgd78059 #define GETTXDESC(afep, member) \ 235*4992Sgd78059 ddi_get32(afep->afe_txdesc_acch, &member) 236*4992Sgd78059 237*4992Sgd78059 #define GETRXDESC(afep, member) \ 238*4992Sgd78059 ddi_get32(afep->afe_rxdesc_acch, &member) 239*4992Sgd78059 240*4992Sgd78059 /* 241*4992Sgd78059 * Receive descriptor fields. 242*4992Sgd78059 */ 243*4992Sgd78059 #define RXSTAT_OWN 0x80000000U /* ownership */ 244*4992Sgd78059 #define RXSTAT_RXLEN 0x3FFF0000U /* frame length, incl. crc */ 245*4992Sgd78059 #define RXSTAT_RXERR 0x00008000U /* error summary */ 246*4992Sgd78059 #define RXSTAT_DESCERR 0x00004000U /* descriptor error */ 247*4992Sgd78059 #define RXSTAT_RXTYPE 0x00003000U /* data type */ 248*4992Sgd78059 #define RXSTAT_RUNT 0x00000800U /* runt frame */ 249*4992Sgd78059 #define RXSTAT_GROUP 0x00000400U /* multicast/brdcast frame */ 250*4992Sgd78059 #define RXSTAT_FIRST 0x00000200U /* first descriptor */ 251*4992Sgd78059 #define RXSTAT_LAST 0x00000100U /* last descriptor */ 252*4992Sgd78059 #define RXSTAT_TOOLONG 0x00000080U /* frame too long */ 253*4992Sgd78059 #define RXSTAT_COLLSEEN 0x00000040U /* late collision seen */ 254*4992Sgd78059 #define RXSTAT_FRTYPE 0x00000020U /* frame type */ 255*4992Sgd78059 #define RXSTAT_WATCHDOG 0x00000010U /* receive watchdog */ 256*4992Sgd78059 #define RXSTAT_DRIBBLE 0x00000004U /* dribbling bit */ 257*4992Sgd78059 #define RXSTAT_CRCERR 0x00000002U /* crc error */ 258*4992Sgd78059 #define RXSTAT_OFLOW 0x00000001U /* fifo overflow */ 259*4992Sgd78059 #define RXSTAT_ERRS (RXSTAT_DESCERR | RXSTAT_RUNT | \ 260*4992Sgd78059 RXSTAT_COLLSEEN | RXSTAT_DRIBBLE | \ 261*4992Sgd78059 RXSTAT_CRCERR | RXSTAT_OFLOW) 262*4992Sgd78059 #define RXLENGTH(x) ((x & RXSTAT_RXLEN) >> 16) 263*4992Sgd78059 264*4992Sgd78059 #define RXCTL_ENDRING 0x02000000U /* end of ring */ 265*4992Sgd78059 #define RXCTL_CHAIN 0x01000000U /* chained descriptors */ 266*4992Sgd78059 #define RXCTL_BUFLEN2 0x003FF800U /* buffer 2 length */ 267*4992Sgd78059 #define RXCTL_BUFLEN1 0x000007FFU /* buffer 1 length */ 268*4992Sgd78059 269*4992Sgd78059 /* 270*4992Sgd78059 * Transmit descriptor fields. 271*4992Sgd78059 */ 272*4992Sgd78059 #define TXSTAT_OWN 0x80000000U /* ownership */ 273*4992Sgd78059 #define TXSTAT_URCNT 0x00C00000U /* underrun count */ 274*4992Sgd78059 #define TXSTAT_TXERR 0x00008000U /* error summary */ 275*4992Sgd78059 #define TXSTAT_JABBER 0x00004000U /* jabber timeout */ 276*4992Sgd78059 #define TXSTAT_CARRLOST 0x00000800U /* lost carrier */ 277*4992Sgd78059 #define TXSTAT_NOCARR 0x00000400U /* no carrier */ 278*4992Sgd78059 #define TXSTAT_LATECOL 0x00000200U /* late collision */ 279*4992Sgd78059 #define TXSTAT_EXCOLL 0x00000100U /* excessive collisions */ 280*4992Sgd78059 #define TXSTAT_SQE 0x00000080U /* heartbeat failure */ 281*4992Sgd78059 #define TXSTAT_COLLCNT 0x00000078U /* collision count */ 282*4992Sgd78059 #define TXSTAT_UFLOW 0x00000002U /* underflow */ 283*4992Sgd78059 #define TXSTAT_DEFER 0x00000001U /* deferred */ 284*4992Sgd78059 #define TXCOLLCNT(x) ((x & TXSTAT_COLLCNT) >> 3) 285*4992Sgd78059 #define TXUFLOWCNT(x) ((x & TXSTAT_URCNT) >> 22) 286*4992Sgd78059 287*4992Sgd78059 #define TXCTL_INTCMPLTE 0x80000000U /* interrupt completed */ 288*4992Sgd78059 #define TXCTL_LAST 0x40000000U /* last descriptor */ 289*4992Sgd78059 #define TXCTL_FIRST 0x20000000U /* first descriptor */ 290*4992Sgd78059 #define TXCTL_NOCRC 0x04000000U /* disable crc */ 291*4992Sgd78059 #define TXCTL_ENDRING 0x02000000U /* end of ring */ 292*4992Sgd78059 #define TXCTL_CHAIN 0x01000000U /* chained descriptors */ 293*4992Sgd78059 #define TXCTL_NOPAD 0x00800000U /* disable padding */ 294*4992Sgd78059 #define TXCTL_HASHPERF 0x00400000U /* hash perfect mode */ 295*4992Sgd78059 #define TXCTL_BUFLEN2 0x003FF800U /* buffer length 2 */ 296*4992Sgd78059 #define TXCTL_BUFLEN1 0x000007FFU /* buffer length 1 */ 297*4992Sgd78059 298*4992Sgd78059 299*4992Sgd78059 /* 300*4992Sgd78059 * Interface flags. 301*4992Sgd78059 */ 302*4992Sgd78059 #define AFE_RUNNING 0x1 /* chip is initialized */ 303*4992Sgd78059 #define AFE_SUSPENDED 0x2 /* interface is suspended */ 304*4992Sgd78059 #define AFE_HASFIBER 0x4 /* internal phy supports fiber (AFE_PHY_MCR) */ 305*4992Sgd78059 306*4992Sgd78059 #define AFE_MODEL(afep) ((afep)->afe_cardp->card_model) 307*4992Sgd78059 308*4992Sgd78059 309*4992Sgd78059 /* 310*4992Sgd78059 * Register definitions located in afe.h exported header file. 311*4992Sgd78059 */ 312*4992Sgd78059 313*4992Sgd78059 /* 314*4992Sgd78059 * Macros to simplify hardware access. 315*4992Sgd78059 */ 316*4992Sgd78059 #define GETCSR(afep, reg) \ 317*4992Sgd78059 ddi_get32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg)) 318*4992Sgd78059 319*4992Sgd78059 #define GETCSR16(afep, reg) \ 320*4992Sgd78059 ddi_get16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg)) 321*4992Sgd78059 322*4992Sgd78059 #define PUTCSR(afep, reg, val) \ 323*4992Sgd78059 ddi_put32(afep->afe_regshandle, (uint32_t *)(afep->afe_regs + reg), val) 324*4992Sgd78059 325*4992Sgd78059 #define PUTCSR16(afep, reg, val) \ 326*4992Sgd78059 ddi_put16(afep->afe_regshandle, (uint16_t *)(afep->afe_regs + reg), val) 327*4992Sgd78059 328*4992Sgd78059 #define SETBIT(afep, reg, val) PUTCSR(afep, reg, GETCSR(afep, reg) | (val)) 329*4992Sgd78059 330*4992Sgd78059 #define CLRBIT(afep, reg, val) PUTCSR(afep, reg, GETCSR(afep, reg) & ~(val)) 331*4992Sgd78059 332*4992Sgd78059 #define SYNCTXDESC(afep, index, who) \ 333*4992Sgd78059 (void) ddi_dma_sync(afep->afe_txdesc_dmah, \ 334*4992Sgd78059 (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who) 335*4992Sgd78059 336*4992Sgd78059 #define SYNCTXBUF(txb, len, who) \ 337*4992Sgd78059 (void) ddi_dma_sync(txb->txb_dmah, 0, len, who) 338*4992Sgd78059 339*4992Sgd78059 #define SYNCRXDESC(afep, index, who) \ 340*4992Sgd78059 (void) ddi_dma_sync(afep->afe_rxdesc_dmah, \ 341*4992Sgd78059 (index * sizeof (afe_desc_t)), sizeof (afe_desc_t), who) 342*4992Sgd78059 343*4992Sgd78059 #define SYNCRXBUF(rxb, len, who) \ 344*4992Sgd78059 (void) ddi_dma_sync(rxb->rxb_dmah, 0, len, who) 345*4992Sgd78059 346*4992Sgd78059 /* 347*4992Sgd78059 * Debugging flags. 348*4992Sgd78059 */ 349*4992Sgd78059 #define DWARN 0x0001 350*4992Sgd78059 #define DINTR 0x0002 351*4992Sgd78059 #define DMACID 0x0008 352*4992Sgd78059 #define DPHY 0x0020 353*4992Sgd78059 #define DPCI 0x0040 354*4992Sgd78059 #define DCHATTY 0x0080 355*4992Sgd78059 #define DDMA 0x0100 356*4992Sgd78059 #define DLINK 0x0200 357*4992Sgd78059 #define DSROM 0x0400 358*4992Sgd78059 #define DRECV 0x0800 359*4992Sgd78059 #define DXMIT 0x1000 360*4992Sgd78059 361*4992Sgd78059 #ifdef DEBUG 362*4992Sgd78059 #define DBG(lvl, ...) afe_dprintf(afep, __func__, lvl, __VA_ARGS__) 363*4992Sgd78059 #else 364*4992Sgd78059 #define DBG(lvl, ...) 365*4992Sgd78059 #endif 366*4992Sgd78059 367*4992Sgd78059 #endif /* _KERNEL */ 368*4992Sgd78059 369*4992Sgd78059 #endif /* _AFEIMPL_H */ 370