3c589.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. /*------------------------------------------------------------------------
  2. . 3c589.c
  3. . This is a driver for 3Com's 3C589 (Etherlink III) PCMCIA Ethernet device.
  4. .
  5. . (C) Copyright 2002
  6. . Sysgo Real-Time Solutions, GmbH <www.elinos.com>
  7. . Rolf Offermanns <rof@sysgo.de>
  8. .
  9. . This program is free software; you can redistribute it and/or modify
  10. . it under the terms of the GNU General Public License as published by
  11. . the Free Software Foundation; either version 2 of the License, or
  12. . (at your option) any later version.
  13. .
  14. . This program is distributed in the hope that it will be useful,
  15. . but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. . MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. . GNU General Public License for more details.
  18. .
  19. . You should have received a copy of the GNU General Public License
  20. . along with this program; if not, write to the Free Software
  21. . Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  22. .
  23. ----------------------------------------------------------------------------*/
  24. #include <common.h>
  25. #include <command.h>
  26. #include <net.h>
  27. #include "3c589.h"
  28. /* Use power-down feature of the chip */
  29. #define POWER_DOWN 0
  30. #define NO_AUTOPROBE
  31. static const char version[] =
  32. "Your ad here! :P\n";
  33. #undef EL_DEBUG
  34. typedef unsigned char byte;
  35. typedef unsigned short word;
  36. typedef unsigned long int dword;
  37. /*------------------------------------------------------------------------
  38. .
  39. . Configuration options, for the experienced user to change.
  40. .
  41. -------------------------------------------------------------------------*/
  42. /*
  43. . Wait time for memory to be free. This probably shouldn't be
  44. . tuned that much, as waiting for this means nothing else happens
  45. . in the system
  46. */
  47. #define MEMORY_WAIT_TIME 16
  48. #if (EL_DEBUG > 2 )
  49. #define PRINTK3(args...) printf(args)
  50. #else
  51. #define PRINTK3(args...)
  52. #endif
  53. #if EL_DEBUG > 1
  54. #define PRINTK2(args...) printf(args)
  55. #else
  56. #define PRINTK2(args...)
  57. #endif
  58. #ifdef EL_DEBUG
  59. #define PRINTK(args...) printf(args)
  60. #else
  61. #define PRINTK(args...)
  62. #endif
  63. #define outb(args...) mmio_outb(args)
  64. #define mmio_outb(value, addr) (*((volatile byte *)(addr)) = value)
  65. #define inb(args...) mmio_inb(args)
  66. #define mmio_inb(addr) (*((volatile byte *)(addr)))
  67. #define outw(args...) mmio_outw(args)
  68. #define mmio_outw(value, addr) (*((volatile word *)(addr)) = value)
  69. #define inw(args...) mmio_inw(args)
  70. #define mmio_inw(addr) (*((volatile word *)(addr)))
  71. #define outsw(args...) mmio_outsw(args)
  72. #define mmio_outsw(r,b,l) ({ int __i; \
  73. word *__b2; \
  74. __b2 = (word *) b; \
  75. for (__i = 0; __i < l; __i++) { \
  76. mmio_outw( *(__b2 + __i), r); \
  77. } \
  78. })
  79. #define insw(args...) mmio_insw(args)
  80. #define mmio_insw(r,b,l) ({ int __i ; \
  81. word *__b2; \
  82. __b2 = (word *) b; \
  83. for (__i = 0; __i < l; __i++) { \
  84. *(__b2 + __i) = mmio_inw(r); \
  85. mmio_inw(0); \
  86. }; \
  87. })
  88. /*------------------------------------------------------------------------
  89. .
  90. . The internal workings of the driver. If you are changing anything
  91. . here with the 3Com stuff, you should have the datasheet and know
  92. . what you are doing.
  93. .
  94. -------------------------------------------------------------------------*/
  95. #define EL_BASE_ADDR 0x20000000
  96. /* Offsets from base I/O address. */
  97. #define EL3_DATA 0x00
  98. #define EL3_TIMER 0x0a
  99. #define EL3_CMD 0x0e
  100. #define EL3_STATUS 0x0e
  101. #define EEPROM_READ 0x0080
  102. #define EL3WINDOW(win_num) mmio_outw(SelectWindow + (win_num), EL_BASE_ADDR + EL3_CMD)
  103. /* The top five bits written to EL3_CMD are a command, the lower
  104. 11 bits are the parameter, if applicable. */
  105. enum c509cmd {
  106. TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
  107. RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11, RxDiscard = 8<<11,
  108. TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
  109. FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
  110. SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
  111. SetTxThreshold = 18<<11, SetTxStart = 19<<11, StatsEnable = 21<<11,
  112. StatsDisable = 22<<11, StopCoax = 23<<11,
  113. };
  114. enum c509status {
  115. IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
  116. TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
  117. IntReq = 0x0040, StatsFull = 0x0080, CmdBusy = 0x1000
  118. };
  119. /* The SetRxFilter command accepts the following classes: */
  120. enum RxFilter {
  121. RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8
  122. };
  123. /* Register window 1 offsets, the window used in normal operation. */
  124. #define TX_FIFO 0x00
  125. #define RX_FIFO 0x00
  126. #define RX_STATUS 0x08
  127. #define TX_STATUS 0x0B
  128. #define TX_FREE 0x0C /* Remaining free bytes in Tx buffer. */
  129. /*
  130. Read a word from the EEPROM using the regular EEPROM access register.
  131. Assume that we are in register window zero.
  132. */
  133. static word read_eeprom(dword ioaddr, int index)
  134. {
  135. int i;
  136. outw(EEPROM_READ + index, ioaddr + 0xa);
  137. /* Reading the eeprom takes 162 us */
  138. for (i = 1620; i >= 0; i--)
  139. if ((inw(ioaddr + 10) & EEPROM_BUSY) == 0)
  140. break;
  141. return inw(ioaddr + 0xc);
  142. }
  143. static void el_get_mac_addr( unsigned char *mac_addr )
  144. {
  145. int i;
  146. union
  147. {
  148. word w;
  149. unsigned char b[2];
  150. } wrd;
  151. unsigned char old_window = inw( EL_BASE_ADDR + EL3_STATUS ) >> 13;
  152. GO_WINDOW(0);
  153. VX_BUSY_WAIT;
  154. for (i = 0; i < 3; i++)
  155. {
  156. wrd.w = read_eeprom(EL_BASE_ADDR, 0xa+i);
  157. #ifdef __BIG_ENDIAN
  158. mac_addr[2*i] = wrd.b[0];
  159. mac_addr[2*i+1] = wrd.b[1];
  160. #else
  161. mac_addr[2*i] = wrd.b[1];
  162. mac_addr[2*i+1] = wrd.b[0];
  163. #endif
  164. }
  165. GO_WINDOW(old_window);
  166. VX_BUSY_WAIT;
  167. }
  168. #if EL_DEBUG > 1
  169. static void print_packet( byte * buf, int length )
  170. {
  171. int i;
  172. int remainder;
  173. int lines;
  174. PRINTK2("Packet of length %d \n", length );
  175. lines = length / 16;
  176. remainder = length % 16;
  177. for ( i = 0; i < lines ; i ++ ) {
  178. int cur;
  179. for ( cur = 0; cur < 8; cur ++ ) {
  180. byte a, b;
  181. a = *(buf ++ );
  182. b = *(buf ++ );
  183. PRINTK2("%02x%02x ", a, b );
  184. }
  185. PRINTK2("\n");
  186. }
  187. for ( i = 0; i < remainder/2 ; i++ ) {
  188. byte a, b;
  189. a = *(buf ++ );
  190. b = *(buf ++ );
  191. PRINTK2("%02x%02x ", a, b );
  192. }
  193. PRINTK2("\n");
  194. }
  195. #endif /* EL_DEBUG > 1 */
  196. /**************************************************************************
  197. ETH_RESET - Reset adapter
  198. ***************************************************************************/
  199. static void el_reset(bd_t *bd)
  200. {
  201. /***********************************************************
  202. Reset 3Com 595 card
  203. *************************************************************/
  204. /* QUICK HACK
  205. * - adjust timing for 3c589
  206. * - enable io for PCMCIA */
  207. outw(0x0004, 0xa0000018);
  208. udelay(100);
  209. outw(0x0041, 0x28010000);
  210. udelay(100);
  211. /* issue global reset */
  212. outw(GLOBAL_RESET, BASE + VX_COMMAND);
  213. /* must wait for at least 1ms */
  214. udelay(100000000);
  215. /* set mac addr */
  216. {
  217. unsigned char *mac_addr = bd->bi_enetaddr;
  218. int i;
  219. el_get_mac_addr( mac_addr );
  220. GO_WINDOW(2);
  221. VX_BUSY_WAIT;
  222. printf("3C589 MAC Addr.: ");
  223. for (i = 0; i < 6; i++)
  224. {
  225. printf("%02x", mac_addr[i]);
  226. outb(mac_addr[i], BASE + VX_W2_ADDR_0 + i);
  227. VX_BUSY_WAIT;
  228. }
  229. printf("\n\n");
  230. }
  231. /* set RX filter */
  232. outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + VX_COMMAND);
  233. VX_BUSY_WAIT;
  234. /* set irq mask and read_zero */
  235. outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
  236. S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
  237. VX_BUSY_WAIT;
  238. outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
  239. S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
  240. VX_BUSY_WAIT;
  241. /* enable TP Linkbeat */
  242. GO_WINDOW(4);
  243. VX_BUSY_WAIT;
  244. outw( ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
  245. VX_BUSY_WAIT;
  246. /*
  247. * Attempt to get rid of any stray interrupts that occured during
  248. * configuration. On the i386 this isn't possible because one may
  249. * already be queued. However, a single stray interrupt is
  250. * unimportant.
  251. */
  252. outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
  253. VX_BUSY_WAIT;
  254. /* enable TX and RX */
  255. outw( RX_ENABLE, BASE + VX_COMMAND );
  256. VX_BUSY_WAIT;
  257. outw( TX_ENABLE, BASE + VX_COMMAND );
  258. VX_BUSY_WAIT;
  259. /* print the diag. regs. */
  260. PRINTK2("Diag. Regs\n");
  261. PRINTK2("--> MEDIA_TYPE: %04x\n", inw(BASE + VX_W4_MEDIA_TYPE));
  262. PRINTK2("--> NET_DIAG: %04x\n", inw(BASE + VX_W4_NET_DIAG));
  263. PRINTK2("--> FIFO_DIAG: %04x\n", inw(BASE + VX_W4_FIFO_DIAG));
  264. PRINTK2("--> CTRLR_STATUS: %04x\n", inw(BASE + VX_W4_CTRLR_STATUS));
  265. PRINTK2("\n\n");
  266. /* enter working mode */
  267. GO_WINDOW(1);
  268. VX_BUSY_WAIT;
  269. /* wait for another 1ms */
  270. udelay(100000000);
  271. }
  272. /*-----------------------------------------------------------------
  273. .
  274. . The driver can be entered at any of the following entry points.
  275. .
  276. .------------------------------------------------------------------ */
  277. extern int eth_init(bd_t *bd);
  278. extern void eth_halt(void);
  279. extern int eth_rx(void);
  280. extern int eth_send(volatile void *packet, int length);
  281. /*
  282. ------------------------------------------------------------
  283. .
  284. . Internal routines
  285. .
  286. ------------------------------------------------------------
  287. */
  288. int eth_init(bd_t *bd)
  289. {
  290. el_reset(bd);
  291. return 0;
  292. }
  293. void eth_halt() {
  294. return;
  295. }
  296. #define EDEBUG 1
  297. /**************************************************************************
  298. ETH_POLL - Wait for a frame
  299. ***************************************************************************/
  300. int eth_rx()
  301. {
  302. word status, rx_status, packet_size;
  303. VX_BUSY_WAIT;
  304. status = inw( BASE + VX_STATUS );
  305. if ( (status & S_RX_COMPLETE) == 0 ) return 0; /* nothing to do */
  306. /* Packet waiting -> check RX_STATUS */
  307. rx_status = inw( BASE + VX_W1_RX_STATUS );
  308. if ( rx_status & ERR_RX )
  309. {
  310. /* error in packet -> discard */
  311. PRINTK("[ERROR] Invalid packet -> discarding\n");
  312. PRINTK("-- error code 0x%02x\n", rx_status & ERR_MASK);
  313. PRINTK("-- rx bytes 0x%04d\n", rx_status & ((1<<11) - 1));
  314. PRINTK("[ERROR] Invalid packet -> discarding\n");
  315. outw( RX_DISCARD_TOP_PACK, BASE + VX_COMMAND );
  316. return 0;
  317. }
  318. /* correct pack. waiting in fifo */
  319. packet_size = rx_status & RX_BYTES_MASK;
  320. PRINTK("Correct packet waiting in fifo, size: %d\n", packet_size);
  321. {
  322. volatile word *packet_start = (word *)(BASE + VX_W1_RX_PIO_RD_1);
  323. word *RcvBuffer = (word *)(NetRxPackets[0]);
  324. int wcount = 0;
  325. for (wcount = 0; wcount < (packet_size >> 1); wcount++)
  326. {
  327. *RcvBuffer++ = *(packet_start);
  328. }
  329. /* handle odd packets */
  330. if ( packet_size & 1 )
  331. {
  332. *RcvBuffer++ = *(packet_start);
  333. }
  334. }
  335. /* fifo should now be empty (besides the padding bytes) */
  336. if ( ((*((word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK) > 3 )
  337. {
  338. PRINTK("[ERROR] Fifo not empty after packet read (remaining pkts: %d)\n",
  339. (((*(word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK));
  340. }
  341. /* discard packet */
  342. *((word *)(BASE + VX_COMMAND)) = RX_DISCARD_TOP_PACK;
  343. /* Pass Packets to upper Layer */
  344. NetReceive(NetRxPackets[0], packet_size);
  345. return packet_size;
  346. }
  347. /**************************************************************************
  348. ETH_TRANSMIT - Transmit a frame
  349. ***************************************************************************/
  350. static char padmap[] = {
  351. 0, 3, 2, 1};
  352. int eth_send(volatile void *packet, int length) {
  353. int pad;
  354. int status;
  355. volatile word *buf = (word *)packet;
  356. int dummy = 0;
  357. /* padding stuff */
  358. pad = padmap[length & 3];
  359. PRINTK("eth_send(), length: %d\n", length);
  360. /* drop acknowledgements */
  361. while(( status=inb(EL_BASE_ADDR + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
  362. if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
  363. outw(TX_RESET, EL_BASE_ADDR + VX_COMMAND);
  364. outw(TX_ENABLE, EL_BASE_ADDR + VX_COMMAND);
  365. PRINTK("Bad status, resetting and reenabling transmitter\n");
  366. }
  367. outb(0x0, EL_BASE_ADDR + VX_W1_TX_STATUS);
  368. }
  369. while (inw(EL_BASE_ADDR + VX_W1_FREE_TX) < length + pad + 4) {
  370. /* no room in FIFO */
  371. if (dummy == 0)
  372. {
  373. PRINTK("No room in FIFO, waiting...\n");
  374. dummy++;
  375. }
  376. }
  377. PRINTK(" ---> FIFO ready\n");
  378. outw(length, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
  379. /* Second dword meaningless */
  380. outw(0x0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
  381. #if EL_DEBUG > 1
  382. print_packet((byte *)buf, length);
  383. #endif
  384. /* write packet */
  385. {
  386. unsigned int i, totw;
  387. totw = ((length + 1) >> 1);
  388. PRINTK("Buffer: (totw = %d)\n", totw);
  389. for (i = 0; i < totw; i++) {
  390. outw( *(buf+i), EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
  391. udelay(10);
  392. }
  393. if(totw & 1)
  394. { /* pad to double word length */
  395. outw( 0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
  396. udelay(10);
  397. }
  398. PRINTK("\n\n");
  399. }
  400. /* wait for Tx complete */
  401. PRINTK("Waiting for Tx to complete...\n");
  402. while(((status = inw(EL_BASE_ADDR + VX_STATUS)) & S_COMMAND_IN_PROGRESS) != 0)
  403. {
  404. udelay(10);
  405. }
  406. PRINTK(" ---> Tx completed, status = 0x%04x\n", status);
  407. return length;
  408. }