📄 if_dc.c
字号:
/* Kickstart transmit */ if (dcKickStartTx) DC_CSR_WRITE (pDrvCtrl->devAdrs, CSR1, CSR1_TPD); pDrvCtrl->txCount++; } /* Scrub the Tx ring */ if (pDrvCtrl->txCount > (pDrvCtrl->dcNumTds/3)) dcTxRingClean (pDrvCtrl);#ifdef DC_DEBUG if (pDrvCtrl->errStats.txQsizeCur > pDrvCtrl->errStats.txQsizeMax) pDrvCtrl->errStats.txQsizeMax = pDrvCtrl->errStats.txQsizeCur;#endif /* DC_DEBUG */ }/********************************************************************************* dcIoctl - the driver I/O control routine** Process an ioctl request.*/LOCAL int dcIoctl ( IDR * ifp, /* pointer interface data record */ int cmd, /* command */ caddr_t data /* data */ ) { int error = 0; DRV_CTRL * pDrvCtrl = (DRV_CTRL *)ifp; /* pointer to device */ switch (cmd) { case SIOCSIFADDR: ifp->ac_ipaddr = IA_SIN (data)->sin_addr; break; case SIOCSIFFLAGS: /* No further work to be done */ break; case IFF_PROMISC: /* set device in promiscuous mode */ DC_CSR_UPDATE (pDrvCtrl->devAdrs, CSR6, CSR6_PR); break; default: error = EINVAL; } return (error); }/********************************************************************************* dcChipReset - hardware reset of chip (stop it)*/LOCAL int dcChipReset ( DRV_CTRL * pDrvCtrl /* pointer to device control structure */ ) { ULONG devAdrs = pDrvCtrl->devAdrs; /* device base address */ ULONG ix; /* index */ DC_CSR_WRITE (devAdrs, CSR6, 0); /* stop rcvr & xmitter */ DC_CSR_WRITE (devAdrs, CSR7, 0); /* mask interrupts */ DC_CSR_WRITE (devAdrs, CSR0, CSR0_SWR); /* Wait Loop, Loop for at least 50 PCI cycles according to chip spec */ for (ix = 0; ix < 0x1000; ix++) ; /* any additional bus mode | give xmit & rcv process equal priority */ DC_CSR_WRITE (devAdrs, CSR0, (dcCSR0Bmr | CSR0_BAR | CSR0_RML | CSR0_CAL_32 | CSR0_PBL_32)); for (ix = 0; ix < 0x1000; ix++) /* loop for some cycles */ ; return (OK); }/********************************************************************************* dc21040AuiTpInit - initialize either AUI or 10BASE-T connection** This function configures 10BASE-T interface. If the link pass state is * not achieved within two seconds then the AUI interface is initialized.*/LOCAL void dc21040AuiTpInit ( ULONG devAdrs /* device base I/O address */ ) { /* reset the SIA registers */ DC_CSR_WRITE (devAdrs, CSR13, 0); DC_CSR_WRITE (devAdrs, CSR14, 0); DC_CSR_WRITE (devAdrs, CSR15, 0); /* configure for the 10BASE-T */ DC_CSR_WRITE (devAdrs, CSR13, CSR13_CAC_CSR); /* 10BT auto configuration */ taskDelay (sysClkRateGet() * 2); /* 2 second delay */ if (DC_CSR_READ (devAdrs, CSR12) & (CSR12_LKF | CSR12_NCR)) { /* 10BASE-T not connected initialize interface for AUI */ DC_CSR_WRITE (devAdrs, CSR13, 0); /* reset SIA registers */ DC_CSR_WRITE (devAdrs, CSR14, 0); DC_CSR_WRITE (devAdrs, CSR15, 0); /* AUI auto configuration */ DC_CSR_WRITE (devAdrs, CSR13, (CSR13_AUI_TP | CSR13_CAC_CSR)); } }/********************************************************************************* dc21140SROMVersionGet - gets the SROM format version** RETURNS: 0 - Undefined/Unknown; 1 - Version 1/A; 3 - Version 3.0*/LOCAL UCHAR dc21140SROMVersionGet ( ULONG devAdrs ) { union SROMData { char Char[6]; /* temporary 6 x Char */ USHORT Short[2]; /* temporary USHORT */ ULONG Long; /* temporay ULONG */ } SROMData; /* Check if SROM is programmed. */ SROMData.Short[0] = dcReadRom (devAdrs, 0); if (SROMData.Short[0] == 0xFFFF) { return (0); } SROMData.Short[0] = dcReadRom (devAdrs, 9); switch (SROMData.Char[1]) { case 1: return (1); case 3: return (3); default: break; } return (0); }/********************************************************************************* dcSetDefaultMediaTypes - initialize Media info for blank SROMs.***/LOCAL void dcSetDefaultMediaTypes ( DRV_CTRL *pDrvCtrl ) { pDrvCtrl->dcMediaBlocks.MediaFound = 3; pDrvCtrl->dcMediaBlocks.ActiveMedia = 0; pDrvCtrl->dcMediaBlocks.GPMask = 0x60; /* AUI */ pDrvCtrl->dcMediaBlocks.MediaArray[0].ValCSR6 = CSR6_BIT25; pDrvCtrl->dcMediaBlocks.MediaArray[0].GPCount = 0; /* 10BaseT */ pDrvCtrl->dcMediaBlocks.MediaArray[1].ValCSR6 = CSR6_PS | CSR6_BIT25; pDrvCtrl->dcMediaBlocks.MediaArray[1].GPCount = 1; pDrvCtrl->dcMediaBlocks.MediaArray[2].GPValue[0] = 0x40; /* 100BaseT4 */ pDrvCtrl->dcMediaBlocks.MediaArray[2].ValCSR6 = CSR6_PS | CSR6_BIT25; pDrvCtrl->dcMediaBlocks.MediaArray[2].GPCount = 1; pDrvCtrl->dcMediaBlocks.MediaArray[2].GPValue[0] = 0x40; }/********************************************************************************* dcDoCompactInfo - initialize Compact Media info for Version 3.0 SROMs.**/LOCAL void dcDoCompactInfo ( DRV_CTRL *pDrvCtrl, CompactFormat *pCompactData, UINT *pCSR6, UINT MediaUnit ) { pDrvCtrl->dcMediaBlocks.MediaArray[MediaUnit].GPCount = 1; pDrvCtrl->dcMediaBlocks.MediaArray[MediaUnit].GPValue[0] = pCompactData->GPPortData; if (pCompactData->Command & 1) *pCSR6 |= CSR6_PS; if (pCompactData->Command & 10) *pCSR6 |= CSR6_TTM; if (pCompactData->Command & 20) *pCSR6 |= CSR6_PCS; if (pCompactData->Command & 40) *pCSR6 |= CSR6_SCR; return; }/********************************************************************************* dc21140AuiMiiInit - initialize either AUI or MII connection** This function configures 21140. The SROM is used to set the chipset* (DEC21140/PHY) if the SROM is configured. The settings are tried and* if there is no errors (link fail, no carrier, ...) the configuration* is used. If an error occurs, the next media info leaf is tried, etc.* If the SROM is not programmed, or contains invalid data, a "generic"* TP setting is used/tried and, if failure, the AUI port is used.*/LOCAL void dc21140AuiMiiInit ( DRV_CTRL *pDrvCtrl, ULONG devAdrs, UINT dcCSR6 ) { union SROMData { char Char[6]; /* temporary 6 x Char */ USHORT Short[2]; /* temporary USHORT */ ULONG Long; /* temporay ULONG */ } SROMData; UINT BlockCount = 0, GPRLength = 0, OldCSR6 = 0, ii, jj; UCHAR *pTmp; InfoLeaf *dcInfoLeaf; InfoBlock *pInfoBlock; UCHAR SROMBuffer [128]; pDrvCtrl->dcMediaBlocks.DontSwitch = 0; dcCSR6 = dcCSR6 | CSR6_BIT25; OldCSR6 = dcCSR6; /* Get SROM version */ switch (dc21140SROMVersionGet (devAdrs)) { /* Valid Version 3 format was found, try info leafs. */ case 3: for ( ii = 0; ii < 64; ii++ ) { SROMData.Short[0] = dcReadRom (devAdrs, ii); SROMBuffer [ii*2] = SROMData.Char[1]; SROMBuffer [(ii*2)+1] = SROMData.Char[0]; } dcInfoLeaf = (InfoLeaf *)(&(SROMBuffer[SROMBuffer[27]])); BlockCount = dcInfoLeaf->BlockCount; pInfoBlock = &dcInfoLeaf->dcInfoBlock; pDrvCtrl->dcMediaBlocks.MediaFound = BlockCount; pDrvCtrl->dcMediaBlocks.GPMask = dcInfoLeaf->GPControl; for (ii = 0; ii < BlockCount; ii++) { pTmp = (UCHAR *)pInfoBlock; if ( !(pInfoBlock->Compact.MediaCode & 0x80) ) { /* Compact Format */ pDrvCtrl->dcMediaBlocks.MediaArray[0].GPCount = 0; dcDoCompactInfo(pDrvCtrl, &(pInfoBlock->Compact), &dcCSR6, ii); pDrvCtrl->dcMediaBlocks.MediaArray[ii].ValCSR6 = dcCSR6; pTmp = &(pTmp[4]); } else { /* Extended Format */ if (pInfoBlock->Extended0.Type) { /* Block Type 1 */ dcCSR6 = dcCSR6 | CSR6_BIT25 | CSR6_PS; /* Get General Purpose Data. */ GPRLength = pInfoBlock->Extended1.BlockData[1]; pDrvCtrl->dcMediaBlocks.MediaArray[ii].GPCount = GPRLength; for (jj = 0; jj < GPRLength; jj++) { pDrvCtrl->dcMediaBlocks.MediaArray[ii].GPValue[jj] = pInfoBlock->Extended1.BlockData[jj+2]; } pDrvCtrl->dcMediaBlocks.MediaArray[ii].GPResetLen = pInfoBlock->Extended1.BlockData[GPRLength+2]; for (jj = 0; jj < pDrvCtrl->dcMediaBlocks.MediaArray[ii]. GPResetLen; jj++) { pDrvCtrl->dcMediaBlocks.MediaArray[ii]. GPResetValue[jj] = pInfoBlock->Extended1. BlockData[GPRLength+jj+3]; } } else { /* Block Type 0 */ dcCSR6 = dcCSR6 | CSR6_TTM | CSR6_BIT25; dcDoCompactInfo (pDrvCtrl, (CompactFormat *) (pInfoBlock->Extended1.BlockData), &dcCSR6, ii); } pDrvCtrl->dcMediaBlocks.MediaArray[ii].ValCSR6 = dcCSR6; pTmp = &(pTmp[(pInfoBlock->Extended0.Length & ~0x80) + 1]); } pDrvCtrl->dcMediaBlocks.ActiveMedia = 0; dcCSR6 = OldCSR6; pInfoBlock = (InfoBlock *)pTmp; } pDrvCtrl->dcMediaBlocks.ActiveMedia = BlockCount - 1; dcSelectMedia (pDrvCtrl); break; default: /* Invalid format was found, try MII then AUI. */ dcSetDefaultMediaTypes (pDrvCtrl); pDrvCtrl->dcMediaBlocks.ActiveMedia = 1; dcSelectMedia (pDrvCtrl); break; } return; }/********************************************************************************* dcMiiPhyRead - read a PHY device register via MII** RETURNS: the contents of a PHY device register.*/LOCAL USHORT dcMiiPhyRead ( DRV_CTRL *pDrvCtrl, UINT phyAdrs, /* PHY address to access */ UINT phyReg /* PHY register to read */ ) { USHORT retVal=0; /* Write 34-bit preamble */ DC_MII_WRITE (pDrvCtrl->devAdrs, MII_PREAMBLE, 32); DC_MII_WRITE (pDrvCtrl->devAdrs, MII_PREAMBLE, 2); /* start of frame + op-code nibble */ DC_MII_WRITE (pDrvCtrl->devAdrs, MII_SOF | MII_RD, 4); /* device address */ DC_MII_WRITE (pDrvCtrl->devAdrs, phyAdrs, 5); DC_MII_WRITE (pDrvCtrl->devAdrs, phyReg, 5); /* turn around */ DC_MII_RTRISTATE (pDrvCtrl->devAdrs); /* read data */ DC_MII_READ (pDrvCtrl->devAdrs, &retVal, 16); return (retVal); }/********************************************************************************* dcMiiPhyWrite - write to a PHY device register via MII*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -