?? sngks32cend.c
字號:
(endClDescTbl[0].clSize + 8)) + sizeof(int); /* +8 is for proper alignment */ /* Allocate the memory for the clusters */ endClDescTbl[0].memArea = (char *) cacheDmaMalloc (endClDescTbl[0].memSize); if (endClDescTbl[0].memArea == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "system memory unavailable\n", 1, 2, 3, 4, 5, 6); return (ERROR); } if ((pDrvCtrl->end.pNetPool = (NET_POOL_ID) malloc (sizeof(NET_POOL))) == NULL) return (ERROR); /* Initialize the memory pool. */ if (netPoolInit(pDrvCtrl->end.pNetPool, &endMclConfig, &endClDescTbl[0], endClDescTblNumEnt, NULL) == ERROR) { return (ERROR); } return OK; }/******************************************************************************** sngks32cEndStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR**/LOCAL STATUS sngks32cEndStart ( END_DEVICE *pDrvCtrl /* device to be started */ ) { BDMARXCON bdmaRxCon; MACRXCON macRxCon; DRV_LOG (DRV_DEBUG_LOAD, "Starting sng \n", 0, 0, 0, 0, 0, 0); if (!pDrvCtrl->loaded) return (ERROR); pDrvCtrl->rxHandling = FALSE; pDrvCtrl->resetting = FALSE; /* init BDMARXCON register */ *(UINT32 *) (&bdmaRxCon) = *(volatile UINT32 *)SNGKS32C_BDMARXCON; bdmaRxCon.rxCon_reg.recvFrameIntrEnb = 1; bdmaRxCon.rxCon_reg.nullListIntrEnb = 1; bdmaRxCon.rxCon_reg.notOwnerIntrEnb = 1; bdmaRxCon.rxCon_reg.enable = 1; *(volatile UINT32 *)SNGKS32C_BDMARXCON = bdmaRxCon.rxCon_resetval; /* init MACRXCON register */ *(UINT32 *)(&macRxCon) = *(volatile UINT32 *)SNGKS32C_MACRXCON; macRxCon.macRxCon_reg.receiveEnable = 1; *(volatile UINT32 *)SNGKS32C_MACRXCON = macRxCon.macRxCon_resetval; /* Connect BDMA and MAC TX and RX interrupts */ intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivecBdmaTx), sngks32cEndBdmaTxInt, (UINT32) NULL); intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivecBdmaRx), sngks32cEndBdmaRxInt, (UINT32) pDrvCtrl); intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivecMacTx), sngks32cEndMacTxInt, (UINT32) pDrvCtrl); intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivecMacRx), sngks32cEndMacRxInt, (UINT32) NULL); /* Enable all the four interrupts */ intEnable (pDrvCtrl->ivecBdmaTx); intEnable (pDrvCtrl->ivecBdmaRx); intEnable (pDrvCtrl->ivecMacTx); intEnable (pDrvCtrl->ivecMacRx);#ifdef DYNAMIC_PHY (void) wdStart (phyPollWdog, PHY_WDOG_PERIOD , (FUNCPTR) phyPoll, 0);#endif /*DYNAMIC_PHY*/ /* Set the flags to indicate that the device is up */ END_FLAGS_SET (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); return (OK); }/***************************************************************************** * sngks32cEndBdmaTxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the BdmaTx controller.** RETURNS: N/A.*/LOCAL void sngks32cEndBdmaTxInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { /**Nothing to be done here**/ }/******************************************************************************* sngks32cEndBdmaRxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the BdmaTx controller.** RETURNS: N/A.*/LOCAL void sngks32cEndBdmaRxInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { BDMASTAT bdmaStat;#ifdef NO_DMA_WHILE_PROCESSING BDMARXCON bdmaRxCon;#endif /*NO_DMA_WHILE_PROCESSING*/ bdmaStat.stat_resetval = *(volatile UINT32 *)SNGKS32C_BDMASTAT; /* Clear status bits */ *(volatile UINT32 *)SNGKS32C_BDMASTAT |= bdmaStat.stat_resetval; if (!pDrvCtrl->rxHandling && !pDrvCtrl->resetting) { pDrvCtrl->rxHandling = TRUE; netJobAdd ((FUNCPTR)sngks32cEndHandleRcvInt, (int)pDrvCtrl, bdmaStat.stat_resetval,0,0,0);#ifdef NO_DMA_WHILE_PROCESSING /* init BDMARXCON register */ *(UINT32 *) (&bdmaRxCon) = *(volatile UINT32 *)SNGKS32C_BDMARXCON; bdmaRxCon.rxCon_reg.enable = 0; *(volatile UINT32 *)SNGKS32C_BDMARXCON = bdmaRxCon.rxCon_resetval;#endif /*NO_DMA_WHILE_PROCESSING*/ } }/******************************************************************************* sngks32cEndMacTxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the MacRx controller.** RETURNS: N/A.*/LOCAL void sngks32cEndMacTxInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { TRANSMIT_FRAME_DESC *pTxDesc; BDMATXPTR bdmaTxPtr; *(UINT32 *) (&bdmaTxPtr) = *(volatile UINT32 *)(SNGKS32C_BDMATXPTR); *(UINT32 *)(&pTxDesc) = (UINT32) (bdmaTxPtr.txPtr_reg.bdmaTxPointer); while (pTxDesc != pDrvCtrl->pTxFrameDesc) { if (pTxDesc->txFrameData.o_bit == OWNED_BY_BDMA) break; /* Ownership is still with BDMA */ if (pTxDesc->txStatusLength.comp) { pDrvCtrl->statistics.txGood++; } else /* Update error statistics */ { if (pTxDesc->txStatusLength.underRun) pDrvCtrl->statistics.txUnderErr++; if (pTxDesc->txStatusLength.exColl) pDrvCtrl->statistics.txExCollErr++; if (pTxDesc->txStatusLength.txDefer) pDrvCtrl->statistics.txDeferredErr++; if (pTxDesc->txStatusLength.paused) pDrvCtrl->statistics.txPaused++; if (pTxDesc->txStatusLength.deferAl) pDrvCtrl->statistics.txDeferErr++; if (pTxDesc->txStatusLength.ncArr) pDrvCtrl->statistics.txNCarrErr++; if (pTxDesc->txStatusLength.sqeErr) pDrvCtrl->statistics.txSQE++; if (pTxDesc->txStatusLength.lateColl) pDrvCtrl->statistics.txLateCollErr++; if (pTxDesc->txStatusLength.txPar) pDrvCtrl->statistics.txParErr++; if (pTxDesc->txStatusLength.txHalted) pDrvCtrl->statistics.txHalted++; } *(UINT32 *)(&pTxDesc->txStatusLength) = 0; /* Clear status field */ pTxDesc = pTxDesc->nextTxFrameDesc; } }/******************************************************************************* sngks32cEndMacRxInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the MacRx controller.** RETURNS: N/A.*/LOCAL void sngks32cEndMacRxInt ( END_DEVICE *pDrvCtrl /* interrupting device */ ) { /***Nothing to be done here***/ }/******************************************************************************** sngks32cEndHandleRcvInt - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.** RETURNS: N/A.*/LOCAL void sngks32cEndHandleRcvInt ( END_DEVICE *pDrvCtrl, /* interrupting device */ UINT32 stat /* receive status */ ) { BDMASTAT bdmaStat; RECEIVE_FRAME_DESC *pReceiveFrameDesc; BDMARXCON bdmaRxCon; BDMARXPTR bdmaRxPtr; bdmaStat.stat_resetval = stat; *(UINT32 *) (&bdmaRxPtr) = *(volatile UINT32 *)(SNGKS32C_BDMARXPTR); *(UINT32 *) (&pReceiveFrameDesc) = bdmaRxPtr.rxPtr_reg.bdmaRxPointer; if ((*(UINT32 *) (&pDrvCtrl->pRxFrameDesc->rxStatusLength)) == 0) return; if (pDrvCtrl->pRxFrameDesc->rxFrameData.o_bit == OWNED_BY_BDMA) return; do { /* * Check if Null list interrupt has occurred. If yes, reset * and restart the Ethernet MAC (as given in Samsung sample code). */ if ((bdmaStat.stat_reg.bdmaRxNullList) || (bdmaStat.stat_reg.bdmaRxNotOwner)) { DRV_LOG (DRV_DEBUG_RX, "sngks32cEndHandleRcvInt: Null list ERROR: " "restarting..\n", 0,0,0,0,0,0); sngks32cEndStop(pDrvCtrl); /* Stop RX and TX */ sngks32cEndReset(pDrvCtrl); /* reset the chip */ sngks32cEndFdFree(pDrvCtrl); /* Free the FDs */ sngks32cEndFdInitialize(pDrvCtrl); /* Reinitialize FDs */ sngks32cEndMacInitialize(pDrvCtrl); /* Initialize MAC */ sngks32cEndStart(pDrvCtrl); /* Start RX and TX */ break; } /* * Received a frame */ /* Check whether any error bit is set in rxStatusLength field */ if ((*(UINT32 *)(&pDrvCtrl->pRxFrameDesc->rxStatusLength)) & 0xbfff0000) { /* Update error statistics counters */ DRV_LOG (DRV_DEBUG_RX_ALL, "sngks32cEndHandleRcvInt: packet error 0x%x\n", (*(UINT32 *)(&pDrvCtrl->pRxFrameDesc->rxStatusLength)) & 0xffff0000, 0,0,0,0,0); pDrvCtrl->statistics.rxBad++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.ovMax) pDrvCtrl->statistics.rxOvMaxSize++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.ctlRcv) pDrvCtrl->statistics.rxCtlRecd++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.rx10Stat) pDrvCtrl->statistics.rx10Stat++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.alignErr) pDrvCtrl->statistics.rxAlignErr++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.crcErr) pDrvCtrl->statistics.rxCRCErr++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.overFlow) pDrvCtrl->statistics.rxOverflowErr++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.longErr) pDrvCtrl->statistics.rxLongErr++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.rxPar) pDrvCtrl->statistics.rxParErr++; if (pDrvCtrl->pRxFrameDesc->rxStatusLength.rxHalted) pDrvCtrl->statistics.rxHalted++; } else if (pDrvCtrl->pRxFrameDesc->rxStatusLength.good) { pDrvCtrl->statistics.rxGood++; sngks32cEndRecv (pDrvCtrl, pDrvCtrl->pRxFrameDesc); }#ifdef BUG_KS32C5000 /* For MAC bug fix */ gStatusLengthPrevious = *(UINT32 *)(&pDrvCtrl->pRxFrameDesc->rxStatusLength);#endif /*BUG_KS32C5000*/ /* Rx status length field */ *(UINT32 *)(&pDrvCtrl->pRxFrameDesc->rxStatusLength) = 0; /* Ownership back to BDMA */ pDrvCtrl->pRxFrameDesc->rxFrameData.o_bit = OWNED_BY_BDMA; pDrvCtrl->pRxFrameDesc = pDrvCtrl->pRxFrameDesc->nextRxFrameDesc; } while (pDrvCtrl->pRxFrameDesc != pReceiveFrameDesc && (*(UINT32 *)(&pDrvCtrl->pRxFrameDesc->rxStatusLength)) != 0 && pDrvCtrl->pRxFrameDesc->rxFrameData.o_bit != OWNED_BY_BDMA); pDrvCtrl->rxHandling = FALSE; *(UINT32 *) (&bdmaRxCon) = *(volatile UINT32 *)SNGKS32C_BDMARXCON; bdmaRxCon.rxCon_reg.enable = 1 ; /* enable rx interrupt */ *(volatile UINT32 *)SNGKS32C_BDMARXCON = bdmaRxCon.rxCon_resetval; }/******************************************************************************** sngks32cEndRecv - process the next incoming packet** Handle one incoming packet. The packet is checked for errors.** RETURNS: N/A.*/LOCAL STATUS sngks32cEndRecv ( END_DEVICE *pDrvCtrl, /* device structure */ RECEIVE_FRAME_DESC *pRxD /* frame descriptor */ ) { M_BLK_ID pMblk = NULL; char *pNewCluster = NULL; CL_BLK_ID pClBlk = NULL; char *pData = (char *)pRxD->rxFrameData.frameDataPtr; UINT32 len = pRxD->rxStatusLength.frameLength;#ifdef BUG_KS32C5000 sngks32cEndBugFix (pRxD); /* Support original KS32C5000 */#endif /*BUG_KS32C5000*/ if (pDrvCtrl->end.pNetPool == NULL) { DRV_LOG (DRV_DEBUG_RX, "sngks32cEndRecv: Illegal pNetPool on entry!\n", 0,0,0,0,0,0); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } /* Add one to our unicast data. */ END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) { DRV_LOG (DRV_DEBUG_RX, "sngks32cEndRecv: Out of M Blocks!\n", 0,0,0,0,0,0); END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1); goto cleanRXD; } pNewCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->end.pNetPool->clTbl[0]); if (pNewCluster == NULL) { DRV_LOG (DRV_DEBUG_RX, "sngks32cEndRecv: Cannot loan!\n", 0,0,0,0,0,0); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->end, &pDrvCtrl->lastError); goto cleanRXD; } /* Grab a cluster block to marry to the cluster we received. */ if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) { DRV_LOG (DRV_DEBUG_RX, "sngks32cEndRecv: Out of Cluster Blocks!\n", 0,0,0,0,0,0); pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError(&pDrvCtrl->end, &pDrvCtrl->lastError); goto cleanRXD; } END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1); pData = END_CACHE_PHYS_TO_VIRT(pData); /* Note: we rely on the hardware to pad 2 bytes so we don't need to copy to * a new buffer to solve alignment problems */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -