00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "chip.h"
00037 #include <string.h>
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051 __STATIC_INLINE int fixed_mod(int a, int b)
00052 {
00053 int rem = a % b;
00054
00055 while (rem < 0)
00056 rem += b;
00057
00058 return rem;
00059 }
00060
00061
00062 #define GCIRC_CNT(head,tail,size) fixed_mod((head) - (tail), (size))
00063
00064
00065
00066 #define GCIRC_SPACE(head,tail,size) GCIRC_CNT((tail),((head)+1),(size))
00067
00068
00069
00070
00071 #define GCIRC_CNT_TO_END(head,tail,size) \
00072 ({int end = (size) - (tail); \
00073 int n = fixed_mod((head) + end, (size)); \
00074 n < end ? n : end;})
00075
00076
00077 #define GCIRC_SPACE_TO_END(head,tail,size) \
00078 ({int end = (size) - 1 - (head); \
00079 int n = fixed_mod(end + (tail), (size)); \
00080 n <= end ? n : end+1;})
00081
00082
00083 #define GCIRC_INC(headortail,size) \
00084 headortail++; \
00085 if (headortail >= size) { \
00086 headortail = 0; \
00087 }
00088
00089
00090 #define GCIRC_EMPTY(head, tail) (head == tail)
00091
00092
00093 #define GCIRC_CLEAR(head, tail) (head = tail = 0)
00094
00095
00096 uint8_t ptpTxQueWriteIdx = 0u;
00097 uint8_t ptpTxQueReadIdx = 0u;
00098
00099
00100 ptpMsgType gPtpMsgTxQue[EFRS_BUFFER_LEN];
00101 uint16_t gPtpMsgTxSeqId[EFRS_BUFFER_LEN];
00102
00103
00104
00105 const uint32_t isrMasks[] = { GMAC_IMR_SFT, GMAC_IMR_DRQFT,
00106 GMAC_IMR_PDRQFT , GMAC_IMR_PDRSFT
00107 };
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 static void GMACD_ResetTx(sGmacd *pDrv, gmacQueList_t queIdx)
00118 {
00119 Gmac *pHw = pDrv->pHw;
00120 uint8_t *pTxBuffer = pDrv->queueList[queIdx].pTxBuffer;
00121 sGmacTxDescriptor *pTd = pDrv->queueList[queIdx].pTxD;
00122 uint32_t Index;
00123 uint32_t Address;
00124
00125
00126 GMAC_TransmitEnable(pHw, 0);
00127
00128
00129 GCIRC_CLEAR(pDrv->queueList[queIdx].wTxHead, pDrv->queueList[queIdx].wTxTail);
00130
00131 for (Index = 0; Index < pDrv->queueList[queIdx].wTxListSize; Index++) {
00132 Address = (uint32_t)(&(pTxBuffer[Index *
00133 pDrv->queueList[queIdx].wTxBufferSize]));
00134 pTd[Index].addr = Address;
00135 pTd[Index].status.val = (uint32_t)GMAC_TX_USED_BIT;
00136 }
00137
00138 pTd[pDrv->queueList[queIdx].wTxListSize - 1].status.val =
00139 GMAC_TX_USED_BIT | GMAC_TX_WRAP_BIT;
00140
00141
00142
00143 GMAC_SetTxQueue(pHw, (uint32_t)pTd, queIdx);
00144 }
00145
00146
00147
00148
00149
00150 static void GMACD_ResetRx(sGmacd *pDrv, gmacQueList_t queIdx)
00151 {
00152 Gmac *pHw = pDrv->pHw;
00153 uint8_t *pRxBuffer = pDrv->queueList[queIdx].pRxBuffer;
00154 sGmacRxDescriptor *pRd = pDrv->queueList[queIdx].pRxD;
00155
00156 uint32_t Index;
00157 uint32_t Address;
00158
00159
00160 GMAC_ReceiveEnable(pHw, 0);
00161
00162
00163 pDrv->queueList[queIdx].wRxI = 0;
00164
00165 for (Index = 0; Index < pDrv->queueList[queIdx].wRxListSize; Index++) {
00166 Address = (uint32_t)(&(pRxBuffer[Index *
00167 pDrv->queueList[queIdx].wRxBufferSize]));
00168
00169 pRd[Index].addr.val = Address & GMAC_ADDRESS_MASK;
00170 pRd[Index].status.val = 0;
00171 }
00172
00173 pRd[pDrv->queueList[queIdx].wRxListSize - 1].addr.val |= GMAC_RX_WRAP_BIT;
00174
00175
00176 GMAC_SetRxQueue(pHw, (uint32_t)pRd, queIdx);
00177 }
00178
00179
00180
00181
00182
00183
00184 static void GMACD_TxCompleteHandler(sGmacd *pGmacd, gmacQueList_t qId)
00185 {
00186 Gmac *pHw = pGmacd->pHw;
00187 sGmacTxDescriptor *pTxTd;
00188 fGmacdTransferCallback fTxCb;
00189 uint32_t tsr;
00190
00191
00192 tsr = GMAC_GetTxStatus(pHw);
00193 GMAC_ClearTxStatus(pHw, tsr);
00194
00195 while (!GCIRC_EMPTY(
00196 pGmacd->queueList[qId].wTxHead, pGmacd->queueList[qId].wTxTail)) {
00197 pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail];
00198
00199
00200
00201
00202
00203
00204
00205 if ((pTxTd->status.val & GMAC_TX_USED_BIT) == 0)
00206 break;
00207
00208
00209 while ((pTxTd->status.val & GMAC_TX_LAST_BUFFER_BIT) == 0) {
00210 GCIRC_INC(pGmacd->queueList[qId].wTxTail,
00211 pGmacd->queueList[qId].wTxListSize);
00212 pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail];
00213 memory_sync();
00214 }
00215
00216
00217 fTxCb = pGmacd->queueList[qId].fTxCbList[pGmacd->queueList[qId].wTxTail];
00218
00219 if (fTxCb)
00220 fTxCb(tsr);
00221
00222
00223 GCIRC_INC(pGmacd->queueList[qId].wTxTail, pGmacd->queueList[qId].wTxListSize);
00224 }
00225
00226
00227
00228 if (pGmacd->queueList[qId].fWakupCb &&
00229 GCIRC_SPACE(pGmacd->queueList[qId].wTxHead,
00230 pGmacd->queueList[qId].wTxTail,
00231 pGmacd->queueList[qId].wTxListSize) >=
00232 pGmacd->queueList[qId].bWakeupThreshold)
00233 pGmacd->queueList[qId].fWakupCb();
00234 }
00235
00236
00237
00238
00239
00240
00241 static void GMACD_TxErrorHandler(sGmacd *pGmacd, gmacQueList_t qId)
00242 {
00243 Gmac *pHw = pGmacd->pHw;
00244 sGmacTxDescriptor *pTxTd;
00245 fGmacdTransferCallback fTxCb;
00246 uint32_t tsr;
00247
00248
00249
00250
00251
00252
00253 GMAC_TransmitEnable(pHw, 0);
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 GMAC_TransmissionHalt(pHw);
00268
00269 while (GMAC_GetTxStatus(pHw) & GMAC_TSR_TXGO);
00270
00271
00272 while (!GCIRC_EMPTY(pGmacd->queueList[qId].wTxHead,
00273 pGmacd->queueList[qId].wTxTail)) {
00274 int tx_completed = 0;
00275 pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail];
00276
00277
00278
00279
00280 if (pTxTd->status.val & GMAC_TX_USED_BIT)
00281 tx_completed = 1;
00282
00283
00284 while ((pTxTd->status.val & GMAC_TX_LAST_BUFFER_BIT) == 0) {
00285 GCIRC_INC(pGmacd->queueList[qId].wTxTail,
00286 pGmacd->queueList[qId].wTxListSize);
00287 pTxTd = &pGmacd->queueList[qId].pTxD[pGmacd->queueList[qId].wTxTail];
00288 }
00289
00290
00291 fTxCb = pGmacd->queueList[qId].fTxCbList[pGmacd->queueList[qId].wTxTail];
00292
00293 if (fTxCb)
00294 fTxCb(tx_completed ? GMAC_TSR_TXCOMP : 0);
00295
00296
00297
00298
00299 GCIRC_INC(pGmacd->queueList[qId].wTxTail, pGmacd->queueList[qId].wTxListSize);
00300 }
00301
00302
00303 GMACD_ResetTx(pGmacd, qId);
00304
00305
00306 tsr = GMAC_GetTxStatus(pHw);
00307 GMAC_ClearTxStatus(pHw, tsr);
00308
00309
00310 GMAC_TransmitEnable(pHw, 1);
00311
00312 if (pGmacd->queueList[qId].fWakupCb)
00313 pGmacd->queueList[qId].fWakupCb();
00314 }
00315
00316
00317
00318
00319
00320
00321
00322 #ifndef PTP_1588_TX_DISABLE
00323
00324 void GMACD_TxPtpEvtMsgCBRegister (sGmacd *pGmacd,
00325 fGmacdTxPtpEvtCallBack pTxPtpEvtCb, gmacQueList_t queIdx)
00326 {
00327 pGmacd->queueList[queIdx].fTxPtpEvtCb = pTxPtpEvtCb;
00328 }
00329
00330 #endif
00331
00332
00333
00334
00335
00336 void GMACD_Handler(sGmacd *pGmacd, gmacQueList_t queIdx)
00337 {
00338 Gmac *pHw = pGmacd->pHw;
00339 uint32_t isr;
00340 uint32_t rsr;
00341
00342
00343 while ((isr = GMAC_GetItStatus(pHw, queIdx)) != 0) {
00344
00345 if (0u != (isr & GMAC_ISR_SFR)) {
00346 rsr = GMAC_ISR_SFR;
00347 memory_barrier();
00348
00349
00350 if (pGmacd->queueList[queIdx].fRxCb)
00351 pGmacd->queueList[queIdx].fRxCb(rsr);
00352 else {
00353 }
00354 } else {
00355 }
00356
00357
00358 if (0u != (isr & GMAC_ISR_PDRQFR)) {
00359 rsr = GMAC_ISR_PDRQFR;
00360 memory_barrier();
00361
00362
00363 if (pGmacd->queueList[queIdx].fRxCb)
00364 pGmacd->queueList[queIdx].fRxCb(rsr);
00365 else {
00366 }
00367 } else {
00368 }
00369
00370
00371 if (0u != (isr & GMAC_ISR_PDRSFR)) {
00372
00373 rsr = GMAC_ISR_PDRSFR;
00374 memory_barrier();
00375
00376
00377 if (pGmacd->queueList[queIdx].fRxCb)
00378 pGmacd->queueList[queIdx].fRxCb(rsr);
00379 else {
00380 }
00381 } else {
00382 }
00383
00384 if (0u != (isr & GMAC_ISR_TSU)) {
00385
00386 rsr = GMAC_ISR_TSU;
00387 memory_barrier();
00388
00389
00390 if (pGmacd->queueList[queIdx].fRxCb)
00391 pGmacd->queueList[queIdx].fRxCb(rsr);
00392 else {
00393 }
00394 } else {
00395 }
00396
00397
00398 if (isr & GMAC_INT_RX_STATUS_BITS) {
00399
00400 rsr = GMAC_GetRxStatus(pHw);
00401 GMAC_ClearRxStatus(pHw, rsr);
00402
00403
00404 if (pGmacd->queueList[queIdx].fRxCb)
00405 pGmacd->queueList[queIdx].fRxCb(rsr);
00406 }
00407
00408
00409 if (isr & GMAC_INT_TX_STATUS_ERR_BITS) {
00410 GMACD_TxErrorHandler(pGmacd, queIdx);
00411 break;
00412 }
00413
00414 #ifndef PTP_1588_TX_DISABLE
00415
00416
00417 if (0u != (isr & isrMasks[gPtpMsgTxQue[ptpTxQueReadIdx]])) {
00418
00419
00420
00421
00422
00423 if (pGmacd->queueList[queIdx].fTxPtpEvtCb) {
00424 switch (gPtpMsgTxQue[ptpTxQueReadIdx]) {
00425 case SYNC_MSG_TYPE:
00426 pGmacd->queueList[queIdx].fTxPtpEvtCb
00427 (gPtpMsgTxQue[ptpTxQueReadIdx],
00428 GMAC_GetTxEvtFrameSec(pHw),
00429 GMAC_GetTxEvtFrameNsec(pHw),
00430 gPtpMsgTxSeqId[ptpTxQueReadIdx]);
00431 isr &= GMAC_IMR_SFT;
00432 break;
00433
00434 case PDELAY_REQ_TYPE:
00435 pGmacd->queueList[queIdx].fTxPtpEvtCb
00436 (gPtpMsgTxQue[ptpTxQueReadIdx],
00437 GMAC_GetTxPeerEvtFrameSec(pHw),
00438 GMAC_GetTxPeerEvtFrameNsec(pHw),
00439 gPtpMsgTxSeqId[ptpTxQueReadIdx]);
00440 isr &= GMAC_IMR_PDRQFT;
00441 break;
00442
00443 case PDELAY_RESP_TYPE:
00444 pGmacd->queueList[queIdx].fTxPtpEvtCb
00445 (gPtpMsgTxQue[ptpTxQueReadIdx],
00446 GMAC_GetTxPeerEvtFrameSec(pHw),
00447 GMAC_GetTxPeerEvtFrameNsec(pHw),
00448 gPtpMsgTxSeqId[ptpTxQueReadIdx]);
00449 isr &= GMAC_IMR_PDRSFT;
00450 break;
00451
00452 default:
00453
00454 break;
00455 };
00456 } else {
00457 }
00458
00459 ptpTxQueReadIdx++;
00460 ptpTxQueReadIdx &= (EFRS_BUFFER_LEN - 1);
00461
00462 } else {
00463
00464 }
00465
00466 #endif
00467
00468
00469 if (isr & GMAC_IER_TCOMP)
00470 GMACD_TxCompleteHandler(pGmacd, queIdx);
00471
00472 if (isr & GMAC_IER_HRESP)
00473 TRACE_ERROR("HRESP\n\r");
00474 }
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486 void GMACD_Init(sGmacd *pGmacd,
00487 Gmac *pHw,
00488 uint8_t bID,
00489 uint8_t enableCAF,
00490 uint8_t enableNBC)
00491 {
00492 uint32_t dwNcfgr;
00493
00494
00495
00496
00497 TRACE_DEBUG("GMAC_Init\n\r");
00498
00499
00500 pGmacd->pHw = pHw;
00501 pGmacd->bId = bID;
00502
00503
00504 PMC_EnablePeripheral(bID);
00505
00506
00507 GMAC_NetworkControl(pHw, 0);
00508 GMAC_DisableAllQueueIt(pHw, ~0u);
00509
00510 GMAC_ClearStatistics(pHw);
00511
00512 GMAC_ClearRxStatus(pHw, GMAC_RSR_RXOVR | GMAC_RSR_REC
00513 | GMAC_RSR_BNA | GMAC_RSR_HNO);
00514
00515
00516 GMAC_ClearTxStatus(pHw, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE
00517 | GMAC_TSR_TXGO | GMAC_TSR_TFC | GMAC_TSR_TXCOMP
00518 | GMAC_TSR_HRESP);
00519
00520
00521 GMAC_GetItStatus(pHw, GMAC_QUE_0);
00522 GMAC_GetItStatus(pHw, GMAC_QUE_1);
00523 GMAC_GetItStatus(pHw, GMAC_QUE_2);
00524
00525
00526
00527 dwNcfgr = GMAC_NCFGR_FD | GMAC_NCFGR_DBW(0) | GMAC_NCFGR_CLK_MCK_64 |
00528 GMAC_NCFGR_MAXFS | GMAC_NCFGR_PEN | GMAC_NCFGR_RFCS;
00529
00530 if (enableCAF)
00531 dwNcfgr |= GMAC_NCFGR_CAF;
00532
00533 if (enableNBC)
00534 dwNcfgr |= GMAC_NCFGR_NBC;
00535
00536 GMAC_Configure(pHw, dwNcfgr);
00537 }
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551 uint8_t GMACD_InitTransfer(sGmacd *pGmacd, const sGmacInit *pInit,
00552 gmacQueList_t queIdx)
00553 {
00554 Gmac *pHw = pGmacd->pHw;
00555 uint8_t *pRxBuffer = pInit->pRxBuffer;
00556 sGmacRxDescriptor *pRxD = pInit->pRxD;
00557 uint16_t wRxBufferSize = pInit->wRxBufferSize;
00558 uint16_t wRxSize = pInit->wRxSize;
00559 uint8_t *pTxBuffer = pInit->pTxBuffer;
00560 sGmacTxDescriptor *pTxD = pInit->pTxD;
00561 uint16_t wTxBufferSize = pInit->wTxBufferSize;
00562 uint16_t wTxSize = pInit->wTxSize;
00563 fGmacdTransferCallback *pTxCb = pInit->pTxCb;
00564 uint32_t dwDmaCfg;
00565
00566 if (wRxSize <= 1 || wTxSize <= 1 || pTxCb == NULL) return GMACD_PARAM;
00567
00568 if (!wRxBufferSize || wRxBufferSize > 16 * 1024 || wRxBufferSize & 0x3f)
00569 return GMACD_PARAM;
00570
00571 if (!wTxBufferSize)
00572 return GMACD_PARAM;
00573
00574 if (pInit->bIsGem) {
00575 if (!queIdx) {
00576 dwDmaCfg = (GMAC_DCFGR_DRBS(wRxBufferSize >> 6))
00577 | GMAC_DCFGR_RXBMS(3) | GMAC_DCFGR_TXPBMS;
00578
00579 switch (pInit->bDmaBurstLength) {
00580 case 16:
00581 dwDmaCfg |= GMAC_DCFGR_FBLDO_INCR16;
00582 break;
00583
00584 case 8:
00585 dwDmaCfg |= GMAC_DCFGR_FBLDO_INCR8;
00586 break;
00587
00588 case 4:
00589 dwDmaCfg |= GMAC_DCFGR_FBLDO_INCR4;
00590 break;
00591
00592 case 1:
00593 dwDmaCfg |= GMAC_DCFGR_FBLDO_SINGLE;
00594 break;
00595
00596 default:
00597 return GMACD_PARAM;
00598 }
00599 } else
00600 dwDmaCfg = (GMAC_RBSRPQ_RBS(wRxBufferSize >> 6));
00601
00602 GMAC_SetDMAConfig(pHw, dwDmaCfg, queIdx);
00603 }
00604
00605 pGmacd->queueList[queIdx].wRxBufferSize = wRxBufferSize;
00606 pGmacd->queueList[queIdx].wTxBufferSize = wTxBufferSize;
00607
00608
00609 if (((uint32_t)pRxBuffer & 0x7)
00610 || ((uint32_t)pRxD & 0x7)) {
00611 wRxSize --;
00612 TRACE_DEBUG("RX list address adjusted\n\r");
00613 }
00614
00615 pGmacd->queueList[queIdx].pRxBuffer = (uint8_t *)((uint32_t)pRxBuffer &
00616 0xFFFFFFF8);
00617 pGmacd->queueList[queIdx].pRxD = (sGmacRxDescriptor *)((
00618 uint32_t)pRxD & 0xFFFFFFF8);
00619 pGmacd->queueList[queIdx].wRxListSize = wRxSize;
00620
00621
00622 if (((uint32_t)pTxBuffer & 0x7)
00623 || ((uint32_t)pTxD & 0x7)) {
00624 wTxSize --;
00625 TRACE_DEBUG("TX list address adjusted\n\r");
00626 }
00627
00628 pGmacd->queueList[queIdx].pTxBuffer = (uint8_t *)((uint32_t)pTxBuffer &
00629 0xFFFFFFF8);
00630 pGmacd->queueList[queIdx].pTxD = (sGmacTxDescriptor *)((
00631 uint32_t)pTxD & 0xFFFFFFF8);
00632 pGmacd->queueList[queIdx].wTxListSize = wTxSize;
00633 pGmacd->queueList[queIdx].fTxCbList = pTxCb;
00634
00635
00636 GMACD_ResetRx(pGmacd, queIdx);
00637 GMACD_ResetTx(pGmacd, queIdx);
00638
00639
00640 switch (queIdx) {
00641 case GMAC_QUE_0:
00642
00643
00644
00645
00646 GMAC_TransmitEnable(pHw, 1);
00647 GMAC_ReceiveEnable(pHw, 1);
00648 GMAC_StatisticsWriteEnable(pHw, 1);
00649
00650 GMAC_EnableIt(pHw,
00651 GMAC_INT_RX_BITS |
00652 GMAC_INT_TX_BITS |
00653 GMAC_INT_TX_ERR_BITS, GMAC_QUE_0);
00654 break;
00655
00656 case GMAC_QUE_1:
00657 GMAC_EnableIt(pHw,
00658 GMAC_INT_RX_BITS |
00659 GMAC_INT_TX_BITS |
00660 GMAC_INT_TX_ERR_BITS, GMAC_QUE_1);
00661 break;
00662
00663 case GMAC_QUE_2:
00664 GMAC_EnableIt(pHw,
00665 GMAC_INT_RX_BITS |
00666 GMAC_INT_TX_BITS |
00667 GMAC_INT_TX_ERR_BITS, GMAC_QUE_2);
00668 break;
00669 };
00670
00671 return GMACD_OK;
00672 }
00673
00674
00675
00676
00677
00678
00679 void GMACD_Reset(sGmacd *pGmacd)
00680 {
00681 Gmac *pHw = pGmacd->pHw;
00682
00683 GMACD_ResetRx(pGmacd, GMAC_QUE_0);
00684 GMACD_ResetRx(pGmacd, GMAC_QUE_1);
00685 GMACD_ResetRx(pGmacd, GMAC_QUE_2);
00686
00687 GMACD_ResetTx(pGmacd, GMAC_QUE_0);
00688 GMACD_ResetTx(pGmacd, GMAC_QUE_1);
00689 GMACD_ResetTx(pGmacd, GMAC_QUE_2);
00690
00691
00692 GMAC_NetworkControl(pHw, GMAC_NCR_TXEN | GMAC_NCR_RXEN
00693 | GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
00694 }
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705 uint8_t GMACD_SendSG(sGmacd *pGmacd,
00706 const sGmacSGList *sgl,
00707 fGmacdTransferCallback fTxCb,
00708 gmacQueList_t queIdx)
00709 {
00710 Gmac *pHw = pGmacd->pHw;
00711 sGmacTxDescriptor *pTd = pGmacd->queueList[queIdx].pTxD;
00712 sGmacTxDescriptor *pTxTd;
00713 uint16_t wTxPos, wTxHead;
00714 int i;
00715
00716 TRACE_DEBUG("%s\n\r", __FUNCTION__);
00717
00718
00719 if (!sgl->len) {
00720 TRACE_ERROR("%s:: ethernet frame is empty.\r\n", __FUNCTION__);
00721 return GMACD_PARAM;
00722 }
00723
00724 if (sgl->len >= pGmacd->queueList[queIdx].wTxListSize) {
00725 TRACE_ERROR("%s: ethernet frame has too many buffers.\r\n", __FUNCTION__);
00726 return GMACD_PARAM;
00727 }
00728
00729
00730 if (GCIRC_SPACE(pGmacd->queueList[queIdx].wTxHead,
00731 pGmacd->queueList[queIdx].wTxTail,
00732 pGmacd->queueList[queIdx].wTxListSize) < (int)sgl->len)
00733 return GMACD_TX_BUSY;
00734
00735
00736 wTxHead = fixed_mod(pGmacd->queueList[queIdx].wTxHead + sgl->len,
00737 pGmacd->queueList[queIdx].wTxListSize);
00738 wTxPos = wTxHead;
00739 pGmacd->queueList[queIdx].fTxCbList[wTxPos] = NULL;
00740 pTxTd = &pTd[wTxPos];
00741 pTxTd->status.val = GMAC_TX_USED_BIT;
00742
00743
00744
00745
00746 for (i = (int)(sgl->len - 1); i >= 0; --i) {
00747 const sGmacSG *sg = &sgl->sg[i];
00748 uint32_t status;
00749
00750 if (sg->size > pGmacd->queueList[queIdx].wTxBufferSize) {
00751 TRACE_ERROR("%s: buffer size is too big.\r\n", __FUNCTION__);
00752 return GMACD_PARAM;
00753 }
00754
00755 if (wTxPos == 0)
00756 wTxPos = pGmacd->queueList[queIdx].wTxListSize - 1;
00757 else
00758 wTxPos--;
00759
00760
00761 pGmacd->queueList[queIdx].fTxCbList[wTxPos] = NULL;
00762
00763 pTxTd = &pTd[wTxPos];
00764 #ifdef GMAC_ZERO_COPY
00765
00766
00767
00768 pTxTd->addr = (uint32_t)sg->pBuffer;
00769
00770 #else
00771
00772
00773 if (sg->pBuffer && sg->size) {
00774 memcpy((void *)pTxTd->addr, sg->pBuffer, sg->size);
00775 SCB_CleanDCache_by_Addr((void *)pTxTd->addr, sg->size);
00776 }
00777
00778 #endif
00779
00780
00781 status = sg->size & GMAC_LENGTH_FRAME;
00782
00783 if (i == (int)(sgl->len - 1)) {
00784 status |= GMAC_TX_LAST_BUFFER_BIT;
00785 pGmacd->queueList[queIdx].fTxCbList[wTxPos] = fTxCb;
00786 }
00787
00788 if (wTxPos == pGmacd->queueList[queIdx].wTxListSize - 1)
00789 status |= GMAC_TX_WRAP_BIT;
00790
00791
00792 pTxTd->status.val = status;
00793
00794 memory_sync();
00795 }
00796
00797
00798 pGmacd->queueList[queIdx].wTxHead = wTxHead;
00799
00800
00801 GMAC_TransmissionStart(pHw);
00802 return GMACD_OK;
00803 }
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815 uint8_t GMACD_Send(sGmacd *pGmacd,
00816 void *pBuffer,
00817 uint32_t size,
00818 fGmacdTransferCallback fTxCb,
00819 gmacQueList_t queIdx)
00820 {
00821 sGmacSGList sgl;
00822 sGmacSG sg;
00823
00824 uint8_t *msgPtr;
00825 ptpMsgType ptpMsg;
00826
00827 sg.size = size;
00828 sg.pBuffer = pBuffer;
00829 sgl.len = 1;
00830 sgl.sg = &sg;
00831
00832
00833
00834 #ifndef PTP_1588_TX_DISABLE
00835
00836 msgPtr = (uint8_t *)pBuffer;
00837
00838 if (0x88u == msgPtr[12] && 0xf7u == msgPtr[13]) {
00839
00840 ptpMsg = (ptpMsgType)(msgPtr[14] & 0x0F);
00841
00842 if (ptpMsg == SYNC_MSG_TYPE || ptpMsg == PDELAY_REQ_TYPE
00843 || ptpMsg == PDELAY_RESP_TYPE) {
00844
00845
00846 gPtpMsgTxQue[ptpTxQueWriteIdx] = ptpMsg;
00847
00848
00849 gPtpMsgTxSeqId[ptpTxQueWriteIdx] =
00850 (uint16_t)(((uint16_t)msgPtr[44] << 8) | msgPtr[45]);
00851 ptpTxQueWriteIdx++;
00852 ptpTxQueWriteIdx &= (EFRS_BUFFER_LEN - 1u);
00853 } else {
00854
00855
00856 }
00857 } else {
00858 }
00859
00860 #endif
00861 return GMACD_SendSG(pGmacd, &sgl, fTxCb, queIdx);
00862 }
00863
00864
00865
00866
00867
00868 uint32_t GMACD_TxLoad(sGmacd *pGmacd, gmacQueList_t queIdx)
00869 {
00870 uint16_t head = pGmacd->queueList[queIdx].wTxHead;
00871 uint16_t tail = pGmacd->queueList[queIdx].wTxTail;
00872 return GCIRC_CNT(head, tail, pGmacd->queueList[queIdx].wTxListSize);
00873 }
00874
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 uint8_t GMACD_Poll(sGmacd *pGmacd,
00886 uint8_t *pFrame,
00887 uint32_t frameSize,
00888 uint32_t *pRcvSize,
00889 gmacQueList_t queIdx)
00890 {
00891
00892 uint16_t bufferLength;
00893 uint32_t tmpFrameSize = 0;
00894 uint8_t *pTmpFrame = 0;
00895 uint32_t tmpIdx = pGmacd->queueList[queIdx].wRxI;
00896 volatile sGmacRxDescriptor *pRxTd =
00897 &pGmacd->queueList[queIdx].pRxD[pGmacd->queueList[queIdx].wRxI];
00898
00899 uint8_t isFrame = 0;
00900
00901 if (pFrame == NULL) return GMACD_PARAM;
00902
00903
00904 *pRcvSize = 0;
00905
00906
00907 while ((pRxTd->addr.val & GMAC_RX_OWNERSHIP_BIT) == GMAC_RX_OWNERSHIP_BIT) {
00908
00909 if ((pRxTd->status.val & GMAC_RX_SOF_BIT) == GMAC_RX_SOF_BIT) {
00910
00911 while (tmpIdx != pGmacd->queueList[queIdx].wRxI) {
00912 pRxTd =
00913 &pGmacd->queueList[queIdx].pRxD[pGmacd->queueList[queIdx].wRxI];
00914 pRxTd->addr.val &= ~(GMAC_RX_OWNERSHIP_BIT);
00915 GCIRC_INC(pGmacd->queueList[queIdx].wRxI,
00916 pGmacd->queueList[queIdx].wRxListSize);
00917 }
00918
00919 pTmpFrame = pFrame;
00920 tmpFrameSize = 0;
00921
00922 isFrame = 1;
00923 }
00924
00925
00926 GCIRC_INC(tmpIdx, pGmacd->queueList[queIdx].wRxListSize);
00927
00928
00929 if (isFrame) {
00930 if (tmpIdx == pGmacd->queueList[queIdx].wRxI) {
00931 TRACE_INFO("no EOF (Invalid of buffers too small)\n\r");
00932
00933 do {
00934 pRxTd =
00935 &pGmacd->queueList[queIdx].pRxD[pGmacd->queueList[queIdx].wRxI];
00936 pRxTd->addr.val &= ~(GMAC_RX_OWNERSHIP_BIT);
00937 GCIRC_INC(pGmacd->queueList[queIdx].wRxI,
00938 pGmacd->queueList[queIdx].wRxListSize);
00939 } while (tmpIdx != pGmacd->queueList[queIdx].wRxI);
00940
00941 return GMACD_RX_NULL;
00942 }
00943
00944
00945 bufferLength = pGmacd->queueList[queIdx].wRxBufferSize;
00946
00947 if ((tmpFrameSize + bufferLength) > frameSize)
00948 bufferLength = frameSize - tmpFrameSize;
00949
00950 SCB_InvalidateDCache_by_Addr((void *)(pRxTd->addr.val & GMAC_ADDRESS_MASK) ,
00951 bufferLength);
00952 memcpy(pTmpFrame, (void *)(pRxTd->addr.val & GMAC_ADDRESS_MASK),
00953 bufferLength);
00954 pTmpFrame += bufferLength;
00955 tmpFrameSize += bufferLength;
00956
00957
00958 if ((pRxTd->status.val & GMAC_RX_EOF_BIT) == GMAC_RX_EOF_BIT) {
00959
00960 *pRcvSize = (pRxTd->status.val & GMAC_LENGTH_FRAME);
00961
00962
00963
00964 if (tmpFrameSize < *pRcvSize)
00965 return GMACD_SIZE_TOO_SMALL;
00966
00967 TRACE_DEBUG("packet %d-%d (%d)\n\r",
00968 pGmacd->queueList[queIdx].wRxI, tmpIdx, *pRcvSize);
00969
00970
00971
00972 while (pGmacd->queueList[queIdx].wRxI != tmpIdx) {
00973 pRxTd =
00974 &pGmacd->queueList[queIdx].pRxD[pGmacd->queueList[queIdx].wRxI];
00975 pRxTd->addr.val &= ~(GMAC_RX_OWNERSHIP_BIT);
00976 GCIRC_INC(pGmacd->queueList[queIdx].wRxI,
00977 pGmacd->queueList[queIdx].wRxListSize);
00978 }
00979
00980 return GMACD_OK;
00981 }
00982 } else {
00983
00984 pRxTd->addr.val &= ~(GMAC_RX_OWNERSHIP_BIT);
00985 pGmacd->queueList[queIdx].wRxI = tmpIdx;
00986 }
00987
00988
00989 pRxTd = &pGmacd->queueList[queIdx].pRxD[tmpIdx];
00990 }
00991
00992 return GMACD_RX_NULL;
00993 }
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006 void GMACD_SetRxCallback(sGmacd *pGmacd, fGmacdTransferCallback fRxCb,
01007 gmacQueList_t queIdx)
01008 {
01009 Gmac *pHw = pGmacd->pHw;
01010
01011 if (fRxCb == NULL) {
01012 GMAC_DisableIt(pHw, GMAC_IDR_RCOMP, queIdx);
01013 pGmacd->queueList[queIdx].fRxCb = NULL;
01014 } else {
01015 pGmacd->queueList[queIdx].fRxCb = fRxCb;
01016 GMAC_EnableIt(pHw, GMAC_IER_RCOMP, queIdx);
01017 }
01018 }
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038 uint8_t GMACD_SetTxWakeupCallback(sGmacd *pGmacd,
01039 fGmacdWakeupCallback fWakeup,
01040 uint8_t bThreshold,
01041 gmacQueList_t queIdx)
01042 {
01043 if (fWakeup == NULL)
01044 pGmacd->queueList[queIdx].fWakupCb = NULL;
01045 else {
01046 if (bThreshold <= pGmacd->queueList[queIdx].wTxListSize) {
01047 pGmacd->queueList[queIdx].fWakupCb = fWakeup;
01048 pGmacd->queueList[queIdx].bWakeupThreshold = bThreshold;
01049 } else
01050 return GMACD_PARAM;
01051 }
01052
01053 return GMACD_OK;
01054 }