📄 el3c90xend.c
字号:
/* Enable receiver and transmitter. */ el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_ENABLE, NONE); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_TX_ENABLE, NONE); /* Restore state of BMCR */ if (pDrvCtrl->pPhyDevType != NULL) el3c90xPhyRegWrite(pDrvCtrl, PHY_BMCR, phyBMCR); return; }/********************************************************************************* el3c90xMemInit - initialize memory for the device** This function initiailizes memory for the device** RETURNS: OK or ERROR**/LOCAL STATUS el3c90xMemInit ( EL3C90X_DEVICE * pDrvCtrl /* device to be initialized */ ) { int memSize = 0; memSize += (sizeof(EL_DESC_BLK) + 16); if (pDrvCtrl->bufMtplr == NONE) pDrvCtrl->bufMtplr = 2; else if (pDrvCtrl->bufMtplr <= 0) printf ( "elPci: invalid buffer multiplier\n"); pDrvCtrl->clDesc.clNum = (EL_UPD_CNT + EL_DND_CNT) * pDrvCtrl->bufMtplr; pDrvCtrl->mClCfg.clBlkNum = pDrvCtrl->clDesc.clNum; pDrvCtrl->mClCfg.mBlkNum = pDrvCtrl->mClCfg.clBlkNum * 2; /* total memory size for mBlks and clBlks */ pDrvCtrl->mClCfg.memSize = (pDrvCtrl->mClCfg.mBlkNum * (MSIZE + sizeof (long))) + (pDrvCtrl->mClCfg.clBlkNum * (CL_BLK_SZ + sizeof (long))); memSize += pDrvCtrl->mClCfg.memSize; /* total memory size for all clusters */ pDrvCtrl->clDesc.clSize = EL3C90X_BUFSIZ; pDrvCtrl->clDesc.memSize = (pDrvCtrl->clDesc.clNum * (pDrvCtrl->clDesc.clSize + 8)) + sizeof(int); memSize += pDrvCtrl->clDesc.memSize; if ((int)pDrvCtrl->memAdrs != NONE) { /* check if the give memory size if enough */ if (pDrvCtrl->memSize < memSize) { printf ( "elPci: memory size too small\n" ); return (ERROR); } pDrvCtrl->pDescMem = (char *)pDrvCtrl->memAdrs; pDrvCtrl->mClCfg.memArea = (char *)((UINT32)(pDrvCtrl->pDescMem) + sizeof(EL_DESC_BLK) + 16); pDrvCtrl->clDesc.memArea = (pDrvCtrl->mClCfg.memArea + pDrvCtrl->mClCfg.memSize); /* assume pool is cache coherent, copy null structure */ pDrvCtrl->cacheFuncs = cacheNullFuncs; DRV_LOG (DRV_DEBUG_LOAD, "Memory checks out\n", 1, 2, 3, 4, 5, 6); } else /* allocate our own memory */ { pDrvCtrl->flags |= EL_MEM_ALLOC_FLAG; if (!CACHE_DMA_IS_WRITE_COHERENT ()) { printf ( "elPci: device requires cache coherent memory\n" ); return (ERROR); } /* allocate memory for upload and download descriptors */ pDrvCtrl->pDescMem = (char *) cacheDmaMalloc (sizeof(EL_DESC_BLK) + 16); if (pDrvCtrl->pDescMem == NULL) { printf ( "elPci: system memory unavailable\n" ); return (ERROR); } /* allocate memory for mBlks and clBlks */ if ((pDrvCtrl->mClCfg.memArea = (char *) memalign (sizeof(long), pDrvCtrl->mClCfg.memSize)) == NULL) { printf ( "elPci: system memory unavailable\n" ); goto elMemInitFail; } /* allocate memory for clusters */ pDrvCtrl->clDesc.memArea = cacheDmaMalloc (pDrvCtrl->clDesc.memSize); if (pDrvCtrl->clDesc.memArea == NULL) { printf ( "elPci: system memory unavailable\n" ); goto elMemInitFail; } /* copy the DMA structure */ pDrvCtrl->cacheFuncs = cacheDmaFuncs; } pDrvCtrl->pDescBlk = (EL_DESC_BLK *)(((int)pDrvCtrl->pDescMem + 0x0f) & ~0x0f); bzero ((char*)pDrvCtrl->pDescBlk, sizeof(EL_DESC_BLK)); /* allocate memory for net pool */ if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL) { printf ( "elPci: system memory unavailable\n" ); goto elMemInitFail; }#ifdef DRV_DEBUG pElXlPool = pDrvCtrl->endObj.pNetPool;#endif /* initialize the device net pool */ if (netPoolInit (pDrvCtrl->endObj.pNetPool, &pDrvCtrl->mClCfg, &pDrvCtrl->clDesc, 1, NULL) == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "Could not init buffering\n", 1, 2, 3, 4, 5, 6); goto elMemInitFail; } /* Store the cluster pool id as others need it later. */ pDrvCtrl->pClPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool, EL3C90X_BUFSIZ, FALSE); return (OK); elMemInitFail: { if (pDrvCtrl->flags & EL_MEM_ALLOC_FLAG) { /* free the memory allocated for descriptors */ if (pDrvCtrl->pDescMem != NULL) cacheDmaFree (pDrvCtrl->pDescMem); /* Free the memory allocated for mBlks and clBlks */ if (pDrvCtrl->mClCfg.memArea != NULL) free (pDrvCtrl->mClCfg.memArea); /* free the memory allocated for clusters */ if (pDrvCtrl->clDesc.memArea != NULL) cacheDmaFree (pDrvCtrl->clDesc.memArea); } if (pDrvCtrl->endObj.pNetPool != NULL) free (pDrvCtrl->endObj.pNetPool); return (ERROR); } }/********************************************************************************* el3c90xDevStop - stop the device** This function stops the adapter and frees up any M_BLKS allocated to the* upload and download descriptors.** RETURNS: N/A*/LOCAL void el3c90xDevStop ( EL3C90X_DEVICE * pDrvCtrl /* pointer to the device control structure */ ) { register int ix; el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_DISABLE, NONE); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_STATS_DISABLE, NONE); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_INTR_ENB, NONE); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_DISCARD, NONE); el3c90xWait(pDrvCtrl); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_TX_DISABLE, NONE); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_COAX_STOP, NONE); el3c90xWait(pDrvCtrl); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_RX_RESET, NONE); el3c90xWait(pDrvCtrl); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_TX_RESET, NONE); el3c90xWait(pDrvCtrl); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, (EL_CMD_INTR_ACK | EL_STAT_INTLATCH), NONE); /* free the mblks in the upload descriptor lists */ for (ix = 0; ix < EL_UPD_CNT; ix++) { if (pDrvCtrl->rxTxChain.rxChain [ix].pMblk != NULL) { netMblkClChainFree(pDrvCtrl->rxTxChain.rxChain [ix].pMblk); pDrvCtrl->rxTxChain.rxChain [ix].pMblk = NULL; } } bzero ((char *)&pDrvCtrl->pDescBlk->rxDescs, sizeof(pDrvCtrl->pDescBlk->rxDescs)); /* free the download descriptors */ for (ix = 0; ix < EL_DND_CNT; ix++) { if (pDrvCtrl->rxTxChain.txChain [ix].pMblk != NULL) { netMblkClChainFree(pDrvCtrl->rxTxChain.txChain[ix].pMblk); pDrvCtrl->rxTxChain.txChain [ix].pMblk = NULL; } } bzero ((char *)&pDrvCtrl->pDescBlk->txDescs, sizeof(pDrvCtrl->pDescBlk->txDescs)); return; }/********************************************************************************* el3c90xReset - reset the device** This function call resets the device completely** RETURNS: N/A*/LOCAL void el3c90xReset ( EL3C90X_DEVICE * pDrvCtrl ) { /* issue the reset command */ el3c90xCsrWriteWord(pDrvCtrl, EL_COMMAND, EL_CMD_RESET, EL_WIN_0); el3c90xWait(pDrvCtrl); /* wait for the command to complete */ /* wait for a while */ SYS_DELAY(1000); return; }/********************************************************************************* el3c90xIntEnable - enable board to cause interrupts** Because the board has maskable status, this routine can simply set the* mask to all ones. We set all the bits symbolically; the effect is the* same. Note that the interrupt latch is not maskable; if none of the other* mask bits are set, no interrupts will occur at all. Only those interrupts* whose status bits are enabled will actually occur. Note that the "intMask"* field in the device control structure is really the status mask.** RETURNS: N/A.*/LOCAL void el3c90xIntEnable ( EL3C90X_DEVICE * pDrvCtrl /* device structure */ ) { UINT16 status; status = el3c90xCsrReadWord (pDrvCtrl, EL_STATUS, NONE); status &= 0x00ff; el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, (EL_CMD_INTR_ACK | status), NONE); el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, (EL_CMD_INTR_ENB | EL_INTRS), NONE); }/********************************************************************************* el3c90xIntDisable - prevent board from causing interrupts** This routine simply sets all the interrupt mask bits to zero.* It is intended for guarding board-critical sections.** RETURNS: N/A.*/LOCAL void el3c90xIntDisable ( EL3C90X_DEVICE * pDrvCtrl /* device structure */ ) { UINT16 status; el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, EL_CMD_INTR_ENB, NONE); status = el3c90xCsrReadWord (pDrvCtrl, EL_STATUS, NONE); status &= 0x00ff; el3c90xCsrWriteWord (pDrvCtrl, EL_COMMAND, (EL_CMD_INTR_ACK | status), NONE); }/********************************************************************************* el3c90xPollStart - start polled mode operations** This function starts polled mode operation.** The device interrupts are disabled, the current mode flag is switched* to indicate Polled mode and the device is reconfigured.** RETURNS: OK or ERROR.*/LOCAL STATUS el3c90xPollStart ( EL3C90X_DEVICE * pDrvCtrl /* device to be polled */ ) { int oldLevel; oldLevel = intLock (); /* disable ints during update */ pDrvCtrl->flags |= EL_POLLING; intUnlock (oldLevel); /* now el3c90xInt won't get confused */ el3c90xIntDisable (pDrvCtrl); ENDLOGMSG (("STARTED\n", 1, 2, 3, 4, 5, 6)); return (OK); }/********************************************************************************* el3c90xPollStop - stop polled mode operations** This function terminates polled mode operation. The device returns to* interrupt mode.** The device interrupts are enabled, the current mode flag is switched* to indicate interrupt mode and the device is then reconfigured for* interrupt operation.** RETURNS: OK or ERROR.*/LOCAL STATUS el3c90xPollStop ( EL3C90X_DEVICE * pDrvCtrl /* device structure */ ) { int oldLevel; oldLevel = intLock (); /* disable ints during register updates */ pDrvCtrl->flags &= ~EL_POLLING; intUnlock (oldLevel); el3c90xIntEnable (pDrvCtrl); ENDLOGMSG (("STOPPED\n", 1, 2, 3, 4, 5, 6)); return (OK); }/********************************************************************************* el3c90xUpdInit - initialize the upload descriptor list** This function initializes the upload descriptors and allocates M_BLKs for* them. Note that we arrange the descriptors in a closed ring, so that the* last descriptor points back to the first.** RETURNS: OK or ENOBUFS*/LOCAL int el3c90xUpdInit ( EL3C90X_DEVICE * pDrvCtrl /* pointer to the device control structure */ ) { EL_RX_TX_CHAIN * pRxTxChain; EL_DESC_BLK * pDescBlk; int ix; pRxTxChain = &pDrvCtrl->rxTxChain; pDescBlk = pDrvCtrl->pDescBlk; for (ix = 0; ix < EL_UPD_CNT; i
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -