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 <sys/mman.h> 11 #include <minix/ds.h> 12 #include <minix/vm.h> 13 #include <machine/pci.h> 14 #include <net/gen/ether.h> 15 #include <net/gen/eth_io.h> 16 #include <assert.h> 17 18 #include "atl2.h" 19 20 #define VERBOSE 0 /* Verbose debugging output */ 21 #define ATL2_FKEY 1 /* Register Shift+F11 for dumping statistics */ 22 23 #if VERBOSE 24 #define ATL2_DEBUG(x) printf x 25 #else 26 #define ATL2_DEBUG(x) 27 #endif 28 29 typedef struct { 30 u32_t hdr; 31 u32_t vtag; 32 u8_t data[ATL2_RXD_SIZE - sizeof(u32_t) * 2]; 33 } rxd_t; 34 35 static struct { 36 int devind; /* PCI device index */ 37 int irq; /* IRQ number */ 38 int hook_id; /* IRQ hook ID */ 39 int mode; /* datalink mode */ 40 volatile u8_t *base; /* base address of memory-mapped registers */ 41 u32_t size; /* size of memory-mapped area */ 42 u32_t hwaddr[2]; /* MAC address, in register representation */ 43 44 u8_t *txd_base; /* local address of TxD ring buffer base */ 45 u32_t *txs_base; /* local address of TxS ring buffer base */ 46 u8_t *rxd_base_u; /* unaligned base address of RxD ring buffer */ 47 rxd_t *rxd_base; /* local address of RxD ring buffer base */ 48 49 int rxd_align; /* alignment offset of RxD ring buffer */ 50 51 vir_bytes txd_phys; /* physical address of TxD ring buffer */ 52 vir_bytes txs_phys; /* physical address of TxS ring buffer */ 53 vir_bytes rxd_phys; /* physical address of RxD ring buffer */ 54 55 int txd_tail; /* tail index into TxD, in bytes */ 56 int txd_num; /* head-tail offset into TxD, in bytes */ 57 int txs_tail; /* tail index into TxS, in elements */ 58 int txs_num; /* head-tail offset into TxS, in elements */ 59 int rxd_tail; /* tail index into RxD, in elements */ 60 61 int flags; /* state flags (ATL2_FLAG_) */ 62 message read_msg; /* suspended read request (READ_PEND) */ 63 message write_msg; /* suspended write request (WRITE_PEND) */ 64 endpoint_t task_endpt; /* requester endpoint (PACK_RCVD|PACK_SENT) */ 65 size_t recv_count; /* packet size (PACK_RCVD) */ 66 67 eth_stat_t stat; /* statistics */ 68 } state; 69 70 #define ATL2_FLAG_RX_AVAIL 0x01 /* packet available for receipt */ 71 #define ATL2_FLAG_READ_PEND 0x02 /* read request pending */ 72 #define ATL2_FLAG_WRITE_PEND 0x04 /* write request pending */ 73 #define ATL2_FLAG_PACK_RCVD 0x08 /* packet received */ 74 #define ATL2_FLAG_PACK_SENT 0x10 /* packet transmitted */ 75 76 #define ATL2_READ_U8(off) (* (u8_t *) (state.base + (off))) 77 #define ATL2_READ_U16(off) (* (u16_t *) (state.base + (off))) 78 #define ATL2_READ_U32(off) (* (u32_t *) (state.base + (off))) 79 #define ATL2_WRITE_U8(off, val) * (u8_t *) (state.base + (off)) = (val); 80 #define ATL2_WRITE_U16(off, val) * (u16_t *) (state.base + (off)) = (val); 81 #define ATL2_WRITE_U32(off, val) * (u32_t *) (state.base + (off)) = (val); 82 83 #define ATL2_ALIGN_32(n) (((n) + 3) & ~3) 84 85 static iovec_s_t iovec[NR_IOREQS]; 86 87 static int instance; 88 89 /*===========================================================================* 90 * atl2_read_vpd * 91 *===========================================================================*/ 92 static int atl2_read_vpd(int index, u32_t *res) 93 { 94 /* Read a value from the VPD register area. 95 */ 96 u32_t off, val; 97 int i; 98 99 ATL2_WRITE_U32(ATL2_VPD_DATA_REG, 0); 100 101 off = ATL2_VPD_REGBASE + index * sizeof(u32_t); 102 103 ATL2_WRITE_U32(ATL2_VPD_CAP_REG, 104 (off << ATL2_VPD_CAP_ADDR_SHIFT) & ATL2_VPD_CAP_ADDR_MASK); 105 106 for (i = 0; i < ATL2_VPD_NTRIES; i++) { 107 micro_delay(ATL2_VPD_DELAY); 108 109 val = ATL2_READ_U32(ATL2_VPD_CAP_REG); 110 if (val & ATL2_VPD_CAP_DONE) 111 break; 112 } 113 114 if (i == ATL2_VPD_NTRIES) { 115 printf("ATL2: timeout reading EEPROM register %d\n", index); 116 return FALSE; 117 } 118 119 *res = ATL2_READ_U32(ATL2_VPD_DATA_REG); 120 return TRUE; 121 } 122 123 /*===========================================================================* 124 * atl2_get_vpd_hwaddr * 125 *===========================================================================*/ 126 static int atl2_get_vpd_hwaddr(void) 127 { 128 /* Read the MAC address from the EEPROM, using the Vital Product Data 129 * register interface. 130 */ 131 u32_t key, val; 132 int i, n, found[2]; 133 134 /* No idea, copied from FreeBSD which copied it from Linux. */ 135 val = ATL2_READ_U32(ATL2_SPICTL_REG); 136 if (val & ATL2_SPICTL_VPD_EN) { 137 val &= ~ATL2_SPICTL_VPD_EN; 138 ATL2_WRITE_U32(ATL2_SPICTL_REG, val); 139 } 140 141 /* Is VPD supported? */ 142 #ifdef PCI_CAP_VPD /* FIXME: just a guess at the future name */ 143 if (!pci_find_cap(state.devind, PCI_CAP_VPD, &n)) 144 return FALSE; 145 #endif 146 147 /* Read out the set of key/value pairs. Look for the two parts that 148 * make up the MAC address. 149 */ 150 found[0] = found[1] = FALSE; 151 for (i = 0; i < ATL2_VPD_NREGS; i += 2) { 152 if (!atl2_read_vpd(i, &key)) 153 break; 154 155 if ((key & ATL2_VPD_SIG_MASK) != ATL2_VPD_SIG) 156 break; 157 158 key >>= ATL2_VPD_REG_SHIFT; 159 160 if (key != ATL2_HWADDR0_REG && key != ATL2_HWADDR1_REG) 161 continue; 162 163 if (!atl2_read_vpd(i + 1, &val)) 164 break; 165 166 n = (key == ATL2_HWADDR1_REG); 167 state.hwaddr[n] = val; 168 found[n] = TRUE; 169 170 if (found[1 - n]) break; 171 } 172 173 return found[0] && found[1]; 174 } 175 176 /*===========================================================================* 177 * atl2_get_hwaddr * 178 *===========================================================================*/ 179 static void atl2_get_hwaddr(void) 180 { 181 /* Get the MAC address of the card. First try the EEPROM; if that 182 * fails, just use whatever the card was already set to. 183 */ 184 185 if (!atl2_get_vpd_hwaddr()) { 186 printf("ATL2: unable to read from VPD\n"); 187 188 state.hwaddr[0] = ATL2_READ_U32(ATL2_HWADDR0_REG); 189 state.hwaddr[1] = ATL2_READ_U32(ATL2_HWADDR1_REG) & 0xffff; 190 } 191 192 ATL2_DEBUG(("ATL2: MAC address %04lx%08lx\n", 193 state.hwaddr[1], state.hwaddr[0])); 194 } 195 196 /*===========================================================================* 197 * atl2_read_mdio * 198 *===========================================================================*/ 199 static int atl2_read_mdio(int addr, u16_t *res) 200 { 201 /* Read a MII PHY register using MDIO. 202 */ 203 u32_t rval; 204 int i; 205 206 rval = ((addr << ATL2_MDIO_ADDR_SHIFT) & ATL2_MDIO_ADDR_MASK) | 207 ATL2_MDIO_START | ATL2_MDIO_READ | ATL2_MDIO_SUP_PREAMBLE | 208 ATL2_MDIO_CLK_25_4; 209 210 ATL2_WRITE_U32(ATL2_MDIO_REG, rval); 211 212 for (i = 0; i < ATL2_MDIO_NTRIES; i++) { 213 micro_delay(ATL2_MDIO_DELAY); 214 215 rval = ATL2_READ_U32(ATL2_MDIO_REG); 216 217 if (!(rval & (ATL2_MDIO_START | ATL2_MDIO_BUSY))) 218 break; 219 } 220 221 if (i == ATL2_MDIO_NTRIES) return FALSE; 222 223 *res = (u16_t) (rval & ATL2_MDIO_DATA_MASK); 224 return TRUE; 225 } 226 227 /*===========================================================================* 228 * atl2_alloc_dma * 229 *===========================================================================*/ 230 static int atl2_alloc_dma(void) 231 { 232 /* Allocate DMA ring buffers. 233 */ 234 235 state.txd_base = alloc_contig(ATL2_TXD_BUFSIZE, 236 AC_ALIGN4K, &state.txd_phys); 237 state.txs_base = alloc_contig(ATL2_TXS_COUNT * sizeof(u32_t), 238 AC_ALIGN4K, &state.txs_phys); 239 240 /* The data buffer in each RxD descriptor must be 128-byte aligned. 241 * The two Tx buffers merely require a 4-byte start alignment. 242 */ 243 state.rxd_align = 128 - offsetof(rxd_t, data); 244 state.rxd_base_u = 245 alloc_contig(state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE, 246 AC_ALIGN4K, &state.rxd_phys); 247 248 /* Unlike mmap, alloc_contig returns NULL on failure. */ 249 if (!state.txd_base || !state.txs_base || !state.rxd_base_u) 250 return ENOMEM; 251 252 state.rxd_base = (rxd_t *) (state.rxd_base_u + state.rxd_align); 253 state.rxd_phys += state.rxd_align; 254 255 /* Zero out just in case. */ 256 memset(state.txd_base, 0, ATL2_TXD_BUFSIZE); 257 memset(state.txs_base, 0, ATL2_TXS_COUNT * sizeof(u32_t)); 258 memset(state.rxd_base, 0, ATL2_RXD_COUNT * ATL2_RXD_SIZE); 259 260 return OK; 261 } 262 263 /*===========================================================================* 264 * atl2_stop * 265 *===========================================================================*/ 266 static int atl2_stop(void) 267 { 268 /* Stop the device. 269 */ 270 u32_t val; 271 int i; 272 273 /* Clear and disable interrupts. */ 274 ATL2_WRITE_U32(ATL2_IMR_REG, 0); 275 ATL2_WRITE_U32(ATL2_ISR_REG, 0xffffffff); 276 277 /* Stop Rx/Tx MACs. */ 278 val = ATL2_READ_U32(ATL2_MAC_REG); 279 if (val & (ATL2_MAC_RX_EN | ATL2_MAC_TX_EN)) { 280 val &= ~(ATL2_MAC_RX_EN | ATL2_MAC_TX_EN); 281 ATL2_WRITE_U32(ATL2_MAC_REG, val); 282 } 283 284 ATL2_WRITE_U8(ATL2_DMAWRITE_REG, 0); 285 ATL2_WRITE_U8(ATL2_DMAREAD_REG, 0); 286 287 /* Wait until everything is idle. */ 288 for (i = 0; i < ATL2_IDLE_NTRIES; i++) { 289 if (ATL2_READ_U32(ATL2_IDLE_REG) == 0) 290 break; 291 292 micro_delay(ATL2_IDLE_DELAY); 293 } 294 295 /* The caller will generally ignore this return value. */ 296 return (i < ATL2_IDLE_NTRIES); 297 } 298 299 /*===========================================================================* 300 * atl2_reset * 301 *===========================================================================*/ 302 static int atl2_reset(void) 303 { 304 /* Reset the device to a known good state. 305 */ 306 u32_t val; 307 int i; 308 309 /* Issue a soft reset, and wait for the device to respond. */ 310 ATL2_WRITE_U32(ATL2_MASTER_REG, ATL2_MASTER_SOFT_RESET); 311 312 for (i = 0; i < ATL2_RESET_NTRIES; i++) { 313 val = ATL2_READ_U32(ATL2_MASTER_REG); 314 if (!(val & ATL2_MASTER_SOFT_RESET)) 315 break; 316 317 micro_delay(ATL2_RESET_DELAY); 318 } 319 320 if (i == ATL2_RESET_NTRIES) 321 return FALSE; 322 323 /* Wait until everything is idle. */ 324 for (i = 0; i < ATL2_IDLE_NTRIES; i++) { 325 if (ATL2_READ_U32(ATL2_IDLE_REG) == 0) 326 break; 327 328 micro_delay(ATL2_IDLE_DELAY); 329 } 330 331 return (i < ATL2_IDLE_NTRIES); 332 } 333 334 /*===========================================================================* 335 * atl2_set_mode * 336 *===========================================================================*/ 337 static void atl2_set_mode(void) 338 { 339 /* Reconfigure the device's promiscuity, multicast, and broadcast mode 340 * settings. 341 */ 342 u32_t val; 343 344 val = ATL2_READ_U32(ATL2_MAC_REG); 345 val &= ~(ATL2_MAC_PROMISC_EN | ATL2_MAC_MCAST_EN | ATL2_MAC_BCAST_EN); 346 347 if (state.mode & DL_PROMISC_REQ) 348 val |= ATL2_MAC_PROMISC_EN; 349 if (state.mode & DL_MULTI_REQ) 350 val |= ATL2_MAC_MCAST_EN; 351 if (state.mode & DL_BROAD_REQ) 352 val |= ATL2_MAC_BCAST_EN; 353 354 ATL2_WRITE_U32(ATL2_MAC_REG, val); 355 } 356 357 /*===========================================================================* 358 * atl2_setup * 359 *===========================================================================*/ 360 static int atl2_setup(void) 361 { 362 /* Set up the device for normal operation. 363 */ 364 u32_t val; 365 366 atl2_stop(); 367 368 if (!atl2_reset()) 369 return FALSE; 370 371 /* Initialize PCIE module. Magic. */ 372 ATL2_WRITE_U32(ATL2_LTSSM_TESTMODE_REG, ATL2_LTSSM_TESTMODE_DEFAULT); 373 ATL2_WRITE_U32(ATL2_DLL_TX_CTRL_REG, ATL2_DLL_TX_CTRL_DEFAULT); 374 375 /* Enable PHY. */ 376 ATL2_WRITE_U32(ATL2_PHY_ENABLE_REG, ATL2_PHY_ENABLE); 377 micro_delay(1000); 378 379 /* Clear and disable interrupts. */ 380 ATL2_WRITE_U32(ATL2_ISR_REG, 0xffffffff); 381 382 /* Set the MAC address. */ 383 ATL2_WRITE_U32(ATL2_HWADDR0_REG, state.hwaddr[0]); 384 ATL2_WRITE_U32(ATL2_HWADDR1_REG, state.hwaddr[1]); 385 386 /* Initialize ring buffer addresses and sizes. */ 387 ATL2_WRITE_U32(ATL2_DESC_ADDR_HI_REG, 0); /* no 64 bit */ 388 ATL2_WRITE_U32(ATL2_TXD_ADDR_LO_REG, state.txd_phys); 389 ATL2_WRITE_U32(ATL2_TXS_ADDR_LO_REG, state.txs_phys); 390 ATL2_WRITE_U32(ATL2_RXD_ADDR_LO_REG, state.rxd_phys); 391 392 ATL2_WRITE_U16(ATL2_RXD_COUNT_REG, ATL2_RXD_COUNT); 393 ATL2_WRITE_U16(ATL2_TXD_BUFSIZE_REG, ATL2_TXD_BUFSIZE / sizeof(u32_t)); 394 ATL2_WRITE_U16(ATL2_TXS_COUNT_REG, ATL2_TXS_COUNT); 395 396 /* A whole lot of other initialization copied from Linux/FreeBSD. */ 397 ATL2_WRITE_U32(ATL2_IFG_REG, ATL2_IFG_DEFAULT); 398 399 ATL2_WRITE_U32(ATL2_HDPX_REG, ATL2_HDPX_DEFAULT); 400 401 ATL2_WRITE_U16(ATL2_IMT_REG, ATL2_IMT_DEFAULT); 402 val = ATL2_READ_U32(ATL2_MASTER_REG); 403 ATL2_WRITE_U32(ATL2_MASTER_REG, val | ATL2_MASTER_IMT_EN); 404 405 ATL2_WRITE_U16(ATL2_ICT_REG, ATL2_ICT_DEFAULT); 406 407 ATL2_WRITE_U32(ATL2_CUT_THRESH_REG, ATL2_CUT_THRESH_DEFAULT); 408 409 ATL2_WRITE_U16(ATL2_FLOW_THRESH_HI_REG, (ATL2_RXD_COUNT / 8) * 7); 410 ATL2_WRITE_U16(ATL2_FLOW_THRESH_LO_REG, ATL2_RXD_COUNT / 12); 411 412 /* Set MTU. */ 413 ATL2_WRITE_U16(ATL2_MTU_REG, ATL2_MTU_DEFAULT); 414 415 /* Reset descriptors, and enable DMA. */ 416 state.txd_tail = state.txs_tail = state.rxd_tail = 0; 417 state.txd_num = state.txs_num = 0; 418 state.flags &= ~ATL2_FLAG_RX_AVAIL; 419 ATL2_WRITE_U16(ATL2_TXD_IDX_REG, 0); 420 ATL2_WRITE_U16(ATL2_RXD_IDX_REG, 0); 421 422 ATL2_WRITE_U8(ATL2_DMAREAD_REG, ATL2_DMAREAD_EN); 423 ATL2_WRITE_U8(ATL2_DMAWRITE_REG, ATL2_DMAWRITE_EN); 424 425 /* Did everything go alright? */ 426 val = ATL2_READ_U32(ATL2_ISR_REG); 427 if (val & ATL2_ISR_PHY_LINKDOWN) { 428 printf("ATL2: initialization failed\n"); 429 return FALSE; 430 } 431 432 /* Clear interrupt status. */ 433 ATL2_WRITE_U32(ATL2_ISR_REG, 0x3fffffff); 434 ATL2_WRITE_U32(ATL2_ISR_REG, 0); 435 436 /* Enable interrupts. */ 437 ATL2_WRITE_U32(ATL2_IMR_REG, ATL2_IMR_DEFAULT); 438 439 /* Configure MAC. */ 440 ATL2_WRITE_U32(ATL2_MAC_REG, ATL2_MAC_DEFAULT); 441 442 /* Inet does not tell us about the multicast addresses that it is 443 * interested in, so we have to simply accept all multicast packets. 444 */ 445 ATL2_WRITE_U32(ATL2_MHT0_REG, 0xffffffff); 446 ATL2_WRITE_U32(ATL2_MHT1_REG, 0xffffffff); 447 448 atl2_set_mode(); 449 450 /* Enable Tx/Rx. */ 451 val = ATL2_READ_U32(ATL2_MAC_REG); 452 ATL2_WRITE_U32(ATL2_MAC_REG, val | ATL2_MAC_TX_EN | ATL2_MAC_RX_EN); 453 454 return TRUE; 455 } 456 457 /*===========================================================================* 458 * atl2_probe * 459 *===========================================================================*/ 460 static int atl2_probe(int skip) 461 { 462 /* Find a matching PCI device. 463 */ 464 u16_t vid, did; 465 #if VERBOSE 466 char *dname; 467 #endif 468 int r, devind; 469 470 pci_init(); 471 472 r = pci_first_dev(&devind, &vid, &did); 473 if (r <= 0) 474 return -1; 475 476 while (skip--) { 477 r = pci_next_dev(&devind, &vid, &did); 478 if (r <= 0) 479 return -1; 480 } 481 482 #if VERBOSE 483 dname = pci_dev_name(vid, did); 484 ATL2_DEBUG(("ATL2: found %s (%x/%x) at %s\n", 485 dname ? dname : "<unknown>", vid, did, 486 pci_slot_name(devind))); 487 #endif 488 489 pci_reserve(devind); 490 491 return devind; 492 } 493 494 /*===========================================================================* 495 * atl2_init * 496 *===========================================================================*/ 497 static void atl2_init(int devind) 498 { 499 /* Initialize the device. 500 */ 501 u32_t bar; 502 int r, flag; 503 504 /* Initialize global state. */ 505 state.devind = devind; 506 state.mode = DL_NOMODE; 507 state.flags = 0; 508 state.recv_count = 0; 509 510 memset(&state.stat, 0, sizeof(state.stat)); 511 512 if ((r = pci_get_bar(devind, PCI_BAR, &bar, &state.size, &flag)) != OK) 513 panic("unable to retrieve bar: %d", r); 514 515 if (state.size < ATL2_MIN_MMAP_SIZE || flag) 516 panic("invalid register bar"); 517 518 state.base = vm_map_phys(SELF, (void *) bar, state.size); 519 if (state.base == MAP_FAILED) 520 panic("unable to map in registers"); 521 522 if ((r = atl2_alloc_dma()) != OK) 523 panic("unable to allocate DMA buffers: %d", r); 524 525 state.irq = pci_attr_r8(devind, PCI_ILR); 526 state.hook_id = 0; 527 528 if ((r = sys_irqsetpolicy(state.irq, 0, &state.hook_id)) != OK) 529 panic("unable to register IRQ: %d", r); 530 531 if (!atl2_reset()) 532 panic("unable to reset hardware"); 533 534 if ((r = sys_irqenable(&state.hook_id)) != OK) 535 panic("unable to enable IRQ: %d", r); 536 537 atl2_get_hwaddr(); 538 539 atl2_setup(); 540 } 541 542 /*===========================================================================* 543 * atl2_tx_stat * 544 *===========================================================================*/ 545 static void atl2_tx_stat(u32_t stat) 546 { 547 /* Update statistics for packet transmission. 548 */ 549 550 if (stat & ATL2_TXS_SUCCESS) 551 state.stat.ets_packetT++; 552 else 553 state.stat.ets_recvErr++; 554 555 if (stat & ATL2_TXS_DEFER) 556 state.stat.ets_transDef++; 557 if (stat & (ATL2_TXS_EXCDEFER | ATL2_TXS_ABORTCOL)) 558 state.stat.ets_transAb++; 559 if (stat & ATL2_TXS_SINGLECOL) 560 state.stat.ets_collision++; 561 if (stat & ATL2_TXS_MULTICOL) 562 state.stat.ets_collision++; 563 if (stat & ATL2_TXS_LATECOL) 564 state.stat.ets_OWC++; 565 if (stat & ATL2_TXS_UNDERRUN) 566 state.stat.ets_fifoUnder++; 567 } 568 569 /*===========================================================================* 570 * atl2_rx_stat * 571 *===========================================================================*/ 572 static void atl2_rx_stat(u32_t stat) 573 { 574 /* Update statistics for packet receipt. 575 */ 576 577 if (stat & ATL2_RXD_SUCCESS) 578 state.stat.ets_packetR++; 579 else 580 state.stat.ets_recvErr++; 581 582 if (stat & ATL2_RXD_CRCERR) 583 state.stat.ets_CRCerr++; 584 if (stat & ATL2_RXD_FRAG) 585 state.stat.ets_collision++; 586 if (stat & ATL2_RXD_TRUNC) 587 state.stat.ets_fifoOver++; 588 if (stat & ATL2_RXD_ALIGN) 589 state.stat.ets_frameAll++; 590 } 591 592 /*===========================================================================* 593 * atl2_tx_advance * 594 *===========================================================================*/ 595 static int atl2_tx_advance(void) 596 { 597 /* Advance the TxD/TxS tails by as many sent packets as found. 598 */ 599 u32_t stat, size, dsize; 600 int advanced; 601 602 advanced = FALSE; 603 604 while (state.txs_num > 0) { 605 /* Has the tail packet been processed by the driver? */ 606 stat = state.txs_base[state.txs_tail]; 607 608 if (!(stat & ATL2_TXS_UPDATE)) 609 break; 610 611 /* The packet size from the status must match the packet size 612 * we put in. If they don't, there's not much we can do.. 613 */ 614 size = stat & ATL2_TXS_SIZE_MASK; 615 616 assert((u32_t) state.txd_tail <= 617 ATL2_TXD_BUFSIZE - sizeof(u32_t)); 618 dsize = * (u32_t *) (state.txd_base + state.txd_tail); 619 if (size != dsize) 620 printf("ATL2: TxD/TxS size mismatch (%x vs %x)\n", 621 size, dsize); 622 623 /* Advance tails accordingly. */ 624 size = sizeof(u32_t) + ATL2_ALIGN_32(dsize); 625 assert((u32_t) state.txd_num >= size); 626 state.txd_tail = (state.txd_tail + size) % ATL2_TXD_BUFSIZE; 627 state.txd_num -= size; 628 629 state.txs_tail = (state.txs_tail + 1) % ATL2_TXS_COUNT; 630 state.txs_num--; 631 632 if (stat & ATL2_TXS_SUCCESS) { 633 ATL2_DEBUG(("ATL2: successfully sent packet\n")); 634 } else { 635 ATL2_DEBUG(("ATL2: failed to send packet\n")); 636 } 637 638 /* Update statistics. */ 639 atl2_tx_stat(stat); 640 641 advanced = TRUE; 642 } 643 644 return advanced; 645 } 646 647 /*===========================================================================* 648 * atl2_rx_advance * 649 *===========================================================================*/ 650 static void atl2_rx_advance(int next) 651 { 652 /* Advance the RxD tail by as many failed receipts as possible, and 653 * see if there is an actual packet left to receive. If 'next' is set, 654 * the packet at the current tail has been processed. 655 */ 656 int update_tail; 657 rxd_t *rxd; 658 u32_t hdr, size; 659 660 update_tail = FALSE; 661 662 if (next) { 663 state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT; 664 update_tail = TRUE; 665 666 ATL2_DEBUG(("ATL2: successfully received packet\n")); 667 668 state.flags &= ~ATL2_FLAG_RX_AVAIL; 669 } 670 671 assert(!(state.flags & ATL2_FLAG_RX_AVAIL)); 672 673 for (;;) { 674 /* Check the RxD tail for updates. */ 675 rxd = &state.rxd_base[state.rxd_tail]; 676 677 hdr = rxd->hdr; 678 679 if (!(hdr & ATL2_RXD_UPDATE)) 680 break; 681 682 rxd->hdr = hdr & ~(ATL2_RXD_UPDATE); 683 684 /* Update statistics. */ 685 atl2_rx_stat(hdr); 686 687 /* Stop at the first successful receipt. The packet will be 688 * picked up by Inet later. 689 */ 690 size = hdr & ATL2_RXD_SIZE_MASK; 691 692 if ((hdr & ATL2_RXD_SUCCESS) && size >= ETH_MIN_PACK_SIZE) { 693 ATL2_DEBUG(("ATL2: packet available, size %ld\n", 694 size)); 695 696 state.flags |= ATL2_FLAG_RX_AVAIL; 697 break; 698 } 699 700 ATL2_DEBUG(("ATL2: packet receipt failed\n")); 701 702 /* Advance tail. */ 703 state.rxd_tail = (state.rxd_tail + 1) % ATL2_RXD_COUNT; 704 update_tail = TRUE; 705 } 706 707 /* If new RxD descriptors are now up for reuse, tell the device. */ 708 if (update_tail) { 709 __insn_barrier(); 710 711 ATL2_WRITE_U32(ATL2_RXD_IDX_REG, state.rxd_tail); 712 } 713 } 714 715 /*===========================================================================* 716 * atl2_reply * 717 *===========================================================================*/ 718 static void atl2_reply(void) 719 { 720 /* Send a task reply to Inet. 721 */ 722 message m; 723 int r, flags; 724 725 flags = DL_NOFLAGS; 726 if (state.flags & ATL2_FLAG_PACK_SENT) 727 flags |= DL_PACK_SEND; 728 if (state.flags & ATL2_FLAG_PACK_RCVD) 729 flags |= DL_PACK_RECV; 730 731 m.m_type = DL_TASK_REPLY; 732 m.m_netdrv_net_dl_task.flags = flags; 733 m.m_netdrv_net_dl_task.count = state.recv_count; 734 735 ATL2_DEBUG(("ATL2: sending reply, flags %x count %d\n", flags, 736 m.m_netdrv_net_dl_task.count)); 737 738 if ((r = ipc_send(state.task_endpt, &m)) != OK) 739 panic("unable to reply: %d", r); 740 741 state.flags &= ~(ATL2_FLAG_PACK_SENT | ATL2_FLAG_PACK_RCVD); 742 state.recv_count = 0; 743 } 744 745 /*===========================================================================* 746 * atl2_readv * 747 *===========================================================================*/ 748 static void atl2_readv(const message *m, int from_int) 749 { 750 /* Read packet data. 751 */ 752 rxd_t *rxd; 753 iovec_s_t *iovp; 754 size_t count, off, left, size; 755 u8_t *pos; 756 int i, j, r, batch; 757 758 /* We can deal with only one read request from Inet at a time. */ 759 assert(from_int || !(state.flags & ATL2_FLAG_READ_PEND)); 760 761 state.task_endpt = m->m_source; 762 763 /* Are there any packets available at all? */ 764 if (!(state.flags & ATL2_FLAG_RX_AVAIL)) 765 goto suspend; 766 767 /* Get the first available packet's size. Cut off the CRC. */ 768 rxd = &state.rxd_base[state.rxd_tail]; 769 770 count = rxd->hdr & ATL2_RXD_SIZE_MASK; 771 count -= ETH_CRC_SIZE; 772 773 ATL2_DEBUG(("ATL2: readv: found packet with length %d\n", count)); 774 775 /* Copy out the packet. */ 776 off = 0; 777 left = count; 778 pos = rxd->data; 779 780 for (i = 0; i < m->m_net_netdrv_dl_readv_s.count && left > 0; i += batch) { 781 /* Copy in the next batch. */ 782 batch = MIN(m->m_net_netdrv_dl_readv_s.count - i, NR_IOREQS); 783 784 r = sys_safecopyfrom(m->m_source, 785 m->m_net_netdrv_dl_readv_s.grant, off, (vir_bytes) iovec, 786 batch * sizeof(iovec[0])); 787 if (r != OK) 788 panic("vector copy failed: %d", r); 789 790 /* Copy out each element in the batch, until we run out. */ 791 for (j = 0, iovp = iovec; j < batch && left > 0; j++, iovp++) { 792 size = MIN(iovp->iov_size, left); 793 794 r = sys_safecopyto(m->m_source, iovp->iov_grant, 0, 795 (vir_bytes) pos, size); 796 if (r != OK) 797 panic("safe copy failed: %d", r); 798 799 pos += size; 800 left -= size; 801 } 802 803 off += batch * sizeof(iovec[0]); 804 } 805 806 /* Not sure what to do here. Inet shouldn't mess this up anyway. */ 807 if (left > 0) { 808 printf("ATL2: truncated packet of %d bytes by %d bytes\n", 809 count, left); 810 count -= left; 811 } 812 813 /* We are done with this packet. Move on to the next. */ 814 atl2_rx_advance(TRUE /*next*/); 815 816 /* We have now successfully received a packet. */ 817 state.flags &= ~ATL2_FLAG_READ_PEND; 818 state.flags |= ATL2_FLAG_PACK_RCVD; 819 state.recv_count = count; 820 821 /* If called from the interrupt handler, the caller will reply. */ 822 if (!from_int) 823 atl2_reply(); 824 825 return; 826 827 suspend: 828 /* No packets are available at this time. If we were not already 829 * trying to resume receipt, save the read request for later, and tell 830 * Inet that the request has been suspended. 831 */ 832 if (from_int) 833 return; 834 835 state.flags |= ATL2_FLAG_READ_PEND; 836 state.read_msg = *m; 837 838 atl2_reply(); 839 } 840 841 /*===========================================================================* 842 * atl2_writev * 843 *===========================================================================*/ 844 static void atl2_writev(const message *m, int from_int) 845 { 846 /* Write packet data. 847 */ 848 iovec_s_t *iovp; 849 size_t off, count, left, pos, skip; 850 vir_bytes size; 851 u8_t *sizep; 852 int i, j, r, batch, maxnum; 853 854 /* We can deal with only one write request from Inet at a time. */ 855 assert(from_int || !(state.flags & ATL2_FLAG_WRITE_PEND)); 856 857 state.task_endpt = m->m_source; 858 859 /* If we are already certain that the packet won't fit, bail out. 860 * Keep at least some space between TxD head and tail, as it is not 861 * clear whether the device deals well with the case that they collide. 862 */ 863 if (state.txs_num >= ATL2_TXS_COUNT) 864 goto suspend; 865 maxnum = ATL2_TXD_BUFSIZE - ETH_MIN_PACK_SIZE - sizeof(u32_t); 866 if (state.txd_num >= maxnum) 867 goto suspend; 868 869 /* Optimistically try to copy in the data; suspend if it turns out 870 * that it does not fit. 871 */ 872 off = 0; 873 count = 0; 874 left = state.txd_num - sizeof(u32_t); 875 pos = (state.txd_tail + state.txd_num + 876 sizeof(u32_t)) % ATL2_TXD_BUFSIZE; 877 878 for (i = 0; i < m->m_net_netdrv_dl_writev_s.count; i += batch) { 879 /* Copy in the next batch. */ 880 batch = MIN(m->m_net_netdrv_dl_writev_s.count - i, NR_IOREQS); 881 882 r = sys_safecopyfrom(m->m_source, 883 m->m_net_netdrv_dl_writev_s.grant, off, (vir_bytes) iovec, 884 batch * sizeof(iovec[0])); 885 if (r != OK) 886 panic("vector copy failed: %d", r); 887 888 /* Copy in each element in the batch. */ 889 for (j = 0, iovp = iovec; j < batch; j++, iovp++) { 890 size = iovp->iov_size; 891 if (size > left) 892 goto suspend; 893 894 skip = 0; 895 if (size > ATL2_TXD_BUFSIZE - pos) { 896 skip = ATL2_TXD_BUFSIZE - pos; 897 r = sys_safecopyfrom(m->m_source, 898 iovp->iov_grant, 0, 899 (vir_bytes) (state.txd_base + pos), 900 skip); 901 if (r != OK) 902 panic("safe copy failed: %d", r); 903 pos = 0; 904 } 905 906 r = sys_safecopyfrom(m->m_source, iovp->iov_grant, 907 skip, (vir_bytes) (state.txd_base + pos), 908 size - skip); 909 if (r != OK) 910 panic("safe copy failed: %d", r); 911 912 pos = (pos + size - skip) % ATL2_TXD_BUFSIZE; 913 left -= size; 914 count += size; 915 } 916 917 off += batch * sizeof(iovec[0]); 918 } 919 920 assert(count <= ETH_MAX_PACK_SIZE_TAGGED); 921 922 /* Write the length to the DWORD right before the packet. */ 923 sizep = state.txd_base + 924 (state.txd_tail + state.txd_num) % ATL2_TXD_BUFSIZE; 925 * (u32_t *) sizep = count; 926 927 /* Update the TxD head. */ 928 state.txd_num += sizeof(u32_t) + ATL2_ALIGN_32(count); 929 pos = ATL2_ALIGN_32(pos) % ATL2_TXD_BUFSIZE; 930 assert((int) pos == 931 (state.txd_tail + state.txd_num) % ATL2_TXD_BUFSIZE); 932 933 /* Initialize and update the TxS head. */ 934 state.txs_base[(state.txs_tail + state.txs_num) % ATL2_TXS_COUNT] = 0; 935 state.txs_num++; 936 937 /* Tell the device about our new position. */ 938 __insn_barrier(); 939 940 ATL2_WRITE_U32(ATL2_TXD_IDX_REG, pos / sizeof(u32_t)); 941 942 /* We have now successfully set up the transmission of a packet. */ 943 state.flags &= ~ATL2_FLAG_WRITE_PEND; 944 state.flags |= ATL2_FLAG_PACK_SENT; 945 946 /* If called from the interrupt handler, the caller will reply. */ 947 if (!from_int) 948 atl2_reply(); 949 950 return; 951 952 suspend: 953 /* We cannot transmit the packet at this time. If we were not already 954 * trying to resume transmission, save the write request for later, 955 * and tell Inet that the request has been suspended. 956 */ 957 if (from_int) 958 return; 959 960 state.flags |= ATL2_FLAG_WRITE_PEND; 961 state.write_msg = *m; 962 963 atl2_reply(); 964 } 965 966 /*===========================================================================* 967 * atl2_intr * 968 *===========================================================================*/ 969 static void atl2_intr(const message *UNUSED(m)) 970 { 971 /* Interrupt received. 972 */ 973 u32_t val; 974 int r, try_write, try_read; 975 976 /* Clear and disable interrupts. */ 977 val = ATL2_READ_U32(ATL2_ISR_REG); 978 979 ATL2_WRITE_U32(ATL2_ISR_REG, val | ATL2_ISR_DISABLE); 980 981 ATL2_DEBUG(("ATL2: interrupt (0x%08lx)\n", val)); 982 983 /* If an error occurred, reset the card. */ 984 if (val & (ATL2_ISR_DMAR_TIMEOUT | ATL2_ISR_DMAW_TIMEOUT | 985 ATL2_ISR_PHY_LINKDOWN)) { 986 atl2_setup(); 987 } 988 989 try_write = try_read = FALSE; 990 991 /* Process sent data, and possibly send pending data. */ 992 if (val & ATL2_ISR_TX_EVENT) { 993 if (atl2_tx_advance()) 994 try_write = (state.flags & ATL2_FLAG_WRITE_PEND); 995 } 996 997 /* Receive new data, and possible satisfy a pending receive request. */ 998 if (val & ATL2_ISR_RX_EVENT) { 999 if (!(state.flags & ATL2_FLAG_RX_AVAIL)) { 1000 atl2_rx_advance(FALSE /*next*/); 1001 1002 try_read = (state.flags & ATL2_FLAG_READ_PEND); 1003 } 1004 } 1005 1006 /* Reenable interrupts. */ 1007 ATL2_WRITE_U32(ATL2_ISR_REG, 0); 1008 1009 if ((r = sys_irqenable(&state.hook_id)) != OK) 1010 panic("unable to enable IRQ: %d", r); 1011 1012 /* Attempt to satisfy pending write and read requests. */ 1013 if (try_write) 1014 atl2_writev(&state.write_msg, TRUE /*from_int*/); 1015 if (try_read) 1016 atl2_readv(&state.read_msg, TRUE /*from_int*/); 1017 if (state.flags & (ATL2_FLAG_PACK_SENT | ATL2_FLAG_PACK_RCVD)) 1018 atl2_reply(); 1019 } 1020 1021 /*===========================================================================* 1022 * atl2_conf * 1023 *===========================================================================*/ 1024 static void atl2_conf(message *m) 1025 { 1026 /* Configure the mode of the card. 1027 */ 1028 ether_addr_t addr; 1029 int r; 1030 1031 state.mode = m->m_net_netdrv_dl_conf.mode; 1032 1033 atl2_set_mode(); 1034 1035 addr.ea_addr[0] = state.hwaddr[1] >> 8; 1036 addr.ea_addr[1] = state.hwaddr[1] & 0xff; 1037 addr.ea_addr[2] = state.hwaddr[0] >> 24; 1038 addr.ea_addr[3] = (state.hwaddr[0] >> 16) & 0xff; 1039 addr.ea_addr[4] = (state.hwaddr[0] >> 8) & 0xff; 1040 addr.ea_addr[5] = state.hwaddr[0] & 0xff; 1041 1042 memcpy(m->m_netdrv_net_dl_conf.hw_addr, &addr, 1043 sizeof(m->m_netdrv_net_dl_conf.hw_addr)); 1044 1045 m->m_type = DL_CONF_REPLY; 1046 m->m_netdrv_net_dl_conf.stat = OK; 1047 1048 if ((r = ipc_send(m->m_source, m)) != OK) 1049 printf("ATL2: unable to send reply (%d)\n", r); 1050 } 1051 1052 /*===========================================================================* 1053 * atl2_getstat * 1054 *===========================================================================*/ 1055 static void atl2_getstat(message *m) 1056 { 1057 /* Copy out statistics. 1058 */ 1059 int r; 1060 1061 sys_safecopyto(m->m_source, m->m_net_netdrv_dl_getstat_s.grant, 0, 1062 (vir_bytes) &state.stat, sizeof(state.stat)); 1063 1064 m->m_type = DL_STAT_REPLY; 1065 1066 if ((r = ipc_send(m->m_source, m)) != OK) 1067 printf("ATL2: unable to send reply (%d)\n", r); 1068 } 1069 1070 /*===========================================================================* 1071 * atl2_dump_link * 1072 *===========================================================================*/ 1073 static void atl2_dump_link(void) 1074 { 1075 /* Dump link status. 1076 */ 1077 u16_t val; 1078 int link_up; 1079 1080 /* The link status bit is latched. Read the status register twice. */ 1081 atl2_read_mdio(ATL2_MII_BMSR, &val); 1082 if (!atl2_read_mdio(ATL2_MII_BMSR, &val)) return; 1083 1084 link_up = val & ATL2_MII_BMSR_LSTATUS; 1085 printf("link status: %4s\t", link_up ? "up" : "down"); 1086 1087 if (!link_up) return; 1088 1089 if (!atl2_read_mdio(ATL2_MII_PSSR, &val)) return; 1090 1091 if (!(val & ATL2_MII_PSSR_RESOLVED)) { 1092 printf("(not resolved)\n"); 1093 1094 return; 1095 } 1096 1097 switch (val & ATL2_MII_PSSR_SPEED) { 1098 case ATL2_MII_PSSR_10: printf("(10Mbps "); break; 1099 case ATL2_MII_PSSR_100: printf("(100Mbps "); break; 1100 case ATL2_MII_PSSR_1000: printf("(1000Mbps "); break; 1101 default: printf("(unknown, "); 1102 } 1103 1104 printf("%s duplex)", (val & ATL2_MII_PSSR_DUPLEX) ? "full" : "half"); 1105 } 1106 1107 /*===========================================================================* 1108 * atl2_dump * 1109 *===========================================================================*/ 1110 static void atl2_dump(void) 1111 { 1112 /* Dump statistics. 1113 */ 1114 1115 printf("\n"); 1116 printf("Attansic L2 statistics:\n"); 1117 1118 printf("recvErr: %8ld\t", state.stat.ets_recvErr); 1119 printf("sendErr: %8ld\t", state.stat.ets_sendErr); 1120 printf("OVW: %8ld\n", state.stat.ets_OVW); 1121 1122 printf("CRCerr: %8ld\t", state.stat.ets_CRCerr); 1123 printf("frameAll: %8ld\t", state.stat.ets_frameAll); 1124 printf("missedP: %8ld\n", state.stat.ets_missedP); 1125 1126 printf("packetR: %8ld\t", state.stat.ets_packetR); 1127 printf("packetT: %8ld\t", state.stat.ets_packetT); 1128 printf("transDef: %8ld\n", state.stat.ets_transDef); 1129 1130 printf("collision: %8ld\t", state.stat.ets_collision); 1131 printf("transAb: %8ld\t", state.stat.ets_transAb); 1132 printf("carrSense: %8ld\n", state.stat.ets_carrSense); 1133 1134 printf("fifoUnder: %8ld\t", state.stat.ets_fifoUnder); 1135 printf("fifoOver: %8ld\t", state.stat.ets_fifoOver); 1136 printf("CDheartbeat: %8ld\n", state.stat.ets_CDheartbeat); 1137 1138 printf("OWC: %8ld\t", state.stat.ets_OWC); 1139 printf("TxD tail: %8d\t", state.txd_tail); 1140 printf("TxD count: %8d\n", state.txd_num); 1141 1142 printf("RxD tail: %8d\t", state.rxd_tail); 1143 printf("TxS tail: %8d\t", state.txs_tail); 1144 printf("TxS count: %8d\n", state.txs_num); 1145 1146 printf("flags: 0x%04x\t", state.flags); 1147 atl2_dump_link(); 1148 printf("\n"); 1149 } 1150 1151 /*===========================================================================* 1152 * sef_cb_init_fresh * 1153 *===========================================================================*/ 1154 static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info)) 1155 { 1156 /* Initialize the atl2 driver. 1157 */ 1158 int r, devind; 1159 long v; 1160 #if ATL2_FKEY 1161 int fkeys, sfkeys; 1162 #endif 1163 1164 /* How many matching devices should we skip? */ 1165 v = 0; 1166 (void) env_parse("instance", "d", 0, &v, 0, 255); 1167 instance = (int) v; 1168 1169 /* Try to find a recognized device. */ 1170 devind = atl2_probe(instance); 1171 1172 if (devind < 0) 1173 panic("no matching device found"); 1174 1175 /* Initialize the device. */ 1176 atl2_init(devind); 1177 1178 /* Announce we are up! */ 1179 netdriver_announce(); 1180 1181 #if ATL2_FKEY 1182 /* Register debug dump function key. */ 1183 fkeys = sfkeys = 0; 1184 bit_set(sfkeys, 11); 1185 if ((r = fkey_map(&fkeys, &sfkeys)) != OK) 1186 printf("ATL2: warning, could not map Shift+F11 key (%d)\n", r); 1187 #endif 1188 1189 return(OK); 1190 } 1191 1192 /*===========================================================================* 1193 * sef_cb_signal_handler * 1194 *===========================================================================*/ 1195 static void sef_cb_signal_handler(int signo) 1196 { 1197 /* In case of a termination signal, shut down this driver. 1198 * Stop the device, and deallocate resources as proof of concept. 1199 */ 1200 int r; 1201 1202 /* Only check for termination signal, ignore anything else. */ 1203 if (signo != SIGTERM) return; 1204 1205 atl2_stop(); 1206 1207 if ((r = sys_irqrmpolicy(&state.hook_id)) != OK) 1208 panic("unable to deregister IRQ: %d", r); 1209 1210 free_contig(state.txd_base, ATL2_TXD_BUFSIZE); 1211 free_contig(state.txs_base, ATL2_TXS_COUNT * sizeof(u32_t)); 1212 free_contig(state.rxd_base_u, 1213 state.rxd_align + ATL2_RXD_COUNT * ATL2_RXD_SIZE); 1214 1215 vm_unmap_phys(SELF, (void *) state.base, state.size); 1216 1217 /* We cannot free the PCI device at this time. */ 1218 1219 exit(0); 1220 } 1221 1222 /*===========================================================================* 1223 * sef_local_startup * 1224 *===========================================================================*/ 1225 static void sef_local_startup(void) 1226 { 1227 /* Register init callbacks. */ 1228 sef_setcb_init_fresh(sef_cb_init_fresh); 1229 sef_setcb_init_lu(sef_cb_init_fresh); 1230 sef_setcb_init_restart(sef_cb_init_fresh); 1231 1232 /* Register live update callbacks. */ 1233 sef_setcb_lu_prepare(sef_cb_lu_prepare_always_ready); 1234 sef_setcb_lu_state_isvalid(sef_cb_lu_state_isvalid_workfree); 1235 1236 /* Register signal callbacks. */ 1237 sef_setcb_signal_handler(sef_cb_signal_handler); 1238 1239 /* Let SEF perform startup. */ 1240 sef_startup(); 1241 } 1242 1243 /*===========================================================================* 1244 * main * 1245 *===========================================================================*/ 1246 int main(int argc, char **argv) 1247 { 1248 /* Driver task. 1249 */ 1250 message m; 1251 int ipc_status; 1252 int r; 1253 1254 /* Initialize SEF. */ 1255 env_setargs(argc, argv); 1256 sef_local_startup(); 1257 1258 while (TRUE) { 1259 if ((r = netdriver_receive(ANY, &m, &ipc_status)) != OK) 1260 panic("netdriver_receive failed: %d", r); 1261 1262 if (is_ipc_notify(ipc_status)) { 1263 switch (m.m_source) { 1264 case HARDWARE: /* interrupt */ 1265 atl2_intr(&m); 1266 1267 break; 1268 1269 case TTY_PROC_NR: /* function key */ 1270 atl2_dump(); 1271 1272 break; 1273 1274 default: 1275 printf("ATL2: illegal notify from %d\n", 1276 m.m_source); 1277 } 1278 1279 continue; 1280 } 1281 1282 /* Process requests from Inet. */ 1283 switch (m.m_type) { 1284 case DL_CONF: atl2_conf(&m); break; 1285 case DL_GETSTAT_S: atl2_getstat(&m); break; 1286 case DL_WRITEV_S: atl2_writev(&m, FALSE); break; 1287 case DL_READV_S: atl2_readv(&m, FALSE); break; 1288 default: 1289 printf("ATL2: illegal message %d from %d\n", 1290 m.m_type, m.m_source); 1291 } 1292 } 1293 } 1294