1*cbe0a0c4SAugustin Cavalier /* 2*cbe0a0c4SAugustin Cavalier * Copyright (c) 2003-2004 Stefano Ceccherini (stefano.ceccherini@gmail.com) 3*cbe0a0c4SAugustin Cavalier * Copyright (c) 1997, 1998 4*cbe0a0c4SAugustin Cavalier * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 5*cbe0a0c4SAugustin Cavalier * 6*cbe0a0c4SAugustin Cavalier * Redistribution and use in source and binary forms, with or without 7*cbe0a0c4SAugustin Cavalier * modification, are permitted provided that the following conditions 8*cbe0a0c4SAugustin Cavalier * are met: 9*cbe0a0c4SAugustin Cavalier * 1. Redistributions of source code must retain the above copyright 10*cbe0a0c4SAugustin Cavalier * notice, this list of conditions and the following disclaimer. 11*cbe0a0c4SAugustin Cavalier * 2. Redistributions in binary form must reproduce the above copyright 12*cbe0a0c4SAugustin Cavalier * notice, this list of conditions and the following disclaimer in the 13*cbe0a0c4SAugustin Cavalier * documentation and/or other materials provided with the distribution. 14*cbe0a0c4SAugustin Cavalier * 3. All advertising materials mentioning features or use of this software 15*cbe0a0c4SAugustin Cavalier * must display the following acknowledgement: 16*cbe0a0c4SAugustin Cavalier * This product includes software developed by Bill Paul. 17*cbe0a0c4SAugustin Cavalier * 4. Neither the name of the author nor the names of any co-contributors 18*cbe0a0c4SAugustin Cavalier * may be used to endorse or promote products derived from this software 19*cbe0a0c4SAugustin Cavalier * without specific prior written permission. 20*cbe0a0c4SAugustin Cavalier * 21*cbe0a0c4SAugustin Cavalier * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 22*cbe0a0c4SAugustin Cavalier * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23*cbe0a0c4SAugustin Cavalier * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24*cbe0a0c4SAugustin Cavalier * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 25*cbe0a0c4SAugustin Cavalier * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26*cbe0a0c4SAugustin Cavalier * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27*cbe0a0c4SAugustin Cavalier * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28*cbe0a0c4SAugustin Cavalier * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29*cbe0a0c4SAugustin Cavalier * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30*cbe0a0c4SAugustin Cavalier * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 31*cbe0a0c4SAugustin Cavalier * THE POSSIBILITY OF SUCH DAMAGE. 32*cbe0a0c4SAugustin Cavalier * 33*cbe0a0c4SAugustin Cavalier */ 34*cbe0a0c4SAugustin Cavalier 35*cbe0a0c4SAugustin Cavalier #ifndef __WB840_H 36*cbe0a0c4SAugustin Cavalier #define __WB840_H 37*cbe0a0c4SAugustin Cavalier 38*cbe0a0c4SAugustin Cavalier #include <PCI.h> 39*cbe0a0c4SAugustin Cavalier #include <KernelExport.h> 40*cbe0a0c4SAugustin Cavalier #include "ether_driver.h" 41*cbe0a0c4SAugustin Cavalier 42*cbe0a0c4SAugustin Cavalier /* 43*cbe0a0c4SAugustin Cavalier * Winbond register definitions. 44*cbe0a0c4SAugustin Cavalier */ 45*cbe0a0c4SAugustin Cavalier enum registers { 46*cbe0a0c4SAugustin Cavalier WB_BUSCTL = 0x00, /* bus control */ 47*cbe0a0c4SAugustin Cavalier WB_TXSTART = 0x04, /* tx start demand */ 48*cbe0a0c4SAugustin Cavalier WB_RXSTART = 0x08, /* rx start demand */ 49*cbe0a0c4SAugustin Cavalier WB_RXADDR = 0x0C, /* rx descriptor list start addr */ 50*cbe0a0c4SAugustin Cavalier WB_TXADDR = 0x10, /* tx descriptor list start addr */ 51*cbe0a0c4SAugustin Cavalier WB_ISR = 0x14, /* interrupt status register */ 52*cbe0a0c4SAugustin Cavalier WB_NETCFG = 0x18, /* network config register */ 53*cbe0a0c4SAugustin Cavalier WB_IMR = 0x1C, /* interrupt mask */ 54*cbe0a0c4SAugustin Cavalier WB_FRAMESDISCARDED = 0x20, /* # of discarded frames */ 55*cbe0a0c4SAugustin Cavalier WB_SIO = 0x24, /* MII and ROM/EEPROM access */ 56*cbe0a0c4SAugustin Cavalier WB_BOOTROMADDR = 0x28, 57*cbe0a0c4SAugustin Cavalier WB_TIMER = 0x2C, /* general timer */ 58*cbe0a0c4SAugustin Cavalier WB_CURRXCTL = 0x30, /* current RX descriptor */ 59*cbe0a0c4SAugustin Cavalier WB_CURRXBUF = 0x34, /* current RX buffer */ 60*cbe0a0c4SAugustin Cavalier WB_MAR0 = 0x38, /* multicast filter 0 */ 61*cbe0a0c4SAugustin Cavalier WB_MAR1 = 0x3C, /* multicast filter 1 */ 62*cbe0a0c4SAugustin Cavalier WB_NODE0 = 0x40, /* physical address 0 */ 63*cbe0a0c4SAugustin Cavalier WB_NODE1 = 0x44, /* physical address 1 */ 64*cbe0a0c4SAugustin Cavalier WB_BOOTROMSIZE = 0x48, /* boot ROM size */ 65*cbe0a0c4SAugustin Cavalier WB_CURTXCTL = 0x4C, /* current TX descriptor */ 66*cbe0a0c4SAugustin Cavalier WB_CURTXBUF = 0x50, /* current TX buffer */ 67*cbe0a0c4SAugustin Cavalier }; 68*cbe0a0c4SAugustin Cavalier 69*cbe0a0c4SAugustin Cavalier /* 70*cbe0a0c4SAugustin Cavalier * Bus control bits. 71*cbe0a0c4SAugustin Cavalier */ 72*cbe0a0c4SAugustin Cavalier enum busControlBits { 73*cbe0a0c4SAugustin Cavalier WB_BUSCTL_RESET = 0x00000001, 74*cbe0a0c4SAugustin Cavalier WB_BUSCTL_ARBITRATION = 0x00000002, 75*cbe0a0c4SAugustin Cavalier WB_BUSCTL_SKIPLEN = 0x0000007C, 76*cbe0a0c4SAugustin Cavalier WB_BUSCTL_BUF_BIGENDIAN = 0x00000080, 77*cbe0a0c4SAugustin Cavalier WB_BUSCTL_BURSTLEN = 0x00003F00, 78*cbe0a0c4SAugustin Cavalier WB_BUSCTL_CACHEALIGN = 0x0000C000, 79*cbe0a0c4SAugustin Cavalier WB_BUSCTL_DES_BIGENDIAN = 0x00100000, 80*cbe0a0c4SAugustin Cavalier WB_BUSCTL_WAIT = 0x00200000, 81*cbe0a0c4SAugustin Cavalier WB_BUSCTL_MUSTBEONE = 0x00400000, 82*cbe0a0c4SAugustin Cavalier 83*cbe0a0c4SAugustin Cavalier WB_SKIPLEN_1LONG = 0x00000004, 84*cbe0a0c4SAugustin Cavalier WB_SKIPLEN_2LONG = 0x00000008, 85*cbe0a0c4SAugustin Cavalier WB_SKIPLEN_3LONG = 0x00000010, 86*cbe0a0c4SAugustin Cavalier WB_SKIPLEN_4LONG = 0x00000020, 87*cbe0a0c4SAugustin Cavalier WB_SKIPLEN_5LONG = 0x00000040, 88*cbe0a0c4SAugustin Cavalier 89*cbe0a0c4SAugustin Cavalier WB_CACHEALIGN_NONE = 0x00000000, 90*cbe0a0c4SAugustin Cavalier WB_CACHEALIGN_8LONG = 0x00004000, 91*cbe0a0c4SAugustin Cavalier WB_CACHEALIGN_16LONG = 0x00008000, 92*cbe0a0c4SAugustin Cavalier WB_CACHEALIGN_32LONG = 0x0000C000, 93*cbe0a0c4SAugustin Cavalier 94*cbe0a0c4SAugustin Cavalier WB_BURSTLEN_USECA = 0x00000000, 95*cbe0a0c4SAugustin Cavalier WB_BURSTLEN_1LONG = 0x00000100, 96*cbe0a0c4SAugustin Cavalier WB_BURSTLEN_2LONG = 0x00000200, 97*cbe0a0c4SAugustin Cavalier WB_BURSTLEN_4LONG = 0x00000400, 98*cbe0a0c4SAugustin Cavalier WB_BURSTLEN_8LONG = 0x00000800, 99*cbe0a0c4SAugustin Cavalier WB_BURSTLEN_16LONG = 0x00001000, 100*cbe0a0c4SAugustin Cavalier WB_BURSTLEN_32LONG = 0x00002000, 101*cbe0a0c4SAugustin Cavalier 102*cbe0a0c4SAugustin Cavalier }; 103*cbe0a0c4SAugustin Cavalier 104*cbe0a0c4SAugustin Cavalier #define WB_BUSCTL_CONFIG (WB_CACHEALIGN_8LONG|WB_SKIPLEN_4LONG|WB_BURSTLEN_8LONG) 105*cbe0a0c4SAugustin Cavalier 106*cbe0a0c4SAugustin Cavalier /* 107*cbe0a0c4SAugustin Cavalier * Interrupt status bits. 108*cbe0a0c4SAugustin Cavalier */ 109*cbe0a0c4SAugustin Cavalier enum InterruptStatusBits { 110*cbe0a0c4SAugustin Cavalier WB_ISR_TX_OK = 0x00000001, 111*cbe0a0c4SAugustin Cavalier WB_ISR_TX_IDLE = 0x00000002, 112*cbe0a0c4SAugustin Cavalier WB_ISR_TX_NOBUF = 0x00000004, 113*cbe0a0c4SAugustin Cavalier WB_ISR_RX_EARLY = 0x00000008, 114*cbe0a0c4SAugustin Cavalier WB_ISR_RX_ERR = 0x00000010, 115*cbe0a0c4SAugustin Cavalier WB_ISR_TX_UNDERRUN = 0x00000020, 116*cbe0a0c4SAugustin Cavalier WB_ISR_RX_OK = 0x00000040, 117*cbe0a0c4SAugustin Cavalier WB_ISR_RX_NOBUF = 0x00000080, 118*cbe0a0c4SAugustin Cavalier WB_ISR_RX_IDLE = 0x00000100, 119*cbe0a0c4SAugustin Cavalier WB_ISR_TX_EARLY = 0x00000400, 120*cbe0a0c4SAugustin Cavalier WB_ISR_TIMER_EXPIRED = 0x00000800, 121*cbe0a0c4SAugustin Cavalier WB_ISR_BUS_ERR = 0x00002000, 122*cbe0a0c4SAugustin Cavalier WB_ISR_ABNORMAL = 0x00008000, 123*cbe0a0c4SAugustin Cavalier WB_ISR_NORMAL = 0x00010000, 124*cbe0a0c4SAugustin Cavalier WB_ISR_RX_STATE = 0x000E0000, 125*cbe0a0c4SAugustin Cavalier WB_ISR_TX_STATE = 0x00700000, 126*cbe0a0c4SAugustin Cavalier WB_ISR_BUSERRTYPE = 0x03800000, 127*cbe0a0c4SAugustin Cavalier }; 128*cbe0a0c4SAugustin Cavalier 129*cbe0a0c4SAugustin Cavalier /* 130*cbe0a0c4SAugustin Cavalier * The RX_STATE and TX_STATE fields are not described anywhere in the 131*cbe0a0c4SAugustin Cavalier * Winbond datasheet, however it appears that the Winbond chip is an 132*cbe0a0c4SAugustin Cavalier * attempt at a DEC 'tulip' clone, hence the ISR register is identical 133*cbe0a0c4SAugustin Cavalier * to that of the tulip chip and we can steal the bit definitions from 134*cbe0a0c4SAugustin Cavalier * the tulip documentation. 135*cbe0a0c4SAugustin Cavalier */ 136*cbe0a0c4SAugustin Cavalier enum rxState { 137*cbe0a0c4SAugustin Cavalier WB_RXSTATE_STOPPED = 0x00000000, /* 000 - Stopped */ 138*cbe0a0c4SAugustin Cavalier WB_RXSTATE_FETCH = 0x00020000, /* 001 - Fetching descriptor */ 139*cbe0a0c4SAugustin Cavalier WB_RXSTATE_ENDCHECK = 0x00040000, /* 010 - check for rx end */ 140*cbe0a0c4SAugustin Cavalier WB_RXSTATE_WAIT = 0x00060000, /* 011 - waiting for packet */ 141*cbe0a0c4SAugustin Cavalier WB_RXSTATE_SUSPEND = 0x00080000, /* 100 - suspend rx */ 142*cbe0a0c4SAugustin Cavalier WB_RXSTATE_CLOSE = 0x000A0000, /* 101 - close tx desc */ 143*cbe0a0c4SAugustin Cavalier WB_RXSTATE_FLUSH = 0x000C0000, /* 110 - flush from FIFO */ 144*cbe0a0c4SAugustin Cavalier WB_RXSTATE_DEQUEUE = 0x000E0000, /* 111 - dequeue from FIFO */ 145*cbe0a0c4SAugustin Cavalier }; 146*cbe0a0c4SAugustin Cavalier 147*cbe0a0c4SAugustin Cavalier enum txState { 148*cbe0a0c4SAugustin Cavalier WB_TXSTATE_RESET = 0x00000000, /* 000 - reset */ 149*cbe0a0c4SAugustin Cavalier WB_TXSTATE_FETCH = 0x00100000, /* 001 - fetching descriptor */ 150*cbe0a0c4SAugustin Cavalier WB_TXSTATE_WAITEND = 0x00200000, /* 010 - wait for tx end */ 151*cbe0a0c4SAugustin Cavalier WB_TXSTATE_READING = 0x00300000, /* 011 - read and enqueue */ 152*cbe0a0c4SAugustin Cavalier WB_TXSTATE_RSVD = 0x00400000, /* 100 - reserved */ 153*cbe0a0c4SAugustin Cavalier WB_TXSTATE_SETUP = 0x00500000, /* 101 - setup packet */ 154*cbe0a0c4SAugustin Cavalier WB_TXSTATE_SUSPEND = 0x00600000, /* 110 - suspend tx */ 155*cbe0a0c4SAugustin Cavalier WB_TXSTATE_CLOSE = 0x00700000, /* 111 - close tx desc */ 156*cbe0a0c4SAugustin Cavalier }; 157*cbe0a0c4SAugustin Cavalier /* 158*cbe0a0c4SAugustin Cavalier * Network config bits. 159*cbe0a0c4SAugustin Cavalier */ 160*cbe0a0c4SAugustin Cavalier enum networkConfigBits { 161*cbe0a0c4SAugustin Cavalier WB_NETCFG_RX_ON = 0x00000002, 162*cbe0a0c4SAugustin Cavalier WB_NETCFG_RX_ALLPHYS = 0x00000008, 163*cbe0a0c4SAugustin Cavalier WB_NETCFG_RX_MULTI = 0x00000010, 164*cbe0a0c4SAugustin Cavalier WB_NETCFG_RX_BROAD = 0x00000020, 165*cbe0a0c4SAugustin Cavalier WB_NETCFG_RX_RUNT = 0x00000040, 166*cbe0a0c4SAugustin Cavalier WB_NETCFG_RX_ERR = 0x00000080, 167*cbe0a0c4SAugustin Cavalier WB_NETCFG_FULLDUPLEX = 0x00000200, 168*cbe0a0c4SAugustin Cavalier WB_NETCFG_LOOPBACK = 0x00000C00, 169*cbe0a0c4SAugustin Cavalier WB_NETCFG_TX_ON = 0x00002000, 170*cbe0a0c4SAugustin Cavalier WB_NETCFG_TX_THRESH = 0x001FC000, 171*cbe0a0c4SAugustin Cavalier WB_NETCFG_RX_EARLYTHRSH = 0x1FE00000, 172*cbe0a0c4SAugustin Cavalier WB_NETCFG_100MBPS = 0x20000000, 173*cbe0a0c4SAugustin Cavalier WB_NETCFG_TX_EARLY_ON = 0x40000000, 174*cbe0a0c4SAugustin Cavalier WB_NETCFG_RX_EARLY_ON = 0x80000000, 175*cbe0a0c4SAugustin Cavalier }; 176*cbe0a0c4SAugustin Cavalier /* 177*cbe0a0c4SAugustin Cavalier * The tx threshold can be adjusted in increments of 32 bytes. 178*cbe0a0c4SAugustin Cavalier */ 179*cbe0a0c4SAugustin Cavalier #define WB_TXTHRESH(x) ((x >> 5) << 14) 180*cbe0a0c4SAugustin Cavalier #define WB_TXTHRESH_CHUNK 32 181*cbe0a0c4SAugustin Cavalier #define WB_TXTHRESH_INIT 0 /*72*/ 182*cbe0a0c4SAugustin Cavalier 183*cbe0a0c4SAugustin Cavalier /* 184*cbe0a0c4SAugustin Cavalier * Interrupt mask bits. 185*cbe0a0c4SAugustin Cavalier */ 186*cbe0a0c4SAugustin Cavalier enum interruptMaskBits { 187*cbe0a0c4SAugustin Cavalier WB_IMR_TX_OK = 0x00000001, 188*cbe0a0c4SAugustin Cavalier WB_IMR_TX_IDLE = 0x00000002, 189*cbe0a0c4SAugustin Cavalier WB_IMR_TX_NOBUF = 0x00000004, 190*cbe0a0c4SAugustin Cavalier WB_IMR_TX_UNDERRUN = 0x00000020, 191*cbe0a0c4SAugustin Cavalier WB_IMR_TX_EARLY = 0x00000400, 192*cbe0a0c4SAugustin Cavalier WB_IMR_RX_EARLY = 0x00000008, 193*cbe0a0c4SAugustin Cavalier WB_IMR_RX_ERR = 0x00000010, 194*cbe0a0c4SAugustin Cavalier WB_IMR_RX_OK = 0x00000040, 195*cbe0a0c4SAugustin Cavalier WB_IMR_RX_NOBUF = 0x00000080, 196*cbe0a0c4SAugustin Cavalier WB_IMR_RX_IDLE = 0x00000100, 197*cbe0a0c4SAugustin Cavalier WB_IMR_TIMER_EXPIRED = 0x00000800, 198*cbe0a0c4SAugustin Cavalier WB_IMR_BUS_ERR = 0x00002000, 199*cbe0a0c4SAugustin Cavalier WB_IMR_ABNORMAL = 0x00008000, 200*cbe0a0c4SAugustin Cavalier WB_IMR_NORMAL = 0x00010000, 201*cbe0a0c4SAugustin Cavalier }; 202*cbe0a0c4SAugustin Cavalier 203*cbe0a0c4SAugustin Cavalier #define WB_INTRS \ 204*cbe0a0c4SAugustin Cavalier (WB_IMR_RX_OK|WB_IMR_RX_IDLE|WB_IMR_RX_ERR|WB_IMR_RX_NOBUF \ 205*cbe0a0c4SAugustin Cavalier |WB_IMR_RX_EARLY|WB_IMR_TX_OK|WB_IMR_TX_EARLY|WB_IMR_TX_NOBUF \ 206*cbe0a0c4SAugustin Cavalier |WB_IMR_TX_UNDERRUN|WB_IMR_TX_IDLE|WB_IMR_BUS_ERR \ 207*cbe0a0c4SAugustin Cavalier |WB_IMR_ABNORMAL|WB_IMR_NORMAL|WB_IMR_TIMER_EXPIRED) 208*cbe0a0c4SAugustin Cavalier 209*cbe0a0c4SAugustin Cavalier /* 210*cbe0a0c4SAugustin Cavalier * Serial I/O (EEPROM/ROM) bits. 211*cbe0a0c4SAugustin Cavalier */ 212*cbe0a0c4SAugustin Cavalier enum EEpromBits { 213*cbe0a0c4SAugustin Cavalier WB_SIO_EE_CS = 0x00000001, /* EEPROM chip select */ 214*cbe0a0c4SAugustin Cavalier WB_SIO_EE_CLK = 0x00000002, /* EEPROM clock */ 215*cbe0a0c4SAugustin Cavalier WB_SIO_EE_DATAIN = 0x00000004, /* EEPROM data output */ 216*cbe0a0c4SAugustin Cavalier WB_SIO_EE_DATAOUT = 0x00000008, /* EEPROM data input */ 217*cbe0a0c4SAugustin Cavalier WB_SIO_ROMDATA4 = 0x00000010, 218*cbe0a0c4SAugustin Cavalier WB_SIO_ROMDATA5 = 0x00000020, 219*cbe0a0c4SAugustin Cavalier WB_SIO_ROMDATA6 = 0x00000040, 220*cbe0a0c4SAugustin Cavalier WB_SIO_ROMDATA7 = 0x00000080, 221*cbe0a0c4SAugustin Cavalier WB_SIO_ROMCTL_WRITE = 0x00000200, 222*cbe0a0c4SAugustin Cavalier WB_SIO_ROMCTL_READ = 0x00000400, 223*cbe0a0c4SAugustin Cavalier WB_SIO_EESEL = 0x00000800, 224*cbe0a0c4SAugustin Cavalier WB_SIO_MII_CLK = 0x00010000, /* MDIO clock */ 225*cbe0a0c4SAugustin Cavalier WB_SIO_MII_DATAIN = 0x00020000, /* MDIO data out */ 226*cbe0a0c4SAugustin Cavalier WB_SIO_MII_DIR = 0x00040000, /* MDIO dir */ 227*cbe0a0c4SAugustin Cavalier WB_SIO_MII_DATAOUT = 0x00080000, /* MDIO data in */ 228*cbe0a0c4SAugustin Cavalier }; 229*cbe0a0c4SAugustin Cavalier 230*cbe0a0c4SAugustin Cavalier enum EEpromCmd { 231*cbe0a0c4SAugustin Cavalier WB_EECMD_WRITE = 0x140, 232*cbe0a0c4SAugustin Cavalier WB_EECMD_READ = 0x180, 233*cbe0a0c4SAugustin Cavalier WB_EECMD_ERASE = 0x1c0 234*cbe0a0c4SAugustin Cavalier }; 235*cbe0a0c4SAugustin Cavalier 236*cbe0a0c4SAugustin Cavalier /* 237*cbe0a0c4SAugustin Cavalier * Winbond TX/RX descriptor structure. 238*cbe0a0c4SAugustin Cavalier */ 239*cbe0a0c4SAugustin Cavalier 240*cbe0a0c4SAugustin Cavalier typedef struct wb_desc wb_desc; 241*cbe0a0c4SAugustin Cavalier struct wb_desc { 242*cbe0a0c4SAugustin Cavalier uint32 wb_status; 243*cbe0a0c4SAugustin Cavalier uint32 wb_ctl; 244*cbe0a0c4SAugustin Cavalier uint32 wb_data; 245*cbe0a0c4SAugustin Cavalier uint32 wb_next; 246*cbe0a0c4SAugustin Cavalier }; 247*cbe0a0c4SAugustin Cavalier 248*cbe0a0c4SAugustin Cavalier enum rxStatusBits { 249*cbe0a0c4SAugustin Cavalier WB_RXSTAT_CRCERR = 0x00000002, 250*cbe0a0c4SAugustin Cavalier WB_RXSTAT_DRIBBLE = 0x00000004, 251*cbe0a0c4SAugustin Cavalier WB_RXSTAT_MIIERR = 0x00000008, 252*cbe0a0c4SAugustin Cavalier WB_RXSTAT_LATEEVENT = 0x00000040, 253*cbe0a0c4SAugustin Cavalier WB_RXSTAT_GIANT = 0x00000080, 254*cbe0a0c4SAugustin Cavalier WB_RXSTAT_LASTFRAG = 0x00000100, 255*cbe0a0c4SAugustin Cavalier WB_RXSTAT_FIRSTFRAG = 0x00000200, 256*cbe0a0c4SAugustin Cavalier WB_RXSTAT_MULTICAST = 0x00000400, 257*cbe0a0c4SAugustin Cavalier WB_RXSTAT_RUNT = 0x00000800, 258*cbe0a0c4SAugustin Cavalier WB_RXSTAT_RXTYPE = 0x00003000, 259*cbe0a0c4SAugustin Cavalier WB_RXSTAT_RXERR = 0x00008000, 260*cbe0a0c4SAugustin Cavalier WB_RXSTAT_RXLEN = 0x3FFF0000, 261*cbe0a0c4SAugustin Cavalier WB_RXSTAT_RXCMP = 0x40000000, 262*cbe0a0c4SAugustin Cavalier WB_RXSTAT_OWN = 0x80000000 263*cbe0a0c4SAugustin Cavalier }; 264*cbe0a0c4SAugustin Cavalier 265*cbe0a0c4SAugustin Cavalier #define WB_RXBYTES(x) ((x & WB_RXSTAT_RXLEN) >> 16) 266*cbe0a0c4SAugustin Cavalier #define WB_RXSTAT (WB_RXSTAT_FIRSTFRAG|WB_RXSTAT_LASTFRAG|WB_RXSTAT_OWN) 267*cbe0a0c4SAugustin Cavalier 268*cbe0a0c4SAugustin Cavalier enum rxControlBits { 269*cbe0a0c4SAugustin Cavalier WB_RXCTL_BUFLEN1 = 0x00000FFF, 270*cbe0a0c4SAugustin Cavalier WB_RXCTL_BUFLEN2 = 0x00FFF000, 271*cbe0a0c4SAugustin Cavalier WB_RXCTL_RLINK = 0x01000000, 272*cbe0a0c4SAugustin Cavalier WB_RXCTL_RLAST = 0x02000000 273*cbe0a0c4SAugustin Cavalier }; 274*cbe0a0c4SAugustin Cavalier 275*cbe0a0c4SAugustin Cavalier 276*cbe0a0c4SAugustin Cavalier enum txStatusBits { 277*cbe0a0c4SAugustin Cavalier WB_TXSTAT_DEFER = 0x00000001, 278*cbe0a0c4SAugustin Cavalier WB_TXSTAT_UNDERRUN = 0x00000002, 279*cbe0a0c4SAugustin Cavalier WB_TXSTAT_COLLCNT = 0x00000078, 280*cbe0a0c4SAugustin Cavalier WB_TXSTAT_SQE = 0x00000080, 281*cbe0a0c4SAugustin Cavalier WB_TXSTAT_ABORT = 0x00000100, 282*cbe0a0c4SAugustin Cavalier WB_TXSTAT_LATECOLL = 0x00000200, 283*cbe0a0c4SAugustin Cavalier WB_TXSTAT_NOCARRIER = 0x00000400, 284*cbe0a0c4SAugustin Cavalier WB_TXSTAT_CARRLOST = 0x00000800, 285*cbe0a0c4SAugustin Cavalier WB_TXSTAT_TXERR = 0x00001000, 286*cbe0a0c4SAugustin Cavalier WB_TXSTAT_OWN = 0x80000000 287*cbe0a0c4SAugustin Cavalier }; 288*cbe0a0c4SAugustin Cavalier 289*cbe0a0c4SAugustin Cavalier enum txControlBits { 290*cbe0a0c4SAugustin Cavalier WB_TXCTL_BUFLEN1 = 0x000007FF, 291*cbe0a0c4SAugustin Cavalier WB_TXCTL_BUFLEN2 = 0x003FF800, 292*cbe0a0c4SAugustin Cavalier WB_TXCTL_PAD = 0x00800000, 293*cbe0a0c4SAugustin Cavalier WB_TXCTL_TLINK = 0x01000000, 294*cbe0a0c4SAugustin Cavalier WB_TXCTL_TLAST = 0x02000000, 295*cbe0a0c4SAugustin Cavalier WB_TXCTL_NOCRC = 0x08000000, 296*cbe0a0c4SAugustin Cavalier WB_TXCTL_FIRSTFRAG = 0x20000000, 297*cbe0a0c4SAugustin Cavalier WB_TXCTL_LASTFRAG = 0x40000000, 298*cbe0a0c4SAugustin Cavalier WB_TXCTL_FINT = 0x80000000 299*cbe0a0c4SAugustin Cavalier }; 300*cbe0a0c4SAugustin Cavalier 301*cbe0a0c4SAugustin Cavalier #define WB_MAXFRAGS 16 302*cbe0a0c4SAugustin Cavalier #define WB_RX_LIST_CNT 64 303*cbe0a0c4SAugustin Cavalier #define WB_TX_LIST_CNT 64 304*cbe0a0c4SAugustin Cavalier #define WB_RX_CNT_MASK (WB_RX_LIST_CNT - 1) 305*cbe0a0c4SAugustin Cavalier #define WB_TX_CNT_MASK (WB_TX_LIST_CNT - 1) 306*cbe0a0c4SAugustin Cavalier #define WB_MIN_FRAMELEN 60 307*cbe0a0c4SAugustin Cavalier #define WB_MAX_FRAMELEN 1536 308*cbe0a0c4SAugustin Cavalier 309*cbe0a0c4SAugustin Cavalier #define WB_UNSENT 0x1234 310*cbe0a0c4SAugustin Cavalier #define WB_BUFBYTES 2048 311*cbe0a0c4SAugustin Cavalier 312*cbe0a0c4SAugustin Cavalier /* Ethernet defines */ 313*cbe0a0c4SAugustin Cavalier #define CRC_SIZE 4 314*cbe0a0c4SAugustin Cavalier #define ETHER_TRANSMIT_TIMEOUT ((bigtime_t)5000000) /* five seconds */ 315*cbe0a0c4SAugustin Cavalier #define WB_TIMEOUT 1000 316*cbe0a0c4SAugustin Cavalier 317*cbe0a0c4SAugustin Cavalier typedef struct wb_mii_frame wb_mii_frame; 318*cbe0a0c4SAugustin Cavalier struct wb_mii_frame { 319*cbe0a0c4SAugustin Cavalier uint8 mii_stdelim; 320*cbe0a0c4SAugustin Cavalier uint8 mii_opcode; 321*cbe0a0c4SAugustin Cavalier uint8 mii_phyaddr; 322*cbe0a0c4SAugustin Cavalier uint8 mii_regaddr; 323*cbe0a0c4SAugustin Cavalier uint8 mii_turnaround; 324*cbe0a0c4SAugustin Cavalier uint16 mii_data; 325*cbe0a0c4SAugustin Cavalier }; 326*cbe0a0c4SAugustin Cavalier 327*cbe0a0c4SAugustin Cavalier /* 328*cbe0a0c4SAugustin Cavalier * MII constants 329*cbe0a0c4SAugustin Cavalier */ 330*cbe0a0c4SAugustin Cavalier #define WB_MII_STARTDELIM 0x01 331*cbe0a0c4SAugustin Cavalier #define WB_MII_READOP 0x02 332*cbe0a0c4SAugustin Cavalier #define WB_MII_WRITEOP 0x01 333*cbe0a0c4SAugustin Cavalier #define WB_MII_TURNAROUND 0x02 334*cbe0a0c4SAugustin Cavalier 335*cbe0a0c4SAugustin Cavalier typedef struct wb_device wb_device; 336*cbe0a0c4SAugustin Cavalier struct wb_device { 337*cbe0a0c4SAugustin Cavalier timer timer; 338*cbe0a0c4SAugustin Cavalier int32 devId; 339*cbe0a0c4SAugustin Cavalier pci_info* pciInfo; 340*cbe0a0c4SAugustin Cavalier uint16 irq; /* IRQ line */ 341*cbe0a0c4SAugustin Cavalier volatile uint32 reg_base; /* hardware register base address */ 342*cbe0a0c4SAugustin Cavalier 343*cbe0a0c4SAugustin Cavalier // rx data 344*cbe0a0c4SAugustin Cavalier volatile wb_desc rxDescriptor[WB_RX_LIST_CNT]; 345*cbe0a0c4SAugustin Cavalier volatile void* rxBuffer[WB_RX_LIST_CNT]; 346*cbe0a0c4SAugustin Cavalier int32 rxLock; 347*cbe0a0c4SAugustin Cavalier sem_id rxSem; 348*cbe0a0c4SAugustin Cavalier spinlock rxSpinlock; 349*cbe0a0c4SAugustin Cavalier area_id rxArea; 350*cbe0a0c4SAugustin Cavalier int16 rxCurrent; 351*cbe0a0c4SAugustin Cavalier int16 rxInterruptIndex; 352*cbe0a0c4SAugustin Cavalier int16 rxFree; 353*cbe0a0c4SAugustin Cavalier 354*cbe0a0c4SAugustin Cavalier //tx data 355*cbe0a0c4SAugustin Cavalier volatile wb_desc txDescriptor[WB_TX_LIST_CNT]; 356*cbe0a0c4SAugustin Cavalier volatile char* txBuffer[WB_TX_LIST_CNT]; 357*cbe0a0c4SAugustin Cavalier int32 txLock; 358*cbe0a0c4SAugustin Cavalier sem_id txSem; 359*cbe0a0c4SAugustin Cavalier spinlock txSpinlock; 360*cbe0a0c4SAugustin Cavalier area_id txArea; 361*cbe0a0c4SAugustin Cavalier int16 txCurrent; 362*cbe0a0c4SAugustin Cavalier int16 txInterruptIndex; 363*cbe0a0c4SAugustin Cavalier int16 txSent; 364*cbe0a0c4SAugustin Cavalier 365*cbe0a0c4SAugustin Cavalier struct mii_phy* firstPHY; 366*cbe0a0c4SAugustin Cavalier struct mii_phy* currentPHY; 367*cbe0a0c4SAugustin Cavalier uint16 phy; 368*cbe0a0c4SAugustin Cavalier bool autoNegotiationComplete; 369*cbe0a0c4SAugustin Cavalier bool link; 370*cbe0a0c4SAugustin Cavalier bool full_duplex; 371*cbe0a0c4SAugustin Cavalier uint16 speed; 372*cbe0a0c4SAugustin Cavalier uint16 fixedMode; 373*cbe0a0c4SAugustin Cavalier 374*cbe0a0c4SAugustin Cavalier volatile int32 blockFlag; 375*cbe0a0c4SAugustin Cavalier ether_address_t MAC_Address; 376*cbe0a0c4SAugustin Cavalier 377*cbe0a0c4SAugustin Cavalier spinlock intLock; 378*cbe0a0c4SAugustin Cavalier const char* deviceName; 379*cbe0a0c4SAugustin Cavalier uint8 wb_type; 380*cbe0a0c4SAugustin Cavalier uint16 wb_txthresh; 381*cbe0a0c4SAugustin Cavalier int wb_cachesize; 382*cbe0a0c4SAugustin Cavalier }; 383*cbe0a0c4SAugustin Cavalier 384*cbe0a0c4SAugustin Cavalier 385*cbe0a0c4SAugustin Cavalier /* MII Interface */ 386*cbe0a0c4SAugustin Cavalier struct mii_phy { 387*cbe0a0c4SAugustin Cavalier struct mii_phy *next; 388*cbe0a0c4SAugustin Cavalier uint16 id0, id1; 389*cbe0a0c4SAugustin Cavalier uint16 address; 390*cbe0a0c4SAugustin Cavalier uint8 types; 391*cbe0a0c4SAugustin Cavalier }; 392*cbe0a0c4SAugustin Cavalier 393*cbe0a0c4SAugustin Cavalier 394*cbe0a0c4SAugustin Cavalier // taken from Axel's Sis900 driver 395*cbe0a0c4SAugustin Cavalier enum MII_address { 396*cbe0a0c4SAugustin Cavalier // standard registers 397*cbe0a0c4SAugustin Cavalier MII_CONTROL = 0x00, 398*cbe0a0c4SAugustin Cavalier MII_STATUS = 0x01, 399*cbe0a0c4SAugustin Cavalier MII_PHY_ID0 = 0x02, 400*cbe0a0c4SAugustin Cavalier MII_PHY_ID1 = 0x03, 401*cbe0a0c4SAugustin Cavalier MII_AUTONEG_ADV = 0x04, 402*cbe0a0c4SAugustin Cavalier MII_AUTONEG_LINK_PARTNER = 0x05, 403*cbe0a0c4SAugustin Cavalier MII_AUTONEG_EXT = 0x06 404*cbe0a0c4SAugustin Cavalier }; 405*cbe0a0c4SAugustin Cavalier 406*cbe0a0c4SAugustin Cavalier enum MII_control { 407*cbe0a0c4SAugustin Cavalier MII_CONTROL_RESET = 0x8000, 408*cbe0a0c4SAugustin Cavalier MII_CONTROL_RESET_AUTONEG = 0x0200, 409*cbe0a0c4SAugustin Cavalier MII_CONTROL_AUTO = 0x1000, 410*cbe0a0c4SAugustin Cavalier MII_CONTROL_FULL_DUPLEX = 0x0100, 411*cbe0a0c4SAugustin Cavalier MII_CONTROL_ISOLATE = 0x0400 412*cbe0a0c4SAugustin Cavalier }; 413*cbe0a0c4SAugustin Cavalier 414*cbe0a0c4SAugustin Cavalier enum MII_commands { 415*cbe0a0c4SAugustin Cavalier MII_CMD_READ = 0x6000, 416*cbe0a0c4SAugustin Cavalier MII_CMD_WRITE = 0x5002, 417*cbe0a0c4SAugustin Cavalier 418*cbe0a0c4SAugustin Cavalier MII_PHY_SHIFT = 7, 419*cbe0a0c4SAugustin Cavalier MII_REG_SHIFT = 2, 420*cbe0a0c4SAugustin Cavalier }; 421*cbe0a0c4SAugustin Cavalier 422*cbe0a0c4SAugustin Cavalier enum MII_status_bits { 423*cbe0a0c4SAugustin Cavalier MII_STATUS_EXT = 0x0001, 424*cbe0a0c4SAugustin Cavalier MII_STATUS_JAB = 0x0002, 425*cbe0a0c4SAugustin Cavalier MII_STATUS_LINK = 0x0004, 426*cbe0a0c4SAugustin Cavalier MII_STATUS_CAN_AUTO = 0x0008, 427*cbe0a0c4SAugustin Cavalier MII_STATUS_FAULT = 0x0010, 428*cbe0a0c4SAugustin Cavalier MII_STATUS_AUTO_DONE = 0x0020, 429*cbe0a0c4SAugustin Cavalier MII_STATUS_CAN_T = 0x0800, 430*cbe0a0c4SAugustin Cavalier MII_STATUS_CAN_T_FDX = 0x1000, 431*cbe0a0c4SAugustin Cavalier MII_STATUS_CAN_TX = 0x2000, 432*cbe0a0c4SAugustin Cavalier MII_STATUS_CAN_TX_FDX = 0x4000, 433*cbe0a0c4SAugustin Cavalier MII_STATUS_CAN_T4 = 0x8000 434*cbe0a0c4SAugustin Cavalier }; 435*cbe0a0c4SAugustin Cavalier 436*cbe0a0c4SAugustin Cavalier enum MII_auto_negotiation { 437*cbe0a0c4SAugustin Cavalier MII_NWAY_NODE_SEL = 0x001f, 438*cbe0a0c4SAugustin Cavalier MII_NWAY_CSMA_CD = 0x0001, 439*cbe0a0c4SAugustin Cavalier MII_NWAY_T = 0x0020, 440*cbe0a0c4SAugustin Cavalier MII_NWAY_T_FDX = 0x0040, 441*cbe0a0c4SAugustin Cavalier MII_NWAY_TX = 0x0080, 442*cbe0a0c4SAugustin Cavalier MII_NWAY_TX_FDX = 0x0100, 443*cbe0a0c4SAugustin Cavalier MII_NWAY_T4 = 0x0200, 444*cbe0a0c4SAugustin Cavalier MII_NWAY_PAUSE = 0x0400, 445*cbe0a0c4SAugustin Cavalier MII_NWAY_RF = 0x2000, 446*cbe0a0c4SAugustin Cavalier MII_NWAY_ACK = 0x4000, 447*cbe0a0c4SAugustin Cavalier MII_NWAY_NP = 0x8000 448*cbe0a0c4SAugustin Cavalier }; 449*cbe0a0c4SAugustin Cavalier 450*cbe0a0c4SAugustin Cavalier 451*cbe0a0c4SAugustin Cavalier enum MII_link_status { 452*cbe0a0c4SAugustin Cavalier MII_LINK_FAIL = 0x4000, 453*cbe0a0c4SAugustin Cavalier MII_LINK_100_MBIT = 0x0080, 454*cbe0a0c4SAugustin Cavalier MII_LINK_FULL_DUPLEX = 0x0040 455*cbe0a0c4SAugustin Cavalier }; 456*cbe0a0c4SAugustin Cavalier 457*cbe0a0c4SAugustin Cavalier enum link_modes { 458*cbe0a0c4SAugustin Cavalier LINK_HALF_DUPLEX = 0x0100, 459*cbe0a0c4SAugustin Cavalier LINK_FULL_DUPLEX = 0x0200, 460*cbe0a0c4SAugustin Cavalier LINK_DUPLEX_MASK = 0xff00, 461*cbe0a0c4SAugustin Cavalier 462*cbe0a0c4SAugustin Cavalier LINK_SPEED_HOME = 1, 463*cbe0a0c4SAugustin Cavalier LINK_SPEED_10_MBIT = 10, 464*cbe0a0c4SAugustin Cavalier LINK_SPEED_100_MBIT = 100, 465*cbe0a0c4SAugustin Cavalier LINK_SPEED_DEFAULT = LINK_SPEED_100_MBIT, 466*cbe0a0c4SAugustin Cavalier LINK_SPEED_MASK = 0x00ff 467*cbe0a0c4SAugustin Cavalier }; 468*cbe0a0c4SAugustin Cavalier 469*cbe0a0c4SAugustin Cavalier /* 470*cbe0a0c4SAugustin Cavalier * Vendor and Card IDs 471*cbe0a0c4SAugustin Cavalier * 472*cbe0a0c4SAugustin Cavalier * Winbond 473*cbe0a0c4SAugustin Cavalier */ 474*cbe0a0c4SAugustin Cavalier #define WB_VENDORID 0x1050 475*cbe0a0c4SAugustin Cavalier #define WB_DEVICEID_840F 0x0840 476*cbe0a0c4SAugustin Cavalier 477*cbe0a0c4SAugustin Cavalier /* 478*cbe0a0c4SAugustin Cavalier * Compex 479*cbe0a0c4SAugustin Cavalier */ 480*cbe0a0c4SAugustin Cavalier #define CP_VENDORID 0x11F6 481*cbe0a0c4SAugustin Cavalier #define CP_DEVICEID_RL100 0x2011 482*cbe0a0c4SAugustin Cavalier 483*cbe0a0c4SAugustin Cavalier /* 484*cbe0a0c4SAugustin Cavalier * Utility Macros 485*cbe0a0c4SAugustin Cavalier */ 486*cbe0a0c4SAugustin Cavalier #define WB_SETBIT(reg, x) write32(reg, read32(reg) | x) 487*cbe0a0c4SAugustin Cavalier #define WB_CLRBIT(reg, x) write32(reg, read32(reg) & ~x) 488*cbe0a0c4SAugustin Cavalier 489*cbe0a0c4SAugustin Cavalier // Prototypes 490*cbe0a0c4SAugustin Cavalier extern int32 wb_interrupt(void* arg); 491*cbe0a0c4SAugustin Cavalier 492*cbe0a0c4SAugustin Cavalier extern status_t wb_create_semaphores(wb_device* device); 493*cbe0a0c4SAugustin Cavalier extern void wb_delete_semaphores(wb_device* device); 494*cbe0a0c4SAugustin Cavalier 495*cbe0a0c4SAugustin Cavalier extern status_t wb_create_rings(wb_device* device); 496*cbe0a0c4SAugustin Cavalier extern void wb_delete_rings(wb_device* device); 497*cbe0a0c4SAugustin Cavalier 498*cbe0a0c4SAugustin Cavalier extern void wb_init(wb_device* device); 499*cbe0a0c4SAugustin Cavalier extern void wb_reset(wb_device* device); 500*cbe0a0c4SAugustin Cavalier extern status_t wb_stop(wb_device* device); 501*cbe0a0c4SAugustin Cavalier 502*cbe0a0c4SAugustin Cavalier extern status_t wb_initPHYs(wb_device* device); 503*cbe0a0c4SAugustin Cavalier 504*cbe0a0c4SAugustin Cavalier extern void wb_disable_interrupts(wb_device* device); 505*cbe0a0c4SAugustin Cavalier extern void wb_enable_interrupts(wb_device* device); 506*cbe0a0c4SAugustin Cavalier 507*cbe0a0c4SAugustin Cavalier extern void wb_set_mode(wb_device* device, int mode); 508*cbe0a0c4SAugustin Cavalier extern int32 wb_read_mode(wb_device* device); 509*cbe0a0c4SAugustin Cavalier 510*cbe0a0c4SAugustin Cavalier extern void wb_set_rx_filter(wb_device* device); 511*cbe0a0c4SAugustin Cavalier 512*cbe0a0c4SAugustin Cavalier extern int32 wb_tick(timer* arg); 513*cbe0a0c4SAugustin Cavalier extern void wb_put_rx_descriptor(volatile wb_desc* desc); 514*cbe0a0c4SAugustin Cavalier 515*cbe0a0c4SAugustin Cavalier extern void print_address(ether_address_t* addr); 516*cbe0a0c4SAugustin Cavalier 517*cbe0a0c4SAugustin Cavalier #endif //__WB840_H 518