📄 dec21x40end.c
字号:
return (OK); }/********************************************************************************* dec21x40InitParse - parse parameter values from initString** The initialization string is modified by muxLib.o to include the unit number* as the first parameter.** RETURNS: OK or ERROR.*/LOCAL STATUS dec21x40InitParse ( DRV_CTRL *pDrvCtrl, char *initString ) { char * tok; /* an initString token */ char * holder=NULL; /* points to initString fragment beyond tok */ DRV_LOG (DRV_DEBUG_LOAD, "InitParse: Initstr=%s\n", (int)initString, 0, 0, 0, 0, 0); tok = strtok_r(initString, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi(tok); tok=strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->devAdrs = strtoul (tok, NULL, 16); tok=strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pciMemBase = strtoul (tok, NULL, 16); tok=strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->ivec = strtoul (tok, NULL, 16); tok=strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->ilevel = strtoul (tok, NULL, 16); tok = strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; if (atoi(tok) < 0) pDrvCtrl->numRds = NUM_RDS_DEF; else pDrvCtrl->numRds = atoi(tok); tok = strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; if (atoi(tok) < 0) pDrvCtrl->numTds = NUM_TDS_DEF; else pDrvCtrl->numTds = atoi(tok); tok=strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->memBase = (char *) strtoul (tok, NULL, 16); tok=strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->memSize = strtoul (tok, NULL, 16); tok=strtok_r(NULL, ":", &holder); if (tok == NULL) return (ERROR); pDrvCtrl->usrFlags = strtoul(tok, NULL, 16); /* decode non-register user flags */ if (pDrvCtrl->usrFlags & DEC_USR_XEA) DRV_FLAGS_SET (DEC_BSP_EADRS); switch (pDrvCtrl->usrFlags & DEC_USR_VER_MSK) { case DEC_USR_21143 : DRV_FLAGS_SET (DEC_21143); break; case DEC_USR_21140 : DRV_FLAGS_SET (DEC_21140); break; default : DRV_FLAGS_SET (DEC_21040); break; } /* print debug info */ DRV_LOG (DRV_DEBUG_LOAD, "EndLoad: unit=%d devAdrs=0x%x ivec=0x%x ilevel=0x%x " "membase=0x%x memSize=0x%x\n", pDrvCtrl->unit, pDrvCtrl->devAdrs, pDrvCtrl->ivec, pDrvCtrl->ilevel, (int)pDrvCtrl->memBase, pDrvCtrl->memSize); DRV_LOG (DRV_DEBUG_LOAD, " pciMemBase=0x%x flags=0x%x usrFlags=0x%x\n", (int)pDrvCtrl->pciMemBase, pDrvCtrl->flags, pDrvCtrl->usrFlags, 0, 0, 0); return OK; }/********************************************************************************* dec21x40InitMem - initialize memory** RETURNS: OK or ERROR.*/LOCAL STATUS dec21x40InitMem ( DRV_CTRL * pDrvCtrl ) { DEC_RD * pRxD = pDrvCtrl->rxRing; DEC_TD * pTxD = pDrvCtrl->txRing; M_CL_CONFIG dcMclBlkConfig; CL_DESC clDesc; /* cluster description */ char * pBuf; int ix; int sz; char * pShMem; /* Establish size of shared memory region we require */ DRV_LOG (DRV_DEBUG_LOAD, "InitMem\n", 0, 0, 0, 0, 0, 0); if ((int)pDrvCtrl->memBase != NONE) /* specified memory pool */ { sz = ((pDrvCtrl->memSize - (RD_SIZ + TD_SIZ)) / (((2 + NUM_LOAN) * DEC_BUFSIZ) + RD_SIZ + TD_SIZ)); pDrvCtrl->numRds = max (sz, MIN_RDS); pDrvCtrl->numTds = max (sz, MIN_TDS); } /* Establish a region of shared memory */ /* OK. We now know how much shared memory we need. If the caller * provides a specific memory region, we check to see if the provided * region is large enough for our needs. If the caller did not * provide a specific region, then we attempt to allocate the memory * from the system, using the cache aware allocation system call. */ switch ((int)pDrvCtrl->memBase) { default : /* caller provided memory */ sz = ((pDrvCtrl->numRds * (DEC_BUFSIZ + RD_SIZ + 8)) + 4 + (pDrvCtrl->numTds * (DEC_BUFSIZ + TD_SIZ + 8)) + 4 + (NUM_LOAN * (DEC_BUFSIZ + 8)) + 4); if ( pDrvCtrl->memSize < sz ) /* not enough space */ { printf( "%s%d: not enough memory provided\n", DRV_NAME, pDrvCtrl->unit); return ( ERROR ); } pShMem = pDrvCtrl->memBase; /* set the beginning of pool */ /* assume pool is cache coherent, copy null structure */ pDrvCtrl->cacheFuncs = cacheNullFuncs; break; case NONE : /* get our own memory */ /* Because the structures that are shared between the device * and the driver may share cache lines, the possibility exists * that the driver could flush a cache line for a structure and * wipe out an asynchronous change by the device to a neighboring * structure. Therefore, this driver cannot operate with memory * that is not write coherent. We check for the availability of * such memory here, and abort if the system did not give us what * we need. */ if (!CACHE_DMA_IS_WRITE_COHERENT ()) { printf ( "dc: device requires cache coherent memory\n" ); return (ERROR); } sz = (((pDrvCtrl->numRds + 1) * RD_SIZ) + ((pDrvCtrl->numTds + 1) * TD_SIZ)); pDrvCtrl->memBase = pShMem = (char *) cacheDmaMalloc ( sz ); if ((int)pShMem == NULL) { printf ( "%s%d - system memory unavailable\n", DRV_NAME, pDrvCtrl->unit); return (ERROR); } pDrvCtrl->memSize = sz; DRV_FLAGS_SET (DEC_MEMOWN); /* copy the DMA structure */ pDrvCtrl->cacheFuncs = cacheDmaFuncs; break; } /* zero the shared memory */ bzero (pShMem, (int) sz); /* carve Rx memory structure */ pRxD = pDrvCtrl->rxRing = (DEC_RD *) (((int)pShMem + 0x03) & ~0x03); /* carve Tx memory structure */ pTxD = pDrvCtrl->txRing = (DEC_TD *) (pDrvCtrl->rxRing + pDrvCtrl->numRds); /* Initialize net buffer pool for tx/rx buffers */ bzero ((char *)&dcMclBlkConfig, sizeof(dcMclBlkConfig)); bzero ((char *)&clDesc, sizeof(clDesc)); dcMclBlkConfig.mBlkNum = pDrvCtrl->numRds * 4; clDesc.clNum = pDrvCtrl->numRds + pDrvCtrl->numTds + NUM_LOAN; dcMclBlkConfig.clBlkNum = clDesc.clNum; /* * mBlk and cluster configuration memory size initialization * memory size adjusted to hold the netPool pointer at the head. */ dcMclBlkConfig.memSize = ((dcMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (dcMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof (long)))); if ((dcMclBlkConfig.memArea = (char *)memalign(sizeof (long), dcMclBlkConfig.memSize)) == NULL) return (ERROR); clDesc.clSize = DEC_BUFSIZ; clDesc.memSize = ((clDesc.clNum * (clDesc.clSize + 4)) + 4); if (DRV_FLAGS_ISSET(DEC_MEMOWN)) { clDesc.memArea = (char *) cacheDmaMalloc (clDesc.memSize); if ((int)clDesc.memArea == NULL) { printf ( "%s%d - system memory unavailable\n", DRV_NAME, pDrvCtrl->unit); return (ERROR); } } else clDesc.memArea = (char *) (pDrvCtrl->txRing + pDrvCtrl->numTds); if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof(NET_POOL))) == NULL) return (ERROR); /* Initialize the net buffer pool with transmit buffers */ if (netPoolInit (pDrvCtrl->endObj.pNetPool, &dcMclBlkConfig, &clDesc, 1, NULL) == ERROR) { printf ("%s%d - netPoolInit failed\n", DRV_NAME, pDrvCtrl->unit); return (ERROR); } /* Save the cluster pool id */ pDrvCtrl->clPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool, DEC_BUFSIZ, FALSE); /* Clear all indices */ pDrvCtrl->rxIndex=0; pDrvCtrl->txIndex=0; pDrvCtrl->txDiIndex=0; /* Setup the receive ring */ for (ix = 0; ix < pDrvCtrl->numRds; ix++, pRxD++) { pBuf = (char *) NET_BUF_ALLOC(); if (pBuf == NULL) { printf ("%s%d - netClusterGet failed\n", DRV_NAME, pDrvCtrl->unit); return (ERROR); } pRxD->rDesc2 = PCISWAP (DEC_VIRT_TO_PCI (pBuf)); /* buffer 1 */ pRxD->rDesc3 = 0; /* no second buffer */ /* buffer size */ pRxD->rDesc1 = PCISWAP (RDESC1_RBS1_VAL (DEC_BUFSIZ) | RDESC1_RBS2_VAL (0)); if (ix == (pDrvCtrl->numRds - 1)) /* if its is last one */ pRxD->rDesc1 |= PCISWAP (RDESC1_RER); /* end of receive ring */ pRxD->rDesc0 = PCISWAP (RDESC0_OWN); /* give ownership to chip */ } /* Setup the transmit ring */ for (ix = 0; ix < pDrvCtrl->numTds; ix++, pTxD++) { /* empty -- no buffers at this time */ pTxD->tDesc2 = 0; pTxD->tDesc3 = 0; pTxD->tDesc1 = PCISWAP ((TDESC1_TBS1_PUT(0) | /* buffer1 size */ TDESC1_TBS2_PUT(0) | /* buffer2 size */ TDESC1_IC | /* intrpt on xmit */ TDESC1_LS | /* last segment */ TDESC1_FS)); /* first segment */ if (ix == (pDrvCtrl->numTds - 1)) /* if its is last one */ pTxD->tDesc1 |= PCISWAP (TDESC1_TER); /* end of Xmit ring */ pTxD->tDesc0 = 0; /* owner is host */ } /* Flush the write pipe */ CACHE_PIPE_FLUSH (); return (OK); }/********************************************************************************* dec21x40Start - start the device** This function initializes the device and calls BSP functions to connect* interrupts and start the device running in interrupt mode.** The complement of this routine is dec21x40Stop. Once a unit is reset by* dec21x40Stop, it may be re-initialized to a running state by this routine.** RETURNS: OK if successful, otherwise ERROR*/LOCAL STATUS dec21x40Start ( DRV_CTRL * pDrvCtrl /* device to start */ ) { int retVal; UINT csr6Val=0; UINT usrFlags = pDrvCtrl->usrFlags; DRV_LOG (DRV_DEBUG_LOAD, "Start\n", 0, 0, 0, 0, 0, 0); /* Reset the device */ DEC_CSR_WRITE (CSR6, 0); dec21x40ChipReset (pDrvCtrl); /* Clear all indices */ pDrvCtrl->rxIndex=0; pDrvCtrl->txIndex=0; pDrvCtrl->txDiIndex=0; pDrvCtrl->txCleaning = FALSE; pDrvCtrl->rxHandling = FALSE; pDrvCtrl->txBlocked = FALSE; if (! DRV_FLAGS_ISSET (DEC_21040)) { if (_func_dec21x40MediaSelect != NULL) retVal = (* _func_dec21x40MediaSelect) (pDrvCtrl, &csr6Val); else if (DRV_FLAGS_ISSET (DEC_21140)) retVal = dec21140MediaSelect (pDrvCtrl, &csr6Val); else retVal = dec21143MediaSelect (pDrvCtrl, &csr6Val); if (retVal == ERROR) return (ERROR); if (csr6Val & CSR6_21140_PS) { DEC_CSR_UPDATE (CSR6, CSR6_21140_PS); dec21x40ChipReset (pDrvCtrl); csr6Val |= CSR6_21140_HBD; } /* wait for the PHY to become ready */ if (usrFlags & DEC_USR_PHY_CHK) dec21x40PhyLinkPoll (pDrvCtrl, DEC_MAX_LINK_TOUT); csr6Val &= DEC_USR_CSR6_MSK; csr6Val |= CSR6_21140_MB1; /* decode CSR6 specific options from userFlags */ if (usrFlags & DEC_USR_SF) csr6Val |= CSR6_21140_SF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -