BPicture: Fix archive constructor.
[haiku.git] / src / add-ons / kernel / drivers / network / wb840 / wb840.h
blobe3ba5beaddd6fa0ffa106a08107001aefee19088
1 /*
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
8 * are met:
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.
35 #ifndef __WB840_H
36 #define __WB840_H
38 #include <PCI.h>
39 #include <KernelExport.h>
40 #include "ether_driver.h"
43 * Winbond register definitions.
45 enum registers {
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 */
70 * Bus control bits.
72 enum busControlBits {
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.
136 enum rxState {
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 */
147 enum txState {
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,
203 #define WB_INTRS \
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.
212 enum EEpromBits {
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 */
230 enum EEpromCmd {
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;
241 struct wb_desc {
242 uint32 wb_status;
243 uint32 wb_ctl;
244 uint32 wb_data;
245 uint32 wb_next;
248 enum rxStatusBits {
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)
268 enum rxControlBits {
269 WB_RXCTL_BUFLEN1 = 0x00000FFF,
270 WB_RXCTL_BUFLEN2 = 0x00FFF000,
271 WB_RXCTL_RLINK = 0x01000000,
272 WB_RXCTL_RLAST = 0x02000000
276 enum txStatusBits {
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
289 enum txControlBits {
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 */
313 #define CRC_SIZE 4
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 {
319 uint8 mii_stdelim;
320 uint8 mii_opcode;
321 uint8 mii_phyaddr;
322 uint8 mii_regaddr;
323 uint8 mii_turnaround;
324 uint16 mii_data;
328 * MII constants
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;
336 struct wb_device {
337 timer timer;
338 int32 devId;
339 pci_info* pciInfo;
340 uint16 irq; /* IRQ line */
341 volatile uint32 reg_base; /* hardware register base address */
343 // rx data
344 volatile wb_desc rxDescriptor[WB_RX_LIST_CNT];
345 volatile void* rxBuffer[WB_RX_LIST_CNT];
346 int32 rxLock;
347 sem_id rxSem;
348 spinlock rxSpinlock;
349 area_id rxArea;
350 int16 rxCurrent;
351 int16 rxInterruptIndex;
352 int16 rxFree;
354 //tx data
355 volatile wb_desc txDescriptor[WB_TX_LIST_CNT];
356 volatile char* txBuffer[WB_TX_LIST_CNT];
357 int32 txLock;
358 sem_id txSem;
359 spinlock txSpinlock;
360 area_id txArea;
361 int16 txCurrent;
362 int16 txInterruptIndex;
363 int16 txSent;
365 struct mii_phy* firstPHY;
366 struct mii_phy* currentPHY;
367 uint16 phy;
368 bool autoNegotiationComplete;
369 bool link;
370 bool full_duplex;
371 uint16 speed;
372 uint16 fixedMode;
374 volatile int32 blockFlag;
375 ether_address_t MAC_Address;
377 spinlock intLock;
378 const char* deviceName;
379 uint8 wb_type;
380 uint16 wb_txthresh;
381 int wb_cachesize;
385 /* MII Interface */
386 struct mii_phy {
387 struct mii_phy *next;
388 uint16 id0, id1;
389 uint16 address;
390 uint8 types;
394 // taken from Axel's Sis900 driver
395 enum MII_address {
396 // standard registers
397 MII_CONTROL = 0x00,
398 MII_STATUS = 0x01,
399 MII_PHY_ID0 = 0x02,
400 MII_PHY_ID1 = 0x03,
401 MII_AUTONEG_ADV = 0x04,
402 MII_AUTONEG_LINK_PARTNER = 0x05,
403 MII_AUTONEG_EXT = 0x06
406 enum MII_control {
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
414 enum MII_commands {
415 MII_CMD_READ = 0x6000,
416 MII_CMD_WRITE = 0x5002,
418 MII_PHY_SHIFT = 7,
419 MII_REG_SHIFT = 2,
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,
439 MII_NWAY_T = 0x0020,
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,
447 MII_NWAY_NP = 0x8000
451 enum MII_link_status {
452 MII_LINK_FAIL = 0x4000,
453 MII_LINK_100_MBIT = 0x0080,
454 MII_LINK_FULL_DUPLEX = 0x0040
457 enum link_modes {
458 LINK_HALF_DUPLEX = 0x0100,
459 LINK_FULL_DUPLEX = 0x0200,
460 LINK_DUPLEX_MASK = 0xff00,
462 LINK_SPEED_HOME = 1,
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
472 * Winbond
474 #define WB_VENDORID 0x1050
475 #define WB_DEVICEID_840F 0x0840
478 * Compex
480 #define CP_VENDORID 0x11F6
481 #define CP_DEVICEID_RL100 0x2011
484 * Utility Macros
486 #define WB_SETBIT(reg, x) write32(reg, read32(reg) | x)
487 #define WB_CLRBIT(reg, x) write32(reg, read32(reg) & ~x)
489 // Prototypes
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);
517 #endif //__WB840_H