3c589.c 12 KB

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