sam7x_emac.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659
  1. #include <rthw.h>
  2. #include <rtthread.h>
  3. #include <netif/ethernetif.h>
  4. #include "sam7x_emac.h"
  5. #include "AT91SAM7X256.h"
  6. #include "lwipopts.h"
  7. #define MAX_ADDR_LEN 6
  8. #ifdef DM9161
  9. #define EMAC_PIO_CFG (AT91C_PB8_EMDC | \
  10. AT91C_PB9_EMDIO | \
  11. AT91C_PB2_ETX0 | \
  12. AT91C_PB3_ETX1 | \
  13. AT91C_PB10_ETX2 | \
  14. AT91C_PB11_ETX3 | \
  15. AT91C_PB1_ETXEN | \
  16. AT91C_PB0_ETXCK_EREFCK | \
  17. AT91C_PB15_ERXDV_ECRSDV | \
  18. AT91C_PB5_ERX0 | \
  19. AT91C_PB6_ERX1 | \
  20. AT91C_PB12_ETXER | \
  21. AT91C_PB13_ERX2 | \
  22. AT91C_PB14_ERX3 | \
  23. AT91C_PB17_ERXCK | \
  24. AT91C_PB16_ECOL | \
  25. AT91C_PB4_ECRS | \
  26. AT91C_PB7_ERXER)
  27. #else
  28. #define EMAC_PIO_CFG (AT91C_PB0_ETXCK_EREFCK | \
  29. AT91C_PB1_ETXEN | \
  30. AT91C_PB2_ETX0 | \
  31. AT91C_PB3_ETX1 | \
  32. AT91C_PB4_ECRS | \
  33. AT91C_PB5_ERX0 | \
  34. AT91C_PB6_ERX1 | \
  35. AT91C_PB7_ERXER | \
  36. AT91C_PB8_EMDC | \
  37. AT91C_PB9_EMDIO | \
  38. AT91C_PB10_ETX2 | \
  39. AT91C_PB11_ETX3 | \
  40. AT91C_PB10_ETX2 | \
  41. AT91C_PB13_ERX2 | \
  42. AT91C_PB14_ERX3 | \
  43. AT91C_PB15_ERXDV_ECRSDV| \
  44. AT91C_PB16_ECOL | \
  45. AT91C_PB17_ERXCK)
  46. #endif
  47. #define RB_BUFFER_SIZE 8 /* max number of receive buffers */
  48. #define ETH_RX_BUF_SIZE 128
  49. #define TB_BUFFER_SIZE 4
  50. #define ETH_TX_BUF_SIZE (PBUF_POOL_BUFSIZE)
  51. struct rbf_t
  52. {
  53. rt_uint32_t addr;
  54. rt_uint32_t status;
  55. };
  56. static rt_uint32_t current_rb_index; /* current receive buffer index */
  57. static volatile struct rbf_t rb_descriptors[RB_BUFFER_SIZE];
  58. static volatile struct rbf_t tb_descriptors[TB_BUFFER_SIZE];
  59. static rt_uint8_t rx_buf[RB_BUFFER_SIZE][ETH_RX_BUF_SIZE] __attribute__ ((aligned (8)));
  60. static rt_uint8_t tx_buf[TB_BUFFER_SIZE][ETH_TX_BUF_SIZE] __attribute__ ((aligned (8)));
  61. static struct rt_semaphore tx_sem;
  62. struct net_device
  63. {
  64. /* inherit from ethernet device */
  65. struct eth_device parent;
  66. /* interface address info. */
  67. rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
  68. };
  69. static struct net_device sam7x_dev_entry;
  70. static struct net_device *sam7x_dev =&sam7x_dev_entry;
  71. AT91PS_EMAC pEmac = AT91C_BASE_EMAC;
  72. rt_inline void write_phy(rt_uint8_t addr, rt_uint32_t value)
  73. {
  74. AT91C_BASE_EMAC->EMAC_MAN = ((0x01<<30) | (2 << 16) | (1 << 28) |
  75. (AT91C_PHY_ADDR << 23) | (addr << 18)) | value;
  76. /* Wait until IDLE bit in Network Status register is cleared */
  77. while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
  78. }
  79. rt_inline rt_uint32_t read_phy(rt_uint8_t addr)
  80. {
  81. AT91C_BASE_EMAC->EMAC_MAN = (0x01<<30) | (0x02 << 16) | (0x02 << 28) |
  82. (AT91C_PHY_ADDR << 23) | (addr << 18);
  83. /* Wait until IDLE bit in Network Status register is cleared */
  84. while (!(AT91C_BASE_EMAC->EMAC_NSR & AT91C_EMAC_IDLE));
  85. return (AT91C_BASE_EMAC->EMAC_MAN & 0x0000ffff);
  86. }
  87. rt_inline void sam7xether_reset_tx_desc(void)
  88. {
  89. static rt_uint32_t index = 0;
  90. if(tb_descriptors[index].status & TxDESC_STATUS_USED)
  91. {
  92. while(!(tb_descriptors[index].status & TxDESC_STATUS_LAST_BUF))
  93. {
  94. index ++;
  95. if(index >= TB_BUFFER_SIZE)index = 0;
  96. tb_descriptors[index].status |= TxDESC_STATUS_USED;
  97. }
  98. index ++;
  99. if(index >= TB_BUFFER_SIZE)index = 0;
  100. }
  101. }
  102. /* interrupt service routing */
  103. static void sam7xether_isr(int irq)
  104. {
  105. /* Variable definitions can be made now. */
  106. volatile rt_uint32_t isr, rsr;
  107. /* get status */
  108. isr = AT91C_BASE_EMAC->EMAC_ISR;
  109. rsr = AT91C_BASE_EMAC->EMAC_RSR;
  110. if( ( isr & AT91C_EMAC_RCOMP ) || ( rsr & AT91C_EMAC_REC ) )
  111. {
  112. rt_err_t result;
  113. /* a frame has been received */
  114. result = eth_device_ready((struct eth_device*)&(sam7x_dev->parent));
  115. RT_ASSERT(result == RT_EOK);
  116. AT91C_BASE_EMAC->EMAC_RSR = AT91C_EMAC_REC;
  117. }
  118. if( isr & AT91C_EMAC_TCOMP )
  119. {
  120. /* A frame has been transmitted. Mark all the buffers as free */
  121. sam7xether_reset_tx_desc();
  122. AT91C_BASE_EMAC->EMAC_TSR = AT91C_EMAC_COMP;
  123. }
  124. }
  125. rt_inline void linksetup(void)
  126. {
  127. rt_uint32_t value, tout, id1, id2;
  128. #ifdef DM9161
  129. rt_uint32_t ulBMSR,ulBMCR,i;
  130. #endif
  131. #ifdef DM9161
  132. //PHY has internal pull down : disable MII isolate
  133. tout = read_phy(PHY_REG_BMCR);
  134. tout = read_phy(PHY_REG_BMCR);
  135. tout &= ~BMCR_ISOLATE;
  136. write_phy(PHY_REG_BMCR, tout);
  137. /* Check if this is a RTL8201 or DM9161 PHY. */
  138. id1 = read_phy(PHY_REG_PHYID1);
  139. id2 = read_phy(PHY_REG_PHYID2);
  140. if (((id1 << 16) | (id2 & 0xfff0)) == MII_DM9161_ID)
  141. {
  142. rt_kprintf("read MII_DM9161_ID ok!\n");
  143. tout = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
  144. DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
  145. write_phy(PHY_REG_ANAR, tout);
  146. // Wait for PHY auto negotiation completed
  147. i = 0;
  148. do {
  149. ulBMSR = read_phy(PHY_REG_BMSR);
  150. ulBMSR = read_phy(PHY_REG_BMSR);
  151. i++;
  152. if(i >= 0xffff)
  153. break;
  154. }while (!(ulBMSR & BMSR_ANEGCOMPLETE));
  155. if(i >= 0xffff)
  156. rt_kprintf("PHY No Link!\n");
  157. else
  158. rt_kprintf("PHY auto negotiation completed!\n");
  159. /* Update the MAC register NCFGR. */
  160. AT91C_BASE_EMAC->EMAC_NCFGR = 0;
  161. ulBMCR = read_phy(PHY_REG_BMCR);
  162. if (ulBMCR & BMCR_ANENABLE)
  163. {
  164. /* AutoNegotiation is enabled. */
  165. if(!(ulBMSR & BMSR_ANEGCOMPLETE))
  166. {
  167. /* Auto-negotitation in progress. */
  168. rt_kprintf("Auto-negotitation in progress!\n");
  169. return;
  170. }
  171. if (ulBMCR & BMCR_SPEED100)
  172. {
  173. /* Speed 100Mbit is enabled. */
  174. AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
  175. }
  176. if (ulBMCR & BMCR_FULLDPLX)
  177. {
  178. /* Full duplex is enabled. */
  179. AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
  180. }
  181. }
  182. }
  183. #else
  184. /* Check if this is a RTL8201 or DM9161 PHY. */
  185. id1 = read_phy(PHY_REG_PHYID1);
  186. id2 = read_phy(PHY_REG_PHYID2);
  187. if (((id2 << 16) | (id1 & 0xfff0)) == MII_RTL8201_ID)
  188. {
  189. rt_kprintf("read MII_RTL8201_ID ok!\n");
  190. /* Configure the PHY device */
  191. /* Use autonegotiation about the link speed. */
  192. write_phy (PHY_REG_BMCR, PHY_AUTO_NEG);
  193. /* Wait to complete Auto_Negotiation. */
  194. for (tout = 0; tout < 0x100000; tout++)
  195. {
  196. value = read_phy (PHY_REG_BMSR);
  197. if (value & BMSR_ANEGCOMPLETE) break; /* autonegotiation finished. */
  198. }
  199. /* Check the link status. */
  200. for (tout = 0; tout < 0x10000; tout++)
  201. {
  202. value = read_phy (PHY_REG_BMSR);
  203. if (value & BMSR_LINKST) break; /* Link is on. */
  204. }
  205. }
  206. value = read_phy (PHY_REG_ANLPAR);
  207. /* Update the MAC register NCFGR. */
  208. AT91C_BASE_EMAC->EMAC_NCFGR &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
  209. /* set full duplex . */
  210. if (value & 0xA000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_FD;
  211. /* set speed */
  212. if (value & 0xC000) AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_SPD;
  213. #endif
  214. }
  215. /*
  216. * Set the MAC address.
  217. */
  218. rt_inline void update_mac_address(struct net_device* device)
  219. {
  220. AT91C_BASE_EMAC->EMAC_SA1L = (device->dev_addr[3] << 24) |
  221. (device->dev_addr[2] << 16) |
  222. (device->dev_addr[1] << 8) |
  223. device->dev_addr[0];
  224. AT91C_BASE_EMAC->EMAC_SA1H = (device->dev_addr[5] << 8) |
  225. device->dev_addr[4];
  226. }
  227. rt_inline void sam7xether_desc_init()
  228. {
  229. rt_uint32_t i;
  230. /* Rx Buffer Descriptor initialization */
  231. current_rb_index = 0;
  232. for (i = 0; i < RB_BUFFER_SIZE; i++)
  233. {
  234. rb_descriptors[i].addr = (rt_uint32_t)&(rx_buf[i][0]);
  235. rb_descriptors[i].status = 0;
  236. }
  237. /* Set the WRAP bit at the end of the list descriptor. */
  238. rb_descriptors[RB_BUFFER_SIZE-1].addr |= 0x02;
  239. /* Set Rx Queue pointer to descriptor list. */
  240. AT91C_BASE_EMAC->EMAC_RBQP = (unsigned int)&(rb_descriptors[0]);
  241. /* Tx Buffer Descriptor initialization */
  242. for (i = 0; i < TB_BUFFER_SIZE; i++)
  243. {
  244. tb_descriptors[i].addr = (rt_uint32_t)&(tx_buf[i][0]);
  245. tb_descriptors[i].status = TxDESC_STATUS_USED;
  246. }
  247. /* Set the WRAP bit at the end of the list descriptor. */
  248. tb_descriptors[TB_BUFFER_SIZE-1].status |= TxDESC_STATUS_WRAP;
  249. /* Set Tx Queue pointer to descriptor list. */
  250. AT91C_BASE_EMAC->EMAC_TBQP = (unsigned int)&(tb_descriptors[0]);
  251. }
  252. /* RT-Thread Device Interface */
  253. /* initialize the interface */
  254. rt_err_t sam7xether_init(rt_device_t dev)
  255. {
  256. rt_uint32_t i;
  257. /* enable peripheral clock for EMAC and PIO B */
  258. AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_PIOB | 1 << AT91C_ID_EMAC;
  259. /* Disable pull up on RXDV => PHY normal mode (not in test mode), */
  260. /* and set MII mode. PHY has internal pull down. */
  261. AT91C_BASE_PIOB->PIO_PPUDR = (1<<16) | (1 << 15);
  262. /* Clear PB18 <=> PHY powerdown */
  263. AT91C_BASE_PIOB->PIO_PER = 1<<18;
  264. AT91C_BASE_PIOB->PIO_OER = 1<<18;
  265. AT91C_BASE_PIOB->PIO_CODR = 1<<18;
  266. /* EMAC IO init for EMAC-PHY communication. */
  267. AT91C_BASE_PIOB->PIO_ASR = EMAC_PIO_CFG;
  268. AT91C_BASE_PIOB->PIO_PDR = EMAC_PIO_CFG; // Set in Periph mode
  269. /* Enable communication between EMAC-PHY. */
  270. AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_MPE;
  271. /* MDC = MCK/32 */
  272. AT91C_BASE_EMAC->EMAC_NCFGR |= 2<<10;
  273. /* Reset PHY */
  274. AT91C_BASE_PIOB->PIO_PPUDR = AT91C_PB7_ERXER;
  275. AT91C_BASE_RSTC->RSTC_RMR = 0xA5000000 | (0x08 << 8) ;
  276. AT91C_BASE_RSTC->RSTC_RCR = 0xA5000000 | AT91C_RSTC_EXTRST;
  277. i = 0;
  278. while(!(AT91C_BASE_RSTC->RSTC_RSR & AT91C_RSTC_NRSTL))
  279. {
  280. i++;
  281. if(i >= 0xfffff)
  282. break;
  283. }
  284. for(i=0; i<0xfffff; i++);//* 等待一段指定的时间,使PHY就绪
  285. linksetup();
  286. rt_kprintf("linksetup ok!\n");
  287. /* Disable management port in MAC control register. */
  288. AT91C_BASE_EMAC->EMAC_NCR &= ~AT91C_EMAC_MPE;
  289. /* Enable EMAC in MII mode, enable clock ERXCK and ETXCK */
  290. AT91C_BASE_EMAC->EMAC_USRIO= AT91C_EMAC_CLKEN;
  291. /* Transmit and Receive disable. */
  292. AT91C_BASE_EMAC->EMAC_NCR &= ~(AT91C_EMAC_RE | AT91C_EMAC_TE);
  293. /* init descriptor */
  294. sam7xether_desc_init();
  295. /* Clear receive and transmit status registers. */
  296. AT91C_BASE_EMAC->EMAC_RSR = (AT91C_EMAC_OVR | AT91C_EMAC_REC | AT91C_EMAC_BNA);
  297. AT91C_BASE_EMAC->EMAC_TSR = (AT91C_EMAC_UND | AT91C_EMAC_COMP| AT91C_EMAC_BEX |
  298. AT91C_EMAC_RLES| AT91C_EMAC_COL | AT91C_EMAC_UBR);
  299. /* Configure EMAC operation mode. */
  300. //AT91C_BASE_EMAC->EMAC_NCFGR |= (AT91C_EMAC_BIG | AT91C_EMAC_DRFCS);
  301. // 复制所有有效帧到接收缓冲区 *不复制FCS字段 不接收广播帧 不接收1526字节长帧
  302. AT91C_BASE_EMAC->EMAC_NCFGR |= AT91C_EMAC_CAF |AT91C_EMAC_DRFCS | AT91C_EMAC_NBC | AT91C_EMAC_BIG;
  303. AT91C_BASE_EMAC->EMAC_NCR |= (AT91C_EMAC_TE | AT91C_EMAC_RE | AT91C_EMAC_WESTAT);
  304. /* update MAC address */
  305. update_mac_address(sam7x_dev);
  306. /* enable interrupt */
  307. AT91C_BASE_EMAC->EMAC_IDR = 0x3fff;
  308. AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP | AT91C_EMAC_TCOMP;
  309. /* setup interrupt */
  310. rt_hw_interrupt_install(AT91C_ID_EMAC, sam7xether_isr, RT_NULL);
  311. *(volatile unsigned int*)(0xFFFFF000 + AT91C_ID_EMAC * 4) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
  312. // AT91C_AIC_SMR(AT91C_ID_EMAC) = AT91C_AIC_SRCTYPE_INT_HIGH_LEVEL | 5;
  313. rt_hw_interrupt_umask(AT91C_ID_EMAC);
  314. return RT_EOK;
  315. }
  316. /* control the interface */
  317. rt_err_t sam7xether_control(rt_device_t dev, rt_uint8_t cmd, void *args)
  318. {
  319. switch(cmd)
  320. {
  321. case NIOCTL_GADDR:
  322. /* get mac address */
  323. if(args) rt_memcpy(args, sam7x_dev_entry.dev_addr, 6);
  324. else return -RT_ERROR;
  325. break;
  326. default :
  327. break;
  328. }
  329. return RT_EOK;
  330. }
  331. /* Open the ethernet interface */
  332. rt_err_t sam7xether_open(rt_device_t dev, rt_uint16_t oflags)
  333. {
  334. return RT_EOK;
  335. }
  336. /* Close the interface */
  337. rt_err_t sam7xether_close(rt_device_t dev)
  338. {
  339. return RT_EOK;
  340. }
  341. /* Read */
  342. rt_size_t sam7xether_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
  343. {
  344. rt_set_errno(-RT_ENOSYS);
  345. return 0;
  346. }
  347. /* Write */
  348. rt_size_t sam7xether_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
  349. {
  350. rt_set_errno(-RT_ENOSYS);
  351. return 0;
  352. }
  353. /* See the header file for descriptions of public functions. */
  354. void sam7xether_write_frame(rt_uint8_t *ptr, rt_uint32_t length, rt_bool_t eof)
  355. {
  356. rt_uint8_t *buf_ptr;
  357. static rt_uint32_t current_tb_index = 0;
  358. rt_uint32_t is_last, tx_offset = 0, remain, pdu_length;
  359. while(tx_offset < length)
  360. {
  361. /* check whether buffer is available */
  362. while(!(tb_descriptors[current_tb_index].status & TxDESC_STATUS_USED))
  363. {
  364. /* no buffer */
  365. rt_thread_delay(5);
  366. }
  367. /* Get the address of the buffer from the descriptor, then copy
  368. the data into the buffer. */
  369. buf_ptr = (rt_uint8_t *)tb_descriptors[current_tb_index].addr;
  370. /* How much can we write to the buffer? */
  371. remain = length - tx_offset;
  372. pdu_length = (remain <= ETH_TX_BUF_SIZE)? remain : ETH_TX_BUF_SIZE;
  373. /* Copy the data into the buffer. */
  374. rt_memcpy(buf_ptr, &ptr[tx_offset], pdu_length );
  375. tx_offset += pdu_length;
  376. /* Is this the last data for the frame? */
  377. if((eof == RT_TRUE) && ( tx_offset >= length )) is_last = TxDESC_STATUS_LAST_BUF;
  378. else is_last = 0;
  379. /* Fill out the necessary in the descriptor to get the data sent,
  380. then move to the next descriptor, wrapping if necessary. */
  381. if(current_tb_index >= (TB_BUFFER_SIZE - 1))
  382. {
  383. tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
  384. | is_last
  385. | TxDESC_STATUS_WRAP;
  386. current_tb_index = 0;
  387. }
  388. else
  389. {
  390. tb_descriptors[current_tb_index].status = ( pdu_length & TxDESC_STATUS_BUF_SIZE )
  391. | is_last;
  392. current_tb_index++;
  393. }
  394. /* If this is the last buffer to be sent for this frame we can
  395. start the transmission. */
  396. if(is_last)
  397. {
  398. AT91C_BASE_EMAC->EMAC_NCR |= AT91C_EMAC_TSTART;
  399. }
  400. }
  401. }
  402. /* ethernet device interface */
  403. /*
  404. * Transmit packet.
  405. */
  406. rt_err_t sam7xether_tx( rt_device_t dev, struct pbuf* p)
  407. {
  408. struct pbuf* q;
  409. /* lock tx operation */
  410. rt_sem_take(&tx_sem, RT_WAITING_FOREVER);
  411. for (q = p; q != NULL; q = q->next)
  412. {
  413. if (q->next == RT_NULL) sam7xether_write_frame(q->payload, q->len, RT_TRUE);
  414. else sam7xether_write_frame(q->payload, q->len, RT_FALSE);
  415. }
  416. rt_sem_release(&tx_sem);
  417. return 0;
  418. }
  419. void sam7xether_read_frame(rt_uint8_t* ptr, rt_uint32_t section_length, rt_uint32_t total)
  420. {
  421. static rt_uint8_t* src_ptr;
  422. register rt_uint32_t buf_remain, section_remain;
  423. static rt_uint32_t section_read = 0, buf_offset = 0, frame_read = 0;
  424. if(ptr == RT_NULL)
  425. {
  426. /* Reset our state variables ready for the next read from this buffer. */
  427. src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
  428. frame_read = (rt_uint32_t)0;
  429. buf_offset = (rt_uint32_t)0;
  430. }
  431. else
  432. {
  433. /* Loop until we have obtained the required amount of data. */
  434. section_read = 0;
  435. while( section_read < section_length )
  436. {
  437. buf_remain = (ETH_RX_BUF_SIZE - buf_offset);
  438. section_remain = section_length - section_read;
  439. if( section_remain > buf_remain )
  440. {
  441. /* more data on section than buffer size */
  442. rt_memcpy(&ptr[ section_read ], &src_ptr[buf_offset], buf_remain);
  443. section_read += buf_remain;
  444. frame_read += buf_remain;
  445. /* free buffer */
  446. rb_descriptors[current_rb_index].addr &= ~RxDESC_FLAG_OWNSHIP;
  447. /* move to the next frame. */
  448. current_rb_index++;
  449. if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
  450. /* Reset the variables for the new buffer. */
  451. src_ptr = (rt_uint8_t *)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
  452. buf_offset = 0;
  453. }
  454. else
  455. {
  456. /* more data on buffer than section size */
  457. rt_memcpy(&ptr[section_read], &src_ptr[buf_offset], section_remain);
  458. buf_offset += section_remain;
  459. section_read += section_remain;
  460. frame_read += section_remain;
  461. /* finish this read */
  462. if((buf_offset >= ETH_RX_BUF_SIZE) || (frame_read >= total))
  463. {
  464. /* free buffer */
  465. rb_descriptors[current_rb_index].addr &= ~(RxDESC_FLAG_OWNSHIP);
  466. /* move to the next frame. */
  467. current_rb_index++;
  468. if( current_rb_index >= RB_BUFFER_SIZE ) current_rb_index = 0;
  469. src_ptr = (rt_uint8_t*)(rb_descriptors[current_rb_index].addr & RxDESC_FLAG_ADDR_MASK);
  470. buf_offset = 0;
  471. }
  472. }
  473. }
  474. }
  475. }
  476. struct pbuf *sam7xether_rx(rt_device_t dev)
  477. {
  478. struct pbuf *p = RT_NULL;
  479. /* skip fragment frame */
  480. while((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP)
  481. && !(rb_descriptors[current_rb_index].status & RxDESC_STATUS_FRAME_START))
  482. {
  483. rb_descriptors[current_rb_index].addr &= (~RxDESC_FLAG_OWNSHIP);
  484. current_rb_index++;
  485. if(current_rb_index >= RB_BUFFER_SIZE) current_rb_index = 0;
  486. }
  487. if ((rb_descriptors[current_rb_index].addr & RxDESC_FLAG_OWNSHIP))
  488. {
  489. struct pbuf* q;
  490. rt_uint32_t index, pkt_len = 0;
  491. /* first of all, find the frame length */
  492. index = current_rb_index;
  493. while (rb_descriptors[index].addr & RxDESC_FLAG_OWNSHIP)
  494. {
  495. pkt_len = rb_descriptors[index].status & RxDESC_STATUS_BUF_SIZE;
  496. if (pkt_len > 0) break;
  497. index ++;
  498. if (index >= RB_BUFFER_SIZE) index = 0;
  499. }
  500. if (pkt_len)
  501. {
  502. //p = pbuf_alloc(PBUF_LINK, pkt_len, PBUF_RAM);
  503. p = pbuf_alloc(PBUF_RAW, pkt_len, PBUF_POOL);
  504. if(p != RT_NULL)
  505. {
  506. sam7xether_read_frame(RT_NULL, 0, pkt_len);
  507. for(q = p; q != RT_NULL; q= q->next)
  508. sam7xether_read_frame(q->payload, q->len, pkt_len);
  509. }
  510. else
  511. {
  512. rt_kprintf("no memory in pbuf\n");
  513. }
  514. }
  515. }
  516. /* enable interrupt */
  517. AT91C_BASE_EMAC->EMAC_IER = AT91C_EMAC_RCOMP;
  518. return p;
  519. }
  520. int sam7xether_register(char *name)
  521. {
  522. rt_err_t result;
  523. /* init rt-thread device interface */
  524. sam7x_dev_entry.parent.parent.init = sam7xether_init;
  525. sam7x_dev_entry.parent.parent.open = sam7xether_open;
  526. sam7x_dev_entry.parent.parent.close = sam7xether_close;
  527. sam7x_dev_entry.parent.parent.read = sam7xether_read;
  528. sam7x_dev_entry.parent.parent.write = sam7xether_write;
  529. sam7x_dev_entry.parent.parent.control = sam7xether_control;
  530. sam7x_dev_entry.parent.eth_rx = sam7xether_rx;
  531. sam7x_dev_entry.parent.eth_tx = sam7xether_tx;
  532. /* Update MAC address */
  533. sam7x_dev_entry.dev_addr[0] = 0x1e;
  534. sam7x_dev_entry.dev_addr[1] = 0x30;
  535. sam7x_dev_entry.dev_addr[2] = 0x6c;
  536. sam7x_dev_entry.dev_addr[3] = 0xa2;
  537. sam7x_dev_entry.dev_addr[4] = 0x45;
  538. sam7x_dev_entry.dev_addr[5] = 0x5e;
  539. /* update mac address */
  540. update_mac_address(sam7x_dev);
  541. rt_sem_init(&tx_sem, "emac", 1, RT_IPC_FLAG_FIFO);
  542. result = eth_device_init(&(sam7x_dev->parent), (char*)name);
  543. RT_ASSERT(result == RT_EOK);
  544. return RT_EOK;
  545. }