📄 ln97xend.c
字号:
if (resetTmp == 0x12345678) return (ERROR); /* enable "software style 3" so we can use 32-bit structs & bursting */ ln97xBcrWrite (pDrvCtrl, BCR(20), BCR20_SWSTYLE_PCNET_II); /* disable DMA burst xfer counter in CSR80 - AMD suggested for PCI */ ln97xCsrWrite (pDrvCtrl, CSR(4), CSR4_DMAPLUS | CSR4_TFC_MASK); /* enable burst read and write operatations - AMD suggested for PCI */ ln97xBcrWrite (pDrvCtrl, BCR(18), BCR18_BSBC_MASK); /* autoselect port tye - 10BT or AUI */ ln97xBcrWrite (pDrvCtrl, BCR(2), BCR2_AUTO_SELECT); /* read BCR */ resetTmp = ln97xBcrRead (pDrvCtrl, BCR(20)); return (OK); }/********************************************************************************* ln97xCsrWrite - select and write a CSR register** This routine selects a register to write, through the RAP register and* then writes the CSR value to the RDP register.** RETURNS: N/A*/LOCAL void ln97xCsrWrite ( LN_97X_DRV_CTRL * pDrvCtrl, /* device to be initialized */ int reg, /* CSR register to select */ UINT32 value /* CSR value to write */ ) { int level; level = intLock (); /* select CSR */ reg &= 0xff; SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg)); CACHE_PIPE_FLUSH (); value &=0xffff; SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRdp, PCI_SWAP (value)); CACHE_PIPE_FLUSH (); intUnlock (level); }/********************************************************************************* ln97xCsrRead - select and read a CSR register** This routine selects a register to read, through the RAP register and* then reads the CSR value from the RDP register.** RETURNS: N/A*/LOCAL UINT32 ln97xCsrRead ( LN_97X_DRV_CTRL * pDrvCtrl, /* device to be initialized */ int reg /* register to select */ ) { int level; UINT32 result; level = intLock (); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg)); CACHE_PIPE_FLUSH (); SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pRdp, result); intUnlock (level); return (PCI_SWAP (result) & 0x0000FFFF); }/********************************************************************************* ln97xBcrWrite - select and write a BCR register** This routine writes the bus configuration register. It first selects the* BCR register to write through the RAP register and then it writes the value* to the BDP register.** RETURNS: N/A*/LOCAL void ln97xBcrWrite ( LN_97X_DRV_CTRL * pDrvCtrl, /* device to be initialized */ int reg, /* BCR register to select */ UINT32 value /* BCR value to write */ ) { int level; reg &= 0xff; value &=0xffff; level = intLock (); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP(reg)); CACHE_PIPE_FLUSH (); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pBdp, PCI_SWAP(value)); intUnlock (level); }/********************************************************************************* ln97xBcrRead - select and read a BCR register** This routine reads the bus configuration register. It first selects the* BCR register to read through the RAP register and then it reads the value* from the BDP register.** RETURNS: N/A*/LOCAL UINT32 ln97xBcrRead ( LN_97X_DRV_CTRL * pDrvCtrl, /* driver control */ int reg /* register to select */ ) { int level; UINT32 result; level = intLock (); SYS_OUT_LONG (pDrvCtrl, pDrvCtrl->pRap, PCI_SWAP (reg)); CACHE_PIPE_FLUSH (); SYS_IN_LONG (pDrvCtrl, pDrvCtrl->pBdp, result); intUnlock (level); return (PCI_SWAP (result) & 0x0000FFFF); }/********************************************************************************* ln97xRestartSetup - setup memory descriptors and turn on chip** This routine initializes all the shared memory structures and turns on* the chip.** RETURNS OK/ERROR*/LOCAL STATUS ln97xRestartSetup ( LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { UINT16 stat; int rsize; /* recv ring length */ int tsize; /* xmit ring length */ LN_TMD * pTmd; /* reset the device */ ln97xReset (pDrvCtrl); /* Fetch and save the contents of the chip ID registers. We * need do this but once, and only when the STOP bit is set. */ if (pDrvCtrl->chipIdLo == 0) { pDrvCtrl->chipIdLo = ln97xCsrRead (pDrvCtrl, CSR(88)); pDrvCtrl->chipIdHi = ln97xCsrRead (pDrvCtrl, CSR(89)); } /* Enable LED programming for Am79c97[1|2]- SPR #30937 */ if ((pDrvCtrl->chipIdLo & CSR88_PART_MSK) > LN970_PARTID_LO) { stat = ln97xBcrRead (pDrvCtrl, BCR(2)); ln97xBcrWrite (pDrvCtrl, BCR(2), stat | BCR2_LEDPE); } /* Setup LED controls */ ln97xBcrWrite (pDrvCtrl, BCR(4), 0x0090); ln97xBcrWrite (pDrvCtrl, BCR(5), 0x0084); ln97xBcrWrite (pDrvCtrl, BCR(7), 0x0083); /* setup Rx buffer descriptors - align on 000 boundary */ rsize = pDrvCtrl->rringLen; /* * setup Tx buffer descriptors - * save unaligned location and align on 000 boundary */ pTmd = pDrvCtrl->pTring; tsize = pDrvCtrl->tringLen; /* setup the initialization block */ pDrvCtrl->ib = (LN_IB *)pDrvCtrl->pShMem; DRV_LOG (DRV_DEBUG_LOAD, "Init block @ 0x%X\n", (int)(pDrvCtrl->ib), 2, 3, 4, 5, 6); bcopy ((char *) END_HADDR(&pDrvCtrl->endObj), pDrvCtrl->ib->lnIBPadr, 6); CACHE_PIPE_FLUSH (); /* point to Rx ring */ LN_ADDR_TO_IB_RMD (pDrvCtrl->pRring, pDrvCtrl->ib, rsize); /* point to Tx ring */ LN_ADDR_TO_IB_TMD (pDrvCtrl->pTring, pDrvCtrl->ib, tsize); DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6); /* reconfigure the device */ ln97xConfig (pDrvCtrl); return (OK); }/********************************************************************************* ln97xRestart - restart the device after a fatal error** This routine takes care of all the messy details of a restart. The device* is reset and re-initialized. The driver state is re-synchronized.** RETURNS: N/A*/LOCAL void ln97xRestart ( LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { ln97xRestartSetup (pDrvCtrl); /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST); }/******************************************************************************** ln97xConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A*/LOCAL void ln97xConfig ( LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { UINT16 stat; void * pTemp; char * pCluster; LN_RMD * pRmd; LN_TMD * pTmd; int ix; int timeoutCount = 0; ULONG ibModeBits = PCI_SWAP(pDrvCtrl->ib->lnIBMode); /* make sure that the transmitter & receiver will be enabled */ ibModeBits &= ~(CSR15_DTX | CSR15_DRX); /* Set promiscuous mode if it's asked for. */ if (END_FLAGS_GET (&pDrvCtrl->endObj) & IFF_PROMISC) { DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode on!\n", 1, 2, 3, 4, 5, 6); /* chip will be in promiscuous mode */ ibModeBits |= CSR15_PROM; /* SPR 27827: CSR15, bit 15 */ pDrvCtrl->flags |= LS_PROMISCUOUS_FLAG; } else { DRV_LOG (DRV_DEBUG_LOAD, "Setting promiscuous mode off!\n", 1, 2, 3, 4, 5, 6); /* turn off CSR15, bit 15 */ ibModeBits &= ~CSR15_PROM; pDrvCtrl->flags &= ~LS_PROMISCUOUS_FLAG; } pDrvCtrl->ib->lnIBMode = PCI_SWAP(ibModeBits); CACHE_PIPE_FLUSH (); ln97xCsrWrite (pDrvCtrl, 0, CSR0_STOP); /* set the stop bit */ /* Set up address filter for multicasting. */ if (END_MULTI_LST_CNT (&pDrvCtrl->endObj) > 0) { ln97xAddrFilterSet (pDrvCtrl); } /* set the bus mode to little endian */ ln97xCsrWrite (pDrvCtrl, 3, pDrvCtrl->csr3B | CSR3_DXSUFLO); /* set the Bus Timeout to a long time */ /* This allows other stuff to hog the bus a bit more */ ln97xCsrWrite (pDrvCtrl, 100, BUS_LATENCY_COUNT); pRmd = pDrvCtrl->pRring; for (ix = 0; ix < pDrvCtrl->rringSize; ix++, pRmd++) { LN_CLEAN_RXD (pRmd); } pDrvCtrl->rmdIndex = 0; pTmd = pDrvCtrl->pTring; for (ix = 0; ix < pDrvCtrl->tringSize; ix++, pTmd++) { /* Are there send-clusters to clean up ? */ if (pTmd->tBufAddr != 0) { LN_TMD_TO_ADDR (pTmd, pCluster); pCluster -= pDrvCtrl->offset; netClFree (pDrvCtrl->endObj.pNetPool, pCluster); pTmd->tBufAddr = 0; } pTmd->tBufTmd2 = 0; /* clear buffer error status */ pTemp = (void *)(TMD1_CNST | TMD1_ENP | TMD1_STP); pTmd->tBufTmd1 = (UINT32) PCI_SWAP (pTemp); } pDrvCtrl->tmdIndex = 0; pDrvCtrl->tmdIndexC = 0; /* Point the device to the initialization block */ pTemp = LN_CACHE_VIRT_TO_PHYS (pDrvCtrl->ib); pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp)); ln97xCsrWrite (pDrvCtrl, CSR(2), (((ULONG)pTemp >> 16) & 0x0000ffff)); ln97xCsrWrite (pDrvCtrl, CSR(1), ((ULONG)pTemp & 0x0000ffff)); ln97xCsrWrite (pDrvCtrl, CSR(0), CSR0_INIT); /* init chip (read IB) */ /* hang until Initialization DONe, ERRor, or timeout */ while (((stat = ln97xCsrRead (pDrvCtrl, 0)) & (CSR0_IDON | CSR0_ERR)) == 0) { if (timeoutCount++ > 0x100) break; taskDelay (2 * timeoutCount); } DRV_LOG (DRV_DEBUG_LOAD, "Timeoutcount %d\n", timeoutCount, 2, 3, 4, 5, 6); /* log chip initialization failure */ if (((stat & CSR0_ERR) == CSR0_ERR) || (timeoutCount >= 0x10000)) { DRV_LOG (DRV_DEBUG_LOAD, "%s: Device initialization failed\n", (int)END_DEV_NAME(&pDrvCtrl->endObj), 0,0,0,0,0); return; } if (!(pDrvCtrl->flags & LS_POLLING)) ln97xCsrWrite (pDrvCtrl, 0, CSR0_IDON | CSR0_INEA | CSR0_STRT); else ln97xCsrWrite (pDrvCtrl, 0, CSR0_STRT); }/******************************************************************************** ln97xAddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the ln97xAddrAdd() routine) and sets the* device's filter correctly.** RETURNS: N/A*/LOCAL void ln97xAddrFilterSet ( LN_97X_DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { ETHER_MULTI * pCurr; LN_IB * pIb; UINT8 * pCp; UINT8 byte; UINT32 crc; int len; int c
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -