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

📄 if_es.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* call input hook if any */    if ((etherInputHookRtn != NULL) &&	(* etherInputHookRtn) (&ls->ls_if, (char *)eh, len))	return (OK);#ifdef BSD43_DRIVER    /* This legacy code is not correct for the BSD 4.4 stack. It would     * also treat multicast addresses like alien packets, and not send     * them up the stack. The higher-level protocols in the new stack     * can handle these addresses, and will discard them if they do not     * match an existing multicast group.     */    /* do software filter if controller is in promiscuous mode */    if (ls->ls_flags & LS_PROMISCUOUS_FLAG)	if ( (bcmp ( (char *)eh->ether_dhost,	/* not our adrs? */		     (char *)ls->ls_enaddr,		    sizeof (eh->ether_dhost)) != 0) &&	     (bcmp ( (char *)eh->ether_dhost,	/* not broadcast? */                     (char *)etherbroadcastaddr,		    sizeof (eh->ether_dhost)) != 0))            return (OK);#endif    if (len >= sizeof (struct ether_header))        len -= sizeof (struct ether_header);    else        len = 0;    pData = ((u_char *) eh) + (sizeof (struct ether_header));#ifdef BSD43_DRIVER    check_trailer (eh, pData, &len, &off, &ls->ls_if);    if (len == 0)	return (OK);    ether_type = eh->ether_type;#endif    m = NULL;    /* we can loan out receive buffers from ESTAR receive ring if:     *     * 1) canLoanRmd is TRUE.  canLoanRmd is set to TRUE if memWidth     *    is NONE (no special restriction in copying data in terms of     *    size and boundary conditions) and each of the buffers in the     *    ESTAR ring is big enough to hold the maximum sized ethernet     *    frame (data-chaining is not being used for the input).     * 2) trailer protocol is not being used for the given input ethernet frame.     * 3) there is available free buffers that can be used to replace the     *    rbuf to be loaned out in the free list 'freeBufs'.     * 4) size of the input ethernet frame is large enough to be used with     *    clustering.     */        if (ls->canLoanRmds && off == 0 && ls->nFree > 0 && USE_CLUSTER (len))	{        m = build_cluster (pData, len, &ls->ls_if, MC_LANCE,			   &(ls->loanRefCnt [ls->ls_rindex]),			   (FUNCPTR)esRmdFree, (int) ls, (int) eh, NULL);	if (m != NULL)	    {	    FAST char *pBuf;	    	    /* get a free buffer from the free list to replace the	     * rbuf loaned out.  replace the rbuf pointers in the RMD	     * to point to the new buffer.	     */	    	    pBuf = ls->freeBufs [--ls->nFree];	    	    rmd->rbuf_ladr = (u_short) ((int) pBuf & 0xff);	    rmd->es_rmd1.es_rmd1b = (rmd->es_rmd1.es_rmd1b & ~esrmd1_HADR)				    | (((int) pBuf >> 16) & esrmd1_HADR);	    }	}    if (m == NULL)#ifdef BSD43_DRIVER	/* Instead of calling copy_to_mbufs (), we call bcopy_to_mbufs ()	 * with ls->memWidth as an addtional argument to specify unit of a	 * copy op.	 *	 * Most drivers would use macro copy_to_mbufs (), which will in turn	 * call bcopy_to_mbufs () telling it to use the normal bcopy ().  Some	 * of the on-board ESTAR hardware implementations require that you	 * copy the data by certain number of bytes from dedicated memory	 * to system memory, so ESTAR driver has a es_bcopy () routine that	 * conforms to this requirement.	 */	m = bcopy_to_mbufs (pData, len, off, (struct ifnet *) &ls->ls_if,			    ls->memWidth);#else        m = bcopy_to_mbufs (pData, len, 0, &ls->ls_if, ls->memWidth);#endif    if (m == NULL)        ++ls->ls_if.if_ierrors;    /* bump error counter */    else#ifdef BSD43_DRIVER        do_protocol_with_type (ether_type, m, &ls->ls_ac, len);#else        do_protocol (eh, m, &ls->ls_ac, len);#endif    return (OK);    }#ifdef BSD43_DRIVER/********************************************************************************* esOutput - Ethernet output routine** Ethernet output routine.* Encapsulate a packet of type family for the local net.* Use trailer local net encapsulation if enough data in first* packet leaves a multiple of 512 bytes of data in remainder.*/LOCAL int esOutput    (    FAST struct ifnet	*ifp,    FAST struct mbuf	*m0,    struct sockaddr	*dst    )    {    return (ether_output (ifp, m0, dst, (FUNCPTR) esStartOutput, 			  &ls_softc [ifp->if_unit]->ls_ac));    }#endif/********************************************************************************* esStartOutput - start pending output** Start output to ESTAR.* Queue up all pending datagrams for which transmit buffers are available.* Kick start the transmitter to avoid the polling interval latency.* This routine is called by esInit (). With BSD 4.3 drivers, it is also called* by esOutput (). BSD 4.4 drivers use a slightly different model in which it* is called directly from the generic ether_output() routine.* It is very important that this routine be executed with splimp set.* If this is not done, another task could allocate the same tmd!*/#ifdef BSD43_DRIVERLOCAL VOID esStartOutput    (    int unit    )    {    FAST struct ls_softc	*ls = ls_softc [unit];#elseLOCAL VOID esStartOutput    (    struct ls_softc * 	ls    )    {#endif    FAST struct mbuf		*m;    FAST es_tmd			*tmd;    char			*buf, *buf0;    u_short			*temp, temp1;    FAST int			len, i;    FAST int			sx;    FAST int			oldLevel;    ES_DEVICE			*dv;    sx = splimp ();    dv = ls->devAdrs;    ls->ls_flags |= LS_START_OUTPUT_FLAG;    /* Loop placing message buffers in output ring until no more or no room */    while (ls->ls_if.if_snd.ifq_head != NULL)        {	/* there is something to send */	if ((tmd = esGetFreeTMD (ls)) == NULL)	/* get a transmit buffer */	    break;	IF_DEQUEUE (&ls->ls_if.if_snd, m); /* get head of next mbuf chain */	buf = (char *) ( (u_int) ls->tmd_ring.t_bufs +                         (u_int) ( ( ( (u_int)tmd - (u_int)ls->ls_tring) /                                     sizeof (es_tmd)) *                          ls->bufSize));	buf0 = buf;	/* copy packet to write buffer */	temp = (u_short *)buf;#ifdef BSD43_DRIVER	bcopy_from_mbufs (buf, m, len, ls->memWidth);#else        bcopy_from_mbufs (buf, m, len, ls->memWidth);#endif	len = max (ETHERSMALL, len);	buf += len;	/* call output hook if any */    	if ((etherOutputHookRtn != NULL) &&	    (* etherOutputHookRtn) (&ls->ls_if, buf, len))	    continue;	/* place a transmit request */    	oldLevel = intLock ();		/* disable ints during update */	tmd->tbuf_tmd3 = 0;		/* clear buffer error status */	tmd->tbuf_bcnt = -len;		/* negative message byte count */	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->es_tmd1.es_tmd1b &= ~estmd1_DEF;	/* clear status bit */	tmd->es_tmd1.es_tmd1b &= ~estmd1_MORE;	tmd->es_tmd1.es_tmd1b &= ~estmd1_ERR;	/* try to output here */	*dlan.dlcr1 = 0;		/* disable ints during update */	i=0;			/* extract the buffer */	if (newdlan == TRUE)             {            while (i*2 < len)                {                if (i*2 < (buf - buf0))                    dv->bmpr0 = *temp++;                else                     dv->bmpr0 = 0;                i += 1;		}            temp1 = (u_short)((len>>8) | (len<<8) | 0x80);	/* set TMST */            dv->bmpr2 = temp1;            }        else             {            while (i*2 < len)                {                if (i*2 < (buf - buf0))                    {                    dv->bmpr0 = (*temp>>8 | *temp<<8);                    temp++;                    }                else                     dv->bmpr0 = 0;                i += 1;                }            dv->bmpr2 = (u_short)(len | 0x8000);	/* set TMST */            }	while ( (*dlan.dlcr0 & es_tmt_ok) == es_tmt_ok)            ;	intUnlock (oldLevel);	/* now esInt won't get confused */	ls->ls_tindex = (ls->ls_tindex + 1) & (ls->ls_tsize - 1);#ifndef BSD43_DRIVER    /* BSD 4.4 ether_output() doesn't bump statistic. */        ls->ls_if.if_opackets++;#endif        }    ls->ls_flags &= ~LS_START_OUTPUT_FLAG;    *dlan.dlcr1 = ES_TMT_MASK;		/* set transmit interrupt mask */    splx (sx);    }/********************************************************************************* esIoctl - Process an ioctl request** Process an ioctl request.*/LOCAL int esIoctl    (    FAST struct ifnet	*ifp,    int			 cmd,    caddr_t		 data    )    {    int			   unit = ifp->if_unit;    FAST struct ls_softc  *ls = ls_softc [unit];    int			   s = splimp ();    int			   error = 0;    switch (cmd)	{	case SIOCSIFADDR:            ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas (ifp, &IA_SIN (data)->sin_addr);	    break;	case SIOCGIFADDR:	    bcopy((caddr_t) ls->ls_enaddr,		  (caddr_t) ((struct ifreq *)data)->ifr_addr.sa_data, 6);	    break;	case SIOCGIFFLAGS:	    *(short *)data = ifp->if_flags;	    break;	case SIOCSIFFLAGS:	    ls->ls_if.if_flags = ifp->if_flags;	    if (ifp->if_flags & IFF_PROMISC)	        ls->ls_flags |= LS_PROMISCUOUS_FLAG;	    else	        ls->ls_flags &= ~LS_PROMISCUOUS_FLAG;	    if (ifp->if_flags & IFF_UP)		ls->ls_if.if_flags |= (IFF_UP|IFF_RUNNING);	    else	        ls->ls_if.if_flags &= ~(IFF_UP|IFF_RUNNING);	    break;	default:	    error = EINVAL;	}    splx (s);    return (error);    }/********************************************************************************* esChipReset - hardware reset of chip (stop it)*/LOCAL VOID esChipReset    (    struct ls_softc  *ls    )    {    *dlan.dlcr1 = 0;			/* reset transmit interrupt mask */    *dlan.dlcr3 = 0;			/* reset receive interrupt mask  */    *dlan.dlcr6 = es_ena_dlc;		/* stop the etherstar            */    *dlan.dlcr2 = 0xcf;			/* clear interrupts */    *dlan.dlcr0 = 0x0f;    }/********************************************************************************* esChipInit - hardware init of chip (init & start it)*/LOCAL VOID esChipInit    (    FAST struct ls_softc  *ls    )    {    u_short temp;    FAST ES_DEVICE	*dv = ls->devAdrs;    /* setup vector */    dv->eth_vector =  ls->ivec;     *dlan.dlcr6 = es_ena_dlc;	/* stop the etherstar			*/    *dlan.dlcr2 = 0xcf;		/* clear all receive errors		*/    *dlan.dlcr3 = 0x8f;		/* reset receive interrupt mask		*/    *dlan.dlcr0 = 0x0f;		/* clear all transmit errors 		*/    *dlan.dlcr1 = 0x00;		/* reset transmit interrupt mask	*/    /* flush the receive buffer memory of the etherstar */    temp = esReadBmpr0 (dv);    while ( !(*dlan.dlcr5 & 0x40) ) temp = esReadBmpr0 (dv);    temp = esReadBmpr0 (dv);    temp = esReadBmpr0 (dv);    /* configure etherstar in normal mode */    *dlan.dlcr4 = es_lbc;	/* loopback disabled, byte swap enabled */    *dlan.dlcr5 = 0x02;		/* physical, multicast and broadcast 	*/    /* copy the enet address into the softc */    *dlan.dlcr8 = esEnetAddr[0];    *dlan.dlcr9 = esEnetAddr[1];	/* setting these registers is only */    *dlan.dlcr10 = esEnetAddr[2];	/* possible when etherstar is stopped */    *dlan.dlcr11 = esEnetAddr[3];    *dlan.dlcr12 = esEnetAddr[4];    *dlan.dlcr13 = esEnetAddr[5];    for ( temp = 20000; temp > 0; temp-- );    /* start chip */    *dlan.dlcr6 = 0x00;		/* start the etherstar			*/    *dlan.dlcr1 = ES_TMT_MASK;	/* set transmit interrupt mask		*/    *dlan.dlcr3 = ES_RCV_MASK;	/* set receive interrupt mask */    }/********************************************************************************* esGetFreeTMD - get next available TMD*/LOCAL es_tmd *esGetFreeTMD    (    FAST struct ls_softc  *ls    )    {    FAST es_tmd	  *tmd;    /* check if buffer is available (owned by host) */    /* also check for tindex overrun onto dindex */    tmd = ls->ls_tring + ls->ls_tindex;    if (((tmd->es_tmd1.es_tmd1b & estmd1_OWN) != 0)	|| (((ls->ls_tindex + 1) & (ls->ls_tsize - 1)) == ls->ls_dindex))        tmd = (es_tmd *) NULL;    return (tmd);    }/********************************************************************************* esGetFullRMD - get next received message RMD*/LOCAL es_rmd *esGetFullRMD    (    FAST struct ls_softc  *ls    )    {    FAST es_rmd	  *rmd;    /* check if buffer is full (owned by host) */    rmd = ls->ls_rring + ls->ls_rindex;    if ((rmd->es_rmd1.es_rmd1b & esrmd1_OWN) == 0)	return (rmd);    else	return ((es_rmd *) NULL);    }/********************************************************************************* esRmdFree - called when loaned out rbuf is freed by MCLFREE.** Puts the loaned out rbuf into free list to be reused as loan replacements.*/LOCAL VOID esRmdFree    (    FAST struct ls_softc	*ls,    FAST char 			*pBuf    )    {    ls->freeBufs [ls->nFree++] = pBuf;    }

⌨️ 快捷键说明

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