dm9161.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712
  1. /*
  2. * File : dm9161.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2009 - 2012, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. */
  13. #include <rtthread.h>
  14. #include <netif/ethernetif.h>
  15. #include "dm9161.h"
  16. #include <sep4020.h>
  17. #include "mii.h"
  18. #define SPEED_10 10
  19. #define SPEED_100 100
  20. #define SPEED_1000 1000
  21. /* Duplex, half or full. */
  22. #define DUPLEX_HALF 0x00
  23. #define DUPLEX_FULL 0x01
  24. /*
  25. * Davicom dm9161EP driver
  26. *
  27. * IRQ_LAN connects to EINT7(GPF7)
  28. * nLAN_CS connects to nGCS4
  29. */
  30. /* #define dm9161_DEBUG 1 */
  31. #if DM9161_DEBUG
  32. #define DM9161_TRACE rt_kprintf
  33. #else
  34. #define DM9161_TRACE(...)
  35. #endif
  36. /*
  37. * dm9161 interrupt line is connected to PF7
  38. */
  39. //--------------------------------------------------------
  40. #define DM9161_PHY 0x40 /* PHY address 0x01 */
  41. #define MAX_ADDR_LEN 6
  42. enum DM9161_PHY_mode
  43. {
  44. DM9161_10MHD = 0, DM9161_100MHD = 1,
  45. DM9161_10MFD = 4, DM9161_100MFD = 5,
  46. DM9161_AUTO = 8, DM9161_1M_HPNA = 0x10
  47. };
  48. enum DM9161_TYPE
  49. {
  50. TYPE_DM9161,
  51. };
  52. struct rt_dm9161_eth
  53. {
  54. /* inherit from ethernet device */
  55. struct eth_device parent;
  56. enum DM9161_TYPE type;
  57. enum DM9161_PHY_mode mode;
  58. rt_uint8_t imr_all;
  59. rt_uint8_t phy_addr;
  60. rt_uint32_t tx_index;
  61. rt_uint8_t packet_cnt; /* packet I or II */
  62. rt_uint16_t queue_packet_len; /* queued packet (packet II) */
  63. /* interface address info. */
  64. rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
  65. };
  66. static struct rt_dm9161_eth dm9161_device;
  67. static struct rt_semaphore sem_ack, sem_lock;
  68. void rt_dm9161_isr(int irqno, void *param);
  69. static void udelay(unsigned long ns)
  70. {
  71. unsigned long i;
  72. while (ns--)
  73. {
  74. i = 100;
  75. while (i--);
  76. }
  77. }
  78. static __inline unsigned long sep_emac_read(unsigned int reg)
  79. {
  80. void __iomem *emac_base = (void __iomem *)reg;
  81. return read_reg(emac_base);
  82. }
  83. /*
  84. * Write to a EMAC register.
  85. */
  86. static __inline void sep_emac_write(unsigned int reg, unsigned long value)
  87. {
  88. void __iomem *emac_base = (void __iomem *)reg;
  89. write_reg(emac_base,value);
  90. }
  91. /* ........................... PHY INTERFACE ........................... */
  92. /* CAN DO MAC CONFIGRATION
  93. * Enable the MDIO bit in MAC control register
  94. * When not called from an interrupt-handler, access to the PHY must be
  95. * protected by a spinlock.
  96. */
  97. static void enable_mdi(void) //need think more
  98. {
  99. unsigned long ctl;
  100. ctl = sep_emac_read(MAC_CTRL);
  101. sep_emac_write(MAC_CTRL, ctl&(~0x3)); /* enable management port */
  102. return;
  103. }
  104. /* CANNOT DO MAC CONFIGRATION
  105. * Disable the MDIO bit in the MAC control register
  106. */
  107. static void disable_mdi(void)
  108. {
  109. unsigned long ctl;
  110. ctl = sep_emac_read(MAC_CTRL);
  111. sep_emac_write(MAC_CTRL, ctl|(0x3)); /* disable management port */
  112. return;
  113. }
  114. /*
  115. * Wait until the PHY operation is complete.
  116. */
  117. static __inline void sep_phy_wait(void)
  118. {
  119. unsigned long timeout = 2;
  120. while ((sep_emac_read(MAC_MII_STATUS) & 0x2))
  121. {
  122. timeout--;
  123. if (!timeout)
  124. {
  125. EOUT("sep_ether: MDIO timeout\n");
  126. break;
  127. }
  128. }
  129. return;
  130. }
  131. /*
  132. * Write value to the a PHY register
  133. * Note: MDI interface is assumed to already have been enabled.
  134. */
  135. static void write_phy(unsigned char phy_addr, unsigned char address, unsigned int value)
  136. {
  137. unsigned short mii_txdata;
  138. mii_txdata = value;
  139. sep_emac_write(MAC_MII_ADDRESS,(unsigned long)(address<<8) | phy_addr);
  140. sep_emac_write(MAC_MII_TXDATA ,mii_txdata);
  141. sep_emac_write(MAC_MII_CMD ,0x4);
  142. udelay(40);
  143. sep_phy_wait();
  144. return;
  145. }
  146. /*
  147. * Read value stored in a PHY register.
  148. * Note: MDI interface is assumed to already have been enabled.
  149. */
  150. static void read_phy(unsigned char phy_addr, unsigned char address, unsigned int *value)
  151. {
  152. unsigned short mii_rxdata;
  153. // unsigned long mii_status;
  154. sep_emac_write(MAC_MII_ADDRESS,(unsigned long)(address<<8) | phy_addr);
  155. sep_emac_write(MAC_MII_CMD ,0x2);
  156. udelay(40);
  157. sep_phy_wait();
  158. mii_rxdata = sep_emac_read(MAC_MII_RXDATA);
  159. *value = mii_rxdata;
  160. return;
  161. }
  162. /* interrupt service routine */
  163. void rt_dm9161_isr(int irqno, void *param)
  164. {
  165. unsigned long intstatus;
  166. rt_uint32_t address;
  167. mask_irq(INTSRC_MAC);
  168. intstatus = sep_emac_read(MAC_INTSRC);
  169. sep_emac_write(MAC_INTSRC,intstatus);
  170. /*Receive complete*/
  171. if(intstatus & 0x04)
  172. {
  173. eth_device_ready(&(dm9161_device.parent));
  174. }
  175. /*Receive error*/
  176. else if(intstatus & 0x08)
  177. {
  178. rt_kprintf("Receive error\n");
  179. }
  180. /*Transmit complete*/
  181. else if(intstatus & 0x03)
  182. {
  183. if(dm9161_device.tx_index == 0)
  184. address = (MAC_TX_BD +(MAX_TX_DESCR-2)*8);
  185. else if(dm9161_device.tx_index == 1)
  186. address = (MAC_TX_BD +(MAX_TX_DESCR-1)*8);
  187. else
  188. address = (MAC_TX_BD + dm9161_device.tx_index*8-16);
  189. //printk("free tx skb 0x%x in inter!!\n",lp->txBuffIndex);
  190. sep_emac_write(address,0x0);
  191. }
  192. else if (intstatus & 0x10)
  193. {
  194. rt_kprintf("ROVER ERROR\n");
  195. }
  196. while(intstatus)
  197. {
  198. sep_emac_write(MAC_INTSRC,intstatus);
  199. intstatus = sep_emac_read(MAC_INTSRC);
  200. }
  201. unmask_irq(INTSRC_MAC);
  202. }
  203. static rt_err_t update_mac_address()
  204. {
  205. rt_uint32_t lo,hi;
  206. hi = sep_emac_read(MAC_ADDR1);
  207. lo = sep_emac_read(MAC_ADDR0);
  208. DBOUT("Before MAC: hi=%x lo=%x\n",hi,lo);
  209. sep_emac_write(MAC_ADDR0,(dm9161_device.dev_addr[2] << 24) | (dm9161_device.dev_addr[3] << 16) | (dm9161_device.dev_addr[4] << 8) | (dm9161_device.dev_addr[5]));
  210. sep_emac_write(MAC_ADDR1,dm9161_device.dev_addr[1]|(dm9161_device.dev_addr[0]<<8));
  211. hi = sep_emac_read(MAC_ADDR1);
  212. lo = sep_emac_read(MAC_ADDR0);
  213. DBOUT("After MAC: hi=%x lo=%x\n",hi,lo);
  214. return RT_EOK;
  215. }
  216. static int mii_link_ok(unsigned long phy_id)
  217. {
  218. /* first, a dummy read, needed to latch some MII phys */
  219. unsigned int value;
  220. read_phy(phy_id, MII_BMSR,&value);
  221. if (value & BMSR_LSTATUS)
  222. return 1;
  223. return 0;
  224. }
  225. static void update_link_speed(unsigned short phy_addr)
  226. {
  227. unsigned int bmsr, bmcr, lpa, mac_cfg;
  228. unsigned int speed, duplex;
  229. if (!mii_link_ok(phy_addr))
  230. {
  231. EOUT("Link Down\n");
  232. //goto result;
  233. }
  234. read_phy(phy_addr,MII_BMSR,&bmsr);
  235. read_phy(phy_addr,MII_BMCR,&bmcr);
  236. if (bmcr & BMCR_ANENABLE) /* AutoNegotiation is enabled */
  237. {
  238. if (!(bmsr & BMSR_ANEGCOMPLETE)) /* Do nothing - another interrupt generated when negotiation complete */
  239. goto result;
  240. read_phy(phy_addr, MII_LPA, &lpa);
  241. if ((lpa & LPA_100FULL) || (lpa & LPA_100HALF))
  242. speed = SPEED_100;
  243. else
  244. speed = SPEED_10;
  245. if ((lpa & LPA_100FULL) || (lpa & LPA_10FULL))
  246. duplex = DUPLEX_FULL;
  247. else
  248. duplex = DUPLEX_HALF;
  249. }
  250. else
  251. {
  252. speed = (bmcr & BMCR_SPEED100) ? SPEED_100 : SPEED_10;
  253. duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : DUPLEX_HALF;
  254. }
  255. /* Update the MAC */
  256. mac_cfg = sep_emac_read(MAC_CTRL);
  257. if (speed == SPEED_100)
  258. {
  259. mac_cfg |= 0x800; /* set speed 100 M */
  260. //bmcr &=(~0x2000);
  261. //write_phy(lp->phy_address, MII_BMCR, bmcr); //将dm9161的速度设为10M
  262. if (duplex == DUPLEX_FULL) /* 100 Full Duplex */
  263. mac_cfg |= 0x400;
  264. else /* 100 Half Duplex */
  265. mac_cfg &= (~0x400);
  266. }
  267. else
  268. {
  269. mac_cfg &= (~0x800); /* set speed 10 M */
  270. if (duplex == DUPLEX_FULL) /* 10 Full Duplex */
  271. mac_cfg |= 0x400;
  272. else /* 10 Half Duplex */
  273. mac_cfg &= (~0x400);
  274. }
  275. sep_emac_write(MAC_CTRL, mac_cfg);
  276. rt_kprintf("Link now %i M-%s\n", speed, (duplex == DUPLEX_FULL) ? "FullDuplex" : "HalfDuplex");
  277. result:
  278. mac_cfg = sep_emac_read(MAC_CTRL);
  279. DBOUT("After mac_cfg=%d\n",mac_cfg);
  280. return;
  281. }
  282. static rt_err_t rt_dm9161_open(rt_device_t dev, rt_uint16_t oflag);
  283. /* RT-Thread Device Interface */
  284. /* initialize the interface */
  285. static rt_err_t rt_dm9161_init(rt_device_t dev)
  286. {
  287. unsigned int phyid1, phyid2;
  288. int detected = -1;
  289. unsigned long phy_id;
  290. unsigned short phy_address = 0;
  291. while ((detected != 0) && (phy_address < 32))
  292. {
  293. /* Read the PHY ID registers */
  294. enable_mdi();
  295. read_phy(phy_address, MII_PHYSID1, &phyid1);
  296. read_phy(phy_address, MII_PHYSID2, &phyid2);
  297. disable_mdi();
  298. phy_id = (phyid1 << 16) | (phyid2 & 0xfff0);
  299. switch (phy_id)
  300. {
  301. case MII_DM9161_ID: /* Davicom 9161: PHY_ID1 = 0x181, PHY_ID2 = B881 */
  302. case MII_DM9161A_ID: /* Davicom 9161A: PHY_ID1 = 0x181, PHY_ID2 = B8A0 */
  303. case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */
  304. case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */
  305. case MII_DP83847_ID: /* National Semiconductor DP83847: */
  306. case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */
  307. case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */
  308. {
  309. enable_mdi();
  310. #warning SHOULD SET MAC ADDR
  311. //get_mac_address(dev); /* Get ethernet address and store it in dev->dev_addr */
  312. update_mac_address(); /* Program ethernet address into MAC */
  313. //用哈希寄存器比较当前群播地址,全双工,添加CRC校验,短数据帧进行填充
  314. sep_emac_write(MAC_CTRL, 0xa413);
  315. #warning SHOULD DETERMIN LINK SPEED
  316. update_link_speed(phy_address);
  317. dm9161_device.phy_addr = phy_address;
  318. disable_mdi();
  319. break;
  320. }
  321. }
  322. phy_address++;
  323. }
  324. rt_dm9161_open(dev,0);
  325. return RT_EOK;
  326. }
  327. /* ................................ MAC ................................ */
  328. /*
  329. * Initialize and start the Receiver and Transmit subsystems
  330. */
  331. static void sepether_start(void)
  332. {
  333. int i;
  334. unsigned int tempaddr;
  335. sep_emac_write(MAC_TXBD_NUM,MAX_TX_DESCR);
  336. //初始化发送和接收描述符
  337. for (i = 0; i < MAX_TX_DESCR; i++)
  338. {
  339. tempaddr=(MAC_TX_BD+i*8);
  340. sep_emac_write(tempaddr,0);
  341. tempaddr=(MAC_TX_BD+i*8+4);
  342. sep_emac_write(tempaddr,0);
  343. }
  344. for (i = 0; i < MAX_RX_DESCR; i++)
  345. {
  346. tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8);
  347. sep_emac_write(tempaddr,0);
  348. tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8+4);
  349. sep_emac_write(tempaddr,0);
  350. }
  351. for (i = 0; i < MAX_RX_DESCR; i++)
  352. {
  353. tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8);
  354. sep_emac_write(tempaddr,0xc000);
  355. tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8+4);
  356. sep_emac_write(tempaddr,ESRAM_BASE+ MAX_TX_DESCR*0x600+i*0x600);
  357. }
  358. /* Set the Wrap bit on the last descriptor */
  359. tempaddr=(MAC_TX_BD + MAX_TX_DESCR*8+i*8-8);
  360. sep_emac_write(tempaddr,0xe000);
  361. for (i = 0; i < MAX_TX_DESCR; i++)
  362. {
  363. tempaddr=(MAC_TX_BD+i*8);
  364. sep_emac_write(tempaddr,0x0);
  365. tempaddr=(MAC_TX_BD+i*8+4);
  366. sep_emac_write(tempaddr,ESRAM_BASE+i*0x600);
  367. }
  368. return;
  369. }
  370. static rt_err_t rt_dm9161_open(rt_device_t dev, rt_uint16_t oflag)
  371. {
  372. unsigned int dsintr;
  373. enable_mdi();
  374. mask_irq(28);
  375. sep_emac_write(MAC_INTMASK,0x0); //首先屏蔽中断
  376. sepether_start();
  377. /* Enable PHY interrupt */
  378. *(volatile unsigned long*)GPIO_PORTA_DIR |= 0x0080 ; //1 stands for in
  379. *(volatile unsigned long*)GPIO_PORTA_SEL |= 0x0080 ; //for common use
  380. *(volatile unsigned long*)GPIO_PORTA_INCTL |= 0x0080; //中断输入方式
  381. *(volatile unsigned long*)GPIO_PORTA_INTRCTL |= (0x3UL<<14); //中断类型为低电平解发
  382. *(volatile unsigned long*)GPIO_PORTA_INTRCLR |= 0x0080; //清除中断
  383. *(volatile unsigned long*)GPIO_PORTA_INTRCLR = 0x0000; //清除中断
  384. rt_hw_interrupt_install(INTSRC_MAC, rt_dm9161_isr, RT_NULL, "EMAC");
  385. enable_irq(INTSRC_EXINT7);
  386. read_phy(dm9161_device.phy_addr, MII_DSINTR_REG, &dsintr);
  387. dsintr = dsintr & ~0xf00; /* clear bits 8..11 */
  388. write_phy(dm9161_device.phy_addr, MII_DSINTR_REG, dsintr);
  389. update_link_speed(dm9161_device.phy_addr);
  390. /************************************************************************************/
  391. /* Enable MAC interrupts */
  392. sep_emac_write(MAC_INTMASK,0xff); //open中断
  393. sep_emac_write(MAC_INTSRC,0xff); //clear all mac irq
  394. unmask_irq(28);
  395. disable_mdi();
  396. rt_kprintf("SEP4020 ethernet interface open!\n\r");
  397. return RT_EOK;
  398. }
  399. static rt_err_t rt_dm9161_close(rt_device_t dev)
  400. {
  401. rt_kprintf("SEP4020 ethernet interface close!\n\r");
  402. /* Disable Receiver and Transmitter */
  403. disable_mdi();
  404. #warning disable ether;
  405. // INT_ENABLE(28);
  406. /* Disable PHY interrupt */
  407. // disable_phyirq(dev);
  408. /* Disable MAC interrupts */
  409. sep_emac_write(MAC_INTMASK,0); //屏蔽中断
  410. // INT_DISABLE(28);
  411. return RT_EOK;
  412. }
  413. static rt_size_t rt_dm9161_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  414. {
  415. rt_set_errno(-RT_ENOSYS);
  416. return 0;
  417. }
  418. static rt_size_t rt_dm9161_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  419. {
  420. rt_set_errno(-RT_ENOSYS);
  421. return 0;
  422. }
  423. static rt_err_t rt_dm9161_control(rt_device_t dev, int cmd, void *args)
  424. {
  425. return RT_EOK;
  426. }
  427. /* ethernet device interface */
  428. /* transmit packet. */
  429. rt_err_t rt_dm9161_tx( rt_device_t dev, struct pbuf* p)
  430. {
  431. rt_uint8_t i;
  432. rt_uint32_t length = 0;
  433. struct pbuf *q;
  434. unsigned long address;
  435. unsigned long tmp_tx_bd;
  436. /* lock DM9000 device */
  437. // rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
  438. /* disable dm9000a interrupt */
  439. #warning SHOULD DISABLE INTEERUPT?
  440. /*Search for available BD*/
  441. for (i = 0;i<MAX_TX_DESCR;)
  442. {
  443. address = MAC_TX_BD + i*8;
  444. tmp_tx_bd = sep_emac_read(address);
  445. if (!(tmp_tx_bd & 0x8000))
  446. {
  447. if (i == (MAX_TX_DESCR-1))
  448. i = 0;
  449. else
  450. i = i+1;
  451. break;
  452. }
  453. if (i == MAX_TX_DESCR-1)
  454. i = 0;
  455. else
  456. i++;
  457. }
  458. q = p;
  459. while (q)
  460. {
  461. rt_memcpy((u8_t*)(ESRAM_BASE + i*0x600 + length),(u8_t*)q->payload,q->len);
  462. length += q->len;
  463. q = q->next;
  464. }
  465. #warning SHOULD NOTICE IT'S LENGTH
  466. length = length << 16;
  467. if (i == MAX_TX_DESCR - 1)
  468. length |= 0xb800;
  469. else
  470. length |= 0x9800;
  471. address = (MAC_TX_BD + i*8);
  472. dm9161_device.tx_index = i;
  473. sep_emac_write(address,length);
  474. //wait for tranfer complete
  475. while(!(sep_emac_read(address)&0x8000));
  476. /* unlock DM9000 device */
  477. // rt_sem_release(&sem_lock);
  478. /* wait ack */
  479. // rt_sem_take(&sem_ack, RT_WAITING_FOREVER);
  480. return RT_EOK;
  481. }
  482. /* reception packet. */
  483. struct pbuf *rt_dm9161_rx(rt_device_t dev)
  484. {
  485. unsigned int temp_rx_bd,address;
  486. rt_uint32_t i = 0;
  487. rt_uint32_t length;
  488. unsigned char *p_recv;
  489. struct pbuf* p = RT_NULL;
  490. /* lock DM9000 device */
  491. rt_sem_take(&sem_lock, RT_WAITING_FOREVER);
  492. while (1)
  493. {
  494. address = MAC_TX_BD + (MAX_TX_DESCR + i) * 8;
  495. temp_rx_bd = sep_emac_read(address);
  496. if (!(temp_rx_bd & 0x8000))
  497. {
  498. length = temp_rx_bd;
  499. length = length >> 16;
  500. p_recv = (unsigned char *)(ESRAM_BASE + (MAX_TX_DESCR + i) * 0x600);
  501. p = pbuf_alloc(PBUF_LINK,length,PBUF_RAM);
  502. if (p != RT_NULL)
  503. {
  504. struct pbuf *q;
  505. rt_int32_t len;
  506. for (q = p; q != RT_NULL; q = q->next)
  507. {
  508. rt_memcpy((rt_uint8_t *)(q->payload),p_recv,q->len);
  509. }
  510. }
  511. else
  512. {
  513. rt_kprintf("Droping %d packet \n",length);
  514. }
  515. if(i == (MAX_RX_DESCR-1))
  516. {
  517. sep_emac_write(address,0xe000);
  518. i = 0;
  519. }
  520. else
  521. {
  522. sep_emac_write(address,0xc000);
  523. i++;
  524. }
  525. }
  526. else
  527. break;
  528. }
  529. rt_sem_release(&sem_lock);
  530. return p;
  531. }
  532. void rt_hw_dm9161_init()
  533. {
  534. rt_sem_init(&sem_ack, "tx_ack", 1, RT_IPC_FLAG_FIFO);
  535. rt_sem_init(&sem_lock, "eth_lock", 1, RT_IPC_FLAG_FIFO);
  536. dm9161_device.type = TYPE_DM9161;
  537. dm9161_device.mode = DM9161_AUTO;
  538. dm9161_device.packet_cnt = 0;
  539. dm9161_device.queue_packet_len = 0;
  540. /*
  541. * SRAM Tx/Rx pointer automatically return to start address,
  542. * Packet Transmitted, Packet Received
  543. */
  544. #warning NOTICE:
  545. //dm9161_device.imr_all = IMR_PAR | IMR_PTM | IMR_PRM;
  546. dm9161_device.dev_addr[0] = 0x01;
  547. dm9161_device.dev_addr[1] = 0x60;
  548. dm9161_device.dev_addr[2] = 0x6E;
  549. dm9161_device.dev_addr[3] = 0x11;
  550. dm9161_device.dev_addr[4] = 0x02;
  551. dm9161_device.dev_addr[5] = 0x0F;
  552. dm9161_device.parent.parent.init = rt_dm9161_init;
  553. dm9161_device.parent.parent.open = rt_dm9161_open;
  554. dm9161_device.parent.parent.close = rt_dm9161_close;
  555. dm9161_device.parent.parent.read = rt_dm9161_read;
  556. dm9161_device.parent.parent.write = rt_dm9161_write;
  557. dm9161_device.parent.parent.control = rt_dm9161_control;
  558. dm9161_device.parent.parent.user_data = RT_NULL;
  559. dm9161_device.parent.eth_rx = rt_dm9161_rx;
  560. dm9161_device.parent.eth_tx = rt_dm9161_tx;
  561. eth_device_init(&(dm9161_device.parent), "e0");
  562. /* instal interrupt */
  563. #warning TODO
  564. //rt_hw_interrupt_install(INTEINT4_7, rt_dm9161_isr, RT_NULL);
  565. //rt_hw_interrupt_umask(INTEINT4_7);
  566. }
  567. void dm9161a(void)
  568. {
  569. }
  570. #ifdef RT_USING_FINSH
  571. #include <finsh.h>
  572. FINSH_FUNCTION_EXPORT(dm9161a, dm9161a register dump);
  573. #endif