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. 5 * 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. 20 * 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. 32 * 33 */ 34 35 #ifndef __WB840_H 36 #define __WB840_H 37 38 #include <PCI.h> 39 #include <KernelExport.h> 40 #include "ether_driver.h" 41 42 /* 43 * Winbond register definitions. 44 */ 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 */ 67 }; 68 69 /* 70 * Bus control bits. 71 */ 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, 82 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, 88 89 WB_CACHEALIGN_NONE = 0x00000000, 90 WB_CACHEALIGN_8LONG = 0x00004000, 91 WB_CACHEALIGN_16LONG = 0x00008000, 92 WB_CACHEALIGN_32LONG = 0x0000C000, 93 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, 101 102 }; 103 104 #define WB_BUSCTL_CONFIG (WB_CACHEALIGN_8LONG|WB_SKIPLEN_4LONG|WB_BURSTLEN_8LONG) 105 106 /* 107 * Interrupt status bits. 108 */ 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, 127 }; 128 129 /* 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. 135 */ 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 */ 145 }; 146 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 */ 156 }; 157 /* 158 * Network config bits. 159 */ 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, 175 }; 176 /* 177 * The tx threshold can be adjusted in increments of 32 bytes. 178 */ 179 #define WB_TXTHRESH(x) ((x >> 5) << 14) 180 #define WB_TXTHRESH_CHUNK 32 181 #define WB_TXTHRESH_INIT 0 /*72*/ 182 183 /* 184 * Interrupt mask bits. 185 */ 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, 201 }; 202 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) 208 209 /* 210 * Serial I/O (EEPROM/ROM) bits. 211 */ 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 */ 228 }; 229 230 enum EEpromCmd { 231 WB_EECMD_WRITE = 0x140, 232 WB_EECMD_READ = 0x180, 233 WB_EECMD_ERASE = 0x1c0 234 }; 235 236 /* 237 * Winbond TX/RX descriptor structure. 238 */ 239 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; 246 }; 247 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 263 }; 264 265 #define WB_RXBYTES(x) ((x & WB_RXSTAT_RXLEN) >> 16) 266 #define WB_RXSTAT (WB_RXSTAT_FIRSTFRAG|WB_RXSTAT_LASTFRAG|WB_RXSTAT_OWN) 267 268 enum rxControlBits { 269 WB_RXCTL_BUFLEN1 = 0x00000FFF, 270 WB_RXCTL_BUFLEN2 = 0x00FFF000, 271 WB_RXCTL_RLINK = 0x01000000, 272 WB_RXCTL_RLAST = 0x02000000 273 }; 274 275 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 287 }; 288 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 299 }; 300 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 308 309 #define WB_UNSENT 0x1234 310 #define WB_BUFBYTES 2048 311 312 /* Ethernet defines */ 313 #define CRC_SIZE 4 314 #define ETHER_TRANSMIT_TIMEOUT ((bigtime_t)5000000) /* five seconds */ 315 #define WB_TIMEOUT 1000 316 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; 325 }; 326 327 /* 328 * MII constants 329 */ 330 #define WB_MII_STARTDELIM 0x01 331 #define WB_MII_READOP 0x02 332 #define WB_MII_WRITEOP 0x01 333 #define WB_MII_TURNAROUND 0x02 334 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 */ 342 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; 353 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; 364 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; 373 374 volatile int32 blockFlag; 375 ether_address_t MAC_Address; 376 377 spinlock intLock; 378 const char* deviceName; 379 uint8 wb_type; 380 uint16 wb_txthresh; 381 int wb_cachesize; 382 }; 383 384 385 /* MII Interface */ 386 struct mii_phy { 387 struct mii_phy *next; 388 uint16 id0, id1; 389 uint16 address; 390 uint8 types; 391 }; 392 393 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 404 }; 405 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 412 }; 413 414 enum MII_commands { 415 MII_CMD_READ = 0x6000, 416 MII_CMD_WRITE = 0x5002, 417 418 MII_PHY_SHIFT = 7, 419 MII_REG_SHIFT = 2, 420 }; 421 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 434 }; 435 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 448 }; 449 450 451 enum MII_link_status { 452 MII_LINK_FAIL = 0x4000, 453 MII_LINK_100_MBIT = 0x0080, 454 MII_LINK_FULL_DUPLEX = 0x0040 455 }; 456 457 enum link_modes { 458 LINK_HALF_DUPLEX = 0x0100, 459 LINK_FULL_DUPLEX = 0x0200, 460 LINK_DUPLEX_MASK = 0xff00, 461 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 467 }; 468 469 /* 470 * Vendor and Card IDs 471 * 472 * Winbond 473 */ 474 #define WB_VENDORID 0x1050 475 #define WB_DEVICEID_840F 0x0840 476 477 /* 478 * Compex 479 */ 480 #define CP_VENDORID 0x11F6 481 #define CP_DEVICEID_RL100 0x2011 482 483 /* 484 * Utility Macros 485 */ 486 #define WB_SETBIT(reg, x) write32(reg, read32(reg) | x) 487 #define WB_CLRBIT(reg, x) write32(reg, read32(reg) & ~x) 488 489 // Prototypes 490 extern int32 wb_interrupt(void* arg); 491 492 extern status_t wb_create_semaphores(wb_device* device); 493 extern void wb_delete_semaphores(wb_device* device); 494 495 extern status_t wb_create_rings(wb_device* device); 496 extern void wb_delete_rings(wb_device* device); 497 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); 501 502 extern status_t wb_initPHYs(wb_device* device); 503 504 extern void wb_disable_interrupts(wb_device* device); 505 extern void wb_enable_interrupts(wb_device* device); 506 507 extern void wb_set_mode(wb_device* device, int mode); 508 extern int32 wb_read_mode(wb_device* device); 509 510 extern void wb_set_rx_filter(wb_device* device); 511 512 extern int32 wb_tick(timer* arg); 513 extern void wb_put_rx_descriptor(volatile wb_desc* desc); 514 515 extern void print_address(ether_address_t* addr); 516 517 #endif //__WB840_H 518