oaknet.c 15 KB

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