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

📄 if_lnsgi.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
* Kick start the transmitter to avoid the polling interval latency.* This routine is called by lnInit () and lnOutput ().* 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 lnStartOutput    (    int unit     )    {    FAST DRV_CTRL * 	ls = ls_softc [unit];#elseLOCAL void lnStartOutput    (    DRV_CTRL * 	ls    )    {#endif    FAST struct mbuf	*m;    FAST ln_tmd		*tmd;    FAST char		*buf;    FAST int		len;    FAST int		sx;    FAST int		oldLevel;    sx = splimp ();    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 so get a transmit buffer */	if ((tmd = lnGetFreeTMD (ls)) == NULL)		    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(ln_tmd)) 	    * ls->bufSize));	/* Copy packet to write buffer */#ifdef BSD43_DRIVER	bcopy_from_mbufs (buf, m, len, ls->memWidth);#else        copy_from_mbufs (buf, m, len);#endif	len = max (ETHERSMALL, 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->lnTMD3 = 0;		/* clear buffer error status */	tmd->tbuf_bcnt = -len;		/* negative message byte count */	tmd->lnTMD1 |= lntmd1_ENP;	/* buffer is end of packet */	tmd->lnTMD1 |= lntmd1_STP;	/* buffer is start of packet */        tmd->lnTMD1 &= ~lntmd1_DEF;   /* clear status bit */        tmd->lnTMD1 &= ~lntmd1_MORE;        tmd->lnTMD1 &= ~lntmd1_ERR;        tmd->lnTMD1 |= lntmd1_OWN;	sysWbFlush ();		intUnlock (oldLevel);	/* now lnInt won't get confused */	ls->ls_tindex = (ls->ls_tindex + 1) & (ls->ls_tsize - 1);        sysWbFlush ();#ifndef BSD43_DRIVER    /* BSD 4.4 ether_output() doesn't bump statistic. */        ls->ls_if.if_opackets++;#endif        }/* * to minimize chip accesses, don't kick start the transmitter. * it will start after the next internal poll. */    ls->ls_flags &= ~LS_START_OUTPUT_FLAG;    splx (sx);    }/********************************************************************************* lnIoctl -** Process an ioctl request.*/LOCAL int lnIoctl    (    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);    }/********************************************************************************* lnChipReset - hardware reset of chip (stop it)*/LOCAL void lnChipReset    (    struct ls_softc  *ls     )    {    lnCsrWrite (ls, 0, lncsr_STOP);     /* set the stop bit */    }/********************************************************************************* lnChipInit - hardware init of chip (init & start it)*/LOCAL void lnChipInit    (    FAST struct ls_softc  *ls     )    {    FAST u_short	stat;    int			timeoutCount = 0;    lnCsrWrite (ls, 0, lncsr_STOP);	/* set the stop bit */				/* can't write csr1..3 if not stopped */    lnCsrWrite (ls, 3, lncsr3_BSWP);    lnCsrWrite (ls, 2, (u_short) ((u_int) (LNADDR(IBUF_INDEX, ls->ib) >> 16) 			& 0xff));    lnCsrWrite (ls, 1, (u_short) (LNADDR(IBUF_INDEX, ls->ib)));    lnCsrWrite (ls, 0, lncsr_INIT);	/* init chip (read IB) */    /* hang until Initialization done, error, or timeout */    while (((stat = lnCsrRead (ls, 0)) & (lncsr_IDON | lncsr_ERR)) == 0)        {        if (timeoutCount++ > 0x10000) break;        taskDelay(100);        }    /* log chip initialization failure */    if (stat & lncsr_ERR)        {        logMsg ("ln%d: ERROR: Lance chip initialization failure, csr0=0x%x\n",                ls->ls_if.if_unit, stat, 0, 0, 0, 0);        }    else if (timeoutCount >= 0x10000)        {        logMsg ("ln%d: ERROR: Lance chip initialization time-out\n",		0, 0, 0, 0, 0, 0);        }    /* start chip */    ls->ls_rindex = 0;		/* chip will start at beginning */    ls->ls_tindex = 0;    ls->ls_dindex = 0;    sysWbFlush ();    lnCsrWrite(ls, 0, lncsr_IDON | lncsr_INEA | lncsr_STRT);					/* reset IDON state */					/* enable interrupts from LANCE */					/* start chip operation */    }/********************************************************************************* lnGetFreeTMD - get next available TMD*/LOCAL ln_tmd *lnGetFreeTMD    (    FAST struct ls_softc  *ls     )    {    FAST ln_tmd	  *tmd;    /* check if buffer is available (owned by host) */    /* also check for tindex overrun onto dindex */    tmd = ls->ls_tring + ls->ls_tindex;    cacheClearEntry(tmd, sizeof(ln_tmd));    if (((tmd->lnTMD1 & lntmd1_OWN) != 0)	|| (((ls->ls_tindex + 1) & (ls->ls_tsize - 1)) == ls->ls_dindex))	{        tmd = (ln_tmd *) NULL;	}    return (tmd);    }/********************************************************************************* lnGetFullRMD - get next received message RMD*/LOCAL ln_rmd *lnGetFullRMD    (    FAST struct ls_softc  *ls     )    {    FAST ln_rmd	  *rmd;    /* check if buffer is full (owned by host) */    rmd = ls->ls_rring + ls->ls_rindex;    cacheClearEntry(rmd, sizeof(ln_rmd));    if ((rmd->lnRMD1 & lnrmd1_OWN) == 0)	{        return (rmd);	}    else	{        return ((ln_rmd *) NULL);	}    }/********************************************************************************* lnCsrRead - select and read a CSR register ** NOTE: LANCE must already be stopped to read CSR1, CSR2 or CSR3.*/LOCAL u_short lnCsrRead    (    FAST struct ls_softc  *ls,	/* LANCE device software structure */    int reg 			/* which CSR to be selected */    )    {    FAST u_short value;    FAST u_short *dv = (u_short *)ls->devAdrs;    volatile u_short *pRAP;    volatile u_short *pCSR0;    pRAP  = (volatile u_short *) (dv + RAPOffset);    pCSR0 = (volatile u_short *) (dv + CSROffset);    *pRAP = reg;		/* select CSR */    sysWbFlush ();    value = *pCSR0;		/* get contents of CSR */    return(value);		/* return contents of CSR */    }/********************************************************************************* lnCsrWrite - select and write a CSR register **/LOCAL void lnCsrWrite    (    FAST struct ls_softc  *ls,	/* LANCE device software structure */    int reg,			/* which CSR to be selected */    u_short value 		/* value to write */    )    {    FAST u_short *dv = (u_short *)ls->devAdrs;    volatile u_short *pRAP;    volatile u_short *pCSR0;    pRAP  = (volatile u_short *) (dv + RAPOffset);    pCSR0 = (volatile u_short *) (dv + CSROffset);    *pRAP = reg;		/* select CSR */    sysWbFlush ();    *pCSR0 = value;		/* write value to CSR */    sysWbFlush ();    }/********************************************************************************* lnCsrIntRead - select and read a CSR register in an ISR ** NOTE: LANCE must already be stopped to read CSR1, CSR2 or CSR3.*/LOCAL u_short lnCsrIntRead    (    FAST struct ls_softc  *ls,	/* LANCE device software structure */    FAST int reg 		/* which CSR to be selected */    )    {    FAST u_short value;    FAST u_short *dv = (u_short *)ls->devAdrs;    volatile u_short *pRAP;    volatile u_short *pCSR0;    pRAP  = (volatile u_short *) (dv + RAPOffset);    pCSR0 = (volatile u_short *) (dv + CSROffset);    *pRAP = reg;		/* select CSR */    sysWbFlush ();    value = *pCSR0;		/* get contents of CSR */    return(value);		/* return contents of CSR */    }/********************************************************************************* lnCsrIntWrite - select and write a CSR register in an ISR.**/LOCAL void lnCsrIntWrite    (    FAST struct ls_softc  *ls,	/* LANCE device software structure */    FAST int reg,		/* which CSR to be selected */    FAST u_short value 		/* value to write */    )    {    FAST u_short *dv = (u_short *)ls->devAdrs;    volatile u_short *pRAP;    volatile u_short *pCSR0;    pRAP  = (volatile u_short *) (dv + RAPOffset);    pCSR0 = (volatile u_short *) (dv + CSROffset);    *pRAP = reg;		/* select CSR */    sysWbFlush ();    *pCSR0 = value;		/* write value to CSR */    sysWbFlush ();    }/********************************************************************************* lnRmdFree - 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 lnRmdFree    (    FAST struct ls_softc	*ls,    FAST char 			*pBuf     )    {    ls->freeBufs [ls->nFree++] = pBuf;    }

⌨️ 快捷键说明

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