📄 sngks32cend.c
字号:
endMclConfig.mBlkNum = END_MBLK_NUM; endClDescTbl[0].clNum = END_CL_NUM; endMclConfig.clBlkNum = endClDescTbl[0].clNum; /* Calculate the total memory for all the M-Blks and CL-Blks. */ endMclConfig.memSize = (endMclConfig.mBlkNum * (MSIZE + sizeof (long))) + (endMclConfig.clBlkNum * (CL_BLK_SZ + sizeof(long))); if ((endMclConfig.memArea = (char *) memalign (sizeof(long), endMclConfig.memSize)) == NULL) return (ERROR); /* Calculate the memory size of all the clusters. */ endClDescTbl[0].memSize = (endClDescTbl[0].clNum * (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); }#else /* NEW_NET_BUF != 0 */ { NETBUF_CFG netBufCfg = {NULL}; char name [END_NAME_MAX + 8]; NETBUF_CL_DESC clDesc; int clNum = END_CL_NUM; clDesc.clNum = clNum; clDesc.clSize = SNGKS32C_CL_SIZE; /* check this */ /* Initialize the pName field */ netBufCfg.pName = name; /* netPoolCreate() copies the name */ sprintf (name, "%s%d%s","sng", pDrvCtrl->unit, "Pool"); /* * Set the attributes to be Cached, Cache aligned, sharable, & * ISR safe */ netBufCfg.attributes = ATTR_AC_SH_ISR; /* Set pDomain to kernel, use NULL. */ netBufCfg.pDomain = NULL; /* Using linkBufPool, one M_LINK per cluster */ netBufCfg.ctrlNumber = clNum; /* Set memory partition of mBlks to kernel, use NULL */ netBufCfg.ctrlPartId = NULL; /* Set extra memory size to zero for now */ netBufCfg.bMemExtraSize = 0; /* Set cluster's memory partition to kernel, use NULL */ netBufCfg.bMemPartId = NULL; /* Allocate memory for network cluster descriptor */ netBufCfg.pClDescTbl = &clDesc; /* Initialize the Cluster Descriptor */ netBufCfg.clDescTblNumEnt = 1; /* Call netPoolCreate() with the Link Pool Function Table */ if ((pDrvCtrl->end.pNetPool = netPoolCreate (&netBufCfg, _pLinkPoolFuncTbl)) == NULL) { return (ERROR); } } pDrvCtrl->rxMblkArray = malloc (RX_FD_NUM * sizeof (M_BLK_ID)); if (pDrvCtrl->rxMblkArray == NULL) return ERROR;#endif /* NEW_NET_BUF != 0 */ 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; BDMARXCON bdmaRxCon; UINT32 statLen; if (pDrvCtrl->pRxFrameDesc->rxFrameData.o_bit == OWNED_BY_BDMA) { goto sngks32cEndHandleRcvInt_out; } bdmaStat.stat_resetval = stat; /* * 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)) { ++ pDrvCtrl->rxResets; DRV_LOG (DRV_DEBUG_RX, "sngks32cEndHandleRcvInt: Null list ERROR: " "restarting..\n", 0,0,0,0,0,0); /* Hmm, we're probably doing a lot more than we need to here */ 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 */ goto sngks32cEndHandleRcvInt_out; } do { statLen = *(volatile UINT32 *)&pDrvCtrl->pRxFrameDesc->rxStatusLength; /* * Received a frame. * If the GOOD bit is on, none of the other error bits should be. */ if (statLen & RX_STAT_GOOD) { pDrvCtrl->statistics.rxGood++; sngks32cEndRecv (pDrvCtrl, pDrvCtrl->pRxFrameDesc, statLen & 0xffff); } /* Check whether any error bit is set in rxStatusLength field */ else if (statLen & 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++; }#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->rxFrameData.o_bit != OWNED_BY_BDMA);sngks32cEndHandleRcvInt_out: 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 */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -