dm9000x.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. /*
  2. dm9000.c: Version 1.2 12/15/2003
  3. A Davicom DM9000 ISA NIC fast Ethernet driver for Linux.
  4. Copyright (C) 1997 Sten Wang
  5. This program is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU General Public License
  7. as published by the Free Software Foundation; either version 2
  8. of the License, or (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. (C)Copyright 1997-1998 DAVICOM Semiconductor,Inc. All Rights Reserved.
  14. V0.11 06/20/2001 REG_0A bit3=1, default enable BP with DA match
  15. 06/22/2001 Support DM9801 progrmming
  16. E3: R25 = ((R24 + NF) & 0x00ff) | 0xf000
  17. E4: R25 = ((R24 + NF) & 0x00ff) | 0xc200
  18. R17 = (R17 & 0xfff0) | NF + 3
  19. E5: R25 = ((R24 + NF - 3) & 0x00ff) | 0xc200
  20. R17 = (R17 & 0xfff0) | NF
  21. v1.00 modify by simon 2001.9.5
  22. change for kernel 2.4.x
  23. v1.1 11/09/2001 fix force mode bug
  24. v1.2 03/18/2003 Weilun Huang <weilun_huang@davicom.com.tw>:
  25. Fixed phy reset.
  26. Added tx/rx 32 bit mode.
  27. Cleaned up for kernel merge.
  28. --------------------------------------
  29. 12/15/2003 Initial port to u-boot by Sascha Hauer <saschahauer@web.de>
  30. TODO: Homerun NIC and longrun NIC are not functional, only internal at the
  31. moment.
  32. */
  33. #include <common.h>
  34. #include <command.h>
  35. #include <net.h>
  36. #include <asm/io.h>
  37. #ifdef CONFIG_DRIVER_DM9000
  38. #include "dm9000x.h"
  39. /* Board/System/Debug information/definition ---------------- */
  40. #define DM9801_NOISE_FLOOR 0x08
  41. #define DM9802_NOISE_FLOOR 0x05
  42. /* #define CONFIG_DM9000_DEBUG */
  43. #ifdef CONFIG_DM9000_DEBUG
  44. #define DM9000_DBG(fmt,args...) printf(fmt ,##args)
  45. #else /* */
  46. #define DM9000_DBG(fmt,args...)
  47. #endif /* */
  48. enum DM9000_PHY_mode { DM9000_10MHD = 0, DM9000_100MHD =
  49. 1, DM9000_10MFD = 4, DM9000_100MFD = 5, DM9000_AUTO =
  50. 8, DM9000_1M_HPNA = 0x10
  51. };
  52. enum DM9000_NIC_TYPE { FASTETHER_NIC = 0, HOMERUN_NIC = 1, LONGRUN_NIC = 2
  53. };
  54. /* Structure/enum declaration ------------------------------- */
  55. typedef struct board_info {
  56. u32 runt_length_counter; /* counter: RX length < 64byte */
  57. u32 long_length_counter; /* counter: RX length > 1514byte */
  58. u32 reset_counter; /* counter: RESET */
  59. u32 reset_tx_timeout; /* RESET caused by TX Timeout */
  60. u32 reset_rx_status; /* RESET caused by RX Statsus wrong */
  61. u16 tx_pkt_cnt;
  62. u16 queue_start_addr;
  63. u16 dbug_cnt;
  64. u8 phy_addr;
  65. u8 device_wait_reset; /* device state */
  66. u8 nic_type; /* NIC type */
  67. unsigned char srom[128];
  68. } board_info_t;
  69. board_info_t dmfe_info;
  70. /* For module input parameter */
  71. static int media_mode = DM9000_AUTO;
  72. static u8 nfloor = 0;
  73. /* function declaration ------------------------------------- */
  74. int eth_init(bd_t * bd);
  75. int eth_send(volatile void *, int);
  76. int eth_rx(void);
  77. void eth_halt(void);
  78. static int dm9000_probe(void);
  79. static u16 phy_read(int);
  80. static void phy_write(int, u16);
  81. u16 read_srom_word(int);
  82. static u8 DM9000_ior(int);
  83. static void DM9000_iow(int reg, u8 value);
  84. /* DM9000 network board routine ---------------------------- */
  85. #define DM9000_outb(d,r) ( *(volatile u8 *)r = d )
  86. #define DM9000_outw(d,r) ( *(volatile u16 *)r = d )
  87. #define DM9000_outl(d,r) ( *(volatile u32 *)r = d )
  88. #define DM9000_inb(r) (*(volatile u8 *)r)
  89. #define DM9000_inw(r) (*(volatile u16 *)r)
  90. #define DM9000_inl(r) (*(volatile u32 *)r)
  91. #ifdef CONFIG_DM9000_DEBUG
  92. static void
  93. dump_regs(void)
  94. {
  95. DM9000_DBG("\n");
  96. DM9000_DBG("NCR (0x00): %02x\n", DM9000_ior(0));
  97. DM9000_DBG("NSR (0x01): %02x\n", DM9000_ior(1));
  98. DM9000_DBG("TCR (0x02): %02x\n", DM9000_ior(2));
  99. DM9000_DBG("TSRI (0x03): %02x\n", DM9000_ior(3));
  100. DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4));
  101. DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5));
  102. DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6));
  103. DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(ISR));
  104. DM9000_DBG("\n");
  105. }
  106. #endif /* */
  107. /*
  108. Search DM9000 board, allocate space and register it
  109. */
  110. int
  111. dm9000_probe(void)
  112. {
  113. u32 id_val;
  114. id_val = DM9000_ior(DM9000_VIDL);
  115. id_val |= DM9000_ior(DM9000_VIDH) << 8;
  116. id_val |= DM9000_ior(DM9000_PIDL) << 16;
  117. id_val |= DM9000_ior(DM9000_PIDH) << 24;
  118. if (id_val == DM9000_ID) {
  119. printf("dm9000 i/o: 0x%x, id: 0x%x \n", CONFIG_DM9000_BASE,
  120. id_val);
  121. return 0;
  122. } else {
  123. printf("dm9000 not found at 0x%08x id: 0x%08x\n",
  124. CONFIG_DM9000_BASE, id_val);
  125. return -1;
  126. }
  127. }
  128. /* Set PHY operationg mode
  129. */
  130. static void
  131. set_PHY_mode(void)
  132. {
  133. u16 phy_reg4 = 0x01e1, phy_reg0 = 0x1000;
  134. if (!(media_mode & DM9000_AUTO)) {
  135. switch (media_mode) {
  136. case DM9000_10MHD:
  137. phy_reg4 = 0x21;
  138. phy_reg0 = 0x0000;
  139. break;
  140. case DM9000_10MFD:
  141. phy_reg4 = 0x41;
  142. phy_reg0 = 0x1100;
  143. break;
  144. case DM9000_100MHD:
  145. phy_reg4 = 0x81;
  146. phy_reg0 = 0x2000;
  147. break;
  148. case DM9000_100MFD:
  149. phy_reg4 = 0x101;
  150. phy_reg0 = 0x3100;
  151. break;
  152. }
  153. phy_write(4, phy_reg4); /* Set PHY media mode */
  154. phy_write(0, phy_reg0); /* Tmp */
  155. }
  156. DM9000_iow(DM9000_GPCR, 0x01); /* Let GPIO0 output */
  157. DM9000_iow(DM9000_GPR, 0x00); /* Enable PHY */
  158. }
  159. /*
  160. Init HomeRun DM9801
  161. */
  162. static void
  163. program_dm9801(u16 HPNA_rev)
  164. {
  165. __u16 reg16, reg17, reg24, reg25;
  166. if (!nfloor)
  167. nfloor = DM9801_NOISE_FLOOR;
  168. reg16 = phy_read(16);
  169. reg17 = phy_read(17);
  170. reg24 = phy_read(24);
  171. reg25 = phy_read(25);
  172. switch (HPNA_rev) {
  173. case 0xb900: /* DM9801 E3 */
  174. reg16 |= 0x1000;
  175. reg25 = ((reg24 + nfloor) & 0x00ff) | 0xf000;
  176. break;
  177. case 0xb901: /* DM9801 E4 */
  178. reg25 = ((reg24 + nfloor) & 0x00ff) | 0xc200;
  179. reg17 = (reg17 & 0xfff0) + nfloor + 3;
  180. break;
  181. case 0xb902: /* DM9801 E5 */
  182. case 0xb903: /* DM9801 E6 */
  183. default:
  184. reg16 |= 0x1000;
  185. reg25 = ((reg24 + nfloor - 3) & 0x00ff) | 0xc200;
  186. reg17 = (reg17 & 0xfff0) + nfloor;
  187. }
  188. phy_write(16, reg16);
  189. phy_write(17, reg17);
  190. phy_write(25, reg25);
  191. }
  192. /*
  193. Init LongRun DM9802
  194. */
  195. static void
  196. program_dm9802(void)
  197. {
  198. __u16 reg25;
  199. if (!nfloor)
  200. nfloor = DM9802_NOISE_FLOOR;
  201. reg25 = phy_read(25);
  202. reg25 = (reg25 & 0xff00) + nfloor;
  203. phy_write(25, reg25);
  204. }
  205. /* Identify NIC type
  206. */
  207. static void
  208. identify_nic(void)
  209. {
  210. struct board_info *db = &dmfe_info; /* Point a board information structure */
  211. u16 phy_reg3;
  212. DM9000_iow(DM9000_NCR, NCR_EXT_PHY);
  213. phy_reg3 = phy_read(3);
  214. switch (phy_reg3 & 0xfff0) {
  215. case 0xb900:
  216. if (phy_read(31) == 0x4404) {
  217. db->nic_type = HOMERUN_NIC;
  218. program_dm9801(phy_reg3);
  219. DM9000_DBG("found homerun NIC\n");
  220. } else {
  221. db->nic_type = LONGRUN_NIC;
  222. DM9000_DBG("found longrun NIC\n");
  223. program_dm9802();
  224. }
  225. break;
  226. default:
  227. db->nic_type = FASTETHER_NIC;
  228. break;
  229. }
  230. DM9000_iow(DM9000_NCR, 0);
  231. }
  232. /* General Purpose dm9000 reset routine */
  233. static void
  234. dm9000_reset(void)
  235. {
  236. DM9000_DBG("resetting\n");
  237. DM9000_iow(DM9000_NCR, NCR_RST);
  238. udelay(1000); /* delay 1ms */
  239. }
  240. /* Initilize dm9000 board
  241. */
  242. int
  243. eth_init(bd_t * bd)
  244. {
  245. int i, oft, lnk;
  246. DM9000_DBG("eth_init()\n");
  247. /* RESET device */
  248. dm9000_reset();
  249. dm9000_probe();
  250. /* NIC Type: FASTETHER, HOMERUN, LONGRUN */
  251. identify_nic();
  252. /* GPIO0 on pre-activate PHY */
  253. DM9000_iow(DM9000_GPR, 0x00); /*REG_1F bit0 activate phyxcer */
  254. /* Set PHY */
  255. set_PHY_mode();
  256. /* Program operating register */
  257. DM9000_iow(DM9000_NCR, 0x0); /* only intern phy supported by now */
  258. DM9000_iow(DM9000_TCR, 0); /* TX Polling clear */
  259. DM9000_iow(DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */
  260. DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* Flow Control : High/Low Water */
  261. DM9000_iow(DM9000_FCR, 0x0); /* SH FIXME: This looks strange! Flow Control */
  262. DM9000_iow(DM9000_SMCR, 0); /* Special Mode */
  263. DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* clear TX status */
  264. DM9000_iow(DM9000_ISR, 0x0f); /* Clear interrupt status */
  265. /* Set Node address */
  266. for (i = 0; i < 6; i++)
  267. ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
  268. if (is_zero_ether_addr(bd->bi_enetaddr) ||
  269. is_multicast_ether_addr(bd->bi_enetaddr)) {
  270. /* try reading from environment */
  271. u8 i;
  272. char *s, *e;
  273. s = getenv ("ethaddr");
  274. for (i = 0; i < 6; ++i) {
  275. bd->bi_enetaddr[i] = s ?
  276. simple_strtoul (s, &e, 16) : 0;
  277. if (s)
  278. s = (*e) ? e + 1 : e;
  279. }
  280. }
  281. printf("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", bd->bi_enetaddr[0],
  282. bd->bi_enetaddr[1], bd->bi_enetaddr[2], bd->bi_enetaddr[3],
  283. bd->bi_enetaddr[4], bd->bi_enetaddr[5]);
  284. for (i = 0, oft = 0x10; i < 6; i++, oft++)
  285. DM9000_iow(oft, bd->bi_enetaddr[i]);
  286. for (i = 0, oft = 0x16; i < 8; i++, oft++)
  287. DM9000_iow(oft, 0xff);
  288. /* read back mac, just to be sure */
  289. for (i = 0, oft = 0x10; i < 6; i++, oft++)
  290. DM9000_DBG("%02x:", DM9000_ior(oft));
  291. DM9000_DBG("\n");
  292. /* Activate DM9000 */
  293. DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* RX enable */
  294. DM9000_iow(DM9000_IMR, IMR_PAR); /* Enable TX/RX interrupt mask */
  295. i = 0;
  296. while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
  297. udelay(1000);
  298. i++;
  299. if (i == 10000) {
  300. printf("could not establish link\n");
  301. return 0;
  302. }
  303. }
  304. /* see what we've got */
  305. lnk = phy_read(17) >> 12;
  306. printf("operating at ");
  307. switch (lnk) {
  308. case 1:
  309. printf("10M half duplex ");
  310. break;
  311. case 2:
  312. printf("10M full duplex ");
  313. break;
  314. case 4:
  315. printf("100M half duplex ");
  316. break;
  317. case 8:
  318. printf("100M full duplex ");
  319. break;
  320. default:
  321. printf("unknown: %d ", lnk);
  322. break;
  323. }
  324. printf("mode\n");
  325. return 0;
  326. }
  327. /*
  328. Hardware start transmission.
  329. Send a packet to media from the upper layer.
  330. */
  331. int
  332. eth_send(volatile void *packet, int length)
  333. {
  334. char *data_ptr;
  335. u32 tmplen, i;
  336. int tmo;
  337. DM9000_DBG("eth_send: length: %d\n", length);
  338. for (i = 0; i < length; i++) {
  339. if (i % 8 == 0)
  340. DM9000_DBG("\nSend: 02x: ", i);
  341. DM9000_DBG("%02x ", ((unsigned char *) packet)[i]);
  342. } DM9000_DBG("\n");
  343. /* Move data to DM9000 TX RAM */
  344. data_ptr = (char *) packet;
  345. DM9000_outb(DM9000_MWCMD, DM9000_IO);
  346. #ifdef CONFIG_DM9000_USE_8BIT
  347. /* Byte mode */
  348. for (i = 0; i < length; i++)
  349. DM9000_outb((data_ptr[i] & 0xff), DM9000_DATA);
  350. #endif /* */
  351. #ifdef CONFIG_DM9000_USE_16BIT
  352. tmplen = (length + 1) / 2;
  353. for (i = 0; i < tmplen; i++)
  354. DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
  355. #endif /* */
  356. #ifdef CONFIG_DM9000_USE_32BIT
  357. tmplen = (length + 3) / 4;
  358. for (i = 0; i < tmplen; i++)
  359. DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);
  360. #endif /* */
  361. /* Set TX length to DM9000 */
  362. DM9000_iow(DM9000_TXPLL, length & 0xff);
  363. DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff);
  364. /* Issue TX polling command */
  365. DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */
  366. /* wait for end of transmission */
  367. tmo = get_timer(0) + 5 * CFG_HZ;
  368. while (DM9000_ior(DM9000_TCR) & TCR_TXREQ) {
  369. if (get_timer(0) >= tmo) {
  370. printf("transmission timeout\n");
  371. break;
  372. }
  373. }
  374. DM9000_DBG("transmit done\n\n");
  375. return 0;
  376. }
  377. /*
  378. Stop the interface.
  379. The interface is stopped when it is brought.
  380. */
  381. void
  382. eth_halt(void)
  383. {
  384. DM9000_DBG("eth_halt\n");
  385. /* RESET devie */
  386. phy_write(0, 0x8000); /* PHY RESET */
  387. DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
  388. DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
  389. DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */
  390. }
  391. /*
  392. Received a packet and pass to upper layer
  393. */
  394. int
  395. eth_rx(void)
  396. {
  397. u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
  398. u16 RxStatus, RxLen = 0;
  399. u32 tmplen, i;
  400. #ifdef CONFIG_DM9000_USE_32BIT
  401. u32 tmpdata;
  402. #endif
  403. /* Check packet ready or not */
  404. DM9000_ior(DM9000_MRCMDX); /* Dummy read */
  405. rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */
  406. if (rxbyte == 0)
  407. return 0;
  408. /* Status check: this byte must be 0 or 1 */
  409. if (rxbyte > 1) {
  410. DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */
  411. DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */
  412. DM9000_DBG("rx status check: %d\n", rxbyte);
  413. }
  414. DM9000_DBG("receiving packet\n");
  415. /* A packet ready now & Get status/length */
  416. DM9000_outb(DM9000_MRCMD, DM9000_IO);
  417. #ifdef CONFIG_DM9000_USE_8BIT
  418. RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
  419. RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8);
  420. #endif /* */
  421. #ifdef CONFIG_DM9000_USE_16BIT
  422. RxStatus = DM9000_inw(DM9000_DATA);
  423. RxLen = DM9000_inw(DM9000_DATA);
  424. #endif /* */
  425. #ifdef CONFIG_DM9000_USE_32BIT
  426. tmpdata = DM9000_inl(DM9000_DATA);
  427. RxStatus = tmpdata;
  428. RxLen = tmpdata >> 16;
  429. #endif /* */
  430. DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen);
  431. /* Move data from DM9000 */
  432. /* Read received packet from RX SRAM */
  433. #ifdef CONFIG_DM9000_USE_8BIT
  434. for (i = 0; i < RxLen; i++)
  435. rdptr[i] = DM9000_inb(DM9000_DATA);
  436. #endif /* */
  437. #ifdef CONFIG_DM9000_USE_16BIT
  438. tmplen = (RxLen + 1) / 2;
  439. for (i = 0; i < tmplen; i++)
  440. ((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA);
  441. #endif /* */
  442. #ifdef CONFIG_DM9000_USE_32BIT
  443. tmplen = (RxLen + 3) / 4;
  444. for (i = 0; i < tmplen; i++)
  445. ((u32 *) rdptr)[i] = DM9000_inl(DM9000_DATA);
  446. #endif /* */
  447. if ((RxStatus & 0xbf00) || (RxLen < 0x40)
  448. || (RxLen > DM9000_PKT_MAX)) {
  449. if (RxStatus & 0x100) {
  450. printf("rx fifo error\n");
  451. }
  452. if (RxStatus & 0x200) {
  453. printf("rx crc error\n");
  454. }
  455. if (RxStatus & 0x8000) {
  456. printf("rx length error\n");
  457. }
  458. if (RxLen > DM9000_PKT_MAX) {
  459. printf("rx length too big\n");
  460. dm9000_reset();
  461. }
  462. } else {
  463. /* Pass to upper layer */
  464. DM9000_DBG("passing packet to upper layer\n");
  465. NetReceive(NetRxPackets[0], RxLen);
  466. return RxLen;
  467. }
  468. return 0;
  469. }
  470. /*
  471. Read a word data from SROM
  472. */
  473. u16
  474. read_srom_word(int offset)
  475. {
  476. DM9000_iow(DM9000_EPAR, offset);
  477. DM9000_iow(DM9000_EPCR, 0x4);
  478. udelay(8000);
  479. DM9000_iow(DM9000_EPCR, 0x0);
  480. return (DM9000_ior(DM9000_EPDRL) + (DM9000_ior(DM9000_EPDRH) << 8));
  481. }
  482. void
  483. write_srom_word(int offset, u16 val)
  484. {
  485. DM9000_iow(DM9000_EPAR, offset);
  486. DM9000_iow(DM9000_EPDRH, ((val >> 8) & 0xff));
  487. DM9000_iow(DM9000_EPDRL, (val & 0xff));
  488. DM9000_iow(DM9000_EPCR, 0x12);
  489. udelay(8000);
  490. DM9000_iow(DM9000_EPCR, 0);
  491. }
  492. /*
  493. Read a byte from I/O port
  494. */
  495. static u8
  496. DM9000_ior(int reg)
  497. {
  498. DM9000_outb(reg, DM9000_IO);
  499. return DM9000_inb(DM9000_DATA);
  500. }
  501. /*
  502. Write a byte to I/O port
  503. */
  504. static void
  505. DM9000_iow(int reg, u8 value)
  506. {
  507. DM9000_outb(reg, DM9000_IO);
  508. DM9000_outb(value, DM9000_DATA);
  509. }
  510. /*
  511. Read a word from phyxcer
  512. */
  513. static u16
  514. phy_read(int reg)
  515. {
  516. u16 val;
  517. /* Fill the phyxcer register into REG_0C */
  518. DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
  519. DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
  520. udelay(100); /* Wait read complete */
  521. DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
  522. val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
  523. /* The read data keeps on REG_0D & REG_0E */
  524. DM9000_DBG("phy_read(%d): %d\n", reg, val);
  525. return val;
  526. }
  527. /*
  528. Write a word to phyxcer
  529. */
  530. static void
  531. phy_write(int reg, u16 value)
  532. {
  533. /* Fill the phyxcer register into REG_0C */
  534. DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
  535. /* Fill the written data into REG_0D & REG_0E */
  536. DM9000_iow(DM9000_EPDRL, (value & 0xff));
  537. DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff));
  538. DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */
  539. udelay(500); /* Wait write complete */
  540. DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */
  541. DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value);
  542. }
  543. #endif /* CONFIG_DRIVER_DM9000 */