tiara.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /**************************************************************************
  2. Etherboot - BOOTP/TFTP Bootstrap Program
  3. TIARA (Fujitsu Etherstar) NIC driver for Etherboot
  4. Copyright (c) Ken Yap 1998
  5. Information gleaned from:
  6. TIARA.ASM Packet driver by Brian Fisher, Queens U, Kingston, Ontario
  7. Fujitsu MB86960 spec sheet (different chip but same family)
  8. ***************************************************************************/
  9. /*
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2, or (at
  13. * your option) any later version.
  14. */
  15. /* to get some global routines like printf */
  16. #include "etherboot.h"
  17. /* to get the interface to the body of the program */
  18. #include "nic.h"
  19. #include "cards.h"
  20. /*
  21. EtherStar I/O Register offsets
  22. */
  23. /* Offsets of registers */
  24. #define DLCR_XMIT_STAT 0x00
  25. #define DLCR_XMIT_MASK 0x01
  26. #define DLCR_RECV_STAT 0x02
  27. #define DLCR_RECV_MASK 0x03
  28. #define DLCR_XMIT_MODE 0x04
  29. #define DLCR_RECV_MODE 0x05
  30. #define DLCR_ENABLE 0x06
  31. #define DLCR_TDR_LOW 0x07
  32. #define DLCR_NODE_ID 0x08
  33. #define DLCR_TDR_HIGH 0x0F
  34. #define BMPR_MEM_PORT 0x10
  35. #define BMPR_PKT_LEN 0x12
  36. #define BMPR_DMA_ENABLE 0x14
  37. #define PROM_ID 0x18
  38. #define TMST 0x80
  39. #define TMT_OK 0x80
  40. #define TMT_16COLL 0x02
  41. #define BUF_EMPTY 0x40
  42. #define CARD_DISABLE 0x80 /* written to DLCR_ENABLE to disable card */
  43. #define CARD_ENABLE 0 /* written to DLCR_ENABLE to enable card */
  44. #define CLEAR_STATUS 0x0F /* used to clear status info */
  45. /*
  46. 00001111B
  47. !!!!!!!!--------
  48. !!!!!!!+--------CLEAR BUS WRITE ERROR
  49. !!!!!!+---------CLEAR 16 COLLISION
  50. !!!!!+----------CLEAR COLLISION
  51. !!!!+-----------CLEAR UNDERFLOW
  52. !!!+------------NC
  53. !!+-------------NC
  54. !+--------------NC
  55. +---------------NC
  56. */
  57. #define NO_TX_IRQS 0 /* written to clear transmit IRQs */
  58. #define CLR_RCV_STATUS 0xCF /* clears receive status */
  59. #define EN_RCV_IRQS 0x80 /* enable receive interrupts */
  60. /*
  61. 10000000B
  62. !!!!!!!!--------
  63. !!!!!!!+--------ENABLE OVERFLOW
  64. !!!!!!+---------ENABLE CRC
  65. !!!!!+----------ENABLE ALIGN
  66. !!!!+-----------ENABLE SHORT PKT
  67. !!!+------------DISABLE REMOTE RESET
  68. !!+-------------RESERVED
  69. !+--------------RESERVED
  70. +---------------ENABLE PKT READY
  71. */
  72. #define XMIT_MODE 0x02
  73. /*
  74. 00000010B
  75. !!!!!!!!---------ENABLE CARRIER DETECT
  76. !!!!!!!+---------DISABLE LOOPBACK
  77. */
  78. #define RECV_MODE 0x02
  79. /*
  80. 00000010B
  81. !!!!!!!!---------ACCEPT ALL PACKETS
  82. !!!!!!!+---------ACCEPT PHYSICAL, MULTICAST, AND
  83. !!!!!!+----------BROADCAST PACKETS
  84. !!!!!+-----------DISABLE REMOTE RESET
  85. !!!!+------------DISABLE SHORT PACKETS
  86. !!!+-------------USE 6 BYTE ADDRESS
  87. !!+--------------NC
  88. !+---------------NC
  89. +----------------DISABLE CRC TEST MODE
  90. */
  91. /* NIC specific static variables go here */
  92. static unsigned short ioaddr;
  93. /**************************************************************************
  94. RESET - Reset adapter
  95. ***************************************************************************/
  96. static void tiara_reset(struct nic *nic)
  97. {
  98. int i;
  99. outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
  100. outb(CLEAR_STATUS, ioaddr + DLCR_XMIT_STAT);
  101. outb(NO_TX_IRQS, ioaddr + DLCR_XMIT_MASK);
  102. outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
  103. outb(XMIT_MODE, ioaddr + DLCR_XMIT_MODE);
  104. outb(RECV_MODE, ioaddr + DLCR_RECV_MODE);
  105. /* Vacuum recv buffer */
  106. while ((inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY) == 0)
  107. inb(ioaddr + BMPR_MEM_PORT);
  108. /* Set node address */
  109. for (i = 0; i < ETH_ALEN; ++i)
  110. outb(nic->node_addr[i], ioaddr + DLCR_NODE_ID + i);
  111. outb(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
  112. outb(CARD_ENABLE, ioaddr + DLCR_ENABLE);
  113. }
  114. /**************************************************************************
  115. POLL - Wait for a frame
  116. ***************************************************************************/
  117. static int tiara_poll(struct nic *nic)
  118. {
  119. unsigned int len;
  120. if (inb(ioaddr + DLCR_RECV_MODE) & BUF_EMPTY)
  121. return (0);
  122. /* Ack packet */
  123. outw(CLR_RCV_STATUS, ioaddr + DLCR_RECV_STAT);
  124. len = inw(ioaddr + BMPR_MEM_PORT); /* throw away status */
  125. len = inw(ioaddr + BMPR_MEM_PORT);
  126. /* Drop overlength packets */
  127. if (len > ETH_FRAME_LEN)
  128. return (0); /* should we drain the buffer? */
  129. insw(ioaddr + BMPR_MEM_PORT, nic->packet, len / 2);
  130. /* If it's our own, drop it */
  131. if (memcmp(nic->packet + ETH_ALEN, nic->node_addr, ETH_ALEN) == 0)
  132. return (0);
  133. nic->packetlen = len;
  134. return (1);
  135. }
  136. /**************************************************************************
  137. TRANSMIT - Transmit a frame
  138. ***************************************************************************/
  139. static void tiara_transmit(
  140. struct nic *nic,
  141. const char *d, /* Destination */
  142. unsigned int t, /* Type */
  143. unsigned int s, /* size */
  144. const char *p) /* Packet */
  145. {
  146. unsigned int len;
  147. unsigned long time;
  148. len = s + ETH_HLEN;
  149. if (len < ETH_ZLEN)
  150. len = ETH_ZLEN;
  151. t = htons(t);
  152. outsw(ioaddr + BMPR_MEM_PORT, d, ETH_ALEN / 2);
  153. outsw(ioaddr + BMPR_MEM_PORT, nic->node_addr, ETH_ALEN / 2);
  154. outw(t, ioaddr + BMPR_MEM_PORT);
  155. outsw(ioaddr + BMPR_MEM_PORT, p, s / 2);
  156. if (s & 1) /* last byte */
  157. outb(p[s-1], ioaddr + BMPR_MEM_PORT);
  158. while (s++ < ETH_ZLEN - ETH_HLEN) /* pad */
  159. outb(0, ioaddr + BMPR_MEM_PORT);
  160. outw(len | (TMST << 8), ioaddr + BMPR_PKT_LEN);
  161. /* wait for transmit complete */
  162. time = currticks() + TICKS_PER_SEC; /* wait one second */
  163. while (currticks() < time && (inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
  164. ;
  165. if ((inb(ioaddr) & (TMT_OK|TMT_16COLL)) == 0)
  166. printf("Tiara timed out on transmit\n");
  167. /* Do we need to ack the transmit? */
  168. }
  169. /**************************************************************************
  170. DISABLE - Turn off ethernet interface
  171. ***************************************************************************/
  172. static void tiara_disable(struct nic *nic)
  173. {
  174. /* Apparently only a power down can do this properly */
  175. outb(CARD_DISABLE, ioaddr + DLCR_ENABLE);
  176. }
  177. static int tiara_probe1(struct nic *nic)
  178. {
  179. /* Hope all the Tiara cards have this vendor prefix */
  180. static char vendor_prefix[] = { 0x08, 0x00, 0x1A };
  181. static char all_ones[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
  182. int i;
  183. for (i = 0; i < ETH_ALEN; ++i)
  184. nic->node_addr[i] = inb(ioaddr + PROM_ID + i);
  185. if (memcmp(nic->node_addr, vendor_prefix, sizeof(vendor_prefix)) != 0)
  186. return (0);
  187. if (memcmp(nic->node_addr, all_ones, sizeof(all_ones)) == 0)
  188. return (0);
  189. printf("\nTiara ioaddr %#hX, addr %!\n", ioaddr, nic->node_addr);
  190. return (1);
  191. }
  192. /**************************************************************************
  193. PROBE - Look for an adapter, this routine's visible to the outside
  194. ***************************************************************************/
  195. struct nic *tiara_probe(struct nic *nic, unsigned short *probe_addrs)
  196. {
  197. /* missing entries are addresses usually already used */
  198. static unsigned short io_addrs[] = {
  199. 0x100, 0x120, 0x140, 0x160,
  200. 0x180, 0x1A0, 0x1C0, 0x1E0,
  201. 0x200, 0x220, 0x240, /*Par*/
  202. 0x280, 0x2A0, 0x2C0, /*Ser*/
  203. 0x300, 0x320, 0x340, /*Par*/
  204. 0x380, /*Vid,Par*/ 0x3C0, /*Ser*/
  205. 0x0
  206. };
  207. unsigned short *p;
  208. /* if probe_addrs is 0, then routine can use a hardwired default */
  209. if (probe_addrs == 0)
  210. probe_addrs = io_addrs;
  211. for (p = probe_addrs; (ioaddr = *p) != 0; ++p)
  212. if (tiara_probe1(nic))
  213. break;
  214. /* if board found */
  215. if (ioaddr != 0)
  216. {
  217. tiara_reset(nic);
  218. /* point to NIC specific routines */
  219. nic->reset = tiara_reset;
  220. nic->poll = tiara_poll;
  221. nic->transmit = tiara_transmit;
  222. nic->disable = tiara_disable;
  223. return nic;
  224. }
  225. else
  226. return (0);
  227. }