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

📄 if_dcfast.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	   dcCsrWrite (devAdrs, CSR12, INIT_CSR12);	   dcCsrWrite (devAdrs, CSR12, SYM_MODE);	      	   if ((pDrvCtrl->dcOpMode & DC_HBE_FLAG) &&		(pDrvCtrl->dcOpMode != NONE))		uTemp = (uTemp & ~CSR6_TTM) | CSR6_PS;	   else		uTemp = (uTemp & ~CSR6_TTM) | CSR6_PS | CSR6_HBD ;	   uTemp = uTemp | (((pDrvCtrl->dcOpMode & DC_SCRAMBLER_FLAG) &&		  (pDrvCtrl->dcOpMode != NONE)) ? CSR6_SCR : 0) |		  (((pDrvCtrl->dcOpMode & DC_PCS_FLAG) &&		  (pDrvCtrl->dcOpMode != NONE)) ? CSR6_PCS : 0);	}	dcCsrWrite (devAdrs, CSR6, uTemp);    }/* RCP: End of DEC21140 Code Addition */    /* clear the status register */    dcCsrWrite (devAdrs, CSR5, 0xffffffff);    /* set the operating mode to start Xmitter only *//* RCP: Modify this call to accomodate DEC21140 , add the Setting of Bit 25*/    dcCsrWrite (devAdrs, CSR6, 	       (dcCsrRead (devAdrs, CSR6) |  CSR6_ST | CSR6_BIT25));/* RCP: Added Loopback modes */    if ((pDrvCtrl->dcOpMode & DC_ILOOPB_FLAG) &&	(pDrvCtrl->dcOpMode != NONE))/* RCP: Internal loopback selected */    	dcCsrWrite (devAdrs, CSR6, (dcCsrRead(devAdrs, CSR6) | CSR6_OM_ILB));    else	    	if ((pDrvCtrl->dcOpMode & DC_ELOOPB_FLAG) &&	    (pDrvCtrl->dcOpMode != NONE))/* RCP: External loopback selected */	   dcCsrWrite (devAdrs, CSR6, (dcCsrRead(devAdrs, CSR6) | CSR6_OM_ELB));    /* Xmit a Filter Setup Frame */    dcFltrFrmXmit (pDrvCtrl, (char *) pDrvCtrl->idr.ac_enaddr, 1);    /* set operating mode any additional operational mode set by user */    dcCsrWrite (devAdrs, CSR6, (dcCsrRead(devAdrs, CSR6) |                                CSR6_SR                   | /* start receiver */   			       (((pDrvCtrl->dcOpMode & DC_MULTICAST_FLAG) &&				 (pDrvCtrl->dcOpMode != NONE)) ? CSR6_PM: 0) |   			       (((pDrvCtrl->dcOpMode & DC_PROMISCUOUS_FLAG) &&				 (pDrvCtrl->dcOpMode != NONE)) ? CSR6_PR: 0)			      ));     /* set up the interrupts *//* RCP: Modified to accomodate DEC21140 */    if (!DEC21140(pDrvCtrl->dcOpMode))    	dcCsrWrite (devAdrs, CSR7, (			       CSR7_NIM |	/* normal interrupt mask */			       CSR7_RIM |	/* rcv  interrupt mask */			       CSR7_TIM |	/* xmit interrupt mask */			       CSR7_TUM |	/* xmit buff unavailble mask */			       CSR7_AIM |	/* abnormal interrupt mask */			       CSR7_SEM |	/* system error mask */			       CSR7_LFM |	/* link fail mask */			       CSR7_RUM		/* rcv buff unavailable mask */			       ));/* RCP: Removed CSR7_LFM for DEC21140 */    else    	dcCsrWrite (devAdrs, CSR7, (			       CSR7_NIM |	/* normal interrupt mask */			       CSR7_RIM |	/* rcv  interrupt mask */			       CSR7_TIM |	/* xmit interrupt mask */			       CSR7_TUM |	/* xmit buff unavailble mask */			       CSR7_AIM |	/* abnormal interrupt mask */			       CSR7_SEM |	/* system error mask */			       CSR7_RUM		/* rcv buff unavailable mask */			       ));    sysLanIntEnable (ilevel);                   /* enable LANCE interrupts */    pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);    /* Set our flag */    pDrvCtrl->attached = TRUE;    return (OK);    }/********************************************************************************* dcReset - reset the interface** Mark interface as inactive & reset the chip*/LOCAL void dcReset    (    int unit    )    {    DRV_CTRL *pDrvCtrl = & drvCtrl [unit];    pDrvCtrl->idr.ac_if.if_flags = 0;    dcChipReset (pDrvCtrl);                           /* reset LANCE */    }/********************************************************************************* dcInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL void dcInt    (    DRV_CTRL *	pDrvCtrl	/* pointer to device control struct */    )    {    DC_TDE *	tmd;		/* pointer to Xmit ring descriptor */    ULONG	stat;		/* status register */    ULONG	devAdrs;	/* device address */    devAdrs = pDrvCtrl->devAdrs;    /* Read the device status register */    stat = dcCsrRead(devAdrs, CSR5);    /* clear the interrupts */    dcCsrWrite(devAdrs, CSR5, stat);    /* If false interrupt, return. */    if ( ! (stat & (CSR5_NIS | CSR5_AIS)) )        return;    /* Check for system error */    if (stat & CSR5_SE)        {        ++pDrvCtrl->idr.ac_if.if_ierrors;        /* restart chip on fatal error */	pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);	(void) netJobAdd (			 (FUNCPTR)dcRestart,			 pDrvCtrl->idr.ac_if.if_unit,			 0,0,0,0			 );	return;        }    /* Have netTask handle any input packets */    if ((stat & CSR5_RI) && (!(stat & CSR5_RPS)))        {	(void) netJobAdd (			 (FUNCPTR)dcHandleRecvInt,			 (int)pDrvCtrl,			 0,0,0,0			 );	/* disable the Rx intr, re-enable in dcHandleRecvInt() */	dcCsrWrite(devAdrs, CSR7, (stat & ~CSR7_RIM));        }    /*     * Did LANCE update any of the TMD's?     * If not then don't bother continuing with transmitter stuff     */    if (!(stat & CSR5_TI))        return;    while (pDrvCtrl->txDiIndex != pDrvCtrl->txIndex)        {        /* disposal has not caught up */        tmd = pDrvCtrl->txRing + pDrvCtrl->txDiIndex;        /* if the buffer is still owned by LANCE, don't touch it */        DC_CACHE_INVALIDATE (tmd, TMD_SIZ);        if (tmd->tDesc0 & PCISWAP(TDESC0_OWN))            break;        /* now bump the tmd disposal index pointer around the ring */        pDrvCtrl->txDiIndex = (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->dcNumTds;        /*         * TDESC0.ES is an "OR" of LC, NC, UF, EC.         * here for error conditions.         */        if (tmd->tDesc0 & PCISWAP(TDESC0_ES))            {            pDrvCtrl->idr.ac_if.if_oerrors++;     /* output error */            pDrvCtrl->idr.ac_if.if_opackets--;            /* If error was due to excess collisions, bump the collision             * counter.             */            if (tmd->tDesc0 & PCISWAP(TDESC0_EC))                pDrvCtrl->idr.ac_if.if_collisions += 16;	    /* bump the collision counter if late collision */            if (tmd->tDesc0 & PCISWAP(TDESC0_LC))                pDrvCtrl->idr.ac_if.if_collisions++;            /* check for no carrier */            if (tmd->tDesc0 & PCISWAP(TDESC0_NC | TDESC0_LO | TDESC0_LF))                logMsg ("dc%d: no carrier\n",                    pDrvCtrl->idr.ac_if.if_unit, 0,0,0,0,0);            /* Restart chip on fatal errors.             * The following code handles the situation where the transmitter             * shuts down due to an underflow error.  This is a situation that             * will occur if the DMA cannot keep up with the transmitter.             * It will occur if the LANCE is being held off from DMA access             * for too long or due to significant memory latency.  DRAM             * refresh or slow memory could influence this.  Many             * implementation use a dedicated LANCE buffer.  This can be             * static RAM to eliminate refresh conflicts; or dual-port RAM             * so that the LANCE can have free run of this memory during its             * DMA transfers.             */            if (tmd->tDesc0 & PCISWAP(TDESC0_UF))                {                pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);                (void) netJobAdd (                                 (FUNCPTR)dcRestart,                                 pDrvCtrl->idr.ac_if.if_unit,                                 0,0,0,0                                 );                return;                }            }	tmd->tDesc0 = 0;	/* clear all error & stat stuff */        }    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    }/********************************************************************************* dcHandleRecvInt - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.*/LOCAL void dcHandleRecvInt    (    DRV_CTRL *	pDrvCtrl	/* pointer to device control struct */    )    {    DC_RDE *	rmd;		/* pointer to Rx ring descriptor */    while ((rmd = dcGetFullRMD (pDrvCtrl)) != NULL)    	dcRecv (pDrvCtrl, rmd);    /* re-enable the Rx interrupt */    dcCsrWrite (pDrvCtrl->devAdrs, CSR7, (dcCsrRead (pDrvCtrl->devAdrs, CSR7) |					  CSR7_RIM));    }/********************************************************************************* dcGetFullRMD - get next received message RMD** Returns ptr to next Rx desc to process, or NULL if none ready.*/LOCAL DC_RDE * dcGetFullRMD    (    DRV_CTRL *	pDrvCtrl	/* pointer to device control struct */    )    {    DC_RDE *	rmd;		/* pointer to Rx ring descriptor */    /* Refuse to do anything if flags are down */    if  (        (pDrvCtrl->idr.ac_if.if_flags & (IFF_UP | IFF_RUNNING) ) !=        (IFF_UP | IFF_RUNNING)        )        return ((DC_RDE *) NULL);    rmd = pDrvCtrl->rxRing + pDrvCtrl->rxIndex;       /* form ptr to Rx desc */    DC_CACHE_INVALIDATE (rmd, RMD_SIZ);    if ((rmd->rDesc0 & PCISWAP(RDESC0_OWN)) == 0)        return (rmd);    else        return ((DC_RDE *) NULL);    }/********************************************************************************* dcRecv - process the next incoming packet**/LOCAL STATUS dcRecv    (    DRV_CTRL *	pDrvCtrl,	/* pointer to device control struct */    DC_RDE *	rmd		/* pointer to Rx ring descriptor */    )    {    ENET_HDR *	pEnetHdr;	/* pointer to ethernet header */    MBUF *	pMbuf = NULL;	/* pointer to mbuf */    u_long	pPhys;    UCHAR *	pData;		/* pointer to data */    int		len;		/* length */    USHORT	ether_type;	/* ether packet type */    /* Packet must be checked for errors. */    if  (rmd->rDesc0 & PCISWAP(RDESC0_ES)) /* If error flag */        {	/* error can occur on overflow, crc error, collision, 	 * frame too long, runt frame or length error	 */        ++pDrvCtrl->idr.ac_if.if_ierrors;       /* bump error stat */        goto cleanRXD;                          /* skip to clean up */        }    ++pDrvCtrl->idr.ac_if.if_ipackets;		/* bump statistic */    len = RDESC0_FL_GET(PCISWAP(rmd->rDesc0));	/* frame length */    len -= 4; 	/* Frame length includes CRC in it so subtract it */    /* Get pointer to packet */    pEnetHdr = DC_CACHE_PHYS_TO_VIRT(PCI_TO_MEM_PHYS(PCISWAP(rmd->rDesc2)));    DC_CACHE_INVALIDATE (pEnetHdr, len);   /* make the packet data coherent */    /* call input hook if any */    if ((etherInputHookRtn == NULL) || ((*etherInputHookRtn)       (& pDrvCtrl->idr.ac_if, (char *) pEnetHdr, len)) == 0)        {        /* Adjust length to size of data only */        len -= SIZEOF_ETHERHEADER;        /* Get pointer to packet data */        pData = ((u_char *) pEnetHdr) + SIZEOF_ETHERHEADER;        ether_type = ntohs ( pEnetHdr->type );        /* OK to loan out buffer ? -> build an mbuf cluster */    	if ((pDrvCtrl->nLoanRx > 0) && (USE_CLUSTER (len))	    &&	    ((pMbuf = build_cluster (pData, len, & pDrvCtrl->idr, MC_LANCE,	     pDrvCtrl->pRefCnt [(pDrvCtrl->nLoanRx - 1)], dcLoanFree,	     (int) pDrvCtrl, (int) pEnetHdr,	     (int) pDrvCtrl->pRefCnt [(pDrvCtrl->nLoanRx - 1)])) != NULL))	    {            pPhys = (u_long) DC_CACHE_VIRT_TO_PHYS(MEM_TO_PCI_PHYS(		    (pDrvCtrl->lPool[--pDrvCtrl->nLoanRx])));	    rmd->rDesc2 = PCISWAP(pPhys);	    }        else            {            if ((pMbuf = bcopy_to_mbufs (pData, len, 0, & pDrvCtrl->idr.ac_if,                pDrvCtrl->memWidth)) == NULL)		{                ++pDrvCtrl->idr.ac_if.if_ierrors;	/* bump error stat */                goto cleanRXD;		}            }        /* send on up... */        do_protocol_with_type (ether_type, pMbuf, & pDrvCtrl->idr, len);

⌨️ 快捷键说明

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