3c589.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  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. uchar mac_addr[6];
  218. int i;
  219. if (!eth_getenv_enetaddr("ethaddr", mac_addr)) {
  220. el_get_mac_addr(mac_addr);
  221. eth_setenv_enetaddr("ethaddr", mac_addr);
  222. }
  223. GO_WINDOW(2);
  224. VX_BUSY_WAIT;
  225. printf("3C589 MAC Addr.: ");
  226. for (i = 0; i < 6; i++)
  227. {
  228. printf("%02x", mac_addr[i]);
  229. outb(mac_addr[i], BASE + VX_W2_ADDR_0 + i);
  230. VX_BUSY_WAIT;
  231. }
  232. printf("\n\n");
  233. }
  234. /* set RX filter */
  235. outw(SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST, BASE + VX_COMMAND);
  236. VX_BUSY_WAIT;
  237. /* set irq mask and read_zero */
  238. outw(SET_RD_0_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
  239. S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
  240. VX_BUSY_WAIT;
  241. outw(SET_INTR_MASK | S_CARD_FAILURE | S_RX_COMPLETE |
  242. S_TX_COMPLETE | S_TX_AVAIL, BASE + VX_COMMAND);
  243. VX_BUSY_WAIT;
  244. /* enable TP Linkbeat */
  245. GO_WINDOW(4);
  246. VX_BUSY_WAIT;
  247. outw( ENABLE_UTP, BASE + VX_W4_MEDIA_TYPE);
  248. VX_BUSY_WAIT;
  249. /*
  250. * Attempt to get rid of any stray interrupts that occured during
  251. * configuration. On the i386 this isn't possible because one may
  252. * already be queued. However, a single stray interrupt is
  253. * unimportant.
  254. */
  255. outw(ACK_INTR | 0xff, BASE + VX_COMMAND);
  256. VX_BUSY_WAIT;
  257. /* enable TX and RX */
  258. outw( RX_ENABLE, BASE + VX_COMMAND );
  259. VX_BUSY_WAIT;
  260. outw( TX_ENABLE, BASE + VX_COMMAND );
  261. VX_BUSY_WAIT;
  262. /* print the diag. regs. */
  263. PRINTK2("Diag. Regs\n");
  264. PRINTK2("--> MEDIA_TYPE: %04x\n", inw(BASE + VX_W4_MEDIA_TYPE));
  265. PRINTK2("--> NET_DIAG: %04x\n", inw(BASE + VX_W4_NET_DIAG));
  266. PRINTK2("--> FIFO_DIAG: %04x\n", inw(BASE + VX_W4_FIFO_DIAG));
  267. PRINTK2("--> CTRLR_STATUS: %04x\n", inw(BASE + VX_W4_CTRLR_STATUS));
  268. PRINTK2("\n\n");
  269. /* enter working mode */
  270. GO_WINDOW(1);
  271. VX_BUSY_WAIT;
  272. /* wait for another 1ms */
  273. udelay(100000000);
  274. }
  275. /*-----------------------------------------------------------------
  276. .
  277. . The driver can be entered at any of the following entry points.
  278. .
  279. .------------------------------------------------------------------ */
  280. extern int eth_init(bd_t *bd);
  281. extern void eth_halt(void);
  282. extern int eth_rx(void);
  283. extern int eth_send(volatile void *packet, int length);
  284. /*
  285. ------------------------------------------------------------
  286. .
  287. . Internal routines
  288. .
  289. ------------------------------------------------------------
  290. */
  291. int eth_init(bd_t *bd)
  292. {
  293. el_reset(bd);
  294. return 0;
  295. }
  296. void eth_halt() {
  297. return;
  298. }
  299. #define EDEBUG 1
  300. /**************************************************************************
  301. ETH_POLL - Wait for a frame
  302. ***************************************************************************/
  303. int eth_rx()
  304. {
  305. word status, rx_status, packet_size;
  306. VX_BUSY_WAIT;
  307. status = inw( BASE + VX_STATUS );
  308. if ( (status & S_RX_COMPLETE) == 0 ) return 0; /* nothing to do */
  309. /* Packet waiting -> check RX_STATUS */
  310. rx_status = inw( BASE + VX_W1_RX_STATUS );
  311. if ( rx_status & ERR_RX )
  312. {
  313. /* error in packet -> discard */
  314. PRINTK("[ERROR] Invalid packet -> discarding\n");
  315. PRINTK("-- error code 0x%02x\n", rx_status & ERR_MASK);
  316. PRINTK("-- rx bytes 0x%04d\n", rx_status & ((1<<11) - 1));
  317. PRINTK("[ERROR] Invalid packet -> discarding\n");
  318. outw( RX_DISCARD_TOP_PACK, BASE + VX_COMMAND );
  319. return 0;
  320. }
  321. /* correct pack. waiting in fifo */
  322. packet_size = rx_status & RX_BYTES_MASK;
  323. PRINTK("Correct packet waiting in fifo, size: %d\n", packet_size);
  324. {
  325. volatile word *packet_start = (word *)(BASE + VX_W1_RX_PIO_RD_1);
  326. word *RcvBuffer = (word *)(NetRxPackets[0]);
  327. int wcount = 0;
  328. for (wcount = 0; wcount < (packet_size >> 1); wcount++)
  329. {
  330. *RcvBuffer++ = *(packet_start);
  331. }
  332. /* handle odd packets */
  333. if ( packet_size & 1 )
  334. {
  335. *RcvBuffer++ = *(packet_start);
  336. }
  337. }
  338. /* fifo should now be empty (besides the padding bytes) */
  339. if ( ((*((word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK) > 3 )
  340. {
  341. PRINTK("[ERROR] Fifo not empty after packet read (remaining pkts: %d)\n",
  342. (((*(word *)(BASE + VX_W1_RX_STATUS))) & RX_BYTES_MASK));
  343. }
  344. /* discard packet */
  345. *((word *)(BASE + VX_COMMAND)) = RX_DISCARD_TOP_PACK;
  346. /* Pass Packets to upper Layer */
  347. NetReceive(NetRxPackets[0], packet_size);
  348. return packet_size;
  349. }
  350. /**************************************************************************
  351. ETH_TRANSMIT - Transmit a frame
  352. ***************************************************************************/
  353. static char padmap[] = {
  354. 0, 3, 2, 1};
  355. int eth_send(volatile void *packet, int length) {
  356. int pad;
  357. int status;
  358. volatile word *buf = (word *)packet;
  359. int dummy = 0;
  360. /* padding stuff */
  361. pad = padmap[length & 3];
  362. PRINTK("eth_send(), length: %d\n", length);
  363. /* drop acknowledgements */
  364. while(( status=inb(EL_BASE_ADDR + VX_W1_TX_STATUS) )& TXS_COMPLETE ) {
  365. if(status & (TXS_UNDERRUN|TXS_MAX_COLLISION|TXS_STATUS_OVERFLOW)) {
  366. outw(TX_RESET, EL_BASE_ADDR + VX_COMMAND);
  367. outw(TX_ENABLE, EL_BASE_ADDR + VX_COMMAND);
  368. PRINTK("Bad status, resetting and reenabling transmitter\n");
  369. }
  370. outb(0x0, EL_BASE_ADDR + VX_W1_TX_STATUS);
  371. }
  372. while (inw(EL_BASE_ADDR + VX_W1_FREE_TX) < length + pad + 4) {
  373. /* no room in FIFO */
  374. if (dummy == 0)
  375. {
  376. PRINTK("No room in FIFO, waiting...\n");
  377. dummy++;
  378. }
  379. }
  380. PRINTK(" ---> FIFO ready\n");
  381. outw(length, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
  382. /* Second dword meaningless */
  383. outw(0x0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
  384. #if EL_DEBUG > 1
  385. print_packet((byte *)buf, length);
  386. #endif
  387. /* write packet */
  388. {
  389. unsigned int i, totw;
  390. totw = ((length + 1) >> 1);
  391. PRINTK("Buffer: (totw = %d)\n", totw);
  392. for (i = 0; i < totw; i++) {
  393. outw( *(buf+i), EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
  394. udelay(10);
  395. }
  396. if(totw & 1)
  397. { /* pad to double word length */
  398. outw( 0, EL_BASE_ADDR + VX_W1_TX_PIO_WR_1);
  399. udelay(10);
  400. }
  401. PRINTK("\n\n");
  402. }
  403. /* wait for Tx complete */
  404. PRINTK("Waiting for Tx to complete...\n");
  405. while(((status = inw(EL_BASE_ADDR + VX_STATUS)) & S_COMMAND_IN_PROGRESS) != 0)
  406. {
  407. udelay(10);
  408. }
  409. PRINTK(" ---> Tx completed, status = 0x%04x\n", status);
  410. return length;
  411. }