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