Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v2.6.14 665 lines 16 kB view raw
1/* 2 * 3 * Copyright (c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> 4 * 5 * Module name: oaknet.c 6 * 7 * Description: 8 * Driver for the National Semiconductor DP83902AV Ethernet controller 9 * on-board the IBM PowerPC "Oak" evaluation board. Adapted from the 10 * various other 8390 drivers written by Donald Becker and Paul Gortmaker. 11 * 12 * Additional inspiration from the "tcd8390.c" driver from TiVo, Inc. 13 * and "enetLib.c" from IBM. 14 * 15 */ 16 17#include <linux/module.h> 18#include <linux/errno.h> 19#include <linux/delay.h> 20#include <linux/netdevice.h> 21#include <linux/etherdevice.h> 22#include <linux/init.h> 23 24#include <asm/board.h> 25#include <asm/io.h> 26 27#include "8390.h" 28 29 30/* Preprocessor Defines */ 31 32#if !defined(TRUE) || TRUE != 1 33#define TRUE 1 34#endif 35 36#if !defined(FALSE) || FALSE != 0 37#define FALSE 0 38#endif 39 40#define OAKNET_START_PG 0x20 /* First page of TX buffer */ 41#define OAKNET_STOP_PG 0x40 /* Last pagge +1 of RX ring */ 42 43#define OAKNET_WAIT (2 * HZ / 100) /* 20 ms */ 44 45/* Experimenting with some fixes for a broken driver... */ 46 47#define OAKNET_DISINT 48#define OAKNET_HEADCHECK 49#define OAKNET_RWFIX 50 51 52/* Global Variables */ 53 54static const char *name = "National DP83902AV"; 55 56static struct net_device *oaknet_devs; 57 58 59/* Function Prototypes */ 60 61static int oaknet_open(struct net_device *dev); 62static int oaknet_close(struct net_device *dev); 63 64static void oaknet_reset_8390(struct net_device *dev); 65static void oaknet_get_8390_hdr(struct net_device *dev, 66 struct e8390_pkt_hdr *hdr, int ring_page); 67static void oaknet_block_input(struct net_device *dev, int count, 68 struct sk_buff *skb, int ring_offset); 69static void oaknet_block_output(struct net_device *dev, int count, 70 const unsigned char *buf, int start_page); 71 72static void oaknet_dma_error(struct net_device *dev, const char *name); 73 74 75/* 76 * int oaknet_init() 77 * 78 * Description: 79 * This routine performs all the necessary platform-specific initiali- 80 * zation and set-up for the IBM "Oak" evaluation board's National 81 * Semiconductor DP83902AV "ST-NIC" Ethernet controller. 82 * 83 * Input(s): 84 * N/A 85 * 86 * Output(s): 87 * N/A 88 * 89 * Returns: 90 * 0 if OK, otherwise system error number on error. 91 * 92 */ 93static int __init oaknet_init(void) 94{ 95 register int i; 96 int reg0, regd; 97 int ret = -ENOMEM; 98 struct net_device *dev; 99#if 0 100 unsigned long ioaddr = OAKNET_IO_BASE; 101#else 102 unsigned long ioaddr = ioremap(OAKNET_IO_BASE, OAKNET_IO_SIZE); 103#endif 104 bd_t *bip = (bd_t *)__res; 105 106 if (!ioaddr) 107 return -ENOMEM; 108 109 dev = alloc_ei_netdev(); 110 if (!dev) 111 goto out_unmap; 112 113 ret = -EBUSY; 114 if (!request_region(OAKNET_IO_BASE, OAKNET_IO_SIZE, name)) 115 goto out_dev; 116 117 /* Quick register check to see if the device is really there. */ 118 119 ret = -ENODEV; 120 if ((reg0 = ei_ibp(ioaddr)) == 0xFF) 121 goto out_region; 122 123 /* 124 * That worked. Now a more thorough check, using the multicast 125 * address registers, that the device is definitely out there 126 * and semi-functional. 127 */ 128 129 ei_obp(E8390_NODMA + E8390_PAGE1 + E8390_STOP, ioaddr + E8390_CMD); 130 regd = ei_ibp(ioaddr + 0x0D); 131 ei_obp(0xFF, ioaddr + 0x0D); 132 ei_obp(E8390_NODMA + E8390_PAGE0, ioaddr + E8390_CMD); 133 ei_ibp(ioaddr + EN0_COUNTER0); 134 135 /* It's no good. Fix things back up and leave. */ 136 137 ret = -ENODEV; 138 if (ei_ibp(ioaddr + EN0_COUNTER0) != 0) { 139 ei_obp(reg0, ioaddr); 140 ei_obp(regd, ioaddr + 0x0D); 141 goto out_region; 142 } 143 144 SET_MODULE_OWNER(dev); 145 146 /* 147 * This controller is on an embedded board, so the base address 148 * and interrupt assignments are pre-assigned and unchageable. 149 */ 150 151 dev->base_addr = ioaddr; 152 dev->irq = OAKNET_INT; 153 154 /* 155 * Disable all chip interrupts for now and ACK all pending 156 * interrupts. 157 */ 158 159 ei_obp(0x0, ioaddr + EN0_IMR); 160 ei_obp(0xFF, ioaddr + EN0_ISR); 161 162 /* Attempt to get the interrupt line */ 163 164 ret = -EAGAIN; 165 if (request_irq(dev->irq, ei_interrupt, 0, name, dev)) { 166 printk("%s: unable to request interrupt %d.\n", 167 name, dev->irq); 168 goto out_region; 169 } 170 171 /* Tell the world about what and where we've found. */ 172 173 printk("%s: %s at", dev->name, name); 174 for (i = 0; i < ETHER_ADDR_LEN; ++i) { 175 dev->dev_addr[i] = bip->bi_enetaddr[i]; 176 printk("%c%.2x", (i ? ':' : ' '), dev->dev_addr[i]); 177 } 178 printk(", found at %#lx, using IRQ %d.\n", dev->base_addr, dev->irq); 179 180 /* Set up some required driver fields and then we're done. */ 181 182 ei_status.name = name; 183 ei_status.word16 = FALSE; 184 ei_status.tx_start_page = OAKNET_START_PG; 185 ei_status.rx_start_page = OAKNET_START_PG + TX_PAGES; 186 ei_status.stop_page = OAKNET_STOP_PG; 187 188 ei_status.reset_8390 = &oaknet_reset_8390; 189 ei_status.block_input = &oaknet_block_input; 190 ei_status.block_output = &oaknet_block_output; 191 ei_status.get_8390_hdr = &oaknet_get_8390_hdr; 192 193 dev->open = oaknet_open; 194 dev->stop = oaknet_close; 195#ifdef CONFIG_NET_POLL_CONTROLLER 196 dev->poll_controller = ei_poll; 197#endif 198 199 NS8390_init(dev, FALSE); 200 ret = register_netdev(dev); 201 if (ret) 202 goto out_irq; 203 204 oaknet_devs = dev; 205 return 0; 206 207out_irq; 208 free_irq(dev->irq, dev); 209out_region: 210 release_region(OAKNET_IO_BASE, OAKNET_IO_SIZE); 211out_dev: 212 free_netdev(dev); 213out_unmap: 214 iounmap(ioaddr); 215 return ret; 216} 217 218/* 219 * static int oaknet_open() 220 * 221 * Description: 222 * This routine is a modest wrapper around ei_open, the 8390-generic, 223 * driver open routine. This just increments the module usage count 224 * and passes along the status from ei_open. 225 * 226 * Input(s): 227 * *dev - Pointer to the device structure for this driver. 228 * 229 * Output(s): 230 * *dev - Pointer to the device structure for this driver, potentially 231 * modified by ei_open. 232 * 233 * Returns: 234 * 0 if OK, otherwise < 0 on error. 235 * 236 */ 237static int 238oaknet_open(struct net_device *dev) 239{ 240 int status = ei_open(dev); 241 return (status); 242} 243 244/* 245 * static int oaknet_close() 246 * 247 * Description: 248 * This routine is a modest wrapper around ei_close, the 8390-generic, 249 * driver close routine. This just decrements the module usage count 250 * and passes along the status from ei_close. 251 * 252 * Input(s): 253 * *dev - Pointer to the device structure for this driver. 254 * 255 * Output(s): 256 * *dev - Pointer to the device structure for this driver, potentially 257 * modified by ei_close. 258 * 259 * Returns: 260 * 0 if OK, otherwise < 0 on error. 261 * 262 */ 263static int 264oaknet_close(struct net_device *dev) 265{ 266 int status = ei_close(dev); 267 return (status); 268} 269 270/* 271 * static void oaknet_reset_8390() 272 * 273 * Description: 274 * This routine resets the DP83902 chip. 275 * 276 * Input(s): 277 * *dev - Pointer to the device structure for this driver. 278 * 279 * Output(s): 280 * N/A 281 * 282 * Returns: 283 * N/A 284 * 285 */ 286static void 287oaknet_reset_8390(struct net_device *dev) 288{ 289 int base = E8390_BASE; 290 291 /* 292 * We have no provision of reseting the controller as is done 293 * in other drivers, such as "ne.c". However, the following 294 * seems to work well enough in the TiVo driver. 295 */ 296 297 printk("Resetting %s...\n", dev->name); 298 ei_obp(E8390_STOP | E8390_NODMA | E8390_PAGE0, base + E8390_CMD); 299 ei_status.txing = 0; 300 ei_status.dmaing = 0; 301} 302 303/* 304 * static void oaknet_get_8390_hdr() 305 * 306 * Description: 307 * This routine grabs the 8390-specific header. It's similar to the 308 * block input routine, but we don't need to be concerned with ring wrap 309 * as the header will be at the start of a page, so we optimize accordingly. 310 * 311 * Input(s): 312 * *dev - Pointer to the device structure for this driver. 313 * *hdr - Pointer to storage for the 8390-specific packet header. 314 * ring_page - ? 315 * 316 * Output(s): 317 * *hdr - Pointer to the 8390-specific packet header for the just- 318 * received frame. 319 * 320 * Returns: 321 * N/A 322 * 323 */ 324static void 325oaknet_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, 326 int ring_page) 327{ 328 int base = dev->base_addr; 329 330 /* 331 * This should NOT happen. If it does, it is the LAST thing you'll 332 * see. 333 */ 334 335 if (ei_status.dmaing) { 336 oaknet_dma_error(dev, "oaknet_get_8390_hdr"); 337 return; 338 } 339 340 ei_status.dmaing |= 0x01; 341 outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, base + OAKNET_CMD); 342 outb_p(sizeof(struct e8390_pkt_hdr), base + EN0_RCNTLO); 343 outb_p(0, base + EN0_RCNTHI); 344 outb_p(0, base + EN0_RSARLO); /* On page boundary */ 345 outb_p(ring_page, base + EN0_RSARHI); 346 outb_p(E8390_RREAD + E8390_START, base + OAKNET_CMD); 347 348 if (ei_status.word16) 349 insw(base + OAKNET_DATA, hdr, 350 sizeof(struct e8390_pkt_hdr) >> 1); 351 else 352 insb(base + OAKNET_DATA, hdr, 353 sizeof(struct e8390_pkt_hdr)); 354 355 /* Byte-swap the packet byte count */ 356 357 hdr->count = le16_to_cpu(hdr->count); 358 359 outb_p(ENISR_RDC, base + EN0_ISR); /* ACK Remote DMA interrupt */ 360 ei_status.dmaing &= ~0x01; 361} 362 363/* 364 * XXX - Document me. 365 */ 366static void 367oaknet_block_input(struct net_device *dev, int count, struct sk_buff *skb, 368 int ring_offset) 369{ 370 int base = OAKNET_BASE; 371 char *buf = skb->data; 372 373 /* 374 * This should NOT happen. If it does, it is the LAST thing you'll 375 * see. 376 */ 377 378 if (ei_status.dmaing) { 379 oaknet_dma_error(dev, "oaknet_block_input"); 380 return; 381 } 382 383#ifdef OAKNET_DISINT 384 save_flags(flags); 385 cli(); 386#endif 387 388 ei_status.dmaing |= 0x01; 389 ei_obp(E8390_NODMA + E8390_PAGE0 + E8390_START, base + E8390_CMD); 390 ei_obp(count & 0xff, base + EN0_RCNTLO); 391 ei_obp(count >> 8, base + EN0_RCNTHI); 392 ei_obp(ring_offset & 0xff, base + EN0_RSARLO); 393 ei_obp(ring_offset >> 8, base + EN0_RSARHI); 394 ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD); 395 if (ei_status.word16) { 396 ei_isw(base + E8390_DATA, buf, count >> 1); 397 if (count & 0x01) { 398 buf[count - 1] = ei_ib(base + E8390_DATA); 399#ifdef OAKNET_HEADCHECK 400 bytes++; 401#endif 402 } 403 } else { 404 ei_isb(base + E8390_DATA, buf, count); 405 } 406#ifdef OAKNET_HEADCHECK 407 /* 408 * This was for the ALPHA version only, but enough people have 409 * been encountering problems so it is still here. If you see 410 * this message you either 1) have a slightly incompatible clone 411 * or 2) have noise/speed problems with your bus. 412 */ 413 414 /* DMA termination address check... */ 415 { 416 int addr, tries = 20; 417 do { 418 /* DON'T check for 'ei_ibp(EN0_ISR) & ENISR_RDC' here 419 -- it's broken for Rx on some cards! */ 420 int high = ei_ibp(base + EN0_RSARHI); 421 int low = ei_ibp(base + EN0_RSARLO); 422 addr = (high << 8) + low; 423 if (((ring_offset + bytes) & 0xff) == low) 424 break; 425 } while (--tries > 0); 426 if (tries <= 0) 427 printk("%s: RX transfer address mismatch," 428 "%#4.4x (expected) vs. %#4.4x (actual).\n", 429 dev->name, ring_offset + bytes, addr); 430 } 431#endif 432 ei_obp(ENISR_RDC, base + EN0_ISR); /* ACK Remote DMA interrupt */ 433 ei_status.dmaing &= ~0x01; 434 435#ifdef OAKNET_DISINT 436 restore_flags(flags); 437#endif 438} 439 440/* 441 * static void oaknet_block_output() 442 * 443 * Description: 444 * This routine... 445 * 446 * Input(s): 447 * *dev - Pointer to the device structure for this driver. 448 * count - Number of bytes to be transferred. 449 * *buf - 450 * start_page - 451 * 452 * Output(s): 453 * N/A 454 * 455 * Returns: 456 * N/A 457 * 458 */ 459static void 460oaknet_block_output(struct net_device *dev, int count, 461 const unsigned char *buf, int start_page) 462{ 463 int base = E8390_BASE; 464#if 0 465 int bug; 466#endif 467 unsigned long start; 468#ifdef OAKNET_DISINT 469 unsigned long flags; 470#endif 471#ifdef OAKNET_HEADCHECK 472 int retries = 0; 473#endif 474 475 /* Round the count up for word writes. */ 476 477 if (ei_status.word16 && (count & 0x1)) 478 count++; 479 480 /* 481 * This should NOT happen. If it does, it is the LAST thing you'll 482 * see. 483 */ 484 485 if (ei_status.dmaing) { 486 oaknet_dma_error(dev, "oaknet_block_output"); 487 return; 488 } 489 490#ifdef OAKNET_DISINT 491 save_flags(flags); 492 cli(); 493#endif 494 495 ei_status.dmaing |= 0x01; 496 497 /* Make sure we are in page 0. */ 498 499 ei_obp(E8390_PAGE0 + E8390_START + E8390_NODMA, base + E8390_CMD); 500 501#ifdef OAKNET_HEADCHECK 502retry: 503#endif 504 505#if 0 506 /* 507 * The 83902 documentation states that the processor needs to 508 * do a "dummy read" before doing the remote write to work 509 * around a chip bug they don't feel like fixing. 510 */ 511 512 bug = 0; 513 while (1) { 514 unsigned int rdhi; 515 unsigned int rdlo; 516 517 /* Now the normal output. */ 518 ei_obp(ENISR_RDC, base + EN0_ISR); 519 ei_obp(count & 0xff, base + EN0_RCNTLO); 520 ei_obp(count >> 8, base + EN0_RCNTHI); 521 ei_obp(0x00, base + EN0_RSARLO); 522 ei_obp(start_page, base + EN0_RSARHI); 523 524 if (bug++) 525 break; 526 527 /* Perform the dummy read */ 528 rdhi = ei_ibp(base + EN0_CRDAHI); 529 rdlo = ei_ibp(base + EN0_CRDALO); 530 ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD); 531 532 while (1) { 533 unsigned int nrdhi; 534 unsigned int nrdlo; 535 nrdhi = ei_ibp(base + EN0_CRDAHI); 536 nrdlo = ei_ibp(base + EN0_CRDALO); 537 if ((rdhi != nrdhi) || (rdlo != nrdlo)) 538 break; 539 } 540 } 541#else 542#ifdef OAKNET_RWFIX 543 /* 544 * Handle the read-before-write bug the same way as the 545 * Crynwr packet driver -- the Nat'l Semi. method doesn't work. 546 * Actually this doesn't always work either, but if you have 547 * problems with your 83902 this is better than nothing! 548 */ 549 550 ei_obp(0x42, base + EN0_RCNTLO); 551 ei_obp(0x00, base + EN0_RCNTHI); 552 ei_obp(0x42, base + EN0_RSARLO); 553 ei_obp(0x00, base + EN0_RSARHI); 554 ei_obp(E8390_RREAD + E8390_START, base + E8390_CMD); 555 /* Make certain that the dummy read has occurred. */ 556 udelay(6); 557#endif 558 559 ei_obp(ENISR_RDC, base + EN0_ISR); 560 561 /* Now the normal output. */ 562 ei_obp(count & 0xff, base + EN0_RCNTLO); 563 ei_obp(count >> 8, base + EN0_RCNTHI); 564 ei_obp(0x00, base + EN0_RSARLO); 565 ei_obp(start_page, base + EN0_RSARHI); 566#endif /* 0/1 */ 567 568 ei_obp(E8390_RWRITE + E8390_START, base + E8390_CMD); 569 if (ei_status.word16) { 570 ei_osw(E8390_BASE + E8390_DATA, buf, count >> 1); 571 } else { 572 ei_osb(E8390_BASE + E8390_DATA, buf, count); 573 } 574 575#ifdef OAKNET_DISINT 576 restore_flags(flags); 577#endif 578 579 start = jiffies; 580 581#ifdef OAKNET_HEADCHECK 582 /* 583 * This was for the ALPHA version only, but enough people have 584 * been encountering problems so it is still here. 585 */ 586 587 { 588 /* DMA termination address check... */ 589 int addr, tries = 20; 590 do { 591 int high = ei_ibp(base + EN0_RSARHI); 592 int low = ei_ibp(base + EN0_RSARLO); 593 addr = (high << 8) + low; 594 if ((start_page << 8) + count == addr) 595 break; 596 } while (--tries > 0); 597 598 if (tries <= 0) { 599 printk("%s: Tx packet transfer address mismatch," 600 "%#4.4x (expected) vs. %#4.4x (actual).\n", 601 dev->name, (start_page << 8) + count, addr); 602 if (retries++ == 0) 603 goto retry; 604 } 605 } 606#endif 607 608 while ((ei_ibp(base + EN0_ISR) & ENISR_RDC) == 0) { 609 if (jiffies - start > OAKNET_WAIT) { 610 printk("%s: timeout waiting for Tx RDC.\n", dev->name); 611 oaknet_reset_8390(dev); 612 NS8390_init(dev, TRUE); 613 break; 614 } 615 } 616 617 ei_obp(ENISR_RDC, base + EN0_ISR); /* Ack intr. */ 618 ei_status.dmaing &= ~0x01; 619} 620 621/* 622 * static void oaknet_dma_error() 623 * 624 * Description: 625 * This routine prints out a last-ditch informative message to the console 626 * indicating that a DMA error occurred. If you see this, it's the last 627 * thing you'll see. 628 * 629 * Input(s): 630 * *dev - Pointer to the device structure for this driver. 631 * *name - Informative text (e.g. function name) indicating where the 632 * DMA error occurred. 633 * 634 * Output(s): 635 * N/A 636 * 637 * Returns: 638 * N/A 639 * 640 */ 641static void 642oaknet_dma_error(struct net_device *dev, const char *name) 643{ 644 printk(KERN_EMERG "%s: DMAing conflict in %s." 645 "[DMAstat:%d][irqlock:%d][intr:%ld]\n", 646 dev->name, name, ei_status.dmaing, ei_status.irqlock, 647 dev->interrupt); 648} 649 650/* 651 * Oak Ethernet module unload interface. 652 */ 653static void __exit oaknet_cleanup_module (void) 654{ 655 /* Convert to loop once driver supports multiple devices. */ 656 unregister_netdev(oaknet_dev); 657 free_irq(oaknet_devs->irq, oaknet_devs); 658 release_region(oaknet_devs->base_addr, OAKNET_IO_SIZE); 659 iounmap(ioaddr); 660 free_netdev(oaknet_devs); 661} 662 663module_init(oaknet_init); 664module_exit(oaknet_cleanup_module); 665MODULE_LICENSE("GPL");