drv_xmac_msg.c 46 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Email: opensource_embedded@phytium.com.cn
  7. *
  8. * Change Logs:
  9. * Date Author Notes
  10. * 2025-05-28 huangjin first commit
  11. */
  12. #include"rtconfig.h"
  13. #ifdef BSP_USING_ETH_MSG
  14. #include "board.h"
  15. #define LOG_TAG "xmac_drv"
  16. #include "drv_log.h"
  17. #include "mm_aspace.h"
  18. #ifdef RT_USING_SMART
  19. #include "ioremap.h"
  20. #endif
  21. #include "eth_board.h"
  22. #include "drv_xmac_msg.h"
  23. #include "fxmac_msg_common.h"
  24. #include "cache.h"
  25. #include "fcache.h"
  26. #define FXMAC_MSG_BD_TO_INDEX(ringptr, bdptr) (((uintptr)bdptr - (uintptr)(ringptr)->base_bd_addr) / (ringptr)->separation)
  27. // static void FXmacMsgInitOnError(FXmacMsgOs *instance_p);
  28. static void FXmacMsgSetupIsr(FXmacMsgOs *instance_p);
  29. static FXmacMsgOs fxmac_os_instace[FXMAC_MSG_NUM] =
  30. {
  31. #if defined(FXMAC0_MSG_ID)
  32. [FXMAC0_MSG_ID] =
  33. {
  34. .config = (0),
  35. .hwaddr = {0x98, 0x0e, 0x24, 0x00, 0x11, 0x0},
  36. },
  37. #endif
  38. #if defined(FXMAC1_MSG_ID)
  39. [FXMAC1_MSG_ID] =
  40. {
  41. .config = (0),
  42. .hwaddr = {0x98, 0x0e, 0x24, 0x00, 0x11, 0x1},
  43. },
  44. #endif
  45. #if defined(FXMAC2_MSG_ID)
  46. [FXMAC2_MSG_ID] =
  47. {
  48. .config = (0),
  49. .hwaddr = {0x98, 0x0e, 0x24, 0x00, 0x11, 0x2},
  50. },
  51. #endif
  52. #if defined(FXMAC3_MSG_ID)
  53. [FXMAC3_MSG_ID] =
  54. {
  55. .config = (0),
  56. .hwaddr = {0x98, 0x0e, 0x24, 0x00, 0x11, 0x3},
  57. },
  58. #endif
  59. };
  60. int isr_calling_flg = 0;
  61. /* queue */
  62. void FXmacQueueInit(PqQueue *q)
  63. {
  64. FASSERT(q != NULL);
  65. q->head = q->tail = q->len = 0;
  66. }
  67. int FXmacPqEnqueue(PqQueue *q, void *p)
  68. {
  69. if (q->len == PQ_QUEUE_SIZE)
  70. {
  71. return -1;
  72. }
  73. q->data[q->head] = (uintptr)p;
  74. q->head = (q->head + 1) % PQ_QUEUE_SIZE;
  75. q->len++;
  76. return 0;
  77. }
  78. void *FXmacPqDequeue(PqQueue *q)
  79. {
  80. int ptail;
  81. if (q->len == 0)
  82. {
  83. return NULL;
  84. }
  85. ptail = q->tail;
  86. q->tail = (q->tail + 1) % PQ_QUEUE_SIZE;
  87. q->len--;
  88. return (void *)q->data[ptail];
  89. }
  90. int FXmacPqQlength(PqQueue *q)
  91. {
  92. return q->len;
  93. }
  94. /* dma */
  95. /**
  96. * @name: IsTxSpaceAvailable
  97. * @msg: Get the number of free BDs in the Bdrings
  98. * @param {ethernetif} *ethernetif_p
  99. * @return {*}
  100. */
  101. static u32 IsTxSpaceAvailable(FXmacMsgOs *instance_p)
  102. {
  103. FXmacMsgBdRing *txring;
  104. u32 freecnt;
  105. FASSERT(instance_p != NULL);
  106. txring = &(FXMAC_MSG_GET_TXRING(instance_p->instance));
  107. /* tx space is available as long as there are valid BD's */
  108. freecnt = FXMAC_MSG_BD_RING_GET_FREE_CNT(txring);
  109. return freecnt;
  110. }
  111. /**
  112. * @name: FXmacMsgProcessSentBds
  113. * @msg: Free up memory space of pbuf on the send queue
  114. * @return {*}
  115. * @param {ethernetif} *ethernetif_p
  116. * @param {FXmacMsgBdRing} *txring
  117. */
  118. void FXmacMsgProcessSentBds(FXmacMsgOs *instance_p, FXmacMsgBdRing *txring)
  119. {
  120. FXmacMsgBd *txbdset;
  121. FXmacMsgBd *curbdpntr;
  122. u32 n_bds;
  123. FError status;
  124. u32 n_pbufs_freed;
  125. u32 bdindex;
  126. struct pbuf *p;
  127. u32 *temp;
  128. while (1)
  129. {
  130. /* obtain processed BD's */
  131. n_bds = FXmacMsgBdRingFromHwTx(txring, FXMAC_MSG_TX_PBUFS_LENGTH, &txbdset);
  132. if (n_bds == 0)
  133. {
  134. return;
  135. }
  136. /* free the processed BD's */
  137. n_pbufs_freed = n_bds;
  138. curbdpntr = txbdset;
  139. while (n_pbufs_freed > 0)
  140. {
  141. bdindex = FXMAC_MSG_BD_TO_INDEX(txring, curbdpntr);
  142. temp = (u32 *)curbdpntr;
  143. *temp = 0; /* Word 0 */
  144. temp++;
  145. if (bdindex == (FXMAC_MSG_TX_PBUFS_LENGTH - 1))
  146. {
  147. *temp = 0xC0000000; /* Word 1 ,used/Wrap – marks last descriptor in transmit buffer descriptor list.*/
  148. }
  149. else
  150. {
  151. *temp = 0x80000000; /* Word 1 , Used – must be zero for GEM to read data to the transmit buffer.*/
  152. }
  153. p = (struct pbuf *)instance_p->buffer.tx_pbufs_storage[bdindex];
  154. if (p != NULL)
  155. {
  156. pbuf_free(p);
  157. }
  158. instance_p->buffer.tx_pbufs_storage[bdindex] = (uintptr)NULL;
  159. curbdpntr = FXMAC_MSG_BD_RING_NEXT(txring, curbdpntr);
  160. n_pbufs_freed--;
  161. }
  162. status = FXmacMsgBdRingFree(txring, n_bds, txbdset);
  163. if (status != FT_SUCCESS)
  164. {
  165. LOG_I("Failure while freeing in Tx Done ISR.");
  166. }
  167. }
  168. return;
  169. }
  170. FError FXmacMsgSgsend(FXmacMsgOs *instance_p, struct pbuf *p)
  171. {
  172. struct pbuf *q;
  173. u32 n_pbufs;
  174. FXmacMsgBd *txbdset, *txbd, *last_txbd = NULL;
  175. FXmacMsgBd *temp_txbd;
  176. FError status;
  177. FXmacMsgBdRing *txring;
  178. u32 bdindex;
  179. uintptr tx_payload ;
  180. u32 max_fr_size;
  181. txring = &(FXMAC_MSG_GET_TXRING(instance_p->instance));
  182. /* first count the number of pbufs */
  183. for (q = p, n_pbufs = 0; q != NULL; q = q->next)
  184. {
  185. n_pbufs++;
  186. }
  187. /* obtain as many BD's */
  188. status = FXmacMsgBdRingAlloc(txring, n_pbufs, &txbdset);
  189. if (status != FT_SUCCESS)
  190. {
  191. LOG_I("sgsend: Error allocating TxBD.");
  192. return ERR_GENERAL;
  193. }
  194. for (q = p, txbd = txbdset; q != NULL; q = q->next)
  195. {
  196. bdindex = FXMAC_MSG_BD_TO_INDEX(txring, txbd);
  197. if (instance_p->buffer.tx_pbufs_storage[bdindex])
  198. {
  199. LOG_I("txbd %p, txring->base_bd_addr %p", txbd, txring->base_bd_addr);
  200. LOG_I("PBUFS not available bdindex is %d ", bdindex);
  201. LOG_I("instance_p->buffer.tx_pbufs_storage[bdindex] %p ", instance_p->buffer.tx_pbufs_storage[bdindex]);
  202. return ERR_GENERAL;
  203. }
  204. /* Send the data from the pbuf to the interface, one pbuf at a
  205. time. The size of the data in each pbuf is kept in the ->len
  206. variable. */
  207. tx_payload = (uintptr)q->payload;
  208. #ifdef RT_USING_SMART
  209. tx_payload += PV_OFFSET;
  210. #endif
  211. FXMAC_MSG_BD_SET_ADDRESS_TX(txbd, (uintptr)tx_payload);
  212. if (instance_p->config & FXMAC_MSG_OS_CONFIG_JUMBO)
  213. {
  214. max_fr_size = FXMAC_MSG_MAX_FRAME_SIZE_JUMBO;
  215. }
  216. else
  217. {
  218. max_fr_size = FXMAC_MSG_MAX_FRAME_SIZE;
  219. }
  220. if (q->len > max_fr_size)
  221. {
  222. FXMAC_MSG_BD_SET_LENGTH(txbd, max_fr_size & 0x3FFF);
  223. }
  224. else
  225. {
  226. FXMAC_MSG_BD_SET_LENGTH(txbd, q->len & 0x3FFF);
  227. }
  228. instance_p->buffer.tx_pbufs_storage[bdindex] = (uintptr)q;
  229. pbuf_ref(q);
  230. last_txbd = txbd;
  231. FXMAC_MSG_BD_CLEAR_LAST(txbd);
  232. txbd = FXMAC_MSG_BD_RING_NEXT(txring, txbd);
  233. }
  234. FXMAC_MSG_BD_SET_LAST(last_txbd);
  235. bdindex = FXMAC_MSG_BD_TO_INDEX(txring, txbd);
  236. /* For fragmented packets, remember the 1st BD allocated for the 1st
  237. packet fragment. The used bit for this BD should be cleared at the end
  238. after clearing out used bits for other fragments. For packets without
  239. just remember the allocated BD. */
  240. temp_txbd = txbdset;
  241. txbd = txbdset;
  242. txbd = FXMAC_MSG_BD_RING_NEXT(txring, txbd);
  243. q = p->next;
  244. for (; q != NULL; q = q->next)
  245. {
  246. FXMAC_MSG_BD_CLEAR_TX_USED(txbd);
  247. txbd = FXMAC_MSG_BD_RING_NEXT(txring, txbd);
  248. }
  249. FXMAC_MSG_BD_CLEAR_TX_USED(temp_txbd);
  250. status = FXmacMsgBdRingToHw(txring, n_pbufs, txbdset);
  251. if (status != FT_SUCCESS)
  252. {
  253. LOG_I("sgsend: Error submitting TxBD.");
  254. return ERR_GENERAL;
  255. }
  256. /* Start transmit */
  257. FXMAC_MSG_WRITE((&instance_p->instance), FXMAC_MSG_TX_PTR(0), bdindex);
  258. return status;
  259. }
  260. void SetupRxBds(FXmacMsgOs *instance_p, FXmacMsgBdRing *rxring)
  261. {
  262. FXmacMsgBd *rxbd;
  263. FError status;
  264. struct pbuf *p;
  265. u32 freebds;
  266. u32 bdindex;
  267. u32 *temp;
  268. uintptr_t pl_paddr;
  269. freebds = FXMAC_MSG_BD_RING_GET_FREE_CNT(rxring);
  270. while (freebds > 0)
  271. {
  272. freebds--;
  273. if (instance_p->config & FXMAC_MSG_OS_CONFIG_JUMBO)
  274. {
  275. p = pbuf_alloc(PBUF_RAW, FXMAC_MSG_MAX_FRAME_SIZE_JUMBO, PBUF_RAM);
  276. }
  277. else
  278. {
  279. p = pbuf_alloc(PBUF_RAW, FXMAC_MSG_MAX_FRAME_SIZE, PBUF_RAM);
  280. }
  281. if (!p)
  282. {
  283. #if LINK_STATS
  284. lwip_stats.link.memerr++;
  285. lwip_stats.link.drop++;
  286. #endif
  287. LOG_I("Unable to alloc pbuf in recv_handler.");
  288. return;
  289. }
  290. status = FXmacMsgBdRingAlloc(rxring, 1, &rxbd);
  291. if (status != FT_SUCCESS)
  292. {
  293. LOG_I("SetupRxBds: Error allocating RxBD.");
  294. pbuf_free(p);
  295. return;
  296. }
  297. status = FXmacMsgBdRingToHw(rxring, 1, rxbd);
  298. if (status != FT_SUCCESS)
  299. {
  300. LOG_I("Error committing RxBD to hardware: ");
  301. if (status == FXMAC_MSG_ERR_SG_LIST)
  302. {
  303. LOG_I("XST_DMA_SG_LIST_ERROR: this function was called out of sequence with FXmacMsgBdRingAlloc().");
  304. }
  305. else
  306. {
  307. LOG_I("Set of BDs was rejected because the first BD did not have its start-of-packet bit set, or the last BD did not have its end-of-packet bit set, or any one of the BD set has 0 as length value.");
  308. }
  309. pbuf_free(p);
  310. FXmacMsgBdRingUnAlloc(rxring, 1, rxbd);
  311. return;
  312. }
  313. bdindex = FXMAC_MSG_BD_TO_INDEX(rxring, rxbd);
  314. temp = (u32 *)rxbd;
  315. if (bdindex == (FXMAC_MSG_RX_PBUFS_LENGTH - 1))
  316. {
  317. *temp = 0x00000002;
  318. }
  319. else
  320. {
  321. *temp = 0;
  322. }
  323. temp++;
  324. *temp = 0;
  325. pl_paddr = (uintptr)p->payload;
  326. #ifdef RT_USING_SMART
  327. pl_paddr += PV_OFFSET;
  328. #endif
  329. FXMAC_MSG_BD_SET_ADDRESS_RX(rxbd, (uintptr)pl_paddr);
  330. instance_p->buffer.rx_pbufs_storage[bdindex] = (uintptr)p;
  331. }
  332. }
  333. void FXmacMsgRecvSemaphoreHandler(void *arg)
  334. {
  335. FXmacMsgOs *instance_p;
  336. rt_err_t result;
  337. if (RT_NULL == arg)
  338. {
  339. LOG_E("Args is NULL");
  340. return;
  341. }
  342. instance_p = (FXmacMsgOs *)arg;
  343. /* 禁用接收完成中断 */
  344. FXmacMsgDisableIrq(&instance_p->instance, 0, FXMAC_MSG_INT_RX_COMPLETE);
  345. result = eth_device_ready(&(instance_p->parent));
  346. if (result != RT_EOK)
  347. {
  348. LOG_I("RxCpltCallback err = %d", result);
  349. }
  350. }
  351. void FXmacMsgRecvHandler(void *arg)
  352. {
  353. struct pbuf *p;
  354. FXmacMsgBd *rxbdset, *curbdptr;
  355. FXmacMsgBd *rxtailbdptr = NULL;
  356. FXmacMsgBdRing *rxring;
  357. volatile u32 bd_processed;
  358. u32 rx_bytes, k;
  359. u32 bdindex = 0;
  360. // u32 regval;
  361. u32 rx_tail_bd_index = 0;
  362. FXmacMsgOs *instance_p;
  363. FASSERT(arg != NULL);
  364. instance_p = (FXmacMsgOs *)arg;
  365. rxring = &FXMAC_MSG_GET_RXRING(instance_p->instance);
  366. /* If Reception done interrupt is asserted, call RX call back function
  367. to handle the processed BDs and then raise the according flag.*/
  368. /* IOP模式没有 发送/接收状态寄存器 */
  369. // regval = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_RXSR_OFFSET);
  370. // FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_RXSR_OFFSET, regval);
  371. while (1)
  372. {
  373. bd_processed = FXmacMsgBdRingFromHwRx(rxring, FXMAC_MSG_RX_PBUFS_LENGTH, &rxbdset);
  374. if (bd_processed <= 0)
  375. {
  376. break;
  377. }
  378. for (k = 0, curbdptr = rxbdset; k < bd_processed; k++)
  379. {
  380. bdindex = FXMAC_MSG_BD_TO_INDEX(rxring, curbdptr);
  381. p = (struct pbuf *)instance_p->buffer.rx_pbufs_storage[bdindex];
  382. /*
  383. * Adjust the buffer size to the actual number of bytes received.
  384. */
  385. if (instance_p->config & FXMAC_MSG_OS_CONFIG_JUMBO)
  386. {
  387. rx_bytes = FXMAC_MSG_GET_RX_FRAME_SIZE(curbdptr);
  388. }
  389. else
  390. {
  391. rx_bytes = FXMAC_MSG_BD_GET_LENGTH(curbdptr);
  392. }
  393. pbuf_realloc(p, rx_bytes);
  394. /* Invalidate RX frame before queuing to handle
  395. * L1 cache prefetch conditions on any architecture.
  396. */
  397. // FCacheDCacheInvalidateRange((uintptr)p->payload, rx_bytes);
  398. // rt_hw_cpu_icache_invalidate((void *)p->payload, rx_bytes);
  399. /* store it in the receive queue,
  400. * where it'll be processed by a different handler
  401. */
  402. if (FXmacPqEnqueue(&instance_p->recv_q, (void *)p) < 0)
  403. {
  404. #if LINK_STATS
  405. lwip_stats.link.memerr++;
  406. lwip_stats.link.drop++;
  407. #endif
  408. pbuf_free(p);
  409. }
  410. instance_p->buffer.rx_pbufs_storage[bdindex] = (uintptr)NULL;
  411. curbdptr = FXMAC_MSG_BD_RING_NEXT(rxring, curbdptr);
  412. rxtailbdptr = curbdptr;
  413. }
  414. /* free up the BD's */
  415. FXmacMsgBdRingFree(rxring, bd_processed, rxbdset);
  416. SetupRxBds(instance_p, rxring);
  417. }
  418. /* 接收尾指针的使用 */
  419. rx_tail_bd_index = FXMAC_MSG_BD_TO_INDEX(rxring, rxtailbdptr);
  420. DSB();
  421. FXMAC_MSG_WRITE((&instance_p->instance), FXMAC_MSG_RX_PTR(0), rx_tail_bd_index);
  422. return;
  423. }
  424. void CleanDmaTxdescs(FXmacMsgOs *instance_p)
  425. {
  426. FXmacMsgBd bdtemplate;
  427. FXmacMsgBdRing *txringptr;
  428. txringptr = &FXMAC_MSG_GET_TXRING((instance_p->instance));
  429. FXMAC_MSG_BD_CLEAR(&bdtemplate);
  430. FXMAC_MSG_BD_SET_STATUS(&bdtemplate, FXMAC_MSG_TXBUF_USED_MASK);
  431. FXmacMsgBdRingCreate(txringptr, (uintptr)instance_p->buffer.tx_bdspace,
  432. (uintptr)instance_p->buffer.tx_bdspace, BD_ALIGNMENT,
  433. sizeof(instance_p->buffer.tx_bdspace));
  434. FXmacMsgBdRingClone(txringptr, &bdtemplate, FXMAC_MSG_SEND);
  435. }
  436. FError FXmacMsgInitDma(FXmacMsgOs *instance_p)
  437. {
  438. FXmacMsgBd bdtemplate;
  439. FXmacMsgBdRing *rxringptr, *txringptr;
  440. FXmacMsgBd *rxbd;
  441. struct pbuf *p;
  442. FError status;
  443. int i;
  444. u32 bdindex;
  445. u32 *temp;
  446. uintptr rx_paddr;
  447. uintptr tx_paddr;
  448. uintptr pl_paddr;
  449. /*
  450. * The BDs need to be allocated in uncached memory. Hence the 1 MB
  451. * address range allocated for Bd_Space is made uncached
  452. * by setting appropriate attributes in the translation table.
  453. * The Bd_Space is aligned to 1MB and has a size of 1 MB. This ensures
  454. * a reserved uncached area used only for BDs.
  455. */
  456. rxringptr = &FXMAC_MSG_GET_RXRING(instance_p->instance);
  457. txringptr = &FXMAC_MSG_GET_TXRING(instance_p->instance);
  458. LOG_I("rxringptr: 0x%08x", rxringptr);
  459. LOG_I("txringptr: 0x%08x", txringptr);
  460. LOG_I("rx_bdspace: %p ", instance_p->buffer.rx_bdspace);
  461. LOG_I("tx_bdspace: %p ", instance_p->buffer.tx_bdspace);
  462. /* Setup RxBD space. */
  463. FXMAC_MSG_BD_CLEAR(&bdtemplate);
  464. rx_paddr = (uintptr)instance_p->buffer.rx_bdspace;
  465. #ifdef RT_USING_SMART
  466. rx_paddr += PV_OFFSET;
  467. #endif
  468. /* Create the RxBD ring */
  469. status = FXmacMsgBdRingCreate(rxringptr, (uintptr)rx_paddr,
  470. (uintptr)instance_p->buffer.rx_bdspace, BD_ALIGNMENT,
  471. FXMAC_MSG_RX_PBUFS_LENGTH);
  472. if (status != FT_SUCCESS)
  473. {
  474. LOG_I("Error setting up RxBD space.");
  475. return ERR_IF;
  476. }
  477. status = FXmacMsgBdRingClone(rxringptr, &bdtemplate, FXMAC_MSG_RECV);
  478. if (status != FT_SUCCESS)
  479. {
  480. LOG_I("Error initializing RxBD space.");
  481. return ERR_IF;
  482. }
  483. FXMAC_MSG_BD_CLEAR(&bdtemplate);
  484. FXMAC_MSG_BD_SET_STATUS(&bdtemplate, FXMAC_MSG_TXBUF_USED_MASK);
  485. tx_paddr = (uintptr)instance_p->buffer.tx_bdspace;
  486. #ifdef RT_USING_SMART
  487. tx_paddr += PV_OFFSET;
  488. #endif
  489. /* Create the TxBD ring */
  490. status = FXmacMsgBdRingCreate(txringptr, (uintptr)tx_paddr,
  491. (uintptr)instance_p->buffer.tx_bdspace, BD_ALIGNMENT,
  492. FXMAC_MSG_TX_PBUFS_LENGTH);
  493. if (status != FT_SUCCESS)
  494. {
  495. return ERR_IF;
  496. }
  497. /* We reuse the bd template, as the same one will work for both rx and tx. */
  498. status = FXmacMsgBdRingClone(txringptr, &bdtemplate, FXMAC_MSG_SEND);
  499. if (status != FT_SUCCESS)
  500. {
  501. return ERR_IF;
  502. }
  503. /*
  504. * Allocate RX descriptors, 1 RxBD at a time.
  505. */
  506. for (i = 0; i < FXMAC_MSG_RX_PBUFS_LENGTH; i++)
  507. {
  508. if (instance_p->config & FXMAC_MSG_OS_CONFIG_JUMBO)
  509. {
  510. p = pbuf_alloc(PBUF_RAW, FXMAC_MSG_MAX_FRAME_SIZE_JUMBO, PBUF_RAM);
  511. }
  512. else
  513. {
  514. p = pbuf_alloc(PBUF_RAW, FXMAC_MSG_MAX_FRAME_SIZE, PBUF_RAM);
  515. }
  516. if (!p)
  517. {
  518. #if LINK_STATS
  519. lwip_stats.link.memerr++;
  520. lwip_stats.link.drop++;
  521. #endif
  522. LOG_E("Unable to alloc pbuf in InitDma.");
  523. return ERR_IF;
  524. }
  525. status = FXmacMsgBdRingAlloc(rxringptr, 1, &rxbd);
  526. if (status != FT_SUCCESS)
  527. {
  528. LOG_E("InitDma: Error allocating RxBD.");
  529. pbuf_free(p);
  530. return ERR_IF;
  531. }
  532. /* Enqueue to HW */
  533. status = FXmacMsgBdRingToHw(rxringptr, 1, rxbd);
  534. if (status != FT_SUCCESS)
  535. {
  536. LOG_E("Error: committing RxBD to HW.");
  537. pbuf_free(p);
  538. FXmacMsgBdRingUnAlloc(rxringptr, 1, rxbd);
  539. return ERR_IF;
  540. }
  541. bdindex = FXMAC_MSG_BD_TO_INDEX(rxringptr, rxbd);
  542. temp = (u32 *)rxbd;
  543. *temp = 0;
  544. if (bdindex == (FXMAC_MSG_RX_PBUFS_LENGTH - 1))
  545. {
  546. *temp = 0x00000002;
  547. }
  548. temp++;
  549. *temp = 0;
  550. pl_paddr = (uintptr)p->payload;
  551. #ifdef RT_USING_SMART
  552. pl_paddr += PV_OFFSET;
  553. #endif
  554. FXMAC_MSG_BD_SET_ADDRESS_RX(rxbd, (uintptr)pl_paddr);
  555. instance_p->buffer.rx_pbufs_storage[bdindex] = (uintptr)p;
  556. }
  557. FXmacMsgSetQueuePtr(&(instance_p->instance), instance_p->instance.tx_bd_queue.bdring.phys_base_addr, 0, (u16)FXMAC_MSG_SEND);
  558. FXmacMsgSetQueuePtr(&(instance_p->instance), instance_p->instance.rx_bd_queue.bdring.phys_base_addr, 0, (u16)FXMAC_MSG_RECV);
  559. return 0;
  560. }
  561. // static void FreeOnlyTxPbufs(FXmacMsgOs *instance_p)
  562. // {
  563. // u32 index;
  564. // struct pbuf *p;
  565. // for (index = 0; index < (FXMAC_MSG_TX_PBUFS_LENGTH); index++)
  566. // {
  567. // if (instance_p->buffer.tx_pbufs_storage[index] != 0)
  568. // {
  569. // p = (struct pbuf *)instance_p->buffer.tx_pbufs_storage[index];
  570. // pbuf_free(p);
  571. // instance_p->buffer.tx_pbufs_storage[index] = (uintptr)NULL;
  572. // }
  573. // instance_p->buffer.tx_pbufs_storage[index] = (uintptr)0;
  574. // }
  575. // }
  576. // static void FreeOnlyRxPbufs(FXmacMsgOs *instance_p)
  577. // {
  578. // u32 index;
  579. // struct pbuf *p;
  580. // for (index = 0; index < (FXMAC_MSG_RX_PBUFS_LENGTH); index++)
  581. // {
  582. // if (instance_p->buffer.rx_pbufs_storage[index] != 0)
  583. // {
  584. // p = (struct pbuf *)instance_p->buffer.rx_pbufs_storage[index];
  585. // pbuf_free(p);
  586. // instance_p->buffer.rx_pbufs_storage[index] = (uintptr)0;
  587. // }
  588. // }
  589. // }
  590. // static void FreeTxRxPbufs(FXmacMsgOs *instance_p)
  591. // {
  592. // u32 rx_queue_len;
  593. // struct pbuf *p;
  594. // /* first :free PqQueue data */
  595. // rx_queue_len = FXmacPqQlength(&instance_p->recv_q);
  596. // while (rx_queue_len)
  597. // {
  598. // /* return one packet from receive q */
  599. // p = (struct pbuf *)FXmacPqDequeue(&instance_p->recv_q);
  600. // pbuf_free(p);
  601. // LOG_E("Delete queue %p", p);
  602. // rx_queue_len--;
  603. // }
  604. // FreeOnlyTxPbufs(instance_p);
  605. // FreeOnlyRxPbufs(instance_p);
  606. // }
  607. /* interrupt */
  608. // static void FXmacMsgHandleDmaTxError(FXmacMsgOs *instance_p)
  609. // {
  610. // s32_t status = FT_SUCCESS;
  611. // u32 dmacrreg;
  612. // FreeTxRxPbufs(instance_p);
  613. // status = FXmacMsgCfgInitialize(&instance_p->instance, &instance_p->instance.config);
  614. // if (status != FT_SUCCESS)
  615. // {
  616. // LOG_E("In %s:EmacPs Configuration Failed....", __func__);
  617. // }
  618. // /* initialize the mac */
  619. // FXmacMsgInitOnError(instance_p); /* need to set mac filter address */
  620. // /* IOP模式下可以直接操作该寄存器吗? */
  621. // dmacrreg = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_DMACR_OFFSET);
  622. // dmacrreg = dmacrreg | (FXMAC_DMACR_ORCE_DISCARD_ON_ERR_MASK); /* force_discard_on_err */
  623. // FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_DMACR_OFFSET, dmacrreg);
  624. // FXmacMsgSetupIsr(instance_p);
  625. // FXmacMsgInitDma(instance_p);
  626. // FXmacMsgStart(&instance_p->instance);
  627. // }
  628. // void FXmacMsgHandleTxErrors(FXmacMsgOs *instance_p)
  629. // {
  630. // u32 netctrlreg;
  631. // netctrlreg = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_NWCTRL_OFFSET);
  632. // netctrlreg = netctrlreg & (~FXMAC_NWCTRL_TXEN_MASK);
  633. // FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_NWCTRL_OFFSET, netctrlreg);
  634. // FreeOnlyTxPbufs(instance_p);
  635. // CleanDmaTxdescs(instance_p);
  636. // netctrlreg = FXMAC_READREG32(instance_p->instance.config.base_address, FXMAC_NWCTRL_OFFSET);
  637. // netctrlreg = netctrlreg | (FXMAC_NWCTRL_TXEN_MASK);
  638. // FXMAC_WRITEREG32(instance_p->instance.config.base_address, FXMAC_NWCTRL_OFFSET, netctrlreg);
  639. // }
  640. // void FXmacMsgErrorHandler(void *arg, u8 direction, u32 error_word)
  641. // {
  642. // FXmacMsgBdRing *rxring;
  643. // FXmacMsgBdRing *txring;
  644. // FXmacMsgOs *instance_p;
  645. // instance_p = (FXmacMsgOs *)arg;
  646. // rxring = &FXMAC_MSG_GET_RXRING(instance_p->instance);
  647. // txring = &FXMAC_MSG_GET_TXRING(instance_p->instance);
  648. // if (error_word != 0)
  649. // {
  650. // switch (direction)
  651. // {
  652. // case FXMAC_MSG_RECV:
  653. // if (error_word & FXMAC_RXSR_HRESPNOK_MASK)
  654. // {
  655. // LOG_I("Receive DMA error.");
  656. // // FXmacMsgHandleDmaTxError(instance_p);
  657. // }
  658. // if (error_word & FXMAC_RXSR_RXOVR_MASK)
  659. // {
  660. // LOG_I("Receive over run.");
  661. // FXmacMsgRecvHandler(arg);
  662. // }
  663. // if (error_word & FXMAC_RXSR_BUFFNA_MASK)
  664. // {
  665. // LOG_I("Receive buffer not available.");
  666. // FXmacMsgRecvHandler(arg);
  667. // }
  668. // break;
  669. // case FXMAC_MSG_SEND:
  670. // if (error_word & FXMAC_TXSR_HRESPNOK_MASK)
  671. // {
  672. // LOG_I("Transmit DMA error.");
  673. // // FXmacMsgHandleDmaTxError(instance_p);
  674. // }
  675. // if (error_word & FXMAC_TXSR_URUN_MASK)
  676. // {
  677. // LOG_I("Transmit under run.");
  678. // // FXmacMsgHandleTxErrors(instance_p);
  679. // }
  680. // if (error_word & FXMAC_TXSR_BUFEXH_MASK)
  681. // {
  682. // LOG_I("Transmit buffer exhausted.");
  683. // // FXmacMsgHandleTxErrors(instance_p);
  684. // }
  685. // if (error_word & FXMAC_TXSR_RXOVR_MASK)
  686. // {
  687. // LOG_I("Transmit retry excessed limits.");
  688. // // FXmacMsgHandleTxErrors(instance_p);
  689. // }
  690. // if (error_word & FXMAC_TXSR_FRAMERX_MASK)
  691. // {
  692. // LOG_I("Transmit collision.");
  693. // FXmacMsgProcessSentBds(instance_p, txring);
  694. // }
  695. // break;
  696. // }
  697. // }
  698. // }
  699. void FXmacMsgLinkChange(void *arg)
  700. {
  701. u32 ctrl;
  702. u32 link, link_status;
  703. FXmacMsgCtrl *xmac_p;
  704. FXmacMsgOs *instance_p;
  705. instance_p = (FXmacMsgOs *)arg;
  706. xmac_p = &instance_p->instance;
  707. if (xmac_p->config.interface == FXMAC_MSG_PHY_INTERFACE_MODE_SGMII)
  708. {
  709. LOG_I("xmac_p->msg_regs: %p, xmac_p->mac_regs: %p", xmac_p->msg_regs, xmac_p->mac_regs);
  710. ctrl = FXMAC_MSG_READ(xmac_p, FXMAC_MSG_PCS_AN_LP);
  711. link = (ctrl & BIT(FXMAC_MSG_PCS_LINK_PARTNER_NEXT_PAGE_INDEX)) >> FXMAC_MSG_PCS_LINK_PARTNER_NEXT_PAGE_INDEX;
  712. switch (link)
  713. {
  714. case 0:
  715. LOG_I("Link status is down");
  716. link_status = FXMAC_MSG_LINKDOWN;
  717. break;
  718. case 1:
  719. LOG_I("Link status is up");
  720. link_status = FXMAC_MSG_LINKUP;
  721. break;
  722. default:
  723. LOG_E("Link status is error 0x%x ", link);
  724. return;
  725. }
  726. if (link_status == FXMAC_MSG_LINKUP)
  727. {
  728. if (link_status != xmac_p->link_status)
  729. {
  730. xmac_p->link_status = FXMAC_MSG_NEGOTIATING;
  731. LOG_I("Need NEGOTIATING.");
  732. }
  733. }
  734. else
  735. {
  736. xmac_p->link_status = FXMAC_MSG_LINKDOWN;
  737. }
  738. }
  739. }
  740. /* phy */
  741. /**
  742. * @name: FXmacMsgPhyLinkDetect
  743. * @msg: Get current link status
  744. * @note:
  745. * @param {FXmacMsgCtrl} *fxmac_p
  746. * @param {u32} phy_addr
  747. * @return {*} 1 is link up , 0 is link down
  748. */
  749. static u32 FXmacMsgPhyLinkDetect(FXmacMsgCtrl *xmac_p, u32 phy_addr)
  750. {
  751. u16 status;
  752. /* Read Phy Status register twice to get the confirmation of the current link status. */
  753. status = FXmacMsgMdioDataReadC22(xmac_p, phy_addr, PHY_STATUS_REG_OFFSET);
  754. if (status & PHY_STAT_LINK_STATUS)
  755. {
  756. return 1;
  757. }
  758. return 0;
  759. }
  760. static u32 FXmacMsgPhyAutonegStatus(FXmacMsgCtrl *xmac_p, u32 phy_addr)
  761. {
  762. u16 status;
  763. /* Read Phy Status register twice to get the confirmation of the current link status. */
  764. status = FXmacMsgMdioDataReadC22(xmac_p, phy_addr, PHY_STATUS_REG_OFFSET);
  765. if (status & PHY_STATUS_AUTONEGOTIATE_COMPLETE)
  766. {
  767. return 1;
  768. }
  769. return 0;
  770. }
  771. enum lwip_port_link_status FXmacMsgLwipPortLinkDetect(FXmacMsgOs *instance_p)
  772. {
  773. u32 phy_link_status;
  774. FXmacMsgCtrl *xmac_p = &instance_p->instance;
  775. if (xmac_p->is_ready != (u32)FT_COMPONENT_IS_READY)
  776. {
  777. return ETH_LINK_UNDEFINED;
  778. }
  779. phy_link_status = FXmacMsgPhyLinkDetect(xmac_p, xmac_p->phy_address);
  780. if ((xmac_p->link_status == FXMAC_MSG_LINKUP) && (!phy_link_status))
  781. {
  782. xmac_p->link_status = FXMAC_MSG_LINKDOWN;
  783. }
  784. switch (xmac_p->link_status)
  785. {
  786. case FXMAC_MSG_LINKUP:
  787. return ETH_LINK_UP;
  788. case FXMAC_MSG_LINKDOWN:
  789. xmac_p->link_status = FXMAC_MSG_NEGOTIATING;
  790. LOG_D("Ethernet Link down.");
  791. return ETH_LINK_DOWN;
  792. case FXMAC_MSG_NEGOTIATING:
  793. if ((phy_link_status == FXMAC_MSG_LINKUP) && FXmacMsgPhyAutonegStatus(xmac_p, xmac_p->phy_address))
  794. {
  795. err_t phy_ret;
  796. phy_ret = FXmacMsgPhyInit(xmac_p, xmac_p->config.speed, xmac_p->config.duplex, xmac_p->config.auto_neg, XMAC_MSG_PHY_RESET_DISABLE);
  797. if (phy_ret != FT_SUCCESS)
  798. {
  799. LOG_E("FXmacMsgPhyInit is error.");
  800. return ETH_LINK_DOWN;
  801. }
  802. FXmacMsgInterfaceConfig(xmac_p, 0);
  803. /* Initiate Phy setup to get link speed */
  804. xmac_p->link_status = FXMAC_MSG_LINKUP;
  805. LOG_D("Ethernet Link up.");
  806. return ETH_LINK_UP;
  807. }
  808. return ETH_LINK_DOWN;
  809. default:
  810. return ETH_LINK_DOWN;
  811. }
  812. }
  813. enum lwip_port_link_status FXmacMsgPhyReconnect(FXmacMsgOs *instance_p)
  814. {
  815. FXmacMsgCtrl *xmac_p;
  816. xmac_p = &instance_p->instance;
  817. if (xmac_p->config.interface == FXMAC_MSG_PHY_INTERFACE_MODE_SGMII)
  818. {
  819. rt_hw_interrupt_mask(xmac_p->config.queue_irq_num[0]);
  820. if (xmac_p->link_status == FXMAC_MSG_NEGOTIATING)
  821. {
  822. /* auto negotiation again*/
  823. err_t phy_ret;
  824. phy_ret = FXmacMsgPhyInit(xmac_p, xmac_p->config.speed, xmac_p->config.duplex, xmac_p->config.auto_neg, XMAC_MSG_PHY_RESET_DISABLE);
  825. if (phy_ret != FT_SUCCESS)
  826. {
  827. LOG_I("FXmacMsgPhyInit is error.");
  828. rt_hw_interrupt_umask(xmac_p->config.queue_irq_num[0]);
  829. return ETH_LINK_DOWN;
  830. }
  831. FXmacMsgInterfaceConfig(xmac_p, 0);
  832. xmac_p->link_status = FXMAC_MSG_LINKUP;
  833. }
  834. rt_hw_interrupt_umask(xmac_p->config.queue_irq_num[0]);
  835. switch (xmac_p->link_status)
  836. {
  837. case FXMAC_MSG_LINKDOWN:
  838. return ETH_LINK_DOWN;
  839. case FXMAC_MSG_LINKUP:
  840. return ETH_LINK_UP;
  841. default:
  842. return ETH_LINK_DOWN;
  843. }
  844. }
  845. else if ((xmac_p->config.interface == FXMAC_MSG_PHY_INTERFACE_MODE_RMII) || (xmac_p->config.interface == FXMAC_MSG_PHY_INTERFACE_MODE_RGMII))
  846. {
  847. return FXmacMsgLwipPortLinkDetect(instance_p);
  848. }
  849. else
  850. {
  851. switch (xmac_p->link_status)
  852. {
  853. case FXMAC_MSG_LINKDOWN:
  854. return ETH_LINK_DOWN;
  855. case FXMAC_MSG_LINKUP:
  856. return ETH_LINK_UP;
  857. default:
  858. return ETH_LINK_DOWN;
  859. }
  860. }
  861. }
  862. static void FXmacMsgOsIntrHandler(s32 vector, void *args)
  863. {
  864. isr_calling_flg++;
  865. FXmacMsgIntrHandler(vector, args);
  866. isr_calling_flg--;
  867. }
  868. void FXmacMsgSendHandler(void *arg)
  869. {
  870. FXmacMsgOs *instance_p;
  871. FXmacMsgBdRing *txringptr;
  872. instance_p = (FXmacMsgOs *)arg;
  873. txringptr = &(FXMAC_MSG_GET_TXRING(instance_p->instance));
  874. /* If Transmit done interrupt is asserted, process completed BD's */
  875. FXmacMsgProcessSentBds(instance_p, txringptr);
  876. }
  877. static void FXmacMsgSetupIsr(FXmacMsgOs *instance_p)
  878. {
  879. /* Setup callbacks */
  880. FXmacMsgSetHandler(&instance_p->instance, FXMAC_MSG_HANDLER_DMASEND, FXmacMsgSendHandler, instance_p);
  881. FXmacMsgSetHandler(&instance_p->instance, FXMAC_MSG_HANDLER_DMARECV, FXmacMsgRecvSemaphoreHandler, instance_p);
  882. // FXmacMsgSetHandler(&instance_p->instance, FXMAC_MSG_HANDLER_ERROR, FXmacMsgErrorHandler, instance_p);
  883. FXmacMsgSetHandler(&instance_p->instance, FXMAC_MSG_HANDLER_LINKCHANGE, FXmacMsgLinkChange, instance_p);
  884. rt_hw_interrupt_install(instance_p->instance.config.queue_irq_num[0], FXmacMsgOsIntrHandler, &instance_p->instance, "fxmac_msg");
  885. rt_hw_interrupt_umask(instance_p->instance.config.queue_irq_num[0]);
  886. }
  887. /* init fxmac instance */
  888. // static void FXmacMsgInitOnError(FXmacMsgOs *instance_p)
  889. // {
  890. // FXmacMsgCtrl *xmac_p;
  891. // u32 status = FT_SUCCESS;
  892. // xmac_p = &instance_p->instance;
  893. // /* set mac address */
  894. // status = FXmacMsgSetMacAddress(xmac_p, (void *)(instance_p->hwaddr));
  895. // if (status != FT_SUCCESS)
  896. // {
  897. // LOG_E("In %s:Emac Mac Address set failed...", __func__);
  898. // }
  899. // }
  900. /* 设置特性 */
  901. void FXmacMsgFeatureSetOptions(u32 feature, FXmacMsgCtrl* xmac_p)
  902. {
  903. u16 cmd_id, cmd_subid;
  904. cmd_id = FXMAC_MSG_CMD_SET;
  905. /* 巨帧 */
  906. if (feature & FXMAC_MSG_OS_CONFIG_JUMBO)
  907. {
  908. cmd_subid = FXMAC_MSG_CMD_SET_ENABLE_JUMBO;
  909. FXmacMsgSendMessage(xmac_p, cmd_id, cmd_subid, NULL, 0, 0);
  910. LOG_I("FXMAC_MSG_JUMBO_ENABLE_OPTION is ok");
  911. }
  912. /* 单播 */
  913. if (feature & FXMAC_MSG_OS_CONFIG_UNICAST_ADDRESS_FILITER)
  914. {
  915. LOG_I("FXMAC_MSG_UNICAST_OPTION is ok");
  916. }
  917. /* 多播 */
  918. if (feature & FXMAC_MSG_OS_CONFIG_MULTICAST_ADDRESS_FILITER)
  919. {
  920. cmd_subid = FXMAC_MSG_CMD_SET_ENABLE_MC;
  921. FXmacMsgSendMessage(xmac_p, cmd_id, cmd_subid, NULL, 0, 1);
  922. LOG_I("FXMAC_MSG_MULTICAST_OPTION is ok");
  923. }
  924. /* 全帧 */
  925. if (feature & FXMAC_MSG_OS_CONFIG_COPY_ALL_FRAMES)
  926. {
  927. cmd_subid = FXMAC_MSG_CMD_SET_ENABLE_PROMISE;
  928. FXmacMsgSendMessage(xmac_p, cmd_id, cmd_subid, NULL, 0, 0);
  929. LOG_I("FXMAC_MSG_PROMISC_OPTION is ok");
  930. }
  931. /* 关闭FCS(帧校验序列)校验 */
  932. if (feature & FXMAC_MSG_OS_CONFIG_CLOSE_FCS_CHECK)
  933. {
  934. LOG_I("FXMAC_MSG_FCS_STRIP_OPTION is ok");
  935. }
  936. }
  937. /* step 1: initialize instance */
  938. /* step 2: depend on config set some options : JUMBO / IGMP */
  939. /* step 3: FXmacSelectClk */
  940. /* step 4: FXmacInitInterface */
  941. /* step 5: initialize phy */
  942. /* step 6: initialize dma */
  943. /* step 7: initialize interrupt */
  944. /* step 8: start mac */
  945. FError FXmacMsgOsInit(FXmacMsgOs *instance_p)
  946. {
  947. FXmacMsgConfig mac_config;
  948. const FXmacMsgConfig *mac_config_p;
  949. FXmacMsgPhyInterface interface = FXMAC_MSG_PHY_INTERFACE_MODE_SGMII;
  950. FXmacMsgCtrl *xmac_p;
  951. FError status;
  952. FASSERT(instance_p != NULL);
  953. FASSERT(instance_p->mac_config.instance_id < FXMAC_MSG_NUM);
  954. xmac_p = &instance_p->instance;
  955. LOG_I("instance_id IS %d", instance_p->mac_config.instance_id);
  956. mac_config_p = FXmacMsgLookupConfig(instance_p->mac_config.instance_id);
  957. if (mac_config_p == NULL)
  958. {
  959. LOG_E("FXmacMsgLookupConfig is error , instance_id is %d", instance_p->mac_config.instance_id);
  960. return RTTHREAD_XMAC_MSG_INIT_ERROR;
  961. }
  962. #ifdef RT_USING_SMART
  963. mac_config_p->base_address = (uintptr)rt_ioremap((void *)mac_config_p->base_address, 0x2000);
  964. #endif
  965. mac_config = *mac_config_p;
  966. switch (instance_p->mac_config.interface)
  967. {
  968. case FXMAC_MSG_OS_INTERFACE_SGMII:
  969. interface = FXMAC_MSG_PHY_INTERFACE_MODE_SGMII;
  970. LOG_I("SGMII select.");
  971. break;
  972. case FXMAC_MSG_OS_INTERFACE_RMII:
  973. interface = FXMAC_MSG_PHY_INTERFACE_MODE_RMII;
  974. LOG_I("RMII select.");
  975. break;
  976. case FXMAC_MSG_OS_INTERFACE_RGMII:
  977. LOG_I("RGMII select.");
  978. interface = FXMAC_MSG_PHY_INTERFACE_MODE_RGMII;
  979. break;
  980. default:
  981. LOG_E("Update interface is error , interface is %d", instance_p->mac_config.instance_id);
  982. return RTTHREAD_XMAC_MSG_INIT_ERROR;
  983. }
  984. mac_config.interface = interface;
  985. if (instance_p->mac_config.autonegotiation)
  986. {
  987. mac_config.auto_neg = 1;
  988. }
  989. else
  990. {
  991. mac_config.auto_neg = 0;
  992. }
  993. switch (instance_p->mac_config.phy_speed)
  994. {
  995. case FXMAC_MSG_PHY_SPEED_10M:
  996. LOG_I("10M select.");
  997. mac_config.speed = FXMAC_MSG_SPEED_10;
  998. break;
  999. case FXMAC_MSG_PHY_SPEED_100M:
  1000. LOG_I("100M select.");
  1001. mac_config.speed = FXMAC_MSG_SPEED_100;
  1002. break;
  1003. case FXMAC_MSG_PHY_SPEED_1000M:
  1004. LOG_I("1000M select.");
  1005. mac_config.speed = FXMAC_MSG_SPEED_1000;
  1006. break;
  1007. default:
  1008. LOG_E("Setting speed is not valid , speed is %d", instance_p->mac_config.phy_speed);
  1009. return RTTHREAD_XMAC_MSG_INIT_ERROR;
  1010. }
  1011. switch (instance_p->mac_config.phy_duplex)
  1012. {
  1013. case FXMAC_MSG_PHY_HALF_DUPLEX:
  1014. LOG_I("Half duplex select.");
  1015. mac_config.duplex = 0;
  1016. break;
  1017. case FXMAC_MSG_PHY_FULL_DUPLEX:
  1018. LOG_I("Full duplex select.");
  1019. mac_config.duplex = 1;
  1020. break;
  1021. }
  1022. status = FXmacMsgCfgInitialize(xmac_p, &mac_config);
  1023. if (status != FT_SUCCESS)
  1024. {
  1025. LOG_E("In %s:EmacPs Configuration Failed....", __func__);
  1026. }
  1027. /* 初始化MSG消息队列 */
  1028. FXmacMsgInitRing(xmac_p);
  1029. /* 获取配置参数 */
  1030. FXmacMsgGetFeatureAll(xmac_p);
  1031. /* 硬件重置 */
  1032. FXmacMsgResetHw(xmac_p);
  1033. /* 设置特性 */
  1034. LOG_I("FXmacMsgFeatureSetOptions: config is %x", instance_p->config);
  1035. FXmacMsgFeatureSetOptions(instance_p->config, xmac_p);
  1036. /* 初始化硬件 */
  1037. FXmacMsgInitHw(xmac_p, instance_p->hwaddr);
  1038. /* 初始化PHY */
  1039. status = FXmacMsgPhyInit(xmac_p, xmac_p->config.speed, xmac_p->config.duplex, xmac_p->config.auto_neg, XMAC_MSG_PHY_RESET_ENABLE);
  1040. if (status != FT_SUCCESS)
  1041. {
  1042. LOG_W("FXmacMsgPhyInit is error.");
  1043. }
  1044. /* 初始化PHY接口 */
  1045. FXmacMsgInterfaceConfig(xmac_p, 0);
  1046. /* 初始化DMA描述符 */
  1047. FXmacMsgInitDma(instance_p);
  1048. /* 初始化中断 */
  1049. FXmacMsgSetupIsr(instance_p);
  1050. return FT_SUCCESS;
  1051. }
  1052. /**
  1053. * @name: FXmacMsgOsRx
  1054. * @msg: struct pbuf *FXmacMsgOsRx(FXmacMsgOs *instance_p)
  1055. * @return {*}
  1056. * @note:
  1057. * @param {FXmacMsgOs} *instance_p
  1058. */
  1059. struct pbuf *FXmacMsgOsRx(FXmacMsgOs *instance_p)
  1060. {
  1061. FASSERT(instance_p != NULL);
  1062. struct pbuf *p;
  1063. /* see if there is data to process */
  1064. if (FXmacPqQlength(&instance_p->recv_q) == 0)
  1065. {
  1066. return NULL;
  1067. }
  1068. /* return one packet from receive q */
  1069. p = (struct pbuf *)FXmacPqDequeue(&instance_p->recv_q);
  1070. return p;
  1071. }
  1072. static FError FXmacMsgOsOutput(FXmacMsgOs *instance_p, struct pbuf *p)
  1073. {
  1074. FError status;
  1075. status = FXmacMsgSgsend(instance_p, p);
  1076. if (status != FT_SUCCESS)
  1077. {
  1078. #if LINK_STATS
  1079. lwip_stats.link.drop++;
  1080. #endif
  1081. }
  1082. #if LINK_STATS
  1083. lwip_stats.link.xmit++;
  1084. #endif /* LINK_STATS */
  1085. return status;
  1086. }
  1087. FError FXmacMsgOsTx(FXmacMsgOs *instance_p, void *tx_buf)
  1088. {
  1089. FXmacMsgBdRing *txring;
  1090. FError ret;
  1091. struct pbuf *p;
  1092. FASSERT(instance_p != NULL);
  1093. FASSERT(tx_buf != NULL);
  1094. p = tx_buf;
  1095. txring = &(FXMAC_MSG_GET_TXRING(instance_p->instance));
  1096. FXmacMsgProcessSentBds(instance_p, txring);
  1097. /* check if space is available to send */
  1098. if (IsTxSpaceAvailable(instance_p))
  1099. {
  1100. ret = FXmacMsgOsOutput(instance_p, p);
  1101. }
  1102. else
  1103. {
  1104. #if LINK_STATS
  1105. lwip_stats.link.drop++;
  1106. #endif
  1107. LOG_E("Pack dropped, no space.");
  1108. ret = RTTHREAD_XMAC_MSG_NO_VALID_SPACE;
  1109. }
  1110. return ret;
  1111. }
  1112. FXmacMsgOs *FXmacMsgOsGetInstancePointer(FXmacMsgOsControl *config_p)
  1113. {
  1114. FXmacMsgOs *instance_p;
  1115. FASSERT(config_p != NULL);
  1116. FASSERT(config_p->instance_id < FXMAC_MSG_NUM);
  1117. FASSERT_MSG(config_p->interface < FXMAC_MSG_OS_INTERFACE_LENGTH, "config_p->interface %d is over %d", config_p->interface, FXMAC_MSG_OS_INTERFACE_LENGTH);
  1118. FASSERT_MSG(config_p->autonegotiation <= 1, "config_p->autonegotiation %d is over 1", config_p->autonegotiation);
  1119. FASSERT_MSG(config_p->phy_speed <= FXMAC_MSG_PHY_SPEED_1000M, "config_p->phy_speed %d is over 1000", config_p->phy_speed);
  1120. FASSERT_MSG(config_p->phy_duplex <= FXMAC_MSG_PHY_FULL_DUPLEX, "config_p->phy_duplex %d is over FXMAC_MSG_PHY_FULL_DUPLEX", config_p->phy_duplex);
  1121. instance_p = &fxmac_os_instace[config_p->instance_id];
  1122. memcpy(&instance_p->mac_config, config_p, sizeof(FXmacMsgOsControl));
  1123. return instance_p;
  1124. }
  1125. void FXmacMsgOsStart(FXmacMsgOs *instance_p)
  1126. {
  1127. FASSERT(instance_p != NULL);
  1128. /* start mac */
  1129. instance_p->instance.mask &= (~(BIT(FXMAC_MSG_TXCOMP_INDEX)));
  1130. FXmacMsgStart(&instance_p->instance);
  1131. }
  1132. static rt_err_t rt_xmac_msg_init(rt_device_t dev)
  1133. {
  1134. struct eth_device *pXmacParent;
  1135. FXmacMsgOs *pOsMac;
  1136. FError ret;
  1137. pXmacParent = rt_container_of(dev, struct eth_device, parent);
  1138. if (NULL == pXmacParent)
  1139. {
  1140. return -RT_ENOMEM;
  1141. }
  1142. pOsMac = rt_container_of(pXmacParent, FXmacMsgOs, parent);
  1143. if (NULL == pOsMac)
  1144. {
  1145. return -RT_ENOMEM;
  1146. }
  1147. ret = FXmacMsgOsInit(pOsMac);
  1148. if (ret != FT_SUCCESS)
  1149. {
  1150. LOG_E("FXmacMsgOsInit is error\r\n");
  1151. return -RT_ERROR;
  1152. }
  1153. rt_kprintf("FXMAC OS Init Success!\n");
  1154. return RT_EOK;
  1155. }
  1156. static rt_err_t rt_xmac_msg_open(rt_device_t dev, rt_uint16_t oflag)
  1157. {
  1158. LOG_D("xmac open");
  1159. return RT_EOK;
  1160. }
  1161. static rt_err_t rt_xmac_msg_close(rt_device_t dev)
  1162. {
  1163. LOG_D("xmac close");
  1164. return RT_EOK;
  1165. }
  1166. static rt_ssize_t rt_xmac_msg_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
  1167. {
  1168. LOG_D("xmac read");
  1169. rt_set_errno(-RT_ENOSYS);
  1170. return 0;
  1171. }
  1172. static rt_ssize_t rt_xmac_msg_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
  1173. {
  1174. LOG_D("xmac write");
  1175. rt_set_errno(-RT_ENOSYS);
  1176. return 0;
  1177. }
  1178. static rt_err_t rt_xmac_msg_control(rt_device_t dev, int cmd, void *args)
  1179. {
  1180. FXmacMsgOs *pOsMac;
  1181. struct eth_device *pXmacParent;
  1182. pXmacParent = rt_container_of(dev, struct eth_device, parent);
  1183. if (NULL == pXmacParent)
  1184. {
  1185. return -RT_ENOMEM;
  1186. }
  1187. pOsMac = rt_container_of(pXmacParent, FXmacMsgOs, parent);
  1188. if (NULL == pOsMac)
  1189. {
  1190. return -RT_ENOMEM;
  1191. }
  1192. switch (cmd)
  1193. {
  1194. case NIOCTL_GADDR:
  1195. /* get mac address */
  1196. if (args)
  1197. {
  1198. rt_memcpy(args, pOsMac->hwaddr, 6);
  1199. }
  1200. else
  1201. {
  1202. return -RT_ERROR;
  1203. }
  1204. break;
  1205. default:
  1206. break;
  1207. }
  1208. return RT_EOK;
  1209. }
  1210. rt_err_t rt_xmac_msg_tx(rt_device_t dev, struct pbuf *p)
  1211. {
  1212. FXmacMsgOs *pOsMac;
  1213. struct eth_device *pXmacParent;
  1214. FError ret;
  1215. pXmacParent = rt_container_of(dev, struct eth_device, parent);
  1216. if (NULL == pXmacParent)
  1217. {
  1218. return -RT_ENOMEM;
  1219. }
  1220. pOsMac = rt_container_of(pXmacParent, FXmacMsgOs, parent);
  1221. if (NULL == pOsMac)
  1222. {
  1223. return -RT_ENOMEM;
  1224. }
  1225. #if RT_LWIP_ETH_PAD_SIZE
  1226. pbuf_header(p, -RT_LWIP_ETH_PAD_SIZE); /* reclaim the padding word */
  1227. #endif
  1228. ret = FXmacMsgOsTx(pOsMac, p);
  1229. #if RT_LWIP_ETH_PAD_SIZE
  1230. pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
  1231. #endif
  1232. if (ret != FT_SUCCESS)
  1233. {
  1234. return ERR_MEM;
  1235. }
  1236. return RT_EOK;
  1237. }
  1238. struct pbuf *rt_xmac_msg_rx(rt_device_t dev)
  1239. {
  1240. FXmacMsgOs *pOsMac;
  1241. struct eth_device *pXmacParent;
  1242. struct pbuf *p;
  1243. pXmacParent = rt_container_of(dev, struct eth_device, parent);
  1244. if (NULL == pXmacParent)
  1245. {
  1246. return RT_NULL;
  1247. }
  1248. pOsMac = rt_container_of(pXmacParent, FXmacMsgOs, parent);
  1249. if (NULL == pOsMac)
  1250. {
  1251. return RT_NULL;
  1252. }
  1253. /* 是否需要在接收完成中断里关闭对应中断,在这里重新打开所有中断 */
  1254. FXmacMsgEnableIrq(&pOsMac->instance, 0, FXMAC_MSG_INT_RX_COMPLETE);
  1255. FXmacMsgRecvHandler(pOsMac);
  1256. p = FXmacMsgOsRx(pOsMac);
  1257. return p;
  1258. }
  1259. enum lwip_port_link_status eth_link_detect(FXmacMsgOs *instance_p)
  1260. {
  1261. if (instance_p->instance.is_ready != FT_COMPONENT_IS_READY)
  1262. {
  1263. return ETH_LINK_UNDEFINED;
  1264. }
  1265. return FXmacMsgPhyReconnect(instance_p);
  1266. }
  1267. static void ethernet_link_thread(void *Args)
  1268. {
  1269. if (RT_NULL == Args)
  1270. {
  1271. return;
  1272. }
  1273. FXmacMsgOs *pOsMac;
  1274. pOsMac = (FXmacMsgOs *)Args;
  1275. while (1)
  1276. {
  1277. /* Call eth_link_detect() every 500ms to detect Ethernet link
  1278. * change.
  1279. */
  1280. switch (eth_link_detect(pOsMac))
  1281. {
  1282. case ETH_LINK_UP:
  1283. if (pOsMac->is_link_up == 0)
  1284. {
  1285. LOG_I("netif flag is link_up\n");
  1286. pOsMac->is_link_up = 1;
  1287. eth_device_linkchange(&pOsMac->parent, RT_TRUE);
  1288. }
  1289. break;
  1290. case ETH_LINK_DOWN:
  1291. default:
  1292. if (pOsMac->is_link_up == 1)
  1293. {
  1294. LOG_I("netif flag is link_down\n");
  1295. pOsMac->is_link_up = 0;
  1296. eth_device_linkchange(&pOsMac->parent, RT_FALSE);
  1297. }
  1298. break;
  1299. }
  1300. rt_thread_mdelay(500);
  1301. }
  1302. }
  1303. #ifdef RT_USING_DEVICE_OPS
  1304. const struct rt_device_ops net_ops=
  1305. {
  1306. rt_xmac_msg_init,
  1307. rt_xmac_msg_open,
  1308. rt_xmac_msg_close,
  1309. rt_xmac_msg_read,
  1310. rt_xmac_msg_write,
  1311. rt_xmac_msg_control
  1312. };
  1313. #endif
  1314. static int rt_hw_xmac_msg_init(FXmacMsgOs *pOsMac, const char *name, const char *link_thread_name)
  1315. {
  1316. rt_err_t state = RT_EOK;
  1317. #ifdef RT_USING_DEVICE_OPS
  1318. pOsMac->parent.parent.ops= &net_ops;
  1319. #else
  1320. pOsMac->parent.parent.init = rt_xmac_msg_init;
  1321. pOsMac->parent.parent.open = rt_xmac_msg_open;
  1322. pOsMac->parent.parent.close = rt_xmac_msg_close;
  1323. pOsMac->parent.parent.read = rt_xmac_msg_read;
  1324. pOsMac->parent.parent.write = rt_xmac_msg_write;
  1325. pOsMac->parent.parent.control = rt_xmac_msg_control;
  1326. #endif
  1327. pOsMac->parent.parent.user_data = RT_NULL;
  1328. pOsMac->parent.eth_rx = rt_xmac_msg_rx;
  1329. pOsMac->parent.eth_tx = rt_xmac_msg_tx;
  1330. /* register eth device */
  1331. state = eth_device_init(&(pOsMac->parent), name);
  1332. if (RT_EOK != state)
  1333. {
  1334. LOG_E("xmac device init faild: %d", state);
  1335. return -RT_ERROR;
  1336. }
  1337. rt_kprintf("Xmac %s Initiailized!\n", name);
  1338. state = rt_thread_init(&pOsMac->_link_thread,
  1339. link_thread_name,
  1340. ethernet_link_thread,
  1341. pOsMac,
  1342. &pOsMac->_link_thread_stack[0],
  1343. sizeof(pOsMac->_link_thread_stack),
  1344. 12, 2);
  1345. if (RT_EOK == state)
  1346. {
  1347. rt_thread_startup(&pOsMac->_link_thread);
  1348. }
  1349. else
  1350. {
  1351. LOG_E("rt_thread_init is error");
  1352. return -RT_ERROR;
  1353. }
  1354. return RT_EOK;
  1355. }
  1356. static int rt_hw_xmac_msg_eth_init(void)
  1357. {
  1358. rt_err_t state = RT_EOK;
  1359. FXmacMsgOsControl os_config;
  1360. FXmacMsgOs *pOsMac;
  1361. #if defined(RT_USING_XMAC0_MSG)
  1362. /* os_config initialize,need to be set manually here */
  1363. os_config.instance_id = MAC_NUM0_CONTROLLER;
  1364. os_config.interface = MAC_NUM0_MII_INTERFACE;
  1365. os_config.autonegotiation = 1; /* 1 is autonegotiation ,0 is manually set */
  1366. os_config.phy_speed = FXMAC_MSG_PHY_SPEED_1000M; /* FXMAC_PHY_SPEED_XXX */
  1367. os_config.phy_duplex = FXMAC_MSG_PHY_FULL_DUPLEX; /* FXMAC_PHY_XXX_DUPLEX */
  1368. pOsMac = FXmacMsgOsGetInstancePointer(&os_config);
  1369. if (pOsMac == NULL)
  1370. {
  1371. LOG_E("FXmacMsgOsGetInstancePointer is error\r\n");
  1372. return -RT_ERROR;
  1373. }
  1374. const char *os_drv_xmac0_name = "e0";
  1375. const char *e0_thread_name = "e0_link_detect";
  1376. state = rt_hw_xmac_msg_init(pOsMac, os_drv_xmac0_name, e0_thread_name);
  1377. extern void set_if(const char *netif_name, const char *ip_addr, const char *gw_addr, const char *nm_addr);
  1378. rt_kprintf("Set netif %s ip addr!\n", os_drv_xmac0_name);
  1379. set_if(os_drv_xmac0_name, "192.168.4.10", "192.168.4.1", "255.255.255.0");
  1380. if (RT_EOK != state)
  1381. {
  1382. goto __exit;
  1383. }
  1384. #endif
  1385. #if defined(RT_USING_XMAC1_MSG)
  1386. os_config.instance_id = MAC_NUM1_CONTROLLER;
  1387. os_config.interface = MAC_NUM1_MII_INTERFACE;
  1388. os_config.autonegotiation = 1; /* 1 is autonegotiation ,0 is manually set */
  1389. os_config.phy_speed = FXMAC_MSG_PHY_SPEED_1000M; /* FXMAC_PHY_SPEED_XXX */
  1390. os_config.phy_duplex = FXMAC_MSG_PHY_FULL_DUPLEX; /* FXMAC_PHY_XXX_DUPLEX */
  1391. pOsMac = FXmacMsgOsGetInstancePointer(&os_config);
  1392. if (pOsMac == NULL)
  1393. {
  1394. LOG_E("FXmacMsgOsGetInstancePointer is error\r\n");
  1395. return -RT_ERROR;
  1396. }
  1397. const char *os_drv_xmac1_name = "e1";
  1398. const char *e1_thread_name = "e1_link_detect";
  1399. state = rt_hw_xmac_msg_init(pOsMac, os_drv_xmac1_name, e1_thread_name);
  1400. rt_kprintf("Set Xmac %s ip addr!\n", os_drv_xmac1_name);
  1401. set_if(os_drv_xmac1_name, "192.168.4.11", "192.168.4.1", "255.255.255.0");
  1402. if (RT_EOK != state)
  1403. {
  1404. goto __exit;
  1405. }
  1406. #endif
  1407. #if defined(RT_USING_XMAC0_MSG)
  1408. rt_kprintf("Start Xmac NUM0 \n");
  1409. FXmacMsgOsStart(&fxmac_os_instace[MAC_NUM0_CONTROLLER]);
  1410. #endif
  1411. #if defined(RT_USING_XMAC1_MSG)
  1412. rt_kprintf("Start Xmac NUM1 \n");
  1413. FXmacMsgOsStart(&fxmac_os_instace[MAC_NUM1_CONTROLLER]);
  1414. #endif
  1415. __exit:
  1416. return state;
  1417. }
  1418. INIT_DEVICE_EXPORT(rt_hw_xmac_msg_eth_init);
  1419. #endif