📄 if_dc.c
字号:
* Default macro definitions for device register accesses: * These macros can be redefined in a wrapper file, to generate * a new module with an optimized interface. */#ifndef DC_CSR_READ#define DC_CSR_READ(devAdrs, csrNum) \ dcCsrRead ((devAdrs), (csrNum))#endif /* DC_CSR_READ */#ifndef DC_CSR_WRITE#define DC_CSR_WRITE(devAdrs, csrNum, csrVal) \ dcCsrWrite((devAdrs), (csrNum), (csrVal))#endif /* DC_CSR_WRITE */#define DC_CSR_UPDATE(devAdrs, csrNum, csrBits) \ DC_CSR_WRITE((devAdrs), (csrNum), \ DC_CSR_READ((devAdrs), (csrNum)) | (csrBits))#define DC_CSR_RESET(devAdrs, csrNum, csrBits) \ DC_CSR_WRITE((devAdrs), (csrNum), \ DC_CSR_READ((devAdrs), (csrNum)) & ~(csrBits)) #define DC_INT_ENABLE(devAdrs, X) \ DC_CSR_UPDATE ((devAdrs), CSR7, (X))#define DC_INT_DISABLE(devAdrs, X) \ DC_CSR_RESET ((devAdrs), CSR7, (X))#define DC_SROM_WRITE(devAdrs, adrs, delay) \ { \ DC_CSR_WRITE ((devAdrs), CSR9, (adrs) | CSR9_SR | CSR9_WR); \ NSDELAY(delay); \ }#define DC_SROM_READ(devAdrs) \ ((DC_CSR_READ ((devAdrs), CSR9) & 0x08) >> 3)/* MII read/write access macros */ #define DC_MII_BIT_READ(devAdrs, pBData) \ { \ DC_CSR_WRITE ((devAdrs), CSR9, CSR9_MII_RD | CSR9_RD); \ NSDELAY (100); \ DC_CSR_WRITE ((devAdrs), CSR9, CSR9_MII_RD | CSR9_RD | CSR9_MDC); \ NSDELAY (100); \ *(pBData) |= CSR9_MII_DBIT_RD (DC_CSR_READ ((devAdrs), CSR9)); \ }#define DC_MII_BIT_WRITE(devAdrs, data) \ { \ DC_CSR_WRITE ((devAdrs), CSR9, CSR9_MII_DBIT_WR(data) | \ CSR9_MII_WR | CSR9_WR); \ NSDELAY (100); \ DC_CSR_WRITE ((devAdrs), CSR9, CSR9_MII_DBIT_WR(data) | \ CSR9_MII_WR | CSR9_WR | CSR9_MDC); \ NSDELAY (100); \ }#define DC_MII_RTRISTATE(devAdrs) \ { \ int retVal; \ DC_MII_BIT_READ ((devAdrs), &retVal); \ }#define DC_MII_WTRISTATE(devAdrs) \ { \ DC_MII_BIT_WRITE((devAdrs), 0x1); \ DC_MII_BIT_WRITE((devAdrs), 0x0); \ }#define DC_MII_WRITE(devAdrs, data, bitCount) \ { \ int i=(bitCount); \ \ while (i--) \ DC_MII_BIT_WRITE ((devAdrs), ((data) >> i) & 0x1); \ }#define DC_MII_READ(devAdrs, pData, bitCount) \ { \ int i=(bitCount); \ \ while (i--) \ { \ *(pData) <<= 1; \ DC_MII_BIT_READ ((devAdrs), (pData)); \ } \ }#define BUILD_CLUSTER(pDrvCtrl, pEnetHdr, pData, len) \ build_cluster ((pData), (len), &(pDrvCtrl)->idr.ac_if, MC_LANCE, \ (pDrvCtrl)->pRefCnt[(pDrvCtrl)->nLoanRx - 1], \ (FUNCPTR) dcLoanFree, (int)(pDrvCtrl), \ (int) (pEnetHdr), \ (int)(pDrvCtrl)->pRefCnt[(pDrvCtrl)->nLoanRx - 1])#ifdef BSD43_DRIVER#define DC_START_OUTPUT(pDrvCtrl) \ dcStartOutput (pDrvCtrl->idr.ac_if.if_unit)#else#define DC_START_OUTPUT(pDrvCtrl) \ dcStartOutput (pDrvCtrl)#endif /* Typedefs for external structures that are not typedef'd in their .h files */typedef struct mbuf MBUF;typedef struct arpcom IDR; /* Interface Data Record wrapper */typedef struct ifnet IFNET; /* real Interface Data Record */typedef struct sockaddr SOCK;#ifdef DC_DEBUGtypedef struct /* dc_stats */ { /* Transmit Error Stats */ int txJbrTmo; int txLostCarrier; int txNoCarrier; int txLateCollision; int txExsCollision; int txHeartBeatFail; int txLinkFail; int txUnderflow; int txDeferred; int txRetries; int txDropped; int txFlushCalled; int txFlushNeeded; int txFlushDone; int txQsizeMax; int txQsizeCur; /* Receive Error Stats */ int rxFiltrErr; int rxDescErr; int rxRuntFrm; int rxTooLong; int rxCollision; int rxDribbleBit; int rxCrcErr; int rxOverflow; int rxMiiErr; int rxMissed; int rxLatency; int rxStart; int rxStop; } DC_STATS;#endif /* DC_DEBUG *//* The definition of the driver control structure */typedef struct /* drv_ctrl */ { IDR idr; /* Interface Data Record */ int dcNumRds; /* RMD ring size */ int rxIndex; /* index into RMD ring */ DC_RDE * rxRing; /* RMD ring */ int dcNumTds; /* TMD ring size */ int txIndex; /* index into TMD ring */ int txDiIndex; /* disposal index into TMD ring */ DC_TDE * txRing; /* TMD ring */ BOOL attached; /* indicates unit is attached */ BOOL txFlushScheduled; int txCount; SEM_ID TxSem; /* transmitter semaphore */ ULONG dcOpMode; /* mode of operation */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ ULONG devAdrs; /* device structure address */ ULONG pciMemBase; /* memory base as seen from PCI*/ int memWidth; /* width of data port */ CACHE_FUNCS cacheFuncs; /* cache function pointers */ int nLoanRx; /* number of Rx buffers left to loan */ char *lPool[DC_L_POOL]; /* receive loaner pool ptrs */ UINT8 *pRefCnt[DC_L_POOL]; /* stack of reference count pointers */ UINT8 refCnt[DC_L_POOL]; /* actual reference count values */ ULONG * pFltrFrm; /* pointer to setup filter frame */ MediaBlocksType dcMediaBlocks; /* SROM Media Data */#ifdef DC_DEBUG DC_STATS errStats;#endif /* DC_DEBUG */ } DRV_CTRL;#define DRV_CTRL_SIZ sizeof(DRV_CTRL)#define RMD_SIZ sizeof(DC_RDE)#define TMD_SIZ sizeof(DC_TDE)#define DC_FLUSH_RETRIES 5#define MAX_TX_RETRIES 2/* globals */#ifdef DC_DEBUGint dcCsrShow (int unit);int dcViewRom (ULONG devAdrs, UCHAR lineCnt, int cnt);#endif /* DC_DEBUG */ULONG dcCSR0Bmr = 0;BOOL dcKickStartTx = DC_KICKSTART_TX;/* locals */LOCAL DRV_CTRL drvCtrl [MAX_UNITS]; /* array of driver control structs */LOCAL int dcNumRds = NUM_RDS; /* number of ring descriptors */LOCAL int dcNumTds = NUM_TDS; /* number of xmit descriptors */LOCAL int dcLPool = DC_L_POOL;/* forward static functions */LOCAL void dcReset (int unit);LOCAL void dcInt (DRV_CTRL *pDrvCtrl);LOCAL void dcHandleRecvInt (DRV_CTRL *pDrvCtrl);LOCAL void dcTxRingClean (DRV_CTRL *pDrvCtrl);LOCAL STATUS dcRecv (DRV_CTRL *pDrvCtrl, DC_RDE *rmd);LOCAL void dcTxFlush (DRV_CTRL *pDrvCtrl);#ifdef BSD43_DRIVERLOCAL int dcOutput (IDR *ifp, MBUF *m0, SOCK *dst);LOCAL void dcStartOutput (int unit);#elseLOCAL void dcStartOutput (DRV_CTRL *pDrvCtrl);#endif /* BSD43_DRIVER */LOCAL int dcIoctl (IDR *ifp, int cmd, caddr_t data);LOCAL int dcChipReset (DRV_CTRL *pDrvCtrl);LOCAL DC_RDE * dcGetFullRMD (DRV_CTRL *pDrvCtrl);LOCAL void dc21040AuiTpInit (ULONG devAdrs);LOCAL void dc21140AuiMiiInit (DRV_CTRL *pDrvCtrl, ULONG devAdrs, UINT dcCSR6);LOCAL void dcSelectMedia (DRV_CTRL *pDrvCtrl);LOCAL void dcCsrWrite (ULONG devAdrs, int reg, ULONG value);LOCAL ULONG dcCsrRead (ULONG devAdrs, int reg);LOCAL void dcRestart (int unit);LOCAL STATUS dcEnetAddrGet (ULONG devAdrs, char * enetAdrs, int len);LOCAL STATUS dc21140EnetAddrGet (ULONG devAdrs, char * enetAdrs, int len);LOCAL void dcLoanFree (DRV_CTRL *pDrvCtrl, char *pRxBuf, UINT8 *pRef);LOCAL int dcFltrFrmSetup (DRV_CTRL * pDrvCtrl, char * pPhysAdrsTbl, int tblLen);LOCAL int dcFltrFrmXmit (DRV_CTRL *pDrvCtrl, char * pPhysAdrsTbl, int tblLen);LOCAL USHORT dcMiiPhyRead (DRV_CTRL *pDrvCrl, UINT phyAdrs, UINT phyReg);LOCAL void dcMiiPhyWrite (DRV_CTRL *pDrvCtrl, UINT phyAdrs, UINT phyReg, USHORT data);LOCAL USHORT dcReadRom (ULONG devAdrs, UCHAR lineCnt);/********************************************************************************* dcInit - device initialization sequence** RETURNS: N/A.*/LOCAL void dcInit ( ULONG devAdrs ) { char dummy_buffer[60]; DC_TDE tmd; tmd.tDesc0 = 0x80000000; tmd.tDesc1 = 0xe200003c; tmd.tDesc2 = (ULONG)dummy_buffer; tmd.tDesc3 = 0; /* start xmit dummy packet, this will never go out to the physical bus */ DC_CSR_WRITE (devAdrs, CSR4, (ULONG)(&tmd)); DC_CSR_WRITE (devAdrs, CSR7, 0); DC_CSR_WRITE (devAdrs, CSR6, 0x2642400); DC_CSR_WRITE (devAdrs, CSR1, CSR1_TPD); /* xmit poll demand */ DELAY(0x8000); /* * Reset the device while xmitting, it ensures the device will not hang * up in its 1st xmit later on */ DC_CSR_UPDATE (devAdrs, CSR0, CSR0_SWR); }/********************************************************************************* dcattach - publish the `dc' network interface.** This routine publishes the `dc' interface by filling in a network interface* record and adding this record to the system list. This routine also* initializes the driver and the device to the operational state.** The <unit> parameter is used to specify the device unit to initialize.** The <devAdrs> is used to specify the I/O address base of the device.** The <ivec> parameter is used to specify the interrupt vector associated* with the device interrupt.** The <ilevel> parater is used to specify the level of the interrupt which* the device would use.** The <memAdrs> parameter can be used to specify the location of the* memory that will be shared between the driver and the device. The value* NONE is used to indicate that the driver should obtain the memory.** The <memSize> parameter is valid only if the <memAdrs> parameter is not* set to NONE, in which case <memSize> indicates the size of the* provided memory region.** The <memWidth> parameter sets the memory pool's data port width (in bytes);* if it is NONE, any data width is used.** The <pciMemBase> parameter defines the main memory base as seen from PCI bus.* * The <dcOpMode> parameter defines the mode in which the device should be* operational.** BUGS** To zero out DEC 21x4x data structures, this routine uses bzero(), which* ignores the <memWidth> specification and uses any size data access to write* to memory.** RETURNS: OK or ERROR.*/STATUS dcattach ( int unit, /* unit number */ ULONG devAdrs, /* device I/O address */ int ivec, /* interrupt vector */ int ilevel, /* interrupt level */ char * memAdrs, /* address of memory pool (-1 = malloc it) */ ULONG memSize, /* only used if memory pool is NOT malloc()'d */ int memWidth, /* byte-width of data (-1 = any width) */ ULONG pciMemBase, /* main memory base as seen from PCI bus */ int dcOpMode /* mode of operation */ ) { DRV_CTRL * pDrvCtrl; /* pointer to drvctrl */ unsigned int sz; /* temporary size holder */ char * pShMem; /* start of the device memory pool */ char * buf; /* temp buffer pointer */ void * pTemp; /* temp pointer */ DC_RDE * rmd; /* pointer to rcv descriptor */ DC_TDE * tmd; /* pointer to xmit descriptor */ int ix; /* counter */ ULONG uTemp; /* temporary storage */ int retVal; /* Sanity check the unit number */ if (unit < 0 || unit >= MAX_UNITS) return (ERROR); uTemp = 0; /* Ensure single invocation per system life */ pDrvCtrl = & drvCtrl [unit]; if (pDrvCtrl->attached) return (OK); pDrvCtrl->ivec = ivec; /* interrupt vector */ pDrvCtrl->ilevel = ilevel; /* interrupt level */ pDrvCtrl->devAdrs = devAdrs; /* device I/O address */ pDrvCtrl->pciMemBase = pciMemBase; /* pci memory base */ pDrvCtrl->memWidth = memWidth; /* memory width */ pDrvCtrl->dcOpMode = (dcOpMode == NONE) ? 0 : dcOpMode; /* operation mode */ /* Publish the interface data record */#ifdef BSD43_DRIVER ether_attach ( & pDrvCtrl->idr.ac_if, unit, "dc", (FUNCPTR) NULL, (FUNCPTR) dcIoctl, (FUNCPTR) dcOutput, (FUNCPTR) dcReset );#else ether_attach ( (IFNET *) &pDrvCtrl->idr, unit, "dc", (FUNCPTR) NULL, (FUNCPTR) dcIoctl, (FUNCPTR) ether_output, (FUNCPTR) dcReset ); pDrvCtrl->idr.ac_if.if_start = (FUNCPTR) dcStartOutput;#endif /* BSD43_DRIVER */#ifdef DC_DEBUG bzero ((char *)&pDrvCtrl->errStats, sizeof (DC_STATS));#endif /* DC_DEBUG */ dcInit(pDrvCtrl->devAdrs); /* Create the transmit semaphore. */ if ((pDrvCtrl->TxSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE)) == NULL) { printf ("dc: error creating transmitter semaphore\n"); return (ERROR); } /* Establish size of shared memory region we require */ if ((int) memAdrs != NONE) /* specified memory pool */ { sz = ((memSize - FLTR_FRM_SIZE + RMD_SIZ + TMD_SIZ) / ((3 * DC_BUFSIZ) + RMD_SIZ + TMD_SIZ)); dcNumRds = max (sz, MIN_RDS); dcNumTds = max (sz, MIN_TDS); dcLPool = min (dcNumRds, DC_L_POOL); } /* add it all up - allow for alignment adjustment */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -