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