Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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