oaknet.c 15 KB

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