1 /* Attansic/Atheros L2 FastEthernet driver, by D.C. van Moolenbroek */ 2 /* 3 * No documentation is available for this card. The FreeBSD driver is based 4 * heavily on the official Linux driver; this driver is based heavily on both. 5 */ 6 7 #include <minix/drivers.h> 8 #include <minix/netdriver.h> 9 10 #include <machine/pci.h> 11 #include <sys/mman.h> 12 #include <assert.h> 13 14 #include "atl2.h" 15 16 #define VERBOSE 0 /* Verbose debugging output */ 17 #define ATL2_FKEY 11 /* Use Shift+Fn to dump statistics (0=off) */ 18 19 #if VERBOSE 20 #define ATL2_DEBUG(x) printf x 21 #else 22 #define ATL2_DEBUG(x) 23 #endif 24 25 typedef struct { 26 uint32_t hdr; 27 uint32_t vtag; 28 uint8_t data[ATL2_RXD_SIZE - sizeof(uint32_t) * 2]; 29 } rxd_t; 30 31 static struct { 32 int devind; /* PCI device index */ 33 int irq; /* IRQ number */ 34 int hook_id; /* IRQ hook ID */ 35 uint8_t *base; /* base address of memory-mapped registers */ 36 uint32_t size; /* size of memory-mapped area */ 37 uint32_t hwaddr[2]; /* MAC address, in register representation */ 38 39 uint8_t *txd_base; /* local address of TxD ring buffer base */ 40 uint32_t *txs_base; /* local address of TxS ring buffer base */ 41 uint8_t *rxd_base_u; /* unaligned base address of RxD ring buffer */ 42 rxd_t *rxd_base; /* local address of RxD ring buffer base */ 43 44 int rxd_align; /* alignment offset of RxD ring buffer */ 45 46 vir_bytes txd_phys; /* physical address of TxD ring buffer */ 47 vir_bytes txs_phys; /* physical address of TxS ring buffer */ 48 vir_bytes rxd_phys; /* physical address of RxD ring buffer */ 49 50 int txd_tail; /* tail index into TxD, in bytes */ 51 int txd_num; /* head-tail offset into TxD, in bytes */ 52 int txs_tail; /* tail index into TxS, in elements */ 53 int txs_num; /* head-tail offset into TxS, in elements */ 54 int rxd_tail; /* tail index into RxD, in elements */ 55 56 int rx_avail; /* is there a packet available for receipt? */ 57 58 eth_stat_t stat; /* statistics */ 59 } state; 60 61 #define ATL2_READ_U8(off) (*(volatile uint8_t *)(state.base + (off))) 62 #define ATL2_READ_U16(off) (*(volatile uint16_t *)(state.base + (off))) 63 #define ATL2_READ_U32(off) (*(volatile uint32_t *)(state.base + (off))) 64 #define ATL2_WRITE_U8(off, val) \ 65 *(volatile uint8_t *)(state.base + (off)) = (val) 66 #define ATL2_WRITE_U16(off, val) \ 67 *(volatile uint16_t *)(state.base + (off)) = (val) 68 #define ATL2_WRITE_U32(off, val) \ 69 *(volatile uint32_t *)(state.base + (off)) = (val) 70 71 #define ATL2_ALIGN_32(n) (((n) + 3) & ~3) 72 73 static int atl2_init(unsigned int instance, ether_addr_t *addr); 74 static void atl2_stop(void); 75 static void atl2_mode(unsigned int mode); 76 static int atl2_send(struct netdriver_data *data, size_t size); 77 static ssize_t atl2_recv(struct netdriver_data *data, size_t max); 78 static void atl2_stat(eth_stat_t *stat); 79 static void atl2_intr(unsigned int mask); 80 static void atl2_other(const message *m_ptr, int ipc_status); 81 82 static const struct netdriver atl2_table = { 83 .ndr_init = atl2_init, 84 .ndr_stop = atl2_stop, 85 .ndr_mode = atl2_mode, 86 .ndr_recv = atl2_recv, 87 .ndr_send = atl2_send, 88 .ndr_stat = atl2_stat, 89 .ndr_intr = atl2_intr, 90 .ndr_other = atl2_other 91 }; 92 93 /* 94 * Read a value from the VPD register area. 95 */ 96 static int 97 atl2_read_vpd(int index, uint32_t * res) 98 { 99 uint32_t off, val; 100 int i; 101 102 ATL2_WRITE_U32(ATL2_VPD_DATA_REG, 0); 103 104 off = ATL2_VPD_REGBASE + index * sizeof(uint32_t); 105 106 ATL2_WRITE_U32(ATL2_VPD_CAP_REG, 107 (off << ATL2_VPD_CAP_ADDR_SHIFT) & ATL2_VPD_CAP_ADDR_MASK); 108 109 for (i = 0; i < ATL2_VPD_NTRIES; i++) { 110 micro_delay(ATL2_VPD_DELAY); 111 112 val = ATL2_READ_U32(ATL2_VPD_CAP_REG); 113 if (val & ATL2_VPD_CAP_DONE) 114 break; 115 } 116 117 if (i == ATL2_VPD_NTRIES) { 118 printf("ATL2: timeout reading EEPROM register %d\n", index); 119 return FALSE; 120 } 121 122 *res = ATL2_READ_U32(ATL2_VPD_DATA_REG); 123 return TRUE; 124 } 125 126 /* 127 * Read the MAC address from the EEPROM, using the Vital Product Data register 128 * interface. 129 */ 130 static int 131 atl2_get_vpd_hwaddr(void) 132 { 133 uint32_t key, val; 134 int i, n, found[2]; 135 136 /* No idea, copied from FreeBSD which copied it from Linux. */ 137 val = ATL2_READ_U32(ATL2_SPICTL_REG); 138 if (val & ATL2_SPICTL_VPD_EN) { 139 val &= ~ATL2_SPICTL_VPD_EN; 140 ATL2_WRITE_U32(ATL2_SPICTL_REG, val); 141 } 142 143 /* Is VPD supported? */ 144 #ifdef PCI_CAP_VPD /* FIXME: just a guess at the future name */ 145 if (!pci_find_cap(state.devind, PCI_CAP_VPD, &n)) 146 return FALSE; 147 #endif 148 149 /* 150 * Read out the set of key/value pairs. Look for the two parts that 151 * make up the MAC address. 152 */ 153 found[0] = found[1] = FALSE; 154 for (i = 0; i < ATL2_VPD_NREGS; i += 2) { 155 if (!atl2_read_vpd(i, &key)) 156 break; 157 158 if ((key & ATL2_VPD_SIG_MASK) != ATL2_VPD_SIG) 159 break; 160 161 key >>= ATL2_VPD_REG_SHIFT; 162 163 if (key != ATL2_HWADDR0_REG && key != ATL2_HWADDR1_REG) 164 continue; 165 166 if (!atl2_read_vpd(i + 1, &val)) 167 break; 168 169 n = (key == ATL2_HWADDR1_REG); 170 state.hwaddr[n] = val; 171 found[n] = TRUE; 172 173 if (found[1 - n]) break; 174 } 175 176 return found[0] && found[1]; 177 } 178 179 /* 180 * Get the MAC address of the card. First try the EEPROM; if that fails, just 181 * use whatever the card was already set to. 182 */ 183 static void 184 atl2_get_hwaddr(ether_addr_t * addr) 185 { 186 187 if (!atl2_get_vpd_hwaddr()) { 188 printf("ATL2: unable to read from VPD\n"); 189 190 state.hwaddr[0] = ATL2_READ_U32(ATL2_HWADDR0_REG); 191 state.hwaddr[1] = ATL2_READ_U32(ATL2_HWADDR1_REG) & 0xffff; 192 } 193 194 ATL2_DEBUG(("ATL2: MAC address %04x%08x\n", 195 state.hwaddr[1], state.hwaddr[0])); 196 197 addr->ea_addr[0] = state.hwaddr[1] >> 8; 198 addr->ea_addr[1] = state.hwaddr[1] & 0xff; 199 addr->ea_addr[2] = state.hwaddr[0] >> 24; 200 addr->ea_addr[3] = (state.hwaddr[0] >> 16) & 0xff; 201 addr->ea_addr[4] = (state.hwaddr[0] >> 8) & 0xff; 202 addr->ea_addr[5] = state.hwaddr[0] & 0xff; 203 } 204 205 /* 206 * Read a MII PHY register using MDIO. 207 */ 208 static int 209 atl2_read_mdio(int addr, uint16_t * res) 210 { 211 uint32_t rval; 212 int i; 213 214 rval = ((addr << ATL2_MDIO_ADDR_SHIFT) & ATL2_MDIO_ADDR_MASK) | 215 ATL2_MDIO_START | ATL2_MDIO_READ | ATL2_MDIO_SUP_PREAMBLE | 216 ATL2_MDIO_CLK_25_4; 217 218 ATL2_WRITE_U32(ATL2_MDIO_REG, rval); 219 220 for (i = 0; i < ATL2_MDIO_NTRIES; i++) { 221 micro_delay(ATL2_MDIO_DELAY); 222 223 rval = ATL2_READ_U32(ATL2_MDIO_REG); 224 225 if (!(rval & (ATL2_MDIO_START | ATL2_MDIO_BUSY))) 226 break; 227 } 228 229 if (i == ATL2_MDIO_NTRIES) return FALSE; 230 231 *res = (uint16_t)(rval & ATL2_MDIO_DATA_MASK); 232 return TRUE; 233 } 234 235 /* 236 * Allocate DMA ring buffers. 237 */ 238 static int 239 atl2_alloc_dma(void) 240 { 241 242 state.txd_base = alloc_contig(ATL2_TXD_BUFSIZE, AC_ALIGN4K, 243 &state.txd_phys); 244 state.txs_base = alloc_contig(ATL2_TXS_COUNT * sizeof(uint32_t), 245 AC_ALIGN4K, &state.txs_phys); 246 247 /* 248 * The data buffer in each RxD descriptor must be 128-byte aligned. 249 * The two Tx buffers merely require a 4-byte start alignment. 250 */ 251 state.rxd_align = 128 - offsetof(rxd_t, data); 252 state.rxd_base_u = alloc_contig(state.rxd_align + 253 ATL2_RXD_COUNT * ATL2_RXD_SIZE, AC_ALIGN4K, &state.rxd_phys); 254 255 /* Unlike mmap, alloc_contig returns NULL on failure. */ 256 if (!state.txd_base || !state.txs_base || !state.rxd_base_u) 257 return ENOMEM; 258 259 state.rxd_base = (rxd_t *)(state.rxd_base_u + state.rxd_align); 260 state.rxd_phys += state.rxd_align; 261 262 /* Zero out just in case. */ 263 memset(state.txd_base, 0, ATL2_TXD_BUFSIZE); 264 memset(state.txs_base, 0, ATL2_TXS_COUNT * sizeof(uint32_t)); 265 memset(state.rxd_base, 0, ATL2_RXD_COUNT * ATL2_RXD_SIZE); 266 267 return OK; 268 } 269 270 /* 271 * Stop the device. 272 */ 273 static void 274 atl2_stop(void) 275 { 276 uint32_t val; 277 int i; 278 279 /* Clear and disable interrupts. */ 280 ATL2_WRITE_U32(ATL2_IMR_REG, 0); 281 ATL2_WRITE_U32(ATL2_ISR_REG, 0xffffffff); 282 283 /* Stop Rx/Tx MACs. */ 284 val = ATL2_READ_U32(ATL2_MAC_REG); 285 if (val & (ATL2_MAC_RX_EN | ATL2_MAC_TX_EN)) { 286 val &= ~(ATL2_MAC_RX_EN | ATL2_MAC_TX_EN); 287 ATL2_WRITE_U32(ATL2_MAC_REG, val); 288 } 289 290 ATL2_WRITE_U8(ATL2_DMAWRITE_REG, 0); 291 ATL2_WRITE_U8(ATL2_DMAREAD_REG, 0); 292 293 /* Wait until everything is idle. */ 294 for (i = 0; i < ATL2_IDLE_NTRIES; i++) { 295 if (ATL2_READ_U32(ATL2_IDLE_REG) == 0) 296 break; 297 298 micro_delay(ATL2_IDLE_DELAY); 299 } 300 301 assert(i < ATL2_IDLE_NTRIES); 302 } 303 304 /* 305 * Reset the device to a known good state. 306 */ 307 static int 308 atl2_reset(void) 309 { 310 uint32_t val; 311 int i; 312 313 /* Issue a soft reset, and wait for the device to respond. */ 314 ATL2_WRITE_U32(ATL2_MASTER_REG, ATL2_MASTER_SOFT_RESET); 315 316 for (i = 0; i < ATL2_RESET_NTRIES; i++) { 317 val = ATL2_READ_U32(ATL2_MASTER_REG); 318 if (!(val & ATL2_MASTER_SOFT_RESET)) 319 break; 320 321 micro_delay(ATL2_RESET_DELAY); 322 } 323 324 if (i == ATL2_RESET_NTRIES) 325 return FALSE; 326 327 /* Wait until everything is idle. */ 328 for (i = 0; i < ATL2_IDLE_NTRIES; i++) { 329 if (ATL2_READ_U32(ATL2_IDLE_REG) == 0) 330 break; 331 332 micro_delay(ATL2_IDLE_DELAY); 333 } 334 335 return (i < ATL2_IDLE_NTRIES); 336 } 337 338 /* 339 * Reconfigure the device's promiscuity, multicast, and broadcast mode 340 * settings. 341 */ 342 static void 343 atl2_mode(unsigned int mode) 344 { 345 uint32_t val; 346 347 val = ATL2_READ_U32(ATL2_MAC_REG); 348 val &= ~(ATL2_MAC_PROMISC_EN | ATL2_MAC_MCAST_EN | ATL2_MAC_BCAST_EN); 349 350 if (mode & NDEV_PROMISC) 351 val |= ATL2_MAC_PROMISC_EN; 352 if (mode & NDEV_MULTI) 353 val |= ATL2_MAC_MCAST_EN; 354 if (mode & NDEV_BROAD) 355 val |= ATL2_MAC_BCAST_EN; 356 357 ATL2_WRITE_U32(ATL2_MAC_REG, val); 358 } 359 360 /* 361 * Set up the device for normal operation. 362 */ 363 static int 364 atl2_setup(void) 365 { 366 uint32_t val; 367 368 atl2_stop(); 369 370 if (!atl2_reset()) 371 return FALSE; 372 373 /* Initialize PCIe module. Magic. */ 374 ATL2_WRITE_U32(ATL2_LTSSM_TESTMODE_REG, ATL2_LTSSM_TESTMODE_DEFAULT); 375 ATL2_WRITE_U32(ATL2_DLL_TX_CTRL_REG, ATL2_DLL_TX_CTRL_DEFAULT); 376 377 /* Enable PHY. */ 378 ATL2_WRITE_U32(ATL2_PHY_ENABLE_REG, ATL2_PHY_ENABLE); 379 micro_delay(1000); 380 381 /* Clear and disable interrupts. */ 382 ATL2_WRITE_U32(ATL2_ISR_REG, 0xffffffff); 383 384 /* Set the MAC address. */ 385 ATL2_WRITE_U32(ATL2_HWADDR0_REG, state.hwaddr[0]); 386 ATL2_WRITE_U32(ATL2_HWADDR1_REG, state.hwaddr[1]); 387 388 /* Initialize ring buffer addresses and sizes. */ 389 ATL2_WRITE_U32(ATL2_DESC_ADDR_HI_REG, 0); /* no 64 bit */ 390 ATL2_WRITE_U32(ATL2_TXD_ADDR_LO_REG, state.txd_phys); 391 ATL2_WRITE_U32(ATL2_TXS_ADDR_LO_REG, state.txs_phys); 392 ATL2_WRITE_U32(ATL2_RXD_ADDR_LO_REG, state.rxd_phys); 393 394 ATL2_WRITE_U16(ATL2_RXD_COUNT_REG, ATL2_RXD_COUNT); 395 ATL2_WRITE_U16(ATL2_TXD_BUFSIZE_REG, 396 ATL2_TXD_BUFSIZE / sizeof(uint32_t)); 397 ATL2_WRITE_U16(ATL2_TXS_COUNT_REG, ATL2_TXS_COUNT); 398 399 /* A whole lot of other initialization copied from Linux/FreeBSD. */ 400 ATL2_WRITE_U32(ATL2_IFG_REG, ATL2_IFG_DEFAULT); 401 402 ATL2_WRITE_U32(ATL2_HDPX_REG, ATL2_HDPX_DEFAULT); 403 404 ATL2_WRITE_U16(ATL2_IMT_REG, ATL2_IMT_DEFAULT); 405 val = ATL2_READ_U32(ATL2_MASTER_REG); 406 ATL2_WRITE_U32(ATL2_MASTER_REG, val | ATL2_MASTER_IMT_EN); 407 408 ATL2_WRITE_U16(ATL2_ICT_REG, ATL2_ICT_DEFAULT); 409 410 ATL2_WRITE_U32(ATL2_CUT_THRESH_REG, ATL2_CUT_THRESH_DEFAULT); 411 412 ATL2_WRITE_U16(ATL2_FLOW_THRESH_HI_REG, (ATL2_RXD_COUNT / 8) * 7); 413 ATL2_WRITE_U16(ATL2_FLOW_THRESH_LO_REG, ATL2_RXD_COUNT / 12); 414 415 /* Set MTU. */ 416 ATL2_WRITE_U16(ATL2_MTU_REG, ATL2_MTU_DEFAULT); 417 418 /* Reset descriptors, and enable DMA. */ 419 state.txd_tail = state.txs_tail = state.rxd_tail = 0; 420 state.txd_num = state.txs_num = 0; 421 state.rx_avail = FALSE; 422 ATL2_WRITE_U16(ATL2_TXD_IDX_REG, 0); 423 ATL2_WRITE_U16(ATL2_RXD_IDX_REG, 0); 424 425 ATL2_WRITE_U8(ATL2_DMAREAD_REG, ATL2_DMAREAD_EN); 426 ATL2_WRITE_U8(ATL2_DMAWRITE_REG, ATL2_DMAWRITE_EN); 427 428 /* Did everything go alright? */ 429 val = ATL2_READ_U32(ATL2_ISR_REG); 430 if (val & ATL2_ISR_PHY_LINKDOWN) { 431 printf("ATL2: initialization failed\n"); 432 return FALSE; 433 } 434 435 /* Clear interrupt status. */ 436 ATL2_WRITE_U32(ATL2_ISR_REG, 0x3fffffff); 437 ATL2_WRITE_U32(ATL2_ISR_REG, 0); 438 439 /* Enable interrupts. */ 440 ATL2_WRITE_U32(ATL2_IMR_REG, ATL2_IMR_DEFAULT); 441 442 /* Configure MAC. */ 443 ATL2_WRITE_U32(ATL2_MAC_REG, ATL2_MAC_DEFAULT); 444 445 /* 446 * Inet does not tell us about the multicast addresses that it is 447 * interested in, so we have to simply accept all multicast packets. 448 */ 449 ATL2_WRITE_U32(ATL2_MHT0_REG, 0xffffffff); 450 ATL2_WRITE_U32(ATL2_MHT1_REG, 0xffffffff); 451 452 atl2_mode(NDEV_NOMODE); 453 454 /* Enable Tx/Rx. */ 455 val = ATL2_READ_U32(ATL2_MAC_REG); 456 ATL2_WRITE_U32(ATL2_MAC_REG, val | ATL2_MAC_TX_EN | ATL2_MAC_RX_EN); 457 458 return TRUE; 459 } 460 461 /* 462 * Find a matching PCI device. 463 */ 464 static int 465 atl2_probe(int skip) 466 { 467 uint16_t vid, did; 468 #if VERBOSE 469 char *dname; 470 #endif 471 int r, devind; 472 473 pci_init(); 474 475 r = pci_first_dev(&devind, &vid, &did); 476 if (r <= 0) 477 return -1; 478 479 while (skip--) { 480 r = pci_next_dev(&devind, &vid, &did); 481 if (r <= 0) 482 return -1; 483 } 484 485 #if VERBOSE 486 dname = pci_dev_name(vid, did); 487 ATL2_DEBUG(("ATL2: found %s (%x/%x) at %s\n", 488 dname ? dname : "<unknown>", vid, did, pci_slot_name(devind))); 489 #endif 490 491 pci_reserve(devind); 492 493 return devind; 494 } 495 496 /* 497 * Initialize the device. 498 */ 499 static void 500 atl2_init_hw(int devind, ether_addr_t * addr) 501 { 502 uint32_t bar; 503 int r, flag; 504 505 /* Initialize global state. */ 506 state.devind = devind; 507 508 if ((r = pci_get_bar(devind, PCI_BAR, &bar, &state.size, &flag)) != OK) 509 panic("unable to retrieve bar: %d", r); 510 511 if (state.size < ATL2_MIN_MMAP_SIZE || flag) 512 panic("invalid register bar"); 513 514 state.base = vm_map_phys(SELF, (void *)bar, state.size); 515 if (state.base == MAP_FAILED) 516 panic("unable to map in registers"); 517 518 if ((r = atl2_alloc_dma()) != OK) 519 panic("unable to allocate DMA buffers: %d", r); 520 521 state.irq = pci_attr_r8(devind, PCI_ILR); 522 state.hook_id = 0; 523 524 if ((r = sys_irqsetpolicy(state.irq, 0, &state.hook_id)) != OK) 525 panic("unable to register IRQ: %d", r); 526 527 if (!atl2_reset()) 528 panic("unable to reset hardware"); 529 530 if ((r = sys_irqenable(&state.hook_id)) != OK) 531 panic("unable to enable IRQ: %d", r); 532 533 atl2_get_hwaddr(addr); 534 535 atl2_setup(); 536 } 537 538 /* 539 * Update statistics for packet transmission. 540 */ 541 static void 542 atl2_tx_stat(uint32_t stat) 543 { 544 545 if (stat & ATL2_TXS_SUCCESS) 546 state.stat.ets_packetT++; 547 else 548 state.stat.ets_recvErr++; 549 550 if (stat & ATL2_TXS_DEFER) 551 state.stat.ets_transDef++; 552 if (stat & (ATL2_TXS_EXCDEFER | ATL2_TXS_ABORTCOL)) 553 state.stat.ets_transAb++; 554 if (stat & ATL2_TXS_SINGLECOL) 555 state.stat.ets_collision++; 556 if (stat & ATL2_TXS_MULTICOL) 557 state.stat.ets_collision++; 558 if (stat & ATL2_TXS_LATECOL) 559 state.stat.ets_OWC++; 560 if (stat & ATL2_TXS_UNDERRUN) 561 state.stat.ets_fifoUnder++; 562 } 563 564 /* 565 * Update statistics for packet receipt. 566 */ 567 static void 568 atl2_rx_stat(uint32_t stat) 569 { 570 571 if (stat & ATL2_RXD_SUCCESS) 572 state.stat.ets_packetR++; 573 else 574 state.stat.ets_recvErr++; 575 576 if (stat & ATL2_RXD_CRCERR) 577 state.stat.ets_CRCerr++; 578 if (stat & ATL2_RXD_FRAG) 579 state.stat.ets_collision++; 580 if (stat & ATL2_RXD_TRUNC) 581 state.stat.ets_fifoOver++; 582 if (stat & ATL2_RXD_ALIGN) 583 state.stat.ets_frameAll++; 584 } 585 586 /* 587 * Advance the TxD/TxS tails by as many sent packets as found. 588 */ 589 static int 590 atl2_tx_advance(void) 591 { 592 uint32_t stat, size, dsize; 593 int advanced; 594 595 advanced = FALSE; 596 597 while (state.txs_num > 0) { 598 /* Has the tail packet been processed by the driver? */ 599 stat = state.txs_base[state.txs_tail]; 600 601 if (!(stat & ATL2_TXS_UPDATE)) 602 break; 603 604 /* 605 * The packet size from the status must match the packet size 606 * we put in. If they don't, there's not much we can do.. 607 */ 608 size = stat & ATL2_TXS_SIZE_MASK; 609 610 assert((uint32_t)state.txd_tail <= 611 ATL2_TXD_BUFSIZE - sizeof(uint32_t)); 612 dsize = 613 *(volatile uint32_t *)(state.txd_base + state.txd_tail); 614 if (size != dsize) 615 printf("ATL2: TxD/TxS size mismatch (%x vs %x)\n", 616 size, dsize); 617 618 /* Advance tails accordingly. */ 619 size = sizeof(uint32_t) + ATL2_ALIGN_32(dsize); 620 assert((uint32_t)state.txd_num >= size); 621 state.txd_tail = (state.txd_tail + size) % ATL2_TXD_BUFSIZE; 622 state.txd_num -= size; 623 624 state.txs_tail = (state.txs_tail + 1) % ATL2_TXS_COUNT; 625 state.txs_num--; 626 627 if (stat & ATL2_TXS_SUCCESS) 628 ATL2_DEBUG(("ATL2: successfully sent packet\n")); 629 else 630 ATL2_DEBUG(("ATL2: failed to send packet\n")); 631 632 /* Update statistics. */ 633 atl2_tx_stat(stat); 634 635 advanced = TRUE; 636 } 637 638 return advanced; 639 } 640 641 /* 642 * Advance the RxD tail by as many failed receipts as possible, and see if 643 * there is an actual packet left to receive. If 'next' is set, the packet at 644 * the current tail has been processed. 645 */ 646 static void 647 atl2_rx_advance(int next) 648 { 649 int update_tail; 650 rxd_t *rxd; 651 uint32_t hdr; 652 size_t size; 653 654 update_tail = FALSE; 655 656 if (next) { 657 state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT; 658 update_tail = TRUE; 659 660 ATL2_DEBUG(("ATL2: successfully received packet\n")); 661 662 state.rx_avail = FALSE; 663 } 664 665 assert(!state.rx_avail); 666 667 for (;;) { 668 /* Check the RxD tail for updates. */ 669 rxd = &state.rxd_base[state.rxd_tail]; 670 671 hdr = rxd->hdr; 672 673 if (!(hdr & ATL2_RXD_UPDATE)) 674 break; 675 676 rxd->hdr = hdr & ~ATL2_RXD_UPDATE; 677 678 /* Update statistics. */ 679 atl2_rx_stat(hdr); 680 681 /* 682 * Stop at the first successful receipt. The packet will be 683 * picked up by Inet later. 684 */ 685 size = hdr & ATL2_RXD_SIZE_MASK; 686 687 if ((hdr & ATL2_RXD_SUCCESS) && 688 size >= ETH_MIN_PACK_SIZE + ETH_CRC_SIZE) { 689 ATL2_DEBUG(("ATL2: packet available, size %zu\n", 690 size)); 691 692 state.rx_avail = TRUE; 693 break; 694 } 695 696 ATL2_DEBUG(("ATL2: packet receipt failed\n")); 697 698 /* Advance tail. */ 699 state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT; 700 update_tail = TRUE; 701 } 702 703 /* If new RxD descriptors are now up for reuse, tell the device. */ 704 if (update_tail) { 705 __insn_barrier(); 706 707 ATL2_WRITE_U32(ATL2_RXD_IDX_REG, state.rxd_tail); 708 } 709 } 710 711 /* 712 * Receive a packet. 713 */ 714 static ssize_t 715 atl2_recv(struct netdriver_data * data, size_t max) 716 { 717 rxd_t *rxd; 718 size_t size; 719 720 /* Are there any packets available at all? */ 721 if (!state.rx_avail) 722 return SUSPEND; 723 724 /* Get the first available packet's size. Cut off the CRC. */ 725 rxd = &state.rxd_base[state.rxd_tail]; 726 727 size = rxd->hdr & ATL2_RXD_SIZE_MASK; 728 size -= ETH_CRC_SIZE; 729 730 ATL2_DEBUG(("ATL2: receiving packet with length %zu\n", size)); 731 732 /* Truncate large packets. */ 733 if (size > max) 734 size = max; 735 736 /* Copy out the packet. */ 737 netdriver_copyout(data, 0, rxd->data, size); 738 739 /* We are done with this packet. Move on to the next. */ 740 atl2_rx_advance(TRUE /*next*/); 741 742 return size; 743 } 744 745 /* 746 * Send a packet. 747 */ 748 static int 749 atl2_send(struct netdriver_data * data, size_t size) 750 { 751 size_t pos, chunk; 752 uint8_t *sizep; 753 754 /* 755 * If the packet won't fit, bail out. Keep at least some space between 756 * TxD head and tail, as it is not clear whether the device deals well 757 * with the case that they collide. 758 */ 759 if (state.txs_num >= ATL2_TXS_COUNT) 760 return SUSPEND; 761 762 if (state.txd_num + sizeof(uint32_t) + ATL2_ALIGN_32(size) >= 763 ATL2_TXD_BUFSIZE) 764 return SUSPEND; 765 766 /* Copy in the packet. */ 767 pos = (state.txd_tail + state.txd_num + 768 sizeof(uint32_t)) % ATL2_TXD_BUFSIZE; 769 chunk = ATL2_TXD_BUFSIZE - pos; 770 if (size > chunk) { 771 netdriver_copyin(data, 0, state.txd_base + pos, chunk); 772 netdriver_copyin(data, chunk, state.txd_base, size - chunk); 773 } else 774 netdriver_copyin(data, 0, state.txd_base + pos, size); 775 776 /* Write the length to the DWORD right before the packet. */ 777 sizep = state.txd_base + 778 (state.txd_tail + state.txd_num) % ATL2_TXD_BUFSIZE; 779 *(volatile uint32_t *)sizep = size; 780 781 /* Update the TxD head. */ 782 state.txd_num += sizeof(uint32_t) + ATL2_ALIGN_32(size); 783 pos = ATL2_ALIGN_32(pos + size) % ATL2_TXD_BUFSIZE; 784 assert((int)pos == 785 (state.txd_tail + state.txd_num) % ATL2_TXD_BUFSIZE); 786 787 /* Initialize and update the TxS head. */ 788 state.txs_base[(state.txs_tail + state.txs_num) % ATL2_TXS_COUNT] = 0; 789 state.txs_num++; 790 791 /* Tell the device about our new position. */ 792 __insn_barrier(); 793 794 ATL2_WRITE_U32(ATL2_TXD_IDX_REG, pos / sizeof(uint32_t)); 795 796 return OK; 797 } 798 799 /* 800 * Process an interrupt. 801 */ 802 static void 803 atl2_intr(unsigned int __unused mask) 804 { 805 uint32_t val; 806 int r, try_send, try_recv; 807 808 /* Clear and disable interrupts. */ 809 val = ATL2_READ_U32(ATL2_ISR_REG); 810 811 ATL2_WRITE_U32(ATL2_ISR_REG, val | ATL2_ISR_DISABLE); 812 813 ATL2_DEBUG(("ATL2: interrupt (0x%08x)\n", val)); 814 815 /* If an error occurred, reset the card. */ 816 if (val & (ATL2_ISR_DMAR_TIMEOUT | ATL2_ISR_DMAW_TIMEOUT | 817 ATL2_ISR_PHY_LINKDOWN)) 818 atl2_setup(); 819 820 try_send = try_recv = FALSE; 821 822 /* Process sent data, and possibly send pending data. */ 823 if (val & ATL2_ISR_TX_EVENT) { 824 if (atl2_tx_advance()) 825 try_send = TRUE; 826 } 827 828 /* Receive new data, and possible satisfy a pending receive request. */ 829 if (val & ATL2_ISR_RX_EVENT) { 830 if (!state.rx_avail) { 831 atl2_rx_advance(FALSE /*next*/); 832 833 try_recv = TRUE; 834 } 835 } 836 837 /* Reenable interrupts. */ 838 ATL2_WRITE_U32(ATL2_ISR_REG, 0); 839 840 if ((r = sys_irqenable(&state.hook_id)) != OK) 841 panic("unable to enable IRQ: %d", r); 842 843 /* Attempt to satisfy pending send and receive requests. */ 844 if (try_send) 845 netdriver_send(); 846 if (try_recv) 847 netdriver_recv(); 848 } 849 850 /* 851 * Copy out statistics. 852 */ 853 static void 854 atl2_stat(eth_stat_t * stat) 855 { 856 857 memcpy(stat, &state.stat, sizeof(*stat)); 858 } 859 860 /* 861 * Dump link status. 862 */ 863 static void 864 atl2_dump_link(void) 865 { 866 uint16_t val; 867 int link_up; 868 869 /* The link status bit is latched. Read the status register twice. */ 870 atl2_read_mdio(ATL2_MII_BMSR, &val); 871 if (!atl2_read_mdio(ATL2_MII_BMSR, &val)) return; 872 873 link_up = val & ATL2_MII_BMSR_LSTATUS; 874 printf("link status: %4s\t", link_up ? "up" : "down"); 875 876 if (!link_up) return; 877 878 if (!atl2_read_mdio(ATL2_MII_PSSR, &val)) return; 879 880 if (!(val & ATL2_MII_PSSR_RESOLVED)) { 881 printf("(not resolved)\n"); 882 883 return; 884 } 885 886 switch (val & ATL2_MII_PSSR_SPEED) { 887 case ATL2_MII_PSSR_10: printf("(10Mbps "); break; 888 case ATL2_MII_PSSR_100: printf("(100Mbps "); break; 889 case ATL2_MII_PSSR_1000: printf("(1000Mbps "); break; 890 default: printf("(unknown, "); 891 } 892 893 printf("%s duplex)", (val & ATL2_MII_PSSR_DUPLEX) ? "full" : "half"); 894 } 895 896 /* 897 * Dump statistics. 898 */ 899 static void 900 atl2_dump(void) 901 { 902 903 printf("\n"); 904 printf("Attansic L2 statistics:\n"); 905 906 printf("recvErr: %8ld\t", state.stat.ets_recvErr); 907 printf("sendErr: %8ld\t", state.stat.ets_sendErr); 908 printf("OVW: %8ld\n", state.stat.ets_OVW); 909 910 printf("CRCerr: %8ld\t", state.stat.ets_CRCerr); 911 printf("frameAll: %8ld\t", state.stat.ets_frameAll); 912 printf("missedP: %8ld\n", state.stat.ets_missedP); 913 914 printf("packetR: %8ld\t", state.stat.ets_packetR); 915 printf("packetT: %8ld\t", state.stat.ets_packetT); 916 printf("transDef: %8ld\n", state.stat.ets_transDef); 917 918 printf("collision: %8ld\t", state.stat.ets_collision); 919 printf("transAb: %8ld\t", state.stat.ets_transAb); 920 printf("carrSense: %8ld\n", state.stat.ets_carrSense); 921 922 printf("fifoUnder: %8ld\t", state.stat.ets_fifoUnder); 923 printf("fifoOver: %8ld\t", state.stat.ets_fifoOver); 924 printf("CDheartbeat: %8ld\n", state.stat.ets_CDheartbeat); 925 926 printf("OWC: %8ld\t", state.stat.ets_OWC); 927 printf("TxD tail: %8d\t", state.txd_tail); 928 printf("TxD count: %8d\n", state.txd_num); 929 930 printf("RxD tail: %8d\t", state.rxd_tail); 931 printf("TxS tail: %8d\t", state.txs_tail); 932 printf("TxS count: %8d\n", state.txs_num); 933 934 atl2_dump_link(); 935 printf("\n"); 936 } 937 938 /* 939 * Process miscellaneous messages. 940 */ 941 static void 942 atl2_other(const message * m_ptr, int ipc_status) 943 { 944 #if ATL2_FKEY 945 int sfkeys; 946 947 if (!is_ipc_notify(ipc_status) || m_ptr->m_source != TTY_PROC_NR) 948 return; 949 950 if (fkey_events(NULL, &sfkeys) == OK && bit_isset(sfkeys, ATL2_FKEY)) 951 atl2_dump(); 952 #endif 953 } 954 955 /* 956 * Initialize the atl2 driver. 957 */ 958 static int 959 atl2_init(unsigned int instance, ether_addr_t * addr) 960 { 961 int devind; 962 #if ATL2_FKEY 963 int r, fkeys, sfkeys; 964 #endif 965 966 memset(&state, 0, sizeof(state)); 967 968 /* Try to find a recognized device. */ 969 devind = atl2_probe(instance); 970 971 if (devind < 0) 972 return ENXIO; 973 974 /* Initialize the device. */ 975 atl2_init_hw(devind, addr); 976 977 #if ATL2_FKEY 978 /* Register debug dump function key. */ 979 fkeys = sfkeys = 0; 980 bit_set(sfkeys, ATL2_FKEY); 981 if ((r = fkey_map(&fkeys, &sfkeys)) != OK) 982 printf("ATL2: warning, could not map Shift+F%u key (%d)\n", 983 r, ATL2_FKEY); 984 #endif 985 986 return OK; 987 } 988 989 #if 0 990 /* 991 * Deallocate resources as proof of concept. Currently unused. 992 */ 993 static void 994 atl2_cleanup(void) 995 { 996 int r; 997 998 if ((r = sys_irqrmpolicy(&state.hook_id)) != OK) 999 panic("unable to deregister IRQ: %d", r); 1000 1001 free_contig(state.txd_base, ATL2_TXD_BUFSIZE); 1002 free_contig(state.txs_base, ATL2_TXS_COUNT * sizeof(uint32_t)); 1003 free_contig(state.rxd_base_u, 1004 state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE); 1005 1006 vm_unmap_phys(SELF, (void *)state.base, state.size); 1007 1008 /* We cannot free the PCI device at this time. */ 1009 } 1010 #endif 1011 1012 /* 1013 * The ATL2 ethernet driver. 1014 */ 1015 int 1016 main(int argc, char ** argv) 1017 { 1018 1019 env_setargs(argc, argv); 1020 1021 netdriver_task(&atl2_table); 1022 1023 return EXIT_SUCCESS; 1024 } 1025