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

📄 if_es.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    esChipReset (ls);				/* reset ESTAR */    (void) intConnect (INUM_TO_IVEC (ivec), esInt, (int)ls);#ifdef BSD43_DRIVER    ether_attach (ifp, unit, "es", (FUNCPTR) esInit, (FUNCPTR) esIoctl,		 (FUNCPTR) esOutput, (FUNCPTR) esReset);#else    ether_attach (                 &ls->ls_ac.ac_if,                  unit,                  "es",                  (FUNCPTR) esInit,                  (FUNCPTR) esIoctl,		 (FUNCPTR) ether_output,                 (FUNCPTR) esReset                 );    ifp->if_start = (FUNCPTR)esStartOutput;#endif    sysIntEnable (ilevel);    esInit (unit);    return (OK);    }/********************************************************************************* esReset - reset the interface** Mark interface as inactive & reset the chip*/LOCAL VOID esReset    (    int unit    )    {    FAST struct ls_softc  *ls = ls_softc [unit];    ls->ls_if.if_flags &= ~IFF_RUNNING;    esChipReset (ls);				/* reset ESTAR */    }/********************************************************************************* esInit - initializes EtherStar connection** Initialization of interface; clear recorded pending operations.* Called at boot time (with interrupts disabled?),* and at ifconfig time via esIoctl, with interrupts disabled.*/LOCAL int esInit    (    int unit    )    {    FAST struct ls_softc  *ls = ls_softc [unit];    FAST struct ifnet	  *ifp = &ls->ls_if;    ifp->if_flags &= ~(IFF_UP | IFF_RUNNING | IFF_PROMISC);    esChipReset (ls);				/* disable chip during init */    esConfig (ls);				/* reset all ring structures */    ifp->if_flags |= (IFF_UP | IFF_RUNNING);    if (ls->ls_flags & LS_PROMISCUOUS_FLAG)	ifp->if_flags |= (IFF_PROMISC);    esChipInit (ls);			/* on return ESTAR is running */#ifdef BSD43_DRIVER    esStartOutput (ls->ls_if.if_unit);	/* tell chip about any pending output */#else    esStartOutput (ls);#endif    return (0);    }/********************************************************************************* esConfig - fill in initialization block with mode information.** Fill in all fields in the Initialization Block with relevant values.* In addition, fill in all fields in Transmit Message Descriptor ring* and Receive Message Descriptor ring.*/LOCAL VOID esConfig    (    FAST struct ls_softc  *ls    )    {    FAST es_rmd	  *rmd;    FAST es_tmd	  *tmd;    FAST char	  *buf;    FAST es_ib	  *ib;    int		   i;    rmd = ls->ls_rring;			/* receive message descriptor ring */    rmd = (es_rmd *)(((int)rmd + 7) & ~7);	/* low 3 bits must be 000 */    ls->ls_rring = rmd;				/* fix softc as well */    buf = ls->rmd_ring.r_bufs;    for (i = 0; i < ls->ls_rsize; i++)        {	rmd->rbuf_ladr = (u_short)((int)buf); /* bits 15:00 of buffer address */	rmd->rbuf_rmd1 = (u_short)((int)buf >> 16) & 0xff;					/* bits 23:16 of buffer address */	rmd->rbuf_bcnt = -(ls->bufSize);/* neg of buffer byte count */	rmd->rbuf_mcnt = 0;		/* no message byte count yet */	rmd->es_rmd1.es_rmd1b |= esrmd1_OWN;	/* buffer now owned by ESTAR */	rmd++;				/* step to next message descriptor */	buf += (ls->bufSize);		/* step to start of next buffer */	ls->loanRefCnt [i] = (u_char) 0;	}    ls->ls_rindex = 0;			/* ESTAR will use at start of ring */    tmd = ls->ls_tring;			/* transmit message descriptor ring */    tmd = (es_tmd *)(((int)tmd + 7) & ~7);	/* low 3 bits must be 000 */    ls->ls_tring = tmd;			/* fix softc as well */    buf = ls->tmd_ring.t_bufs;    for (i = 0; i < ls->ls_tsize; i++)        {	tmd->tbuf_ladr = (u_short)((int)buf); /* bits 15:00 of buffer address */	tmd->tbuf_tmd1 = (u_short)((int)buf >> 16) & 0xff;					/* bits 23:16 of buffer address */	tmd->tbuf_bcnt = 0;		/* no message byte count yet */	tmd->tbuf_tmd3 = 0;		/* no error status yet */	tmd->es_tmd1.es_tmd1b |= estmd1_ENP;	/* buffer is end of packet */	tmd->es_tmd1.es_tmd1b |= estmd1_STP;	/* buffer is start of packet */	tmd++;				/* step to next message descriptor */	buf += (ls->bufSize);		/* step to start of next buffer */	}    ls->ls_tindex = 0;			/* ESTAR */    ls->ls_dindex = 0;			/* buffer disposal will lag tindex */    ib = ls->ib;    if (ls->ls_flags & LS_PROMISCUOUS_FLAG)        ib->esIBMode = 0x8000;	/* chip will be in promiscuous receive mode */    else        ib->esIBMode = 0;	/* chip will be in normal receive mode */    swab ((char *)ls->ls_enaddr, ib->esIBPadr, 6);    ib->esIBRdraLow = (u_short)((int)ls->ls_rring);    ib->esIBRdraHigh = (u_short)(((int)ls->ls_rring >> 16) & 0xff)      			 | (ls->ls_rpo2 << 13);    ib->esIBTdraLow = (u_short)((int)ls->ls_tring);    ib->esIBTdraHigh = (u_short)(((int)ls->ls_tring >> 16) & 0xff)      			 | (ls->ls_tpo2 << 13);    }/********************************************************************************* esInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL VOID esInt    (    FAST struct ls_softc  *ls    )    {    FAST ES_DEVICE	*dv;    FAST es_rmd		*rmd;    FAST es_tmd		*tmd;    FAST int 		*pDindex;    FAST int		*pTindex;    FAST int		*pTsize;    FAST es_tmd		*pTring;    FAST u_short	w, temp;    FAST int		i;    FAST char		*buf;        dv = ls->devAdrs;    *dlan.dlcr1 = 0x00;	/* clear transmit masks */    *dlan.dlcr3 = 0x00;	/* clear receive masks */    /* read any receive packets */    while (!(*dlan.dlcr5 & 0x40))    {	*dlan.dlcr2 = 0x80;	/* clear pkt_rdy */	rmd = ls->ls_rring + recIndex;	recIndex = (recIndex + 1) & (ls->ls_rsize - 1);	rmd->es_rmd1.es_rmd1b &= ~esrmd1_OWN;  /* rbuf_own = 0; */	buf = (char *) ((u_int) ls->rmd_ring.r_bufs +	      (u_int) ((((u_int)rmd - (u_int)ls->ls_rring) / sizeof(es_rmd))	      * ls->bufSize));	temp = esReadBmpr0 (dv);	/* read status */	if (newdlan == TRUE) {		temp = esReadBmpr0 (dv);	/* and count */		i = (temp>>8 | temp<<8) & 0xffff;		rmd->rbuf_mcnt = i;	/* save count */		rmd->es_rmd1.es_rmd1b |= esrmd1_STP;  /* rbuf_stp = 1; */		rmd->es_rmd1.es_rmd1b |= esrmd1_ENP;  /* rbuf_enp = 1; */		while (i > 0)		{		    w = esReadBmpr0 (dv);		    *(u_short *)buf = w;		    buf +=2;		    i -= 2;		/* count down */		}	}	else {		i = esReadBmpr0 (dv);	/* and count */		rmd->rbuf_mcnt = i;	/* save count */		rmd->es_rmd1.es_rmd1b |= esrmd1_STP;  /* rbuf_stp = 1; */		rmd->es_rmd1.es_rmd1b |= esrmd1_ENP;  /* rbuf_enp = 1; */		while (i > 0)		{		    w = esReadBmpr0 (dv);		    *(u_short *)buf = (w>>8 | w<<8);		    buf +=2;		    i -= 2;		/* count down */		}	}    }    if (*dlan.dlcr2 & es_bus_rd_err)	*dlan.dlcr2 = es_bus_rd_err;    if ((rmd = esGetFullRMD (ls)) != NULL)	{	if ((ls->ls_flags & LS_RCV_HANDLING_FLAG) == 0)	    {	    ls->ls_flags |= LS_RCV_HANDLING_FLAG;	    (void) netJobAdd ((FUNCPTR) esHandleRecvInt, (int) ls, 0, 0, 0, 0);	    }	}    /* Did etherstar update any of the TMD's? */    if (!(*dlan.dlcr0 & ES_TMT_MASK))	{	*dlan.dlcr3 = ES_RCV_MASK;	return;	}    *dlan.dlcr1 = 0x00;		/* clear transmit mask */    *dlan.dlcr0 = 0x0f;		/* reset error conditions */    *dlan.dlcr2 = 0x4f;		/* reset packet ready */    pDindex = &ls->ls_dindex;    pTindex = &ls->ls_tindex;    pTsize  = &ls->ls_tsize;    pTring  = ls->ls_tring;    while (*pDindex != *pTindex)        {	/* disposal has not caught up */	tmd = pTring + *pDindex;	/* if the buffer is still owned by ESTAR, don't touch it */	if (tmd->tbuf_tmd1 & TMD_OWN)	    {	    break;	    }	/*	 * tbuf_err (TMD1.ERR) is an "OR" of LCOL, LCAR, UFLO or RTRY.	 * Note that BUFF is not indicated in TMD1.ERR.	 * We should therefore check both tbuf_err and tbuf_buff	 * here for error conditions.	 */	if ((tmd->tbuf_tmd1 & TMD_ERR) || (tmd->tbuf_tmd3 & TMD_BUFF))	    {	    ls->ls_if.if_oerrors++;	/* output error */	    ls->ls_if.if_opackets--;	    /* check for no carrier */	    if (tmd->tbuf_tmd3 & TMD_LCAR)		logMsg ("es%d: no carrier\n", ls->ls_if.if_unit, 0, 0, 0, 0, 0);	    /* every esLogCount errors show other interesting bits of tmd3 */	    if ((tmd->tbuf_tmd3 & 0xfc00) && esLogCount &&		(ls->ls_if.if_oerrors % esLogCount) == 0)		logMsg ("es%d: xmit error, status(tmd3)=0x%x, err count=%d\n",			ls->ls_if.if_unit, tmd->tbuf_tmd3 & 0xfc00,			ls->ls_if.if_oerrors, 0, 0, 0);	    /* restart chip on fatal errors */	    if ((tmd->tbuf_tmd3 & TMD_BUFF) || (tmd->tbuf_tmd3 & TMD_UFLO))		{		(void) netJobAdd ((FUNCPTR) esInit,				  ls->ls_if.if_unit, 0, 0, 0, 0);		break;		}	    }	tmd->tbuf_tmd1 &= 0xff;		/* clear high byte */	tmd->tbuf_tmd3 = 0;		/* clear all error & stat stuff */	/* now bump the tmd disposal index pointer around the ring */	*pDindex = (*pDindex + 1) & (*pTsize - 1);	}    if (ls->ls_if.if_snd.ifq_head != NULL &&	(ls->ls_flags & LS_START_OUTPUT_FLAG) == 0)	{	ls->ls_flags |= LS_START_OUTPUT_FLAG;#ifdef BSD43_DRIVER        (void) netJobAdd ( (FUNCPTR) esStartOutput,                           ls->ls_if.if_unit, 0, 0, 0, 0);#else        (void) netJobAdd ( (FUNCPTR) esStartOutput, (int)ls, 0, 0, 0, 0);#endif	}    *dlan.dlcr3 = ES_RCV_MASK;    }/********************************************************************************* esReadBmpr0 - prevents optimizer from stripping required accesses to device** prevents optimizer from stripping required accesses to the device*/LOCAL u_short esReadBmpr0    (    FAST ES_DEVICE *dv    )    {    return ( dv->bmpr0);    }/********************************************************************************* esHandleRecvInt - 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 esHandleRecvInt    (    FAST struct ls_softc *ls    )    {    FAST es_rmd		*rmd;    FAST int 		oldIndex;    do	{	ls->ls_flags |= LS_RCV_HANDLING_FLAG;	while ((rmd = esGetFullRMD (ls)) != NULL)	    {					    /* RMD available */	    oldIndex = ls->ls_rindex;	    if (esRecv (ls, rmd) == OK)		for (; oldIndex != ls->ls_rindex; 		     oldIndex = (oldIndex + 1) & (ls->ls_rsize - 1))		    {		    rmd = ls->ls_rring + oldIndex;		    ES_RMD_GIVE_TO_ESTAR (rmd);		    }	    else	        break;	    }		/*	 * There is a RACE right here.  The ISR could add a receive packet	 * and check the boolean below, and decide to exit.  Thus the	 * packet could be dropped if we don't double check before we	 * return.	 */	ls->ls_flags &= ~LS_RCV_HANDLING_FLAG;	}  while (esGetFullRMD (ls) != NULL);	/* this double check solves the RACE */	{	}    *dlan.dlcr3 = ES_RCV_MASK;    }/********************************************************************************* esRecv - process Ethernet receive completion** Process Ethernet receive completion:*	If input error just drop packet.*	Otherwise purge input buffered data path and examine *	packet to determine type.  If can't determine length*	from type, then have to drop packet.  Otherwise decapsulate*	packet based on type and pass to type-specific higher-level*	input routine.** RETURNS: ERROR if RMD shouldn't be returned back to ESTAR yet.*          Otherwise, returns OK to return the RMD back to ESTAR.*/LOCAL STATUS esRecv    (    struct ls_softc	   *ls,    FAST es_rmd		   *rmd    )    {    FAST struct ether_header	*eh;    FAST struct mbuf		*m;    FAST u_char			*pData;    int				len;    int				off;#ifdef BSD43_DRIVER    u_short			ether_type;#endif    /*     * If both STP and ENP are set, ESTAR didn't try to     * use data chaining.     */    if (((rmd->es_rmd1.es_rmd1b & esrmd1_STP) == esrmd1_STP) &&	((rmd->es_rmd1.es_rmd1b & esrmd1_ENP) == esrmd1_ENP))	{	len = rmd->rbuf_mcnt;	ls->ls_rindex = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);	}    else	{	ls->ls_rindex = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);	++ls->ls_if.if_ierrors;	if (esLogCount && (ls->ls_if.if_ierrors % esLogCount) == 0)	    logMsg ("es%d: receive error, stp %d enp %d\n",		    ls->ls_if.if_unit,		    (rmd->es_rmd1.es_rmd1b & esrmd1_STP) >> 9,		    (rmd->es_rmd1.es_rmd1b & esrmd1_ENP) >> 8, 0, 0, 0);	return (OK);		/* intentional */	}    /*    eh = (struct ether_header *)(rmd->rbuf_ladr | (rmd->rbuf_hadr << 16));    ItoK (eh, struct ether_header *, ls->memBase);    */    ++ls->ls_if.if_ipackets;    /* bump statistic */    eh =(struct ether_header *) ((u_int) ls->rmd_ring.r_bufs +	(u_int) ((((u_int)rmd - (u_int)ls->ls_rring) / sizeof(es_rmd))	* ls->bufSize));

⌨️ 快捷键说明

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