2 * Copyright (c) 2003-2004 Stefano Ceccherini (stefano.ceccherini@gmail.com)
3 * Copyright (c) 1997, 1998
4 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. All advertising materials mentioning features or use of this software
15 * must display the following acknowledgement:
16 * This product includes software developed by Bill Paul.
17 * 4. Neither the name of the author nor the names of any co-contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
31 * THE POSSIBILITY OF SUCH DAMAGE.
39 #include <KernelExport.h>
40 #include "ether_driver.h"
43 * Winbond register definitions.
46 WB_BUSCTL
= 0x00, /* bus control */
47 WB_TXSTART
= 0x04, /* tx start demand */
48 WB_RXSTART
= 0x08, /* rx start demand */
49 WB_RXADDR
= 0x0C, /* rx descriptor list start addr */
50 WB_TXADDR
= 0x10, /* tx descriptor list start addr */
51 WB_ISR
= 0x14, /* interrupt status register */
52 WB_NETCFG
= 0x18, /* network config register */
53 WB_IMR
= 0x1C, /* interrupt mask */
54 WB_FRAMESDISCARDED
= 0x20, /* # of discarded frames */
55 WB_SIO
= 0x24, /* MII and ROM/EEPROM access */
56 WB_BOOTROMADDR
= 0x28,
57 WB_TIMER
= 0x2C, /* general timer */
58 WB_CURRXCTL
= 0x30, /* current RX descriptor */
59 WB_CURRXBUF
= 0x34, /* current RX buffer */
60 WB_MAR0
= 0x38, /* multicast filter 0 */
61 WB_MAR1
= 0x3C, /* multicast filter 1 */
62 WB_NODE0
= 0x40, /* physical address 0 */
63 WB_NODE1
= 0x44, /* physical address 1 */
64 WB_BOOTROMSIZE
= 0x48, /* boot ROM size */
65 WB_CURTXCTL
= 0x4C, /* current TX descriptor */
66 WB_CURTXBUF
= 0x50, /* current TX buffer */
73 WB_BUSCTL_RESET
= 0x00000001,
74 WB_BUSCTL_ARBITRATION
= 0x00000002,
75 WB_BUSCTL_SKIPLEN
= 0x0000007C,
76 WB_BUSCTL_BUF_BIGENDIAN
= 0x00000080,
77 WB_BUSCTL_BURSTLEN
= 0x00003F00,
78 WB_BUSCTL_CACHEALIGN
= 0x0000C000,
79 WB_BUSCTL_DES_BIGENDIAN
= 0x00100000,
80 WB_BUSCTL_WAIT
= 0x00200000,
81 WB_BUSCTL_MUSTBEONE
= 0x00400000,
83 WB_SKIPLEN_1LONG
= 0x00000004,
84 WB_SKIPLEN_2LONG
= 0x00000008,
85 WB_SKIPLEN_3LONG
= 0x00000010,
86 WB_SKIPLEN_4LONG
= 0x00000020,
87 WB_SKIPLEN_5LONG
= 0x00000040,
89 WB_CACHEALIGN_NONE
= 0x00000000,
90 WB_CACHEALIGN_8LONG
= 0x00004000,
91 WB_CACHEALIGN_16LONG
= 0x00008000,
92 WB_CACHEALIGN_32LONG
= 0x0000C000,
94 WB_BURSTLEN_USECA
= 0x00000000,
95 WB_BURSTLEN_1LONG
= 0x00000100,
96 WB_BURSTLEN_2LONG
= 0x00000200,
97 WB_BURSTLEN_4LONG
= 0x00000400,
98 WB_BURSTLEN_8LONG
= 0x00000800,
99 WB_BURSTLEN_16LONG
= 0x00001000,
100 WB_BURSTLEN_32LONG
= 0x00002000,
104 #define WB_BUSCTL_CONFIG (WB_CACHEALIGN_8LONG|WB_SKIPLEN_4LONG|WB_BURSTLEN_8LONG)
107 * Interrupt status bits.
109 enum InterruptStatusBits
{
110 WB_ISR_TX_OK
= 0x00000001,
111 WB_ISR_TX_IDLE
= 0x00000002,
112 WB_ISR_TX_NOBUF
= 0x00000004,
113 WB_ISR_RX_EARLY
= 0x00000008,
114 WB_ISR_RX_ERR
= 0x00000010,
115 WB_ISR_TX_UNDERRUN
= 0x00000020,
116 WB_ISR_RX_OK
= 0x00000040,
117 WB_ISR_RX_NOBUF
= 0x00000080,
118 WB_ISR_RX_IDLE
= 0x00000100,
119 WB_ISR_TX_EARLY
= 0x00000400,
120 WB_ISR_TIMER_EXPIRED
= 0x00000800,
121 WB_ISR_BUS_ERR
= 0x00002000,
122 WB_ISR_ABNORMAL
= 0x00008000,
123 WB_ISR_NORMAL
= 0x00010000,
124 WB_ISR_RX_STATE
= 0x000E0000,
125 WB_ISR_TX_STATE
= 0x00700000,
126 WB_ISR_BUSERRTYPE
= 0x03800000,
130 * The RX_STATE and TX_STATE fields are not described anywhere in the
131 * Winbond datasheet, however it appears that the Winbond chip is an
132 * attempt at a DEC 'tulip' clone, hence the ISR register is identical
133 * to that of the tulip chip and we can steal the bit definitions from
134 * the tulip documentation.
137 WB_RXSTATE_STOPPED
= 0x00000000, /* 000 - Stopped */
138 WB_RXSTATE_FETCH
= 0x00020000, /* 001 - Fetching descriptor */
139 WB_RXSTATE_ENDCHECK
= 0x00040000, /* 010 - check for rx end */
140 WB_RXSTATE_WAIT
= 0x00060000, /* 011 - waiting for packet */
141 WB_RXSTATE_SUSPEND
= 0x00080000, /* 100 - suspend rx */
142 WB_RXSTATE_CLOSE
= 0x000A0000, /* 101 - close tx desc */
143 WB_RXSTATE_FLUSH
= 0x000C0000, /* 110 - flush from FIFO */
144 WB_RXSTATE_DEQUEUE
= 0x000E0000, /* 111 - dequeue from FIFO */
148 WB_TXSTATE_RESET
= 0x00000000, /* 000 - reset */
149 WB_TXSTATE_FETCH
= 0x00100000, /* 001 - fetching descriptor */
150 WB_TXSTATE_WAITEND
= 0x00200000, /* 010 - wait for tx end */
151 WB_TXSTATE_READING
= 0x00300000, /* 011 - read and enqueue */
152 WB_TXSTATE_RSVD
= 0x00400000, /* 100 - reserved */
153 WB_TXSTATE_SETUP
= 0x00500000, /* 101 - setup packet */
154 WB_TXSTATE_SUSPEND
= 0x00600000, /* 110 - suspend tx */
155 WB_TXSTATE_CLOSE
= 0x00700000, /* 111 - close tx desc */
158 * Network config bits.
160 enum networkConfigBits
{
161 WB_NETCFG_RX_ON
= 0x00000002,
162 WB_NETCFG_RX_ALLPHYS
= 0x00000008,
163 WB_NETCFG_RX_MULTI
= 0x00000010,
164 WB_NETCFG_RX_BROAD
= 0x00000020,
165 WB_NETCFG_RX_RUNT
= 0x00000040,
166 WB_NETCFG_RX_ERR
= 0x00000080,
167 WB_NETCFG_FULLDUPLEX
= 0x00000200,
168 WB_NETCFG_LOOPBACK
= 0x00000C00,
169 WB_NETCFG_TX_ON
= 0x00002000,
170 WB_NETCFG_TX_THRESH
= 0x001FC000,
171 WB_NETCFG_RX_EARLYTHRSH
= 0x1FE00000,
172 WB_NETCFG_100MBPS
= 0x20000000,
173 WB_NETCFG_TX_EARLY_ON
= 0x40000000,
174 WB_NETCFG_RX_EARLY_ON
= 0x80000000,
177 * The tx threshold can be adjusted in increments of 32 bytes.
179 #define WB_TXTHRESH(x) ((x >> 5) << 14)
180 #define WB_TXTHRESH_CHUNK 32
181 #define WB_TXTHRESH_INIT 0 /*72*/
184 * Interrupt mask bits.
186 enum interruptMaskBits
{
187 WB_IMR_TX_OK
= 0x00000001,
188 WB_IMR_TX_IDLE
= 0x00000002,
189 WB_IMR_TX_NOBUF
= 0x00000004,
190 WB_IMR_TX_UNDERRUN
= 0x00000020,
191 WB_IMR_TX_EARLY
= 0x00000400,
192 WB_IMR_RX_EARLY
= 0x00000008,
193 WB_IMR_RX_ERR
= 0x00000010,
194 WB_IMR_RX_OK
= 0x00000040,
195 WB_IMR_RX_NOBUF
= 0x00000080,
196 WB_IMR_RX_IDLE
= 0x00000100,
197 WB_IMR_TIMER_EXPIRED
= 0x00000800,
198 WB_IMR_BUS_ERR
= 0x00002000,
199 WB_IMR_ABNORMAL
= 0x00008000,
200 WB_IMR_NORMAL
= 0x00010000,
204 (WB_IMR_RX_OK|WB_IMR_RX_IDLE|WB_IMR_RX_ERR|WB_IMR_RX_NOBUF \
205 |WB_IMR_RX_EARLY|WB_IMR_TX_OK|WB_IMR_TX_EARLY|WB_IMR_TX_NOBUF \
206 |WB_IMR_TX_UNDERRUN|WB_IMR_TX_IDLE|WB_IMR_BUS_ERR \
207 |WB_IMR_ABNORMAL|WB_IMR_NORMAL|WB_IMR_TIMER_EXPIRED)
210 * Serial I/O (EEPROM/ROM) bits.
213 WB_SIO_EE_CS
= 0x00000001, /* EEPROM chip select */
214 WB_SIO_EE_CLK
= 0x00000002, /* EEPROM clock */
215 WB_SIO_EE_DATAIN
= 0x00000004, /* EEPROM data output */
216 WB_SIO_EE_DATAOUT
= 0x00000008, /* EEPROM data input */
217 WB_SIO_ROMDATA4
= 0x00000010,
218 WB_SIO_ROMDATA5
= 0x00000020,
219 WB_SIO_ROMDATA6
= 0x00000040,
220 WB_SIO_ROMDATA7
= 0x00000080,
221 WB_SIO_ROMCTL_WRITE
= 0x00000200,
222 WB_SIO_ROMCTL_READ
= 0x00000400,
223 WB_SIO_EESEL
= 0x00000800,
224 WB_SIO_MII_CLK
= 0x00010000, /* MDIO clock */
225 WB_SIO_MII_DATAIN
= 0x00020000, /* MDIO data out */
226 WB_SIO_MII_DIR
= 0x00040000, /* MDIO dir */
227 WB_SIO_MII_DATAOUT
= 0x00080000, /* MDIO data in */
231 WB_EECMD_WRITE
= 0x140,
232 WB_EECMD_READ
= 0x180,
233 WB_EECMD_ERASE
= 0x1c0
237 * Winbond TX/RX descriptor structure.
240 typedef struct wb_desc wb_desc
;
249 WB_RXSTAT_CRCERR
= 0x00000002,
250 WB_RXSTAT_DRIBBLE
= 0x00000004,
251 WB_RXSTAT_MIIERR
= 0x00000008,
252 WB_RXSTAT_LATEEVENT
= 0x00000040,
253 WB_RXSTAT_GIANT
= 0x00000080,
254 WB_RXSTAT_LASTFRAG
= 0x00000100,
255 WB_RXSTAT_FIRSTFRAG
= 0x00000200,
256 WB_RXSTAT_MULTICAST
= 0x00000400,
257 WB_RXSTAT_RUNT
= 0x00000800,
258 WB_RXSTAT_RXTYPE
= 0x00003000,
259 WB_RXSTAT_RXERR
= 0x00008000,
260 WB_RXSTAT_RXLEN
= 0x3FFF0000,
261 WB_RXSTAT_RXCMP
= 0x40000000,
262 WB_RXSTAT_OWN
= 0x80000000
265 #define WB_RXBYTES(x) ((x & WB_RXSTAT_RXLEN) >> 16)
266 #define WB_RXSTAT (WB_RXSTAT_FIRSTFRAG|WB_RXSTAT_LASTFRAG|WB_RXSTAT_OWN)
269 WB_RXCTL_BUFLEN1
= 0x00000FFF,
270 WB_RXCTL_BUFLEN2
= 0x00FFF000,
271 WB_RXCTL_RLINK
= 0x01000000,
272 WB_RXCTL_RLAST
= 0x02000000
277 WB_TXSTAT_DEFER
= 0x00000001,
278 WB_TXSTAT_UNDERRUN
= 0x00000002,
279 WB_TXSTAT_COLLCNT
= 0x00000078,
280 WB_TXSTAT_SQE
= 0x00000080,
281 WB_TXSTAT_ABORT
= 0x00000100,
282 WB_TXSTAT_LATECOLL
= 0x00000200,
283 WB_TXSTAT_NOCARRIER
= 0x00000400,
284 WB_TXSTAT_CARRLOST
= 0x00000800,
285 WB_TXSTAT_TXERR
= 0x00001000,
286 WB_TXSTAT_OWN
= 0x80000000
290 WB_TXCTL_BUFLEN1
= 0x000007FF,
291 WB_TXCTL_BUFLEN2
= 0x003FF800,
292 WB_TXCTL_PAD
= 0x00800000,
293 WB_TXCTL_TLINK
= 0x01000000,
294 WB_TXCTL_TLAST
= 0x02000000,
295 WB_TXCTL_NOCRC
= 0x08000000,
296 WB_TXCTL_FIRSTFRAG
= 0x20000000,
297 WB_TXCTL_LASTFRAG
= 0x40000000,
298 WB_TXCTL_FINT
= 0x80000000
301 #define WB_MAXFRAGS 16
302 #define WB_RX_LIST_CNT 64
303 #define WB_TX_LIST_CNT 64
304 #define WB_RX_CNT_MASK (WB_RX_LIST_CNT - 1)
305 #define WB_TX_CNT_MASK (WB_TX_LIST_CNT - 1)
306 #define WB_MIN_FRAMELEN 60
307 #define WB_MAX_FRAMELEN 1536
309 #define WB_UNSENT 0x1234
310 #define WB_BUFBYTES 2048
312 /* Ethernet defines */
314 #define ETHER_TRANSMIT_TIMEOUT ((bigtime_t)5000000) /* five seconds */
315 #define WB_TIMEOUT 1000
317 typedef struct wb_mii_frame wb_mii_frame
;
318 struct wb_mii_frame
{
323 uint8 mii_turnaround
;
330 #define WB_MII_STARTDELIM 0x01
331 #define WB_MII_READOP 0x02
332 #define WB_MII_WRITEOP 0x01
333 #define WB_MII_TURNAROUND 0x02
335 typedef struct wb_device wb_device
;
340 uint16 irq
; /* IRQ line */
341 volatile uint32 reg_base
; /* hardware register base address */
344 volatile wb_desc rxDescriptor
[WB_RX_LIST_CNT
];
345 volatile void* rxBuffer
[WB_RX_LIST_CNT
];
351 int16 rxInterruptIndex
;
355 volatile wb_desc txDescriptor
[WB_TX_LIST_CNT
];
356 volatile char* txBuffer
[WB_TX_LIST_CNT
];
362 int16 txInterruptIndex
;
365 struct mii_phy
* firstPHY
;
366 struct mii_phy
* currentPHY
;
368 bool autoNegotiationComplete
;
374 volatile int32 blockFlag
;
375 ether_address_t MAC_Address
;
378 const char* deviceName
;
387 struct mii_phy
*next
;
394 // taken from Axel's Sis900 driver
396 // standard registers
401 MII_AUTONEG_ADV
= 0x04,
402 MII_AUTONEG_LINK_PARTNER
= 0x05,
403 MII_AUTONEG_EXT
= 0x06
407 MII_CONTROL_RESET
= 0x8000,
408 MII_CONTROL_RESET_AUTONEG
= 0x0200,
409 MII_CONTROL_AUTO
= 0x1000,
410 MII_CONTROL_FULL_DUPLEX
= 0x0100,
411 MII_CONTROL_ISOLATE
= 0x0400
415 MII_CMD_READ
= 0x6000,
416 MII_CMD_WRITE
= 0x5002,
422 enum MII_status_bits
{
423 MII_STATUS_EXT
= 0x0001,
424 MII_STATUS_JAB
= 0x0002,
425 MII_STATUS_LINK
= 0x0004,
426 MII_STATUS_CAN_AUTO
= 0x0008,
427 MII_STATUS_FAULT
= 0x0010,
428 MII_STATUS_AUTO_DONE
= 0x0020,
429 MII_STATUS_CAN_T
= 0x0800,
430 MII_STATUS_CAN_T_FDX
= 0x1000,
431 MII_STATUS_CAN_TX
= 0x2000,
432 MII_STATUS_CAN_TX_FDX
= 0x4000,
433 MII_STATUS_CAN_T4
= 0x8000
436 enum MII_auto_negotiation
{
437 MII_NWAY_NODE_SEL
= 0x001f,
438 MII_NWAY_CSMA_CD
= 0x0001,
440 MII_NWAY_T_FDX
= 0x0040,
441 MII_NWAY_TX
= 0x0080,
442 MII_NWAY_TX_FDX
= 0x0100,
443 MII_NWAY_T4
= 0x0200,
444 MII_NWAY_PAUSE
= 0x0400,
445 MII_NWAY_RF
= 0x2000,
446 MII_NWAY_ACK
= 0x4000,
451 enum MII_link_status
{
452 MII_LINK_FAIL
= 0x4000,
453 MII_LINK_100_MBIT
= 0x0080,
454 MII_LINK_FULL_DUPLEX
= 0x0040
458 LINK_HALF_DUPLEX
= 0x0100,
459 LINK_FULL_DUPLEX
= 0x0200,
460 LINK_DUPLEX_MASK
= 0xff00,
463 LINK_SPEED_10_MBIT
= 10,
464 LINK_SPEED_100_MBIT
= 100,
465 LINK_SPEED_DEFAULT
= LINK_SPEED_100_MBIT
,
466 LINK_SPEED_MASK
= 0x00ff
470 * Vendor and Card IDs
474 #define WB_VENDORID 0x1050
475 #define WB_DEVICEID_840F 0x0840
480 #define CP_VENDORID 0x11F6
481 #define CP_DEVICEID_RL100 0x2011
486 #define WB_SETBIT(reg, x) write32(reg, read32(reg) | x)
487 #define WB_CLRBIT(reg, x) write32(reg, read32(reg) & ~x)
490 extern int32
wb_interrupt(void* arg
);
492 extern status_t
wb_create_semaphores(wb_device
* device
);
493 extern void wb_delete_semaphores(wb_device
* device
);
495 extern status_t
wb_create_rings(wb_device
* device
);
496 extern void wb_delete_rings(wb_device
* device
);
498 extern void wb_init(wb_device
* device
);
499 extern void wb_reset(wb_device
* device
);
500 extern status_t
wb_stop(wb_device
* device
);
502 extern status_t
wb_initPHYs(wb_device
* device
);
504 extern void wb_disable_interrupts(wb_device
* device
);
505 extern void wb_enable_interrupts(wb_device
* device
);
507 extern void wb_set_mode(wb_device
* device
, int mode
);
508 extern int32
wb_read_mode(wb_device
* device
);
510 extern void wb_set_rx_filter(wb_device
* device
);
512 extern int32
wb_tick(timer
* arg
);
513 extern void wb_put_rx_descriptor(volatile wb_desc
* desc
);
515 extern void print_address(ether_address_t
* addr
);