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