1 /**
2     *****************************************************************************
3     * @file     cmem7_eth.c
4     *
5     * @brief    CMEM7 ethernet source file
6     *
7     *
8     * @version  V2.0
9     * @date     3. September 2014
10     *
11     * @note
12     *
13     *****************************************************************************
14     * @attention
15     *
16     * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
17     * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
18     * TIME. AS A RESULT, CAPITAL-MICRO SHALL NOT BE HELD LIABLE FOR ANY DIRECT,
19     * INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
20     * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
21     * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
22     *
23     * <h2><center>&copy; COPYRIGHT 2013 Capital-micro </center></h2>
24     *****************************************************************************
25     */
26 
27 #include "cmem7_eth.h"
28 #include "cmem7_misc.h"
29 
30 typedef struct {
31     union {
32     uint32_t  TX0;
33 
34         struct {
35             uint32_t                                :  1;
36             uint32_t UNDERFLOW_ERR  :  1;    /*!< [OUT] Underflow error                                                     */
37             uint32_t                                :  1;
38             uint32_t COLLISION_CNT  :  4;        /*!< [OUT] Collision count                                       */
39             uint32_t                                :  1;
40             uint32_t EX_COLLISION   :  1;        /*!< [OUT] Excessive collision error                         */
41             uint32_t LATE_COLLISION :  1;        /*!< [OUT] Late collision error                              */
42             uint32_t NO_CARRIER     :  1;        /*!< [OUT] No carrier error                                    */
43             uint32_t LOSS_CARRIER   :  1;        /*!< [OUT] loss of carrier error                           */
44             uint32_t PAYLOAD_ERR        :  1;        /*!< [OUT] IP payload error                                    */
45             uint32_t                                :  2;
46             uint32_t ERR_SUM                :  1;        /*!< [OUT] Error summary                                           */
47             uint32_t HEADER_ERR         :  1;        /*!< [OUT] IP header error                                         */
48             uint32_t                                :  3;
49             uint32_t TCH                        :  1;        /*!< Second Address Chained                                */
50             uint32_t                                :  4;
51             uint32_t TTSE           :  1;    /*!< enables IEEE1588 hardware timestamping in first segment */
52             uint32_t                              :  2;
53             uint32_t FS             :  1;    /*!< first segment flag                                    */
54             uint32_t LS             :  1;    /*!< last segment flag                                     */
55             uint32_t IC             :  1;    /*!< Interrupt on Completion                               */
56             uint32_t OWN            :  1;    /*!< Descriptor is owned by self or hardware               */
57         } TX0_b;
58     } TX_0;
59 
60     union {
61     uint32_t  TX1;
62 
63         struct {
64             uint32_t SIZE                       : 13;    /*!< buffer size                                           */
65             uint32_t                : 19;
66         } TX1_b;
67     } TX_1;
68 
69     uint32_t bufAddr;
70     uint32_t nextDescAddr;
71   uint64_t reserved;
72     uint64_t timeStamp;                                  /*!< time stamp in the last segment                         */
73 } INNER_ETH_TX_DESC;
74 
75 typedef struct {
76     union {
77     uint32_t  RX0;
78 
79         struct {
80             uint32_t                                :  1;
81             uint32_t CRC_ERR        :  1;    /*!< [OUT] CRC error while last segment                        */
82             uint32_t                                :  5;
83             uint32_t TTSE           :  1;    /*!< timestamp available while last segment                */
84             uint32_t LS             :  1;    /*!< last segment flag                                     */
85             uint32_t FS             :  1;    /*!< first segment flag                                    */
86             uint32_t                                :  1;
87             uint32_t OVERFLOW_ERR   :  1;    /*!< [OUT] FIFO overflow while last segment                */
88             uint32_t LENGTH_ERR     :  1;    /*!< [OUT] length error while last segment                 */
89             uint32_t                                :  2;
90             uint32_t ERR_SUM        :  1;    /*!< [OUT] Error summary while last segment                */
91             uint32_t FL             : 14;    /*!< frame length while last segment                       */
92             uint32_t                    :  1;
93             uint32_t OWN            :  1;    /*!< Descriptor is owned by self or hardware               */
94         } RX0_b;
95     } RX_0;
96 
97     union {
98     uint32_t  RX1;
99 
100         struct {
101             uint32_t SIZE                       : 13;    /*!< buffer size                                           */
102             uint32_t                    :  1;
103             uint32_t RCH            :  1;    /*!< Second Address Chained                                */
104             uint32_t                    : 16;
105             uint32_t DIC              :  1;      /*!< Disable interrupt on Completion                       */
106         } RX1_b;
107     } RX_1;
108 
109     uint32_t bufAddr;
110     uint32_t nextDescAddr;
111   uint64_t reserved;
112     uint64_t timeStamp;                                  /*!< time stamp while the last segment                     */
113 } INNER_ETH_RX_DESC;
114 
115 
116 #define PHY_OP_READ                 0x0
117 #define PHY_OP_WRITE                0x1
118 
119 #define ETH_BURST_MODE_FIXED        0x0
120 #define ETH_BURST_MODE_UNDERSIZE    0x1
121 #define ETH_BURST_MODE_MIXED        0x2
122 
123 #define ETH_BURST_LENGTH_MIN        1
124 #define ETH_BURST_LENGTH_MAX        256
125 #define ETH_BURST_LENGTH_8X_SWITCH  32
126 #define ETH_BURST_LENGTH_8X_MIN     8
127 
128 #define ETH_DMA_ARBITRATION_ROUND_ROBIN         0x0
129 #define ETH_DMA_ARBITRATION_FIXED_PRIORITY  0x1
130 
131 #define ETH_RX_THRESHOLD_64         0x0
132 #define ETH_RX_THRESHOLD_32         0x1
133 #define ETH_RX_THRESHOLD_96         0x2
134 #define ETH_RX_THRESHOLD_128        0x3
135 
136 #define ETH_TX_THRESHOLD_64         0x0
137 #define ETH_TX_THRESHOLD_128        0x1
138 #define ETH_TX_THRESHOLD_192        0x2
139 #define ETH_TX_THRESHOLD_256        0x3
140 #define ETH_TX_THRESHOLD_40         0x4
141 #define ETH_TX_THRESHOLD_32         0x5
142 #define ETH_TX_THRESHOLD_24         0x6
143 #define ETH_TX_THRESHOLD_16         0x7
144 
145 #define ETH_INT_ABNORMAL_SUMMARY    0x8000
146 #define ETH_INT_NORMAL_SUMMARY      0x10000
147 
148 #define IS_ETH_INT_NORMAL(INT)      ((INT & ETH_INT_TX_COMPLETE_FRAME)  || \
149                                                                          (INT & ETH_INT_TX_BUF_UNAVAI)          || \
150                                                                          (INT & ETH_INT_RX_COMPLETE_FRAME))
151 
152 #define IS_ETH_INT_ABNORMAL(INT)    ((INT & ETH_INT_TX_STOP)                        || \
153                                                                          (INT & ETH_INT_RX_OVERFLOW)        || \
154                                                                          (INT & ETH_INT_TX_UNDERFLOW)       || \
155                                                                          (INT & ETH_INT_RX_BUF_UNAVAI)          || \
156                                                                          (INT & ETH_INT_RX_STOP)                        || \
157                                                                          (INT & ETH_INT_BUS_FATAL_ERROR))
158 
159 #define ETH_PREAMBLE_7_BYTE         0x0
160 #define ETH_PREAMBLE_5_BYTE         0x1
161 #define ETH_PREAMBLE_3_BYTE         0x2
162 
163 #define ETH_LINE_SPEED_1000M_BPS        0x0
164 #define ETH_LINE_SPEED_10_100M_BPS  0x1
165 
166 #define ETH_EXACT_SPEED_10M_BPS         0x0
167 #define ETH_EXACT_SPEED_100M_BPS        0x1
168 
169 #define ETH_SOURCE_ADDR_REPLACE     0x3
170 
171 #define ETH_PASS_CTRL_FRAME_ALL     0x0
172 
173 #define ETH_DESC_OWN_BY_SELF        0x0
174 #define ETH_DESC_OWN_BY_HW          0x1
175 
176 
mac_SwReset(void)177 static void mac_SwReset(void) {
178     ETH->BUS_MODE_b.SWR = 1;
179     while (ETH->BUS_MODE_b.SWR) ;
180     while (ETH->AHB_STATUS_b.BUSY) ;
181 }
182 
mac_SetConfig(ETH_InitTypeDef * init)183 static void mac_SetConfig(ETH_InitTypeDef *init) {
184     ETH->CONFIG_b.PRELEN = ETH_PREAMBLE_7_BYTE;
185     ETH->CONFIG_b.RX_EN = init->ETH_RxEn;
186     ETH->CONFIG_b.TX_EN = init->ETH_TxEn;
187     ETH->CONFIG_b.DC_EN = FALSE;
188     ETH->CONFIG_b.ACS = FALSE;
189     ETH->CONFIG_b.LUD = init->ETH_LinkUp;
190     ETH->CONFIG_b.IPC = init->ETH_ChecksumOffload;
191     ETH->CONFIG_b.DM = init->ETH_Duplex;
192     ETH->CONFIG_b.LM = FALSE;
193     ETH->MMCRIMR = 0xFFFFFFFF;
194     ETH->MMCTIMR = 0xFFFFFFFF;
195     ETH->MMCIRCOIM = 0xFFFFFFFF;
196 
197     if (init->ETH_Speed == ETH_SPEED_10M) {
198         ETH->CONFIG_b.FES = ETH_EXACT_SPEED_10M_BPS;
199         ETH->CONFIG_b.PS = ETH_LINE_SPEED_10_100M_BPS;
200     } else if (init->ETH_Speed == ETH_SPEED_100M) {
201         ETH->CONFIG_b.FES = ETH_EXACT_SPEED_100M_BPS;
202         ETH->CONFIG_b.PS = ETH_LINE_SPEED_10_100M_BPS;
203     } else {
204         ETH->CONFIG_b.FES = ETH_EXACT_SPEED_100M_BPS;
205         ETH->CONFIG_b.PS = ETH_LINE_SPEED_1000M_BPS;
206     }
207 
208     ETH->CONFIG_b.JE = init->ETH_JumboFrame;
209 
210     ETH->CONFIG_b.JD = TRUE;
211     ETH->CONFIG_b.WD = TRUE;
212     ETH->CONFIG_b.TC = FALSE;
213     ETH->CONFIG_b.CST = TRUE;
214     ETH->CONFIG_b.TWOKPE = FALSE;
215     ETH->CONFIG_b.SARC = ETH_SOURCE_ADDR_REPLACE;
216 }
217 
mac_SetMacAddr(uint8_t * mac)218 static void mac_SetMacAddr(uint8_t *mac) {
219     ETH->ADDR0_HIGH = (mac[5] << 8) | mac[4];
220     ETH->ADDR0_LOW = (mac[3] << 24) | (mac[2] << 16) |
221           (mac[1] << 8) | mac[0];
222 }
223 
mac_SetBurst(uint8_t mode,uint32_t rxBurstLen,uint32_t txBurstLen)224 static void mac_SetBurst(
225   uint8_t mode, uint32_t rxBurstLen, uint32_t txBurstLen) {
226     ETH->BUS_MODE_b.RIB = FALSE;
227     ETH->BUS_MODE_b.AAL = FALSE;
228 
229     if (mode == ETH_BURST_MODE_FIXED) {
230         ETH->BUS_MODE_b.FB = TRUE;
231         ETH->BUS_MODE_b.MB = FALSE;
232     } else if (mode == ETH_BURST_MODE_UNDERSIZE) {
233         ETH->BUS_MODE_b.FB = FALSE;
234         ETH->BUS_MODE_b.MB = FALSE;
235     } else {
236         ETH->BUS_MODE_b.FB = TRUE;
237         ETH->BUS_MODE_b.MB = TRUE;
238     }
239 
240     rxBurstLen = 1 << rxBurstLen;
241     rxBurstLen = (rxBurstLen > ETH_BURST_LENGTH_MAX) ?
242       ETH_BURST_LENGTH_MAX : rxBurstLen;
243 
244     txBurstLen = 1 << txBurstLen;
245     txBurstLen = (txBurstLen > ETH_BURST_LENGTH_MAX) ?
246       ETH_BURST_LENGTH_MAX : txBurstLen;
247 
248     // Regrading PBLx8 register, if one of PBL and RPBL is more than
249     // ETH_BURST_LENGTH_8X_SWITCH, another should be more than
250     // ETH_BURST_LENGTH_8X_MIN.
251     // If not, the greater level down to ETH_BURST_LENGTH_8X_SWITCH.
252     if ((txBurstLen < ETH_BURST_LENGTH_8X_MIN) ||
253         (rxBurstLen < ETH_BURST_LENGTH_8X_MIN)) {
254         if (rxBurstLen > ETH_BURST_LENGTH_8X_SWITCH) {
255             rxBurstLen = ETH_BURST_LENGTH_8X_SWITCH;
256         }
257 
258         if (txBurstLen > ETH_BURST_LENGTH_8X_SWITCH) {
259             txBurstLen = ETH_BURST_LENGTH_8X_SWITCH;
260         }
261     }
262 
263     ETH->BUS_MODE_b.USP = (rxBurstLen == txBurstLen) ? FALSE : TRUE;
264   if ((txBurstLen > ETH_BURST_LENGTH_8X_SWITCH) ||
265         (rxBurstLen > ETH_BURST_LENGTH_8X_SWITCH)) {
266         ETH->BUS_MODE_b.PBLx8 = TRUE;
267     } else {
268         ETH->BUS_MODE_b.PBLx8 = FALSE;
269     }
270 
271     if (ETH->BUS_MODE_b.PBLx8) {
272         ETH->BUS_MODE_b.RPBL = rxBurstLen >> 3;
273         ETH->BUS_MODE_b.PBL = txBurstLen >> 3;
274     } else {
275         ETH->BUS_MODE_b.RPBL = rxBurstLen;
276         ETH->BUS_MODE_b.PBL = txBurstLen;
277     }
278 }
279 
mac_SetPriority(BOOL isRxPrior,uint8_t priorityRate)280 static void mac_SetPriority(BOOL isRxPrior, uint8_t priorityRate) {
281   ETH->BUS_MODE_b.PRWG = 0;
282     ETH->BUS_MODE_b.DA = ETH_DMA_ARBITRATION_ROUND_ROBIN;
283 
284     ETH->BUS_MODE_b.TXPR = isRxPrior ? FALSE : TRUE;
285     ETH->BUS_MODE_b.PR = priorityRate;
286 }
287 
mac_SetDescMode(BOOL isAlternate,uint8_t gap)288 static void mac_SetDescMode(BOOL isAlternate, uint8_t gap) {
289   ETH->BUS_MODE_b.ATDS = isAlternate;
290     ETH->BUS_MODE_b.DSL = gap;
291 }
292 
mac_SetOpertionMode(void)293 static void mac_SetOpertionMode(void) {
294     ETH->OPERATION_b.OSF = FALSE;
295     ETH->OPERATION_b.RT = ETH_RX_THRESHOLD_32;
296     ETH->OPERATION_b.RSF = FALSE;
297 
298     ETH->OPERATION_b.DGF = FALSE;
299     ETH->OPERATION_b.FUF = FALSE;
300     ETH->OPERATION_b.FEF = FALSE;
301     ETH->OPERATION_b.TT = ETH_TX_THRESHOLD_64;
302     ETH->OPERATION_b.TSF = FALSE;
303 
304     ETH->OPERATION_b.FTF = TRUE;
305     ETH->OPERATION_b.DFF = TRUE;
306 }
307 
mac_SetFrameFilter(ETH_FrameFilter * filter)308 static void mac_SetFrameFilter(ETH_FrameFilter *filter) {
309     ETH->FF_b.PR = FALSE;
310     ETH->FF_b.HUC = FALSE;
311     ETH->FF_b.HMC = FALSE;
312     ETH->FF_b.DAIF = FALSE;
313     ETH->FF_b.PM = FALSE;
314     ETH->FF_b.DBF = FALSE;
315     ETH->FF_b.PCF = ETH_PASS_CTRL_FRAME_ALL;
316     ETH->FF_b.SAIF = FALSE;
317     ETH->FF_b.SAF = FALSE;
318     ETH->FF_b.HPF = FALSE;
319     ETH->FF_b.VTFE = FALSE;
320     ETH->FF_b.IPFE = FALSE;
321     ETH->FF_b.DNTU = FALSE;
322     ETH->FF_b.RA = FALSE;//TRUE
323 
324     // receive all
325     if (!filter) {
326         return ;
327     }
328 
329     // broadcast
330     if (filter->ETH_BroadcastFilterEnable) {
331         ETH->FF_b.RA = FALSE;
332         ETH->FF_b.DBF = TRUE;
333     }
334 
335     // DA
336     if (filter->ETH_OwnFilterEnable) {
337         ETH->FF_b.RA = FALSE;
338         ETH->FF_b.DAIF = filter->ETH_SelfDrop;
339     }
340 
341     // SA
342     if (filter->ETH_SourceFilterEnable) {
343         uint32_t value;
344 
345     ETH->FF_b.RA = FALSE;
346         ETH->FF_b.SAF = TRUE;
347         ETH->FF_b.SAIF = filter->ETH_SourceDrop;
348         ETH->ADDR1_HIGH_b.AE = TRUE;
349         ETH->ADDR1_HIGH_b.SA = TRUE;
350     ETH->ADDR1_HIGH_b.ADDR =
351             (filter->ETH_SourceMacAddr[5] << 8) | filter->ETH_SourceMacAddr[4];
352 
353 
354 //      value = (filter->ETH_SourceMacAddr[5] << 8) | filter->ETH_SourceMacAddr[4];
355 //     CMEM7_BFI(&(ETH->ADDR1_HIGH), value, 0, 16);
356     ETH->ADDR1_LOW = (filter->ETH_SourceMacAddr[3] << 24) |
357             (filter->ETH_SourceMacAddr[2] << 16) |
358           (filter->ETH_SourceMacAddr[1] << 8) |
359             filter->ETH_SourceMacAddr[0];
360     }
361 }
362 
mac_setFlowControl(void)363 static void mac_setFlowControl(void) {
364   ETH->FC_b.FCB = FALSE;
365     ETH->FC_b.TFE = FALSE;//TRUE
366     ETH->FC_b.RFE = FALSE;//TRUE
367     ETH->FC_b.UP = FALSE;//TRUE
368 }
369 
ETH_PhyRead(uint32_t phyAddr,uint32_t phyReg)370 uint32_t ETH_PhyRead(uint32_t phyAddr, uint32_t phyReg) {
371     ETH->GMII_ADDR_b.PA = phyAddr;
372     ETH->GMII_ADDR_b.GR = phyReg;
373     ETH->GMII_ADDR_b.GW = PHY_OP_READ;
374 
375     ETH->GMII_ADDR_b.BUSY = TRUE;
376     while (ETH->GMII_ADDR_b.BUSY) ;
377 
378     return ETH->GMII_DATA;
379 }
380 
ETH_PhyWrite(uint32_t phyAddr,uint32_t phyReg,uint32_t data)381 void ETH_PhyWrite(uint32_t phyAddr, uint32_t phyReg, uint32_t data) {
382     ETH->GMII_ADDR_b.PA = phyAddr;
383     ETH->GMII_ADDR_b.GR = phyReg;
384     ETH->GMII_ADDR_b.GW = PHY_OP_WRITE;
385   ETH->GMII_DATA = data;
386 
387     ETH->GMII_ADDR_b.BUSY = TRUE;
388     while (ETH->GMII_ADDR_b.BUSY) ;
389 }
390 
ETH_StructInit(ETH_InitTypeDef * init)391 void ETH_StructInit(ETH_InitTypeDef* init)
392 {
393     init->ETH_Speed = ETH_SPEED_10M;
394     init->ETH_Duplex = ETH_DUPLEX_FULL;
395     init->ETH_JumboFrame = FALSE;
396     init->ETH_LinkUp = FALSE;
397     init->ETH_RxEn = TRUE;
398     init->ETH_TxEn = TRUE;
399     init->ETH_ChecksumOffload = FALSE;
400     init->ETH_Filter = 0;
401     init->ETH_MacAddr[0] = 0;
402     init->ETH_MacAddr[1] = 0;
403     init->ETH_MacAddr[2] = 0;
404     init->ETH_MacAddr[3] = 0;
405     init->ETH_MacAddr[4] = 0;
406     init->ETH_MacAddr[5] = 0;
407 
408 }
ETH_Init(ETH_InitTypeDef * init)409 BOOL ETH_Init(ETH_InitTypeDef *init) {
410     assert_param(init);
411     assert_param(IS_ETH_SPEED(init->ETH_Speed));
412     assert_param(IS_ETH_DUPLEX(init->ETH_Duplex));
413 
414     mac_SwReset();
415     mac_SetConfig(init);
416     mac_SetMacAddr(init->ETH_MacAddr);
417 
418     mac_SetBurst(ETH_BURST_MODE_MIXED, 3, 4);
419     mac_SetPriority(TRUE, 0);
420     mac_SetDescMode(TRUE, 0);
421     mac_SetOpertionMode();
422     mac_SetFrameFilter(init->ETH_Filter);
423     mac_setFlowControl();
424 
425     return TRUE;
426 }
427 
ETH_ITConfig(uint32_t Int,BOOL enable)428 void ETH_ITConfig(uint32_t Int, BOOL enable) {
429     assert_param(IS_ETH_INT(Int));
430 
431     if (enable) {
432         if (IS_ETH_INT_NORMAL(Int)) {
433             ETH->INT_EN_b.NIE = TRUE;
434         }
435 
436         if (IS_ETH_INT_ABNORMAL(Int)) {
437             ETH->INT_EN_b.AIE = TRUE;
438         }
439 
440         ETH->INT_EN |= Int;
441     } else {
442         ETH->INT_EN &= ~Int;
443 
444         if (!IS_ETH_INT_NORMAL(ETH->INT_EN)) {
445             ETH->INT_EN_b.NIE = FALSE;
446         }
447 
448         if (!IS_ETH_INT_ABNORMAL(ETH->INT_EN)) {
449             ETH->INT_EN_b.AIE = FALSE;
450         }
451     }
452 }
ETH_GetITStatus(uint32_t Int)453 BOOL ETH_GetITStatus(uint32_t Int) {
454     assert_param(IS_ETH_INT(Int));
455 
456     Int &= ETH->INT_EN;
457     if (0 != (ETH->STATUS & Int)) {
458         return TRUE;
459     }
460 
461     return FALSE;
462 }
ETH_ClearITPendingBit(uint32_t Int)463 void ETH_ClearITPendingBit(uint32_t Int) {
464     uint32_t sta;
465     assert_param(IS_ETH_INT(Int));
466 
467     sta = ETH->STATUS;
468     sta &= ETH->INT_EN;
469     sta &= ~Int;
470 
471     // write 1 clear
472     ETH->STATUS = Int;
473 
474     if (IS_ETH_INT_NORMAL(Int)) {
475         if (!IS_ETH_INT_NORMAL(sta)) {
476             // write 1 clear NIS
477             ETH->STATUS = ETH_INT_NORMAL_SUMMARY;
478         }
479     }
480 
481     if (IS_ETH_INT_ABNORMAL(Int)) {
482         if (!IS_ETH_INT_ABNORMAL(sta)) {
483             // write 1 clear AIS
484             ETH->STATUS = ETH_INT_ABNORMAL_SUMMARY;
485         }
486     }
487 }
488 
ETH_GetMacAddr(uint8_t * mac)489 void ETH_GetMacAddr(uint8_t *mac) {
490   uint32_t tmp;
491 
492     if (!mac) {
493         return ;
494     }
495 
496     tmp = ETH->ADDR0_LOW;
497     *(mac + 0) = (tmp >> 0) & 0xFF;
498     *(mac + 1) = (tmp >> 8) & 0xFF;
499     *(mac + 2) = (tmp >> 16) & 0xFF;
500     *(mac + 3) = (tmp >> 24) & 0xFF;
501     tmp = ETH->ADDR0_HIGH;
502     *(mac + 4) = (tmp >> 0) & 0xFF;
503     *(mac + 5) = (tmp >> 8) & 0xFF;
504 }
505 
ETH_SetTxDescRing(ETH_TX_DESC * ring)506 BOOL ETH_SetTxDescRing(ETH_TX_DESC *ring) {
507     ETH_TX_DESC *buf = ring;
508 
509     if (!ring) {
510         return FALSE;
511     }
512 
513     if (ETH->OPERATION_b.ST) {
514         return FALSE;
515     }
516 
517   /* If code mapping */
518   ring = (ETH_TX_DESC *)GLB_ConvertToMappingFromAddr((uint32_t)ring);
519   buf = ring;
520 
521     do {
522         INNER_ETH_TX_DESC *desc = (INNER_ETH_TX_DESC *)buf;
523     uint8_t first = desc->TX_0.TX0_b.FS;
524     uint8_t last = desc->TX_0.TX0_b.LS;
525 
526     // clear all bits
527     desc->TX_0.TX0 = 0;
528     desc->TX_0.TX0_b.FS = first;
529     desc->TX_0.TX0_b.LS = last;
530         desc->TX_0.TX0_b.TCH = TRUE;
531         desc->TX_0.TX0_b.IC = TRUE;
532         desc->TX_0.TX0_b.OWN = ETH_DESC_OWN_BY_SELF;
533 
534     buf->bufAddr = GLB_ConvertToMappingFromAddr(buf->bufAddr);
535     buf->nextDescAddr = GLB_ConvertToMappingFromAddr(buf->nextDescAddr);
536         buf = (ETH_TX_DESC *)buf->nextDescAddr;
537     } while (buf != ring);
538 
539     ETH->TDESLA = (uint32_t)ring;
540 
541     return TRUE;
542 }
543 
ETH_StartTx()544 void ETH_StartTx() {
545     ETH->OPERATION_b.ST = TRUE;
546 }
547 
ETH_StopTx()548 void ETH_StopTx() {
549     ETH->OPERATION_b.ST = FALSE;
550 }
551 
ETH_ResumeTx()552 void ETH_ResumeTx() {
553     ETH->TPD = 0;
554 }
555 
ETH_AcquireFreeTxDesc(void)556 ETH_TX_DESC *ETH_AcquireFreeTxDesc(void) {
557     uint32_t cur = ETH->CURTDESAPTR;
558     INNER_ETH_TX_DESC *desc = (INNER_ETH_TX_DESC *)cur;
559 
560     do {
561         if (desc->TX_0.TX0_b.OWN == ETH_DESC_OWN_BY_SELF) {
562             return (ETH_TX_DESC *)desc;
563         }
564         desc = (INNER_ETH_TX_DESC *)desc->nextDescAddr;
565     } while ((uint32_t)desc != cur);
566 
567   return 0;
568 }
569 
ETH_IsFreeTxDesc(ETH_TX_DESC * desc)570 BOOL ETH_IsFreeTxDesc(ETH_TX_DESC *desc) {
571     INNER_ETH_TX_DESC *inner;
572 
573     if (!desc) {
574         return FALSE;
575     }
576 
577     inner = (INNER_ETH_TX_DESC *)desc;
578     return (inner->TX_0.TX0_b.OWN == ETH_DESC_OWN_BY_SELF) ? TRUE : FALSE;
579 }
580 
ETH_ReleaseTxDesc(ETH_TX_DESC * desc)581 void ETH_ReleaseTxDesc(ETH_TX_DESC *desc) {
582     INNER_ETH_TX_DESC *inner;
583 
584     if (!desc) {
585         return;
586     }
587 
588     inner = (INNER_ETH_TX_DESC *)desc;
589     inner->TX_0.TX0_b.OWN = ETH_DESC_OWN_BY_HW;
590 }
591 
ETH_SetTxDescBufAddr(ETH_TX_DESC * desc,uint32_t bufAddr)592 void ETH_SetTxDescBufAddr(ETH_TX_DESC *desc, uint32_t bufAddr) {
593     if (desc) {
594         desc->bufAddr = GLB_ConvertToMappingFromAddr(bufAddr);;
595     }
596 }
597 
ETH_GetTxDescBufAddr(ETH_TX_DESC * desc)598 uint32_t ETH_GetTxDescBufAddr(ETH_TX_DESC *desc) {
599   return (desc ? GLB_ConvertToMappingToAddr(desc->bufAddr) : 0);
600 }
601 
ETH_SetRxDescRing(ETH_RX_DESC * ring)602 BOOL ETH_SetRxDescRing(ETH_RX_DESC *ring) {
603     ETH_RX_DESC *buf = ring;
604 
605     if (!ring) {
606         return FALSE;
607     }
608 
609     if (ETH->OPERATION_b.SR) {
610         return FALSE;
611     }
612 
613   /* If code mapping */
614   ring = (ETH_RX_DESC *)GLB_ConvertToMappingFromAddr((uint32_t)ring);
615   buf = ring;
616     do {
617         INNER_ETH_RX_DESC *desc = (INNER_ETH_RX_DESC *)buf;
618         desc->RX_1.RX1_b.RCH = TRUE;
619         desc->RX_1.RX1_b.DIC = FALSE;
620         desc->RX_0.RX0_b.OWN = ETH_DESC_OWN_BY_HW;
621 
622     buf->bufAddr = GLB_ConvertToMappingFromAddr(buf->bufAddr);
623     buf->nextDescAddr = GLB_ConvertToMappingFromAddr(buf->nextDescAddr);
624         buf = (ETH_RX_DESC *)buf->nextDescAddr;
625     } while (buf != ring);
626 
627     ETH->RDESLA = (uint32_t)ring;
628 
629     return TRUE;
630 }
631 
ETH_StartRx()632 void ETH_StartRx() {
633     ETH->OPERATION_b.SR = TRUE;
634 }
635 
ETH_StopRx()636 void ETH_StopRx() {
637     ETH->OPERATION_b.SR = FALSE;
638 }
639 
ETH_ResumeRx()640 void ETH_ResumeRx() {
641     ETH->RPD = 0;
642 }
643 
ETH_AcquireFreeRxDesc(void)644 ETH_RX_DESC *ETH_AcquireFreeRxDesc(void) {
645     uint32_t cur = ETH->CURRDESAPTR;
646     INNER_ETH_RX_DESC *desc = (INNER_ETH_RX_DESC *)cur;
647 
648     do {
649         if (desc->RX_0.RX0_b.OWN == ETH_DESC_OWN_BY_SELF) {
650             return (ETH_RX_DESC *)desc;
651         }
652         desc = (INNER_ETH_RX_DESC *)desc->nextDescAddr;
653     } while ((uint32_t)desc != cur);
654 
655   return 0;
656 }
657 
ETH_IsFreeRxDesc(ETH_RX_DESC * desc)658 BOOL ETH_IsFreeRxDesc(ETH_RX_DESC *desc) {
659     INNER_ETH_RX_DESC *inner;
660 
661     if (!desc) {
662         return FALSE;
663     }
664 
665     inner = (INNER_ETH_RX_DESC *)desc;
666     return (inner->RX_0.RX0_b.OWN == ETH_DESC_OWN_BY_SELF) ? TRUE : FALSE;
667 }
668 
ETH_ReleaseRxDesc(ETH_RX_DESC * desc)669 void ETH_ReleaseRxDesc(ETH_RX_DESC *desc) {
670     INNER_ETH_RX_DESC *inner;
671 
672     if (!desc) {
673         return;
674     }
675 
676     inner = (INNER_ETH_RX_DESC *)desc;
677     inner->RX_0.RX0_b.OWN = ETH_DESC_OWN_BY_HW;
678 }
679 
680 
ETH_SetRxDescBufAddr(ETH_RX_DESC * desc,uint32_t bufAddr)681 void ETH_SetRxDescBufAddr(ETH_RX_DESC *desc, uint32_t bufAddr) {
682     if (desc) {
683         desc->bufAddr = GLB_ConvertToMappingFromAddr(bufAddr);;
684     }
685 }
686 
ETH_GetRxDescBufAddr(ETH_RX_DESC * desc)687 uint32_t ETH_GetRxDescBufAddr(ETH_RX_DESC *desc) {
688   return (desc ? GLB_ConvertToMappingToAddr(desc->bufAddr) : 0);
689 }
690 
691 
692 
693