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>© 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