📄 gei82543end.c
字号:
{ /* * if user has provided a shared memory, we assume * it is a cache safe area */ if (pDrvCtrl->memSize < size) { DRV_LOG (DRV_DEBUG_LOAD, ("GEI82543EndMemInit: not enough memory\n"), 1, 2, 3, 4, 5, 6); return ERROR; } pDrvCtrl->cacheFuncs = cacheNullFuncs; pDrvCtrl->memAllocFlag = FALSE; } /* zero the pre-provided or allocated memory */ memset((void *)pDrvCtrl->pMemBase, 0, size); /* set the TX descriptor base address, align to 128 byte */ pDrvCtrl->pTxDescBase = (char *)(((UINT32)(pDrvCtrl->pMemBase) + (GEI_DESC_ALIGN_BYTE - 1)) & ~(GEI_DESC_ALIGN_BYTE - 1)); /* set the RX descriptor base Address */ pDrvCtrl->pRxDescBase = (char *)GEI_GET_TX_DESC_ADDR(pDrvCtrl->txDescNum); tmpBase = (UINT32)GEI_GET_RX_DESC_ADDR(pDrvCtrl->rxDescNum); /* set the RX buffer base address */ pDrvCtrl->pRxBufBase = (char *)(((tmpBase + (GEI_DESC_ALIGN_BYTE)) & ~(GEI_DESC_ALIGN_BYTE - 1)) - CL_OVERHEAD); /* allocate memory for txDescriptor manager array */ size = pDrvCtrl->txDescNum * sizeof(TX_DESCTL); pDrvCtrl->pTxDesCtlBase = (P_TX_DESCTL) malloc (size); if ((pDrvCtrl->pTxDesCtlBase) == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: TxDesCtl memory unavailable\n",1, 2, 3, 4, 5, 6); goto errorExit; } /* get a buffer for TX polling mode */ pDrvCtrl->pTxPollBufAdr = cacheDmaMalloc (bufSz); if ((pDrvCtrl->pTxPollBufAdr) == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: Tx Polling memory unavailable\n",1, 2, 3, 4, 5, 6); goto errorExit; } /* clean up txDesCtl memory */ memset((void *)pDrvCtrl->pTxDesCtlBase, 0, size); /* * set up RX mBlk pool * This is how we set up and END netPool using netBufLib(1). * This code is pretty generic. */ if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL) goto errorExit; bzero ((char *)&geiMclBlkConfig, sizeof(geiMclBlkConfig)); bzero ((char *)&geiClDesc, sizeof(geiClDesc)); geiMclBlkConfig.mBlkNum = pDrvCtrl->rxDescNum * (DEFAULT_MBLK_NUM_FACTOR + 1); geiClDesc.clNum = pDrvCtrl->rxDescNum * (DEFAULT_LOAN_RXBUF_FACTOR + 1); geiClDesc.clSize = bufSz - CL_OVERHEAD; geiMclBlkConfig.clBlkNum = geiClDesc.clNum; /* calculate the total memory for all the M-Blks and CL-Blks. */ geiMclBlkConfig.memSize = ((geiMclBlkConfig.mBlkNum * (M_BLK_SZ + sizeof (long))) + (geiMclBlkConfig.clBlkNum * CL_BLK_SZ + sizeof(long))); if ((geiMclBlkConfig.memArea = (char *) memalign (sizeof(long), geiMclBlkConfig.memSize)) == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: MclBlkConfig memory unavailable\n",1, 2, 3, 4, 5, 6); goto errorExit; } pDrvCtrl->pMclkArea = geiMclBlkConfig.memArea; geiClDesc.memSize = geiClDesc.clNum * (geiClDesc.clSize + CL_OVERHEAD); geiClDesc.memArea = (char *)(pDrvCtrl->pRxBufBase); geiClDesc.memArea = (char *)(((UINT32) geiClDesc.memArea + 0x3) & ~0x3); /* initialize the memory pool. */ if (netPoolInit(pDrvCtrl->end.pNetPool, &geiMclBlkConfig, &geiClDesc, 1,NULL) == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: Could not init buffering\n", 1, 2, 3, 4, 5, 6); goto errorExit; } if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool, geiClDesc.clSize, FALSE)) == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit: Could not find specified pool ID\n", 1, 2, 3, 4, 5, 6); goto errorExit; } CACHE_PIPE_FLUSH (); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit...OK\n", 1, 2, 3, 4, 5, 6); return OK;errorExit: DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndMemInit...ERROR\n", 1, 2, 3,4,5,6); return ERROR; }/*************************************************************************** gei82543EndStart - setup and start the device ** This routine connects interrupts, initializes receiver and transmitter, * and enable the device for running ** RETURNS: OK or ERROR*/LOCAL STATUS gei82543EndStart ( END_DEVICE * pDrvCtrl /* device ID */ ) { STATUS result; /* results of start device */ DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart...\n", 1, 2, 3, 4, 5, 6); if (pDrvCtrl->attach != TRUE) return ERROR; /* disable all chip interrupts */ gei82543DisableChipInt (pDrvCtrl); /* turn off system interrupts */ SYS_INT_DISABLE(pDrvCtrl); /* initialize the hardware and set up link */ if (gei82543HwInit (pDrvCtrl) != OK) { DRV_LOG (DRV_DEBUG_LOAD, ("gei82543EndStart: link setup fails\n"), 1, 2, 3, 4, 5, 6); LOGMSG("link fails\n", 1, 2, 3, 4, 5, 6); } /* disable TX/RX now */ gei82543TxRxDisable (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: set up TX structure\n", 1, 2, 3, 4, 5, 6); /* initialize SW/HW structures for TX */ gei82543TxSetup (pDrvCtrl); /* initialize SW/HW structure for RX */ gei82543RxSetup (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: configure device\n", 1, 2, 3, 4, 5, 6); /* configure devices */ pDrvCtrl->flags = DEFAULT_DRV_FLAGS; END_FLAGS_CLR (&pDrvCtrl->end, IFF_UP | IFF_RUNNING); gei82543EndConfigure (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: Connect interrupt\n", 1, 2, 3, 4, 5, 6); /* connect interrupt handler */ SYS_INT_CONNECT(pDrvCtrl, gei82543EndInt, (int)pDrvCtrl, &result); if (result == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: connect interrupt ERROR !\n", 1, 2, 3, 4, 5, 6); return ERROR; } /* clean up all statistic registers */ gei82543HwStatusDump (pDrvCtrl); /* clean all pending interrupts */ gei82543DisableChipInt (pDrvCtrl); /* turn on system interrupt */ SYS_INT_ENABLE(pDrvCtrl); /* enable interrupt in chip level */ gei82543EnableChipInt (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart: Interrupt enable\n", 1, 2, 3, 4, 5, 6); /* set the END flags, make driver ready to start */ END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST)); gei82543EndConfigure (pDrvCtrl); /* wait for chip to settle down */ taskDelay (sysClkRateGet () / 20); /* check link status again before really start */ if (gei82543linkStatusCheck (pDrvCtrl) != OK) { LOGMSG("gei82543EndStart:Link is down \n", 1, 2, 3, 4, 5, 6); } /* set the internal timer */ if (pDrvCtrl->adaptor.boardType == PRO1000_546_BOARD) { ADAPTOR_INFO * pBoard = &pDrvCtrl->adaptor; /* pointer to board specific struct */ if (pBoard->sysGeiInitTimerSetup != NULL) if (pBoard->sysGeiInitTimerSetup (&pDrvCtrl->adaptor)) { if (!(pBoard->devTimerUpdate.rdtrVal & 0xffff0000)) GEI_WRITE_REG(INTEL_82543GC_RDTR,pBoard->devTimerUpdate.rdtrVal); if (!(pBoard->devTimerUpdate.radvVal & 0xffff0000)) GEI_WRITE_REG(INTEL_82546EB_RADV,pBoard->devTimerUpdate.radvVal); if (!(pBoard->devTimerUpdate.itrVal & 0xffff0000)) GEI_WRITE_REG(INTEL_82546EB_ITR,pBoard->devTimerUpdate.itrVal); pDrvCtrl->timerInterval = (pBoard->devTimerUpdate.watchDogIntVal <= 0) ? DEFAULT_TIMER_INTERVAL : (pBoard->devTimerUpdate.watchDogIntVal); } } /* start the timer if configured */ if (pDrvCtrl->usrFlags & GEI_END_SET_TIMER) { if (pDrvCtrl->timerId) wdStart(pDrvCtrl->timerId, pDrvCtrl->timerInterval * sysClkRateGet(), (FUNCPTR) gei82543EndTimerHandler, (int) pDrvCtrl); } /* set the device start flag */ pDrvCtrl->devStartFlag = TRUE; /* enable TX and RX operation */ gei82543TxRxEnable (pDrvCtrl); DRV_LOG (DRV_DEBUG_LOAD, "gei82543EndStart...Done\n", 1, 2, 3, 4, 5, 6); return (OK); }/*************************************************************************** gei82543EndSend - driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it. This is done by a higher layer. ** RETURNS: OK or ERROR.** ERRNO: EINVAL*/LOCAL STATUS gei82543EndSend ( END_DEVICE * pDrvCtrl, /* device ptr */ M_BLK_ID pMblk /* data to send */ ) { M_BLK_ID pMblkDup = pMblk; /* temporary pMblk */ int mBlkNum; /* num of mBlk of a packet */ DRV_LOG (DRV_DEBUG_TX, "gei82543EndSend...\n", 1, 2, 3, 4, 5, 6); if (pMblk == NULL) return ERROR; /* return if entering polling mode */ if (pDrvCtrl->flags & FLAG_POLLING_MODE) { netMblkClChainFree (pMblk); errno = EINVAL; return (ERROR); } END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER); /* get the mBlk number in this packet */ mBlkNum = 0; while (pMblkDup != NULL) { mBlkNum++; pMblkDup = pMblkDup->mBlkHdr.mNext; } /* * release mBlks if the number of mBlks in this packet exceeds the maximum * available transmit descriptors */ if (mBlkNum >= pDrvCtrl->txDescNum) { DRV_LOG (DRV_DEBUG_TX, ("gei82543EndSend:mBlks num exceeds max TX desc\n"), 1, 2, 3, 4, 5, 6); netMblkClChainFree (pMblk); errno = EINVAL; END_TX_SEM_GIVE (&pDrvCtrl->end); return (ERROR); } if ((mBlkNum > pDrvCtrl->txDescFreeNum) && (mBlkNum > gei82543TxDesCleanGet(pDrvCtrl,FREE_ALL_AUTO))) { /* not enough TX descriptors */ DRV_LOG (DRV_DEBUG_TX, ("gei82543EndSend: No TX descriptor available\n"), 1, 2, 3, 4, 5, 6); if (pDrvCtrl->txStall != TRUE) { pDrvCtrl->txStall = TRUE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -