⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 if_dcfast.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* RCP: This is a redundant increment of incoming packets, removed from original driver *//*        ++pDrvCtrl->idr.ac_if.if_ipackets;*/	/* bump statistic */        }    /* Done with descriptor, clean up and give it to the device. */    cleanRXD:    /* clear status bits and give ownership to device */    rmd->rDesc0 = PCISWAP(RDESC0_OWN);    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    /* Advance our management index */    pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->dcNumRds;    return (OK);    }/********************************************************************************* dcOutput - the driver output routine**/LOCAL int dcOutput    (    IDR  *	pIDR,		/* pointer to interface data record */    MBUF *	pMbuf,		/* pointer to mbuf */    SOCK *	pDest		/* pointer to destination sock */    )    {    char 	destEnetAddr [6];	/* space for enet addr */    USHORT	packetType;		/* type field for the packet */    DRV_CTRL *	pDrvCtrl;		/* pointer to device control struct */    DC_TDE *	tmd;			/* pointer to Tx ring descriptor */    char *	buf;			/* pointer to buffer */    int		len;			/* length */    /* Check ifnet flags. Return error if incorrect. */    if  (        (pIDR->ac_if.if_flags & (IFF_UP | IFF_RUNNING)) !=        (IFF_UP | IFF_RUNNING)        )        return (ENETDOWN);    /* Attempt to convert socket addr into enet addr and packet type.     * Note that if ARP resolution of the address is required, the ARP     * module will call our routine again to transmit the ARP request     * packet.  This means we may actually call ourselves recursively!     */    if (convertDestAddr (pIDR,pDest, destEnetAddr, &packetType, pMbuf) == FALSE)        return (OK);    /* I KNOW returning OK is stupid, but it is correct */    /* Get driver control pointer */    pDrvCtrl = & drvCtrl [pIDR->ac_if.if_unit];    /* Obtain exclusive access to transmitter.  This is necessary because     * certain events can cause netTask to run a job that attempts to transmit     * a packet.  We can only allow one task here at a time.     */    semTake (pDrvCtrl->TxSem, WAIT_FOREVER);    /* See if next TXD is available */    tmd = pDrvCtrl->txRing + pDrvCtrl->txIndex;    DC_CACHE_INVALIDATE (tmd, TMD_SIZ);    if  (        ((tmd->tDesc0 & PCISWAP(TDESC0_OWN)) != 0) ||        (        ((pDrvCtrl->txIndex + 1) % pDrvCtrl->dcNumTds) == pDrvCtrl->txDiIndex	)        )        {        m_freem (pMbuf);            /* Discard data */        goto outputDone;        }    /* Get pointer to transmit buffer */    buf = (char *)DC_CACHE_PHYS_TO_VIRT(PCI_TO_MEM_PHYS(PCISWAP(tmd->tDesc2)));    /* Copy packet from MBUFs to our transmit buffer.  MBUFs are     * transparently freed.     */    bcopy_from_mbufs ((buf + SIZEOF_ETHERHEADER), pMbuf, len,		      pDrvCtrl->memWidth);    /* Fill in the Ethernet header */    bcopy (destEnetAddr, buf, 6);    bcopy ( (char *) pIDR->ac_enaddr, (buf + 6), 6);    ((ENET_HDR *)buf)->type = packetType;    tmd->tDesc0 = 0;				/* clear buffer error status */    tmd->tDesc1 &= PCISWAP(~TDESC1_TBS1_MSK);    tmd->tDesc1 |= PCISWAP(TDESC1_TBS1_PUT(max (ETHERSMALL, 						(len + SIZEOF_ETHERHEADER))));    tmd->tDesc0 = PCISWAP(TDESC0_OWN); 		/* give ownership to device */    CACHE_PIPE_FLUSH ();			/* Flush the write pipe */    /* Advance our management index */    pDrvCtrl->txIndex = (pDrvCtrl->txIndex + 1) % pDrvCtrl->dcNumTds;        if (dcKickStartTx)    	dcCsrWrite(pDrvCtrl->devAdrs, CSR1, CSR1_TPD);	/* xmit poll demand */    /* Bump the statistic counter. */    pIDR->ac_if.if_opackets++;    outputDone:    /* Release exclusive access. */    semGive (pDrvCtrl->TxSem);    return (OK);    }/********************************************************************************* 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 */	    dcCsrWrite (pDrvCtrl->devAdrs, CSR6, 			(dcCsrRead(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 */	    dcCsrWrite(devAdrs, CSR6, 0);		/* stop rcvr & xmitter */    dcCsrWrite(devAdrs, CSR7, 0);		/* mask interrupts */        dcCsrWrite(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 */    dcCsrWrite (devAdrs, CSR0, dcCSR0Bmr | CSR0_BAR);    for (ix = 0; ix < 0x1000; ix++)		/* loop for some cycles */	;    return (OK);    }/********************************************************************************* dcAuiTpInit - 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 dcAuiTpInit    (    ULONG       devAdrs        /* device base I/O address */    )    {    /* reset the SIA registers */    dcCsrWrite (devAdrs, CSR13, 0);    dcCsrWrite (devAdrs, CSR14, 0);    dcCsrWrite (devAdrs, CSR15, 0);    /* configure for the 10BASE-T */    dcCsrWrite (devAdrs, CSR13, CSR13_CAC_CSR);	/* 10BT auto configuration */    taskDelay (sysClkRateGet() * 2);		/* 2 second delay */    if (dcCsrRead (devAdrs, CSR12) & (CSR12_LKF | CSR12_NCR))	{	/* 10BASE-T not connected initialize interface for AUI */	dcCsrWrite (devAdrs, CSR13, 0);		/* reset SIA registers */	dcCsrWrite (devAdrs, CSR14, 0);	dcCsrWrite (devAdrs, CSR15, 0);	/* AUI auto configuration */	dcCsrWrite (devAdrs, CSR13, (CSR13_AUI_TP | CSR13_CAC_CSR));	}    }/********************************************************************************* dcCsrWrite - select and write a CSR register**/LOCAL void dcCsrWrite    (    ULONG 	devAdrs,		/* device address base */    int 	reg,			/* register to select */    ULONG 	value			/* value to write */    )    {    ULONG *	csrReg;    csrReg = (ULONG *)(devAdrs + (reg * DECPCI_REG_OFFSET));    /* write val to CSR */    *(csrReg) = PCISWAP(value);    }/********************************************************************************* dcCsrRead - select and read a CSR register**/LOCAL ULONG dcCsrRead    (    ULONG	devAdrs,		/* device address base */    int		reg			/* register to select */    )    {    ULONG *	csrReg;			/* csr register */    ULONG	csrData;		/* data in csr register */    csrReg = (ULONG *)(devAdrs + (reg * DECPCI_REG_OFFSET));    csrData = *csrReg;    /* get contents of CSR */    return ( PCISWAP(csrData));    }/********************************************************************************* dcRestart - 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.*/LOCAL void dcRestart    (    int 	unit		/* unit to restart */    )    {    ULONG	status;		/* status register */	    int		ix;		/* index variable */    DC_RDE *	rmd;		/* pointer to receive descriptor */    DC_TDE *	tmd;		/* pointer to Xmit descriptor */    DRV_CTRL *	pDrvCtrl = & drvCtrl [unit];    rmd = pDrvCtrl->rxRing;      /* receive ring */    tmd = pDrvCtrl->txRing;      /* transmit ring */    pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING );    fprintf (stderr, "Fatal Error. DEC Ethernet Chip Restarted\n");    status = dcCsrRead(pDrvCtrl->devAdrs, CSR6);    dcCsrWrite (pDrvCtrl->devAdrs, CSR6, 0);	/* reset mode register */    for (ix = 0; ix < pDrvCtrl->dcNumRds; ix++, rmd++)        {	/* buffer size */	rmd->rDesc1 = PCISWAP(RDESC1_RBS1_VAL(DC_BUFSIZ) | 			      RDESC1_RBS2_VAL(0));	if (ix == (pDrvCtrl->dcNumRds - 1)) /* if its is last one */	rmd->rDesc1 |= PCISWAP(RDESC1_RER); /* end of receive ring */	rmd->rDesc0 = PCISWAP(RDESC0_OWN); /* give ownership to lance */        }    for (ix = 0; ix < pDrvCtrl->dcNumTds; ix++, tmd++)        {	tmd->tDesc1 = PCISWAP((TDESC1_TBS1_PUT(0) |			       TDESC1_TBS2_PUT(0) |			       TDESC1_IC	  | 	/* intrpt on xmit */			       TDESC1_LS          |	/* last segment */			       TDESC1_FS));		/* first segment */	if (ix == (pDrvCtrl->dcNumTds - 1))	/* if its is last one */	    tmd->tDesc1 |= PCISWAP(TDESC1_TER);	/* end of Xmit ring */	tmd->tDesc0 = 0 ;			/* clear status */        }    /* clear the status register */    dcCsrWrite (pDrvCtrl->devAdrs, CSR5, 0xffffffff);    dcCsrWrite (pDrvCtrl->devAdrs, CSR6, status);	/* restore mode */    pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);    }/********************************************************************************* dcLoanFree - return the given buffer to loaner pool** This routine returns <pRxBuf> to the pool of available loaner buffers.* It also returns <pRef> to the pool of available loaner reference counters,* then zeroes the reference count.** RETURNS: N/A*/ LOCAL void dcLoanFree    (    DRV_CTRL *	pDrvCtrl,	/* pointer to device control structure */    char *	pRxBuf,		/* pointer to receive buffer to free */    UINT8 *	pRef		/* pointer to reference count */    )    {    /* return loaned buffer to pool */     pDrvCtrl->lPool[pDrvCtrl->nLoanRx] = pRxBuf;     /* return loaned reference count to pool */     pDrvCtrl->pRefCnt[pDrvCtrl->nLoanRx++] = pRef;    /* reset reference count - should have been done from above, but... */     *pRef = 0;    }/********************************************************************************* dcEnetAddrGet - gets the ethernet address from the ROM register.** This routine gets the ethernet address from the ROM register.* This routine returns the ethernet address into the pointer supplied to it.* * RETURNS: OK/ERROR*/LOCAL STATUS dcEnetAddrGet    (    ULONG	devAdrs,	/* device base I/O address */    char * 	enetAdrs,	/* pointer to the ethernet address */     int		len		/* number of bytes to read */    )    {    FAST ULONG	csr9Value;		/* register to hold CSR9 */    int		ix;			/* index register */    BOOL	eRomReady = FALSE;	/* ethernet ROM register state */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -