xref: /haiku/src/add-ons/kernel/drivers/network/ether/wb840/wb840.h (revision 268f99dd7dc4bd7474a8bd2742d3f1ec1de6752a)
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