1 /*
2  * File      : emac.c
3  * This file is part of RT-Thread RTOS
4  * COPYRIGHT (C) 2006-2021, RT-Thread Develop Team
5  *
6  * The license and distribution terms for this file may be
7  * found in the file LICENSE in this distribution or at
8  * http://openlab.rt-thread.com/license/LICENSE
9  *
10  * Change Logs:
11  * Date           Author       Notes
12  * 2014-08-29     aozima       first implementation
13  */
14 
15 #include <rtthread.h>
16 #include <netif/ethernetif.h>
17 #include "lwipopts.h"
18 
19 #include "board.h"
20 
21 #include "app_phy.h"
22 
23 /* debug option */
24 #define ETH_DEBUG
25 //#define ETH_RX_DUMP
26 //#define ETH_TX_DUMP
27 
28 #ifdef ETH_DEBUG
29 #define CME_ETH_PRINTF          rt_kprintf
30 #else
31 #define CME_ETH_PRINTF(...)
32 #endif
33 
34 #define MAX_ADDR_LEN 6
35 struct rt_cme_eth
36 {
37     /* inherit from ethernet device */
38     struct eth_device parent;
39 
40     /* interface address info. */
41     rt_uint8_t  dev_addr[MAX_ADDR_LEN];         /* hw address   */
42 
43     uint32_t    ETH_Speed;
44     uint32_t    ETH_Mode;
45 
46     struct rt_semaphore tx_buf_free;
47     struct rt_mutex     lock;
48 };
49 static struct rt_cme_eth cme_eth_device;
50 
51 #if defined(ETH_RX_DUMP) ||  defined(ETH_TX_DUMP)
packet_dump(const char * msg,const struct pbuf * p)52 static void packet_dump(const char * msg, const struct pbuf* p)
53 {
54     const struct pbuf* q;
55     rt_uint32_t i,j;
56     rt_uint8_t *ptr;
57 
58     rt_kprintf("%s %d byte\n", msg, p->tot_len);
59 
60     i=0;
61     for(q=p; q != RT_NULL; q= q->next)
62     {
63         ptr = q->payload;
64 
65         for(j=0; j<q->len; j++)
66         {
67             if( (i%8) == 0 )
68             {
69                 rt_kprintf("  ");
70             }
71             if( (i%16) == 0 )
72             {
73                 rt_kprintf("\r\n");
74             }
75             rt_kprintf("%02x ",*ptr);
76 
77             i++;
78             ptr++;
79         }
80     }
81 
82     rt_kprintf("\n\n");
83 }
84 #else
85 #define packet_dump(...)
86 #endif /* dump */
87 
88 /////////////////////////////////////////////////////////////////
89 uint32_t rxTotalMemory = 0x2000;
90 uint32_t rxDescNum = 3;
91 uint32_t rxBufSize = 0x400;
92 uint32_t rxBaseAddr = 0x2000C000;// C000-48K
93 uint32_t txBaseAddr = 0x2000E000;// E000-56K
94 uint32_t txTotalMemory = 0x2000;
95 BOOL isRxNoBuf = FALSE;
96 
97 #define ETH_MAX_PACKET_SIZE    1520    /* ETH_HEADER + ETH_EXTRA + MAX_ETH_PAYLOAD + ETH_CRC */
98 #define ETH_RXBUFNB         4
99 #define ETH_TXBUFNB         2
100 
101 struct eth_rx_buffer
102 {
103     ETH_RX_DESC desc;
104     uint32_t buffer[ETH_MAX_PACKET_SIZE/4];
105 };
106 
107 struct eth_tx_buffer
108 {
109     ETH_TX_DESC desc;
110     uint32_t buffer[ETH_MAX_PACKET_SIZE/4];
111 };
112 
113 static struct eth_rx_buffer rx_buffer[ETH_RXBUFNB];
114 static struct eth_tx_buffer tx_buffer[ETH_TXBUFNB];
115 
RxDescChainInit(void)116 static void RxDescChainInit(void)
117 {
118     uint32_t i;
119 
120     // initialize rx descriptor
121     ETH_RX_DESC *desc = &rx_buffer[0].desc;
122 
123     for (i = 0; i < ETH_RXBUFNB; i++)
124     {
125         desc->RX_1.RX1_b.SIZE = ETH_MAX_PACKET_SIZE;
126         desc->bufAddr = (uint32_t)rx_buffer[i].buffer;
127 
128         if((i+1) == ETH_RXBUFNB)
129             desc->nextDescAddr = (uint32_t)&rx_buffer[0].desc;
130         else
131             desc->nextDescAddr = (uint32_t)&rx_buffer[i+1].desc;
132 
133         desc = (ETH_RX_DESC *)desc->nextDescAddr;
134     }
135 
136     ETH_SetRxDescRing(&rx_buffer[0].desc);
137 }
138 
TxDescChainInit(void)139 static void TxDescChainInit(void)
140 {
141     uint32_t i;
142 
143     // initialize tx descriptor
144     ETH_TX_DESC *desc = &tx_buffer[0].desc;
145 
146     for (i = 0; i < ETH_TXBUFNB; i++)
147     {
148         desc->TX_1.TX1_b.SIZE = ETH_MAX_PACKET_SIZE;
149         desc->bufAddr = (uint32_t)tx_buffer[i].buffer;
150 
151         if((i+1) == ETH_TXBUFNB)
152             desc->nextDescAddr = (uint32_t)&tx_buffer[0].desc;
153         else
154             desc->nextDescAddr = (uint32_t)&tx_buffer[i+1].desc;
155 
156         desc = (ETH_TX_DESC *)desc->nextDescAddr;
157     }
158 
159     ETH_SetTxDescRing(&tx_buffer[0].desc);
160 }
161 
162 /////////////////////////////////////////////////////////////////
163 
164 /* initialize the interface */
rt_cme_eth_init(rt_device_t dev)165 static rt_err_t rt_cme_eth_init(rt_device_t dev)
166 {
167     struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
168 
169     ETH_InitTypeDef init;
170     ETH_FrameFilter flt;
171 
172     init.ETH_Speed = phy_GetSpeed();
173     init.ETH_Duplex = phy_GetDuplex();
174     init.ETH_LinkUp = phy_IsLink();
175     init.ETH_RxEn = TRUE;
176     init.ETH_TxEn = TRUE;
177     init.ETH_ChecksumOffload = FALSE;
178     init.ETH_JumboFrame = FALSE;
179 
180     memcpy(init.ETH_MacAddr, cme_eth->dev_addr, sizeof(init.ETH_MacAddr));
181 
182     // Disable broadcast;
183     // TODO: why?
184     memset(&flt, 0, sizeof(ETH_FrameFilter));
185     flt.ETH_BroadcastFilterEnable = FALSE;
186     flt.ETH_OwnFilterEnable = FALSE;
187     flt.ETH_SelfDrop = FALSE;
188     flt.ETH_SourceFilterEnable = FALSE;
189     flt.ETH_SourceDrop = FALSE;
190 
191     init.ETH_Filter = &flt;
192 
193     if (!phy_Init())
194     {
195         rt_kprintf("phy_Init failed!\n");
196         while (1);
197     }
198 
199     if (!ETH_Init(&init))
200     {
201         rt_kprintf("ETH_Init failed!\n");
202         while (1);
203     }
204 
205     RxDescChainInit();
206     TxDescChainInit();
207 
208     ETH_ITConfig(ETH_INT_BUS_FATAL_ERROR, TRUE);
209 
210     ETH_ITConfig(ETH_INT_RX_COMPLETE_FRAME, TRUE);
211     ETH_ITConfig(ETH_INT_RX_BUF_UNAVAI, TRUE);
212     ETH_ITConfig(ETH_INT_RX_STOP, TRUE);
213     ETH_StartRx();
214 
215     ETH_ITConfig(ETH_INT_TX_COMPLETE_FRAME, TRUE);
216     ETH_StartTx();
217 
218     return RT_EOK;
219 }
220 
rt_cme_eth_open(rt_device_t dev,rt_uint16_t oflag)221 static rt_err_t rt_cme_eth_open(rt_device_t dev, rt_uint16_t oflag)
222 {
223     return RT_EOK;
224 }
225 
rt_cme_eth_close(rt_device_t dev)226 static rt_err_t rt_cme_eth_close(rt_device_t dev)
227 {
228     return RT_EOK;
229 }
230 
rt_cme_eth_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)231 static rt_ssize_t rt_cme_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
232 {
233     rt_set_errno(-RT_ENOSYS);
234     return 0;
235 }
236 
rt_cme_eth_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)237 static rt_ssize_t rt_cme_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
238 {
239     rt_set_errno(-RT_ENOSYS);
240     return 0;
241 }
242 
rt_cme_eth_control(rt_device_t dev,int cmd,void * args)243 static rt_err_t rt_cme_eth_control(rt_device_t dev, int cmd, void *args)
244 {
245     switch(cmd)
246     {
247     case NIOCTL_GADDR:
248         /* get mac address */
249         if(args) rt_memcpy(args, cme_eth_device.dev_addr, 6);
250         else return -RT_ERROR;
251         break;
252 
253     default :
254         break;
255     }
256 
257     return RT_EOK;
258 }
259 
260 /* ethernet device interface */
261 /* transmit packet. */
rt_cme_eth_tx(rt_device_t dev,struct pbuf * p)262 rt_err_t rt_cme_eth_tx( rt_device_t dev, struct pbuf* p)
263 {
264     rt_err_t result = RT_EOK;
265     ETH_TX_DESC *desc;
266     struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
267 
268     rt_mutex_take(&cme_eth->lock, RT_WAITING_FOREVER);
269 
270 #ifdef ETH_TX_DUMP
271     packet_dump("TX dump", p);
272 #endif /* ETH_TX_DUMP */
273 
274     /* get free tx buffer */
275     {
276         rt_err_t result;
277         result = rt_sem_take(&cme_eth->tx_buf_free, RT_TICK_PER_SECOND/10);
278         if (result != RT_EOK)
279         {
280             result = -RT_ERROR;
281             goto _exit;
282         }
283     }
284 
285     desc = ETH_AcquireFreeTxDesc();
286     if(desc == RT_NULL)
287     {
288         CME_ETH_PRINTF("TxDesc not ready!\n");
289         RT_ASSERT(0);
290             result = -RT_ERROR;
291             goto _exit;
292     }
293 
294     desc->TX_0.TX0_b.FS = TRUE;
295     desc->TX_0.TX0_b.LS = TRUE;
296     desc->TX_1.TX1_b.SIZE = p->tot_len;
297 
298     pbuf_copy_partial(p, ( void *)(desc->bufAddr), p->tot_len, 0);
299 
300     ETH_ReleaseTxDesc(desc);
301     ETH_ResumeTx();
302 
303 _exit:
304     rt_mutex_release(&cme_eth->lock);
305     return result;
306 }
307 
308 /* reception packet. */
rt_cme_eth_rx(rt_device_t dev)309 struct pbuf *rt_cme_eth_rx(rt_device_t dev)
310 {
311     struct pbuf* p = RT_NULL;
312     ETH_RX_DESC *desc;
313     uint32_t framelength;
314     struct rt_cme_eth * cme_eth = (struct rt_cme_eth *)dev;
315     rt_err_t result;
316 
317     result = rt_mutex_take(&cme_eth->lock, RT_WAITING_FOREVER);
318     if (result == -RT_ETIMEOUT)
319     {
320         rt_kprintf("Take mutex time out.\n");
321         goto _exit;
322     }
323     else if (result == -RT_ERROR)
324     {
325         rt_kprintf("Take mutex error.\n");
326         goto _exit;
327     }
328 
329     desc = ETH_AcquireFreeRxDesc();
330     if(desc == RT_NULL)
331     {
332         ETH_ITConfig(ETH_INT_RX_COMPLETE_FRAME, TRUE);
333         ETH_ITConfig(ETH_INT_RX_BUF_UNAVAI, TRUE);
334         ETH_ResumeRx();
335         goto _exit;
336     }
337 
338     framelength = desc->RX_0.RX0_b.FL;
339 
340     /* allocate buffer */
341     p = pbuf_alloc(PBUF_LINK, framelength, PBUF_RAM);
342     if (p != RT_NULL)
343     {
344         pbuf_take(p, (const void *)(desc->bufAddr), framelength);
345 #ifdef ETH_RX_DUMP
346         packet_dump("RX dump", p);
347 #endif /* ETH_RX_DUMP */
348     }
349 
350     ETH_ReleaseRxDesc(desc);
351 
352 _exit:
353     rt_mutex_release(&cme_eth->lock);
354     return p;
355 }
356 
NVIC_Configuration(void)357 static void NVIC_Configuration(void)
358 {
359     NVIC_InitTypeDef NVIC_InitStructure;
360 
361     /* Enable the USARTy Interrupt */
362     NVIC_InitStructure.NVIC_IRQChannel = ETH_INT_IRQn;
363     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
364     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
365     NVIC_InitStructure.NVIC_IRQChannelCmd = TRUE;
366     NVIC_Init(&NVIC_InitStructure);
367 }
368 
cme_m7_eth_init(void)369 int cme_m7_eth_init(void)
370 {
371 //    /* PHY RESET: PA4 */
372 //    {
373 //        GPIO_ResetBits(GPIOA, GPIO_Pin_4);
374 //        rt_thread_delay(2);
375 //        GPIO_SetBits(GPIOA, GPIO_Pin_4);
376 //        rt_thread_delay(2);
377 //    }
378 
379 //    GPIO_Configuration();
380     NVIC_Configuration();
381 
382 //    cme_eth_device.ETH_Speed = ETH_Speed_100M;
383 //    cme_eth_device.ETH_Mode  = ETH_Mode_FullDuplex;
384 
385     /* OUI 00-80-E1 STMICROELECTRONICS. */
386     cme_eth_device.dev_addr[0] = 0x00;
387     cme_eth_device.dev_addr[1] = 0x80;
388     cme_eth_device.dev_addr[2] = 0xE1;
389     /* generate MAC addr from 96bit unique ID (only for test). */
390 //    cme_eth_device.dev_addr[3] = *(rt_uint8_t*)(0x1FFF7A10+4);
391 //    cme_eth_device.dev_addr[4] = *(rt_uint8_t*)(0x1FFF7A10+2);
392 //    cme_eth_device.dev_addr[5] = *(rt_uint8_t*)(0x1FFF7A10+0);
393     cme_eth_device.dev_addr[3] = 12;
394     cme_eth_device.dev_addr[4] = 34;
395     cme_eth_device.dev_addr[5] = 56;
396 
397     cme_eth_device.parent.parent.init       = rt_cme_eth_init;
398     cme_eth_device.parent.parent.open       = rt_cme_eth_open;
399     cme_eth_device.parent.parent.close      = rt_cme_eth_close;
400     cme_eth_device.parent.parent.read       = rt_cme_eth_read;
401     cme_eth_device.parent.parent.write      = rt_cme_eth_write;
402     cme_eth_device.parent.parent.control    = rt_cme_eth_control;
403     cme_eth_device.parent.parent.user_data  = RT_NULL;
404 
405     cme_eth_device.parent.eth_rx     = rt_cme_eth_rx;
406     cme_eth_device.parent.eth_tx     = rt_cme_eth_tx;
407 
408     /* init EMAC lock */
409     rt_mutex_init(&cme_eth_device.lock, "emac0", RT_IPC_FLAG_PRIO);
410 
411     /* init tx buffer free semaphore */
412     rt_sem_init(&cme_eth_device.tx_buf_free,
413                 "tx_buf",
414                 ETH_TXBUFNB,
415                 RT_IPC_FLAG_FIFO);
416 
417     /* register eth device */
418     eth_device_init(&(cme_eth_device.parent), "e0");
419 
420     return RT_EOK;
421 }
422 
ETH_IRQHandler(void)423 void ETH_IRQHandler(void)
424 {
425     /* enter interrupt */
426     rt_interrupt_enter();
427 
428     if (ETH_GetITStatus(ETH_INT_TX_COMPLETE_FRAME))
429     {
430         rt_sem_release(&cme_eth_device.tx_buf_free);
431         ETH_ClearITPendingBit(ETH_INT_TX_COMPLETE_FRAME);
432     }
433 
434     if (ETH_GetITStatus(ETH_INT_RX_STOP))
435     {
436         CME_ETH_PRINTF("ETH_INT_RX_STOP\n");
437         ETH_ClearITPendingBit(ETH_INT_RX_STOP);
438     }
439 
440     if ((ETH_GetITStatus(ETH_INT_RX_BUF_UNAVAI)) ||
441             (ETH_GetITStatus(ETH_INT_RX_COMPLETE_FRAME)))
442     {
443         /* a frame has been received */
444         eth_device_ready(&(cme_eth_device.parent));
445 
446         ETH_ITConfig(ETH_INT_RX_COMPLETE_FRAME, FALSE);
447         ETH_ITConfig(ETH_INT_RX_BUF_UNAVAI, FALSE);
448         ETH_ClearITPendingBit(ETH_INT_RX_BUF_UNAVAI);
449         ETH_ClearITPendingBit(ETH_INT_RX_COMPLETE_FRAME);
450     }
451 
452     /* leave interrupt */
453     rt_interrupt_leave();
454 }
455 
456