drv_pcnet32.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670
  1. /*
  2. * Copyright (c) 2006-2021, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-08-19 JasonHu first version
  9. */
  10. #include <board.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <rthw.h>
  14. #include <netif/ethernetif.h>
  15. #include <pci.h>
  16. #include <mmu.h>
  17. #define DBG_LVL DBG_INFO
  18. #define DBG_TAG "PCNET32"
  19. #include <rtdbg.h>
  20. #include "drv_pcnet32.h"
  21. #define DEV_NAME "e0"
  22. #define GET_PCNET32(eth) (struct eth_device_pcnet32 *)(eth)
  23. /**
  24. * rx ring desc struct
  25. */
  26. struct pcnet32_rx_desc
  27. {
  28. rt_uint32_t base; /* buffer base addr */
  29. rt_uint16_t buf_length; /* two`s complement of length */
  30. rt_uint16_t status; /* desc status */
  31. rt_uint16_t msg_length; /* Message Byte Count is the length in bytes of the received message. */
  32. rt_uint16_t rpc_rcc;
  33. rt_uint32_t reserved;
  34. } __attribute__ ((packed));
  35. /**
  36. * tx ring desc struct
  37. */
  38. struct pcnet32_tx_desc
  39. {
  40. rt_uint32_t base; /* buffer base addr */
  41. rt_uint16_t buf_length; /* two`s complement of length */
  42. rt_uint16_t status; /* desc status */
  43. rt_uint32_t misc;
  44. rt_uint32_t reserved;
  45. } __attribute__ ((packed));
  46. /**
  47. * The PCNET32 32-Bit initialization block, described in databook.
  48. * The Mode Register (CSR15) allows alteration of the chip's operating
  49. * parameters. The Mode field of the Initialization Block is copied directly
  50. * into CSR15. Normal operation is the result of configuring the Mode field
  51. * with all bits zero.
  52. */
  53. struct pcnet32_init_block
  54. {
  55. rt_uint16_t mode;
  56. rt_uint16_t tlen_rlen;
  57. rt_uint8_t phys_addr[6];
  58. rt_uint16_t reserved;
  59. rt_uint32_t filter[2];
  60. /* Receive and transmit ring base, along with extra bits. */
  61. rt_uint32_t rx_ring;
  62. rt_uint32_t tx_ring;
  63. } __attribute__ ((packed));
  64. struct eth_device_pcnet32
  65. {
  66. /* inherit from Ethernet device */
  67. struct eth_device parent;
  68. /* interface address info. */
  69. rt_uint8_t dev_addr[ETH_ALEN]; /* MAC address */
  70. rt_pci_device_t *pci_dev; /* pci device info */
  71. rt_uint32_t iobase; /* io port base */
  72. rt_uint32_t irqno; /* irq number */
  73. rt_mq_t rx_mqueue; /* msg queue for rx */
  74. struct pcnet32_init_block *init_block;
  75. rt_uint16_t rx_len_bits;
  76. rt_uint16_t tx_len_bits;
  77. rt_ubase_t rx_ring_dma_addr;
  78. rt_ubase_t tx_ring_dma_addr;
  79. rt_ubase_t init_block_dma_addr;
  80. rt_ubase_t rx_buffer_ptr;
  81. rt_ubase_t tx_buffer_ptr; /* pointers to transmit/receive buffers */
  82. rt_size_t rx_buffer_count; /* total number of receive buffers */
  83. rt_size_t tx_buffer_count; /* total number of transmit buffers */
  84. rt_size_t buffer_size; /* length of each packet buffer */
  85. rt_size_t de_size; /* length of descriptor entry */
  86. struct pcnet32_rx_desc *rdes; /* pointer to ring buffer of receive des */
  87. struct pcnet32_tx_desc *tdes; /* pointer to ring buffer of transmit des */
  88. rt_uint32_t rx_buffers; /* physical address of actual receive buffers (< 4 GiB) */
  89. rt_uint32_t tx_buffers; /* physical address of actual transmit buffers (< 4 GiB) */
  90. };
  91. static struct eth_device_pcnet32 eth_dev;
  92. static rt_uint8_t rx_cache_send_buf[RX_MSG_SIZE] = {0}; /* buf for rx packet, put size and data into mq */
  93. static rt_uint8_t rx_cache_recv_buf[RX_MSG_SIZE] = {0}; /* buf for rx packet, get size and data from mq */
  94. static rt_uint8_t tx_cache_pbuf[TX_CACHE_BUF_SIZE] = {0}; /* buf for tx packet, get data from pbuf payload */
  95. /**
  96. * does the driver own the particular buffer?
  97. */
  98. rt_inline rt_bool_t pcnet32_is_driver_own(struct eth_device_pcnet32 *dev, rt_bool_t is_tx, rt_uint32_t idx)
  99. {
  100. return (rt_bool_t)(is_tx ? ((dev->tdes[idx].status & PCNET32_DESC_STATUS_OWN) == 0) :
  101. ((dev->rdes[idx].status & PCNET32_DESC_STATUS_OWN) == 0));
  102. }
  103. /*
  104. * get the next desc buffer index
  105. */
  106. rt_inline rt_uint32_t pcnet32_get_next_desc(struct eth_device_pcnet32 *dev, rt_uint32_t cur_idx, rt_uint32_t buf_count)
  107. {
  108. return (cur_idx + 1) % buf_count;
  109. }
  110. static void pcnet32_init_rx_desc_entry(struct eth_device_pcnet32 *dev, rt_uint32_t idx)
  111. {
  112. struct pcnet32_rx_desc *des = dev->rdes + idx;
  113. rt_memset(des, 0, dev->de_size);
  114. des->base = dev->rx_buffers + idx * dev->buffer_size;
  115. /* next 2 bytes are 0xf000 OR'd with the first 12 bits of the 2s complement of the length */
  116. rt_uint16_t bcnt = (rt_uint16_t)(-dev->buffer_size);
  117. bcnt &= 0x0fff;
  118. bcnt |= 0xf000; /* high 4 bits fixed 1 */
  119. des->buf_length = bcnt;
  120. /* finally, set ownership bit - transmit buffers are owned by us, receive buffers by the card */
  121. des->status = PCNET32_DESC_STATUS_OWN;
  122. }
  123. static void pcnet32_init_tx_desc_entry(struct eth_device_pcnet32 *dev, rt_uint32_t idx)
  124. {
  125. struct pcnet32_tx_desc *des = dev->tdes + idx;
  126. rt_memset(des, 0, dev->de_size);
  127. des->base = dev->tx_buffers + idx * dev->buffer_size;
  128. /* next 2 bytes are 0xf000 OR'd with the first 12 bits of the 2s complement of the length */
  129. rt_uint16_t bcnt = (rt_uint16_t)(-dev->buffer_size);
  130. bcnt &= 0x0fff;
  131. bcnt |= 0xf000; /* high 4 bits fixed 1 */
  132. des->buf_length = bcnt;
  133. }
  134. static rt_uint16_t pcnet32_wio_read_mac(rt_uint32_t addr, int index)
  135. {
  136. return inw(addr + index);
  137. }
  138. /*
  139. * write index to RAP, read data from RDP
  140. */
  141. static rt_uint16_t pcnet32_wio_read_csr(rt_uint32_t addr, int index)
  142. {
  143. outw(addr + PCNET32_WIO_RAP, index);
  144. return inw(addr + PCNET32_WIO_RDP);
  145. }
  146. /**
  147. * write index to RAP, write data to RDP
  148. */
  149. static void pcnet32_wio_write_csr(rt_uint32_t addr, int index, rt_uint16_t val)
  150. {
  151. outw(addr + PCNET32_WIO_RAP, index);
  152. outw(addr + PCNET32_WIO_RDP, val);
  153. }
  154. static void pcnet32_wio_write_bcr(rt_uint32_t addr, int index, rt_uint16_t val)
  155. {
  156. outw(addr + PCNET32_WIO_RAP, index);
  157. outw(addr + PCNET32_WIO_BDP, val);
  158. }
  159. /*
  160. * Reset causes the device to cease operation and clear its internal logic.
  161. */
  162. static void pcnet32_wio_reset(rt_uint32_t addr)
  163. {
  164. inw(addr + PCNET32_WIO_RESET);
  165. }
  166. static int pcnet32_get_pci(struct eth_device_pcnet32 *dev)
  167. {
  168. /* get pci device */
  169. rt_pci_device_t *pci_dev = rt_pci_device_get(PCNET32_VENDOR_ID, PCNET32_DEVICE_ID);
  170. if (pci_dev == RT_NULL)
  171. {
  172. LOG_E("device not find on pci device.\n");
  173. return -1;
  174. }
  175. dev->pci_dev = pci_dev;
  176. dbg_log(DBG_LOG, "find device, vendor id: 0x%x, device id: 0x%x\n",
  177. pci_dev->vendor_id, pci_dev->device_id);
  178. /* enable bus mastering */
  179. rt_pci_enable_bus_mastering(pci_dev);
  180. /* get io port address */
  181. dev->iobase = rt_pci_device_get_io_addr(pci_dev);
  182. if (dev->iobase == 0)
  183. {
  184. LOG_E("invalid pci device io address.\n");
  185. return -1;
  186. }
  187. dbg_log(DBG_LOG, "io base address: 0x%x\n", dev->iobase);
  188. /* get irq */
  189. dev->irqno = rt_pci_device_get_irq_line(pci_dev);
  190. if (dev->irqno == 0xff)
  191. {
  192. LOG_E("invalid irqno.\n");
  193. return -1;
  194. }
  195. dbg_log(DBG_LOG, "irqno %d\n", dev->irqno);
  196. return 0;
  197. }
  198. static int pcnet32_transmit(struct eth_device_pcnet32 *dev, rt_uint8_t *buf, rt_size_t len)
  199. {
  200. if(len > ETH_FRAME_LEN)
  201. {
  202. len = ETH_FRAME_LEN;
  203. }
  204. rt_uint32_t tx_retry = PCNET32_TX_RETRY;
  205. while (tx_retry > 0)
  206. {
  207. /* the next available descriptor entry index is in tx_buffer_ptr */
  208. if(!pcnet32_is_driver_own(dev, RT_TRUE, dev->tx_buffer_ptr))
  209. {
  210. /* try encourage the card to send all buffers. */
  211. pcnet32_wio_write_csr(dev->iobase, CSR0, pcnet32_wio_read_csr(dev->iobase, CSR0) | CSR0_TXPOLL);
  212. }
  213. else
  214. {
  215. break;
  216. }
  217. --tx_retry;
  218. }
  219. if (!tx_retry) /* retry end, no entry available */
  220. {
  221. dbg_log(DBG_ERROR, "transmit no available descriptor entry\n")
  222. return -1;
  223. }
  224. rt_memcpy((void *)(dev->tx_buffers + dev->tx_buffer_ptr * dev->buffer_size), buf, len);
  225. struct pcnet32_tx_desc *tdes = dev->tdes + dev->tx_buffer_ptr;
  226. /**
  227. * set the STP bit in the descriptor entry (signals this is the first
  228. * frame in a split packet - we only support single frames)
  229. */
  230. tdes->status |= PCNET32_DESC_STATUS_STP;
  231. /* similarly, set the ENP bit to state this is also the end of a packet */
  232. tdes->status |= PCNET32_DESC_STATUS_ENP;
  233. rt_uint16_t bcnt = (rt_uint16_t)(-len);
  234. bcnt &= 0xfff;
  235. bcnt |= 0xf000; /* high 4 bits fixed 1 */
  236. tdes->buf_length = bcnt;
  237. /* finally, flip the ownership bit back to the card */
  238. tdes->status |= PCNET32_DESC_STATUS_OWN;
  239. dev->tx_buffer_ptr = pcnet32_get_next_desc(dev, dev->tx_buffer_ptr, dev->tx_buffer_count);
  240. return 0;
  241. }
  242. static rt_err_t pcnet32_tx(rt_device_t device, struct pbuf *p)
  243. {
  244. rt_err_t err = RT_EOK;
  245. /* copy data from pbuf to tx cache */
  246. pbuf_copy_partial(p, (void *)&tx_cache_pbuf[0], p->tot_len, 0);
  247. if (pcnet32_transmit(GET_PCNET32(device), tx_cache_pbuf, p->tot_len) < 0)
  248. {
  249. err = RT_ERROR;
  250. }
  251. return err;
  252. }
  253. static struct pbuf *pcnet32_rx(rt_device_t device)
  254. {
  255. struct eth_device_pcnet32 *dev = GET_PCNET32(device);
  256. int recv_len = 0;
  257. struct pbuf *pbuf = RT_NULL;
  258. rt_err_t err;
  259. /* get data from rx queue. */
  260. err = rt_mq_recv_interruptible(dev->rx_mqueue, rx_cache_recv_buf, RX_MSG_SIZE, 0);
  261. if (err != RT_EOK)
  262. {
  263. return pbuf;
  264. }
  265. /* get recv len from rx cache, 0~3: recv len, 3-n: frame data */
  266. recv_len = *(int *)rx_cache_recv_buf;
  267. if (recv_len > 0)
  268. {
  269. pbuf = pbuf_alloc(PBUF_LINK, recv_len, PBUF_RAM);
  270. rt_memcpy(pbuf->payload, (char *)rx_cache_recv_buf + 4, recv_len);
  271. }
  272. return pbuf;
  273. }
  274. static rt_err_t pcnet32_control(rt_device_t device, int cmd, void *args)
  275. {
  276. struct eth_device_pcnet32 *dev = GET_PCNET32(device);
  277. switch(cmd)
  278. {
  279. case NIOCTL_GADDR:
  280. /* get MAC address */
  281. if(args)
  282. {
  283. rt_memcpy(args, dev->dev_addr, ETH_ALEN);
  284. }
  285. else
  286. {
  287. return -RT_ERROR;
  288. }
  289. break;
  290. default :
  291. break;
  292. }
  293. return RT_EOK;
  294. }
  295. static void pcnet32_rx_packet(struct eth_device_pcnet32 *dev)
  296. {
  297. while (pcnet32_is_driver_own(dev, RT_FALSE, dev->rx_buffer_ptr))
  298. {
  299. struct pcnet32_rx_desc *rdes = dev->rdes + dev->rx_buffer_ptr;
  300. rt_uint32_t plen = rdes->msg_length; /* msg len no need to negate it unlike BCNT above */
  301. void *pbuf = (void *)(dev->rx_buffers + dev->rx_buffer_ptr * dev->buffer_size);
  302. dbg_log(DBG_LOG, "recv packet on ring %d: buf=%p, len=%d\n", dev->rx_buffer_ptr, pbuf, plen);
  303. /* merge size and data into receive pkg */
  304. rt_memcpy(rx_cache_send_buf, &plen, 4);
  305. rt_memcpy(&rx_cache_send_buf[4], pbuf, plen);
  306. rt_mq_send_interrupt(dev->rx_mqueue, rx_cache_send_buf, plen + 4);
  307. eth_device_ready(&dev->parent); /* notify eth thread to read packet */
  308. /* hand the buffer back to the card */
  309. rdes->status = PCNET32_DESC_STATUS_OWN;
  310. dev->rx_buffer_ptr = pcnet32_get_next_desc(dev, dev->rx_buffer_ptr, dev->rx_buffer_count);
  311. }
  312. }
  313. static void rt_hw_pcnet32_isr(int vector, void *param)
  314. {
  315. struct eth_device_pcnet32 *dev = GET_PCNET32(param);
  316. rt_uint32_t iobase = dev->iobase;
  317. rt_uint32_t csr0 = pcnet32_wio_read_csr(iobase, 0);
  318. if (csr0 & CSR0_RINT) /* recv packet */
  319. {
  320. dbg_log(DBG_LOG, "RX intr occur!\n");
  321. pcnet32_rx_packet(dev);
  322. }
  323. else if ((csr0 & CSR0_TINT)) /* packet transmitted */
  324. {
  325. dbg_log(DBG_LOG, "TX intr occur!\n");
  326. }
  327. else if ((csr0 & CSR0_IDON))
  328. {
  329. dbg_log(DBG_INFO, "init done\n");
  330. }
  331. else if ((csr0 & CSR0_MERR))
  332. {
  333. dbg_log(DBG_WARNING, "memory error!\n");
  334. }
  335. else if ((csr0 & CSR0_MISS))
  336. {
  337. dbg_log(DBG_WARNING, "missed frame!\n");
  338. }
  339. else if ((csr0 & CSR0_CERR))
  340. {
  341. dbg_log(DBG_WARNING, "collision error!\n");
  342. }
  343. else if ((csr0 & CSR0_BABL))
  344. {
  345. dbg_log(DBG_WARNING, "transmitter time-out error!\n");
  346. }
  347. else
  348. {
  349. dbg_log(DBG_WARNING, "unknown intr\n");
  350. }
  351. /* ack pcnet32 interrupt as handled */
  352. pcnet32_wio_write_csr(iobase, 0, csr0);
  353. }
  354. static rt_err_t pcnet32_alloc_ring_buffer(struct eth_device_pcnet32 *dev)
  355. {
  356. dev->rdes = rt_malloc_align(dev->rx_buffer_count * dev->de_size, 16);
  357. if (dev->rdes == RT_NULL)
  358. {
  359. dbg_log(DBG_ERROR, "alloc memory for rx ring failed!");
  360. return RT_ERROR;
  361. }
  362. dev->tdes = rt_malloc_align(dev->tx_buffer_count * dev->de_size, 16);
  363. if (dev->tdes == RT_NULL)
  364. {
  365. dbg_log(DBG_ERROR, "alloc memory for tx ring failed!");
  366. rt_free_align(dev->rdes);
  367. return RT_ERROR;
  368. }
  369. dev->rx_buffers = (uint32_t)rt_malloc_align(dev->rx_buffer_count * dev->buffer_size, 16);
  370. if (dev->rx_buffers == 0)
  371. {
  372. dbg_log(DBG_ERROR, "alloc memory for rx ring buffer failed!");
  373. rt_free_align(dev->rdes);
  374. rt_free_align(dev->tdes);
  375. return RT_ERROR;
  376. }
  377. dev->tx_buffers = (uint32_t)rt_malloc_align(dev->tx_buffer_count * dev->buffer_size, 16);
  378. if (dev->tx_buffers == 0)
  379. {
  380. dbg_log(DBG_ERROR, "alloc memory for tx ring buffer failed!");
  381. rt_free_align(dev->rdes);
  382. rt_free_align(dev->tdes);
  383. rt_free_align((void *)dev->rx_buffers);
  384. return RT_ERROR;
  385. }
  386. dbg_log(DBG_LOG, "rdes:%p tdes:%p rbuf:%p tbuf:%p\n", dev->rdes, dev->tdes, dev->rx_buffers, dev->tx_buffers);
  387. int i = 0;
  388. for (i = 0; i < dev->rx_buffer_count; i++)
  389. {
  390. pcnet32_init_rx_desc_entry(dev, i);
  391. }
  392. for (i = 0; i < dev->tx_buffer_count; i++)
  393. {
  394. pcnet32_init_tx_desc_entry(dev, i);
  395. }
  396. return RT_EOK;
  397. }
  398. static void pcnet32_free_ring_buffer(struct eth_device_pcnet32 *dev)
  399. {
  400. rt_free_align(dev->rdes);
  401. rt_free_align(dev->tdes);
  402. rt_free_align((void *)dev->rx_buffers);
  403. rt_free_align((void *)dev->tx_buffers);
  404. }
  405. static void pcnet32_print_init_block(struct eth_device_pcnet32 *dev)
  406. {
  407. rt_uint32_t iobase = dev->iobase;
  408. struct pcnet32_init_block *init_block = dev->init_block;
  409. dbg_log(DBG_LOG, "============\nprint init block\n");
  410. dbg_log(DBG_LOG, "mode: %x, tlen_rlen:%x\n", init_block->mode, init_block->tlen_rlen);
  411. dbg_log(DBG_LOG, "mac: %x:%x:%x:%x:%x:%x\n",
  412. init_block->phys_addr[0],
  413. init_block->phys_addr[1],
  414. init_block->phys_addr[2],
  415. init_block->phys_addr[3],
  416. init_block->phys_addr[4],
  417. init_block->phys_addr[5]);
  418. dbg_log(DBG_LOG, "filter0: %x, filter1: %x\n", init_block->filter[0], init_block->filter[1]);
  419. dbg_log(DBG_LOG, "rx ring dma: %x, tx ring dma: %x\n", init_block->rx_ring, init_block->tx_ring);
  420. dbg_log(DBG_LOG, "init block dma: %x\n", dev->init_block_dma_addr);
  421. int i = 0;
  422. for (; i <= 46; i++)
  423. {
  424. dbg_log(DBG_LOG, "csr%d=%x\n", i, pcnet32_wio_read_csr(iobase, i));
  425. }
  426. }
  427. static rt_err_t pcnet32_init(rt_device_t device)
  428. {
  429. struct eth_device_pcnet32 *dev = GET_PCNET32(device);
  430. rt_uint32_t iobase = dev->iobase;
  431. /* init buffer info */
  432. dev->rx_buffer_ptr = 0;
  433. dev->tx_buffer_ptr = 0;
  434. dev->rx_buffer_count = PCNET32_RX_BUFFERS;
  435. dev->tx_buffer_count = PCNET32_TX_BUFFERS;
  436. dev->buffer_size = ETH_FRAME_LEN;
  437. dev->de_size = PCNET32_RING_DE_SIZE;
  438. if (pcnet32_alloc_ring_buffer(dev) != RT_EOK)
  439. {
  440. return RT_ERROR;
  441. }
  442. dev->rx_ring_dma_addr = (rt_ubase_t)rt_hw_vir2phy(dev->rdes);
  443. dev->tx_ring_dma_addr = (rt_ubase_t)rt_hw_vir2phy(dev->tdes);
  444. /* create msg queue for eth rx */
  445. dev->rx_mqueue = rt_mq_create("rx_mqueue", RX_MSG_SIZE, RX_MSG_CNT, 0);
  446. if (dev->rx_mqueue == RT_NULL)
  447. {
  448. LOG_E("crete msg queue for rx buffer failed!\n");
  449. pcnet32_free_ring_buffer(dev);
  450. return RT_ERROR;
  451. }
  452. /* alloc init block, must 16 bit align */
  453. dev->init_block = rt_malloc_align(sizeof(struct pcnet32_init_block), 16);
  454. if (dev->init_block == RT_NULL)
  455. {
  456. dbg_log(DBG_ERROR, "alloc memory for init block failed!");
  457. rt_mq_delete(dev->rx_mqueue);
  458. pcnet32_free_ring_buffer(dev);
  459. return RT_ERROR;
  460. }
  461. dev->init_block_dma_addr = (rt_ubase_t)rt_hw_vir2phy(dev->init_block);
  462. dbg_log(DBG_LOG, "init block addr:%p size:%d\n", dev->init_block, sizeof(struct pcnet32_init_block));
  463. /* fill init block */
  464. dev->init_block->mode = 0;
  465. dev->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 4);
  466. dev->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
  467. dev->init_block->tlen_rlen = (dev->tx_len_bits << 8) | dev->rx_len_bits;
  468. int i = 0;
  469. for (i = 0; i < ETH_ALEN; i++)
  470. {
  471. dev->init_block->phys_addr[i] = dev->dev_addr[i];
  472. }
  473. dev->init_block->filter[0] = 0x00000000;
  474. dev->init_block->filter[1] = 0x00000000;
  475. dev->init_block->rx_ring = dev->rx_ring_dma_addr;
  476. dev->init_block->tx_ring = dev->tx_ring_dma_addr;
  477. /* register init block, CSR1 save low 16 bit, CSR1 save high 16 bit */
  478. pcnet32_wio_write_csr(iobase, CSR1, (dev->init_block_dma_addr & 0xffff));
  479. pcnet32_wio_write_csr(iobase, CSR2, (dev->init_block_dma_addr >> 16) & 0xffff);
  480. /* register intr */
  481. if (rt_hw_interrupt_install(dev->irqno, rt_hw_pcnet32_isr, (void *) dev, "pcnet32") < 0)
  482. {
  483. LOG_E("install IRQ failed!\n");
  484. rt_free_align(dev->init_block);
  485. rt_mq_delete(dev->rx_mqueue);
  486. pcnet32_free_ring_buffer(dev);
  487. return RT_ERROR;
  488. }
  489. rt_hw_interrupt_umask(dev->irqno);
  490. /* Start init */
  491. pcnet32_wio_write_csr(iobase, CSR0, CSR0_INIT | CSR0_INTEN);
  492. dbg_log(DBG_LOG, "card init done.\n");
  493. /* add auto pad amd strip recv */
  494. rt_uint16_t csr4 = pcnet32_wio_read_csr(iobase, CSR4);
  495. pcnet32_wio_write_csr(iobase, CSR4, csr4 | CSR4_ASTRP_RCV | CSR4_APAD_XMT);
  496. /* start work */
  497. pcnet32_wio_write_csr(iobase, CSR0, CSR0_START | CSR0_INTEN);
  498. pcnet32_print_init_block(dev);
  499. eth_device_linkchange(&dev->parent, RT_TRUE);
  500. return RT_EOK;
  501. }
  502. #ifdef RT_USING_DEVICE_OPS
  503. const static struct rt_device_ops pcnet32_ops =
  504. {
  505. pcnet32_init,
  506. RT_NULL,
  507. RT_NULL,
  508. RT_NULL,
  509. RT_NULL,
  510. pcnet32_control
  511. };
  512. #endif
  513. static rt_err_t pcnet32_init_hw(struct eth_device_pcnet32 *dev)
  514. {
  515. rt_uint32_t iobase = dev->iobase;
  516. /* reset card to 16 bit io mode */
  517. pcnet32_wio_reset(iobase);
  518. /* use dealy to wait reset done, at least 1 microsecond */
  519. rt_thread_delay(1);
  520. /* switch to 32 bit soft-style mode, use 32 bit struct */
  521. pcnet32_wio_write_bcr(iobase, 20, 0x102);
  522. /* stop card work */
  523. pcnet32_wio_write_csr(iobase, 0, 0x4);
  524. /* read mac addr */
  525. rt_uint16_t mac0 = pcnet32_wio_read_mac(iobase, 0);
  526. rt_uint16_t mac1 = pcnet32_wio_read_mac(iobase, 2);
  527. rt_uint16_t mac2 = pcnet32_wio_read_mac(iobase, 4);
  528. dev->dev_addr[0] = mac0 & 0xff;
  529. dev->dev_addr[1] = (mac0 >> 8) & 0xff;
  530. dev->dev_addr[2] = mac1 & 0xff;
  531. dev->dev_addr[3] = (mac1 >> 8) & 0xff;
  532. dev->dev_addr[4] = mac2 & 0xff;
  533. dev->dev_addr[5] = (mac2 >> 8) & 0xff;
  534. dbg_log(DBG_INFO, "MAC addr: %x:%x:%x:%x:%x:%x\n",
  535. dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
  536. dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
  537. return RT_EOK;
  538. }
  539. static int rt_hw_pcnet32_init(void)
  540. {
  541. rt_memset(&eth_dev, 0x0, sizeof(eth_dev));
  542. if (pcnet32_get_pci(&eth_dev) < 0)
  543. {
  544. return -1;
  545. }
  546. if (pcnet32_init_hw(&eth_dev) != RT_EOK)
  547. {
  548. return -1;
  549. }
  550. /* set device opts */
  551. #ifdef RT_USING_DEVICE_OPS
  552. eth_dev.parent.parent.ops = &pcnet32_ops;
  553. #else
  554. eth_dev.parent.parent.init = pcnet32_init;
  555. eth_dev.parent.parent.open = RT_NULL;
  556. eth_dev.parent.parent.close = RT_NULL;
  557. eth_dev.parent.parent.read = RT_NULL;
  558. eth_dev.parent.parent.write = RT_NULL;
  559. eth_dev.parent.parent.control = pcnet32_control;
  560. #endif
  561. eth_dev.parent.parent.user_data = RT_NULL;
  562. eth_dev.parent.eth_rx = pcnet32_rx;
  563. eth_dev.parent.eth_tx = pcnet32_tx;
  564. /* register ETH device */
  565. if (eth_device_init(&(eth_dev.parent), DEV_NAME) != RT_EOK)
  566. {
  567. return -1;
  568. }
  569. return 0;
  570. }
  571. INIT_DEVICE_EXPORT(rt_hw_pcnet32_init);