oaknet.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:16k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

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