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

📄 if_lnsgi.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    if ((int) memAdrs == NONE)        ls->ls_flags |= LS_MEM_ALLOC_FLAG;        ls->bufSize = bufSize;    /* if memWidth is NONE (we can copy any byte size/boundaries) and     * bufSize is big enough to hold the biggest ethernet frame     * we can loan out rmds.  On systems that cannot afford to have     * big enough RMD's, LANCE will use data-chaining on receive     * buffers.  Our current implementation of RMD loans does not work     * with receive side data-chains.     */    if (ls->memWidth == NONE && ls->bufSize == LN_BUFSIZE)	{	int	ix;	char	*pBuf;	        ls->canLoanRmds		= TRUE;	ls->nFree		= LN_NUM_RESERVES;	if ((pBuf = (char *) malloc ((u_int) (LN_NUM_RESERVES * bufSize))) 	    == NULL)	    {	    (void) free (memPool);	    (void) free ((char *) ls);	    return (ERROR);	    }	for (ix = 0; ix < LN_NUM_RESERVES; ix++)	    ls->freeBufs [ix] = (char *) ((int) pBuf + (bufSize * ix));	}    else        ls->canLoanRmds = FALSE;    /* allocate initialization block */    ls->ib = (ln_ib *)memPool;    sz = sizeof (ln_ib);		/* size of initialization block */    bzero ((char *)ls->ib, (int) sz);	/* zero out entire ib */    /* allocate receive message descriptor (RMD) ring structure */    ls->ls_rpo2 = lnRsize;		/* remember for lnConfig */    ls->ls_rsize = (1 << lnRsize);	/* receive msg descriptor ring size */    /* leave room to adjust low three bits */    ls->ls_rring = (ln_rmd *) ((int)ls->ib + sz);   /* of pointer to be 000 */    sz = ((1 << lnRsize) + 1) * sizeof (ln_rmd);    bzero ((char *)ls->ls_rring, (int)sz);	/* zero out entire RMD ring */    /* allocate receive buffer space */    sz = sz + 2;		/* this makes the rx_buffers un-aligned, */                                /* but with ether-header prepended, they are */    ls->rmd_ring.r_bufs = (char *)((int)ls->ls_rring + sz);    sz = (bufSize << lnRsize);	 /* room for all the receive buffers */    bzero (ls->rmd_ring.r_bufs, (int)sz);/* zero out entire rbuf area */    /* allocate transmit message descriptor (TMD) ring structure */    ls->ls_tpo2 = lnTsize;		/* remember for lnConfig */    ls->ls_tsize = (1 << lnTsize);	/* transmit msg descriptor ring size */    sz = sz + 2;			/* make ls_tring aligned again */    ls->ls_tring = (ln_tmd *) ((int)ls->rmd_ring.r_bufs + sz);    sz = ((1 << lnTsize) + 1) * sizeof (ln_tmd);    bzero ((char *)ls->ls_tring, (int)sz);	/* zero out entire TMD ring */    /* allocate transmit buffer space */    sz = sz + 2;	/* this makes the tx_buffers un-aligned, */		        /* but with ether-header prepended, they are */    ls->tmd_ring.t_bufs = (char *)((int)ls->ls_tring + sz);    sz = (bufSize << lnTsize);	/* room for all the transmit buffers */    bzero (ls->tmd_ring.t_bufs, (int)sz);	/* zero out entire tbuf area */    ls_softc [unit] = ls;		/* remember address for this unit */    /* initialize device structure */    ls->ivec    	= ivec;			/* interrupt vector */    ls->ilevel		= ilevel;		/* interrupt level */    ls->devAdrs		= (LN_DEVICE *)devAdrs;	/* LANCE i/o address */    /* copy the enet address into the softc */    bcopy ((char *) lnsgiEnetAddr, (char *)ls->ls_enaddr, sizeof (ls->ls_enaddr));    ifp = &ls->ls_if;    /* attach and enable the LANCE interrupt service routine to vector */    lnChipReset (ls);				/* reset LANCE */    (void) intConnect (INUM_TO_IVEC (ivec), lnInt, (int)ls);#ifdef BSD43_DRIVER    ether_attach (ifp, unit, "lnsgi", (FUNCPTR) lnInit, (FUNCPTR) lnIoctl, 		  (FUNCPTR) lnOutput, (FUNCPTR) lnReset);#else    ether_attach (                 ifp,                  unit,                  "lnsgi",                 (FUNCPTR) lnInit,                  (FUNCPTR) lnIoctl, 		 (FUNCPTR) ether_output,                  (FUNCPTR) lnReset                 );    ifp->if_start = (FUNCPTR) lnStartOutput; #endif    sysLanIntEnable (ilevel);    lnInit (unit);    return (OK);    }/********************************************************************************* lnReset - reset the interface** Mark interface as inactive & reset the chip*/LOCAL void lnReset    (    int unit     )    {    FAST DRV_CTRL * 	ls = ls_softc [unit];    ls->ls_if.if_flags &= ~IFF_RUNNING;    lnChipReset (ls);				/* reset LANCE */    }/********************************************************************************* lnInit -** Initialization of interface; clear recorded pending operations.* Called during driver attach routine at boot time and by interrupt service* routines when fatal errors occur.*/LOCAL int lnInit    (    int unit     )    {    FAST DRV_CTRL * 	ls = ls_softc [unit];    FAST struct ifnet * ifp = &ls->ls_if;    ifp->if_flags &= ~(IFF_UP | IFF_RUNNING | IFF_PROMISC);    lnChipReset (ls);				/* disable chip during init */    lnConfig (ls);				/* reset all ring structures */    ifp->if_flags |= (IFF_UP | IFF_RUNNING);    if (ls->ls_flags & LS_PROMISCUOUS_FLAG)	ifp->if_flags |= (IFF_PROMISC);    lnChipInit (ls);			/* on return LANCE is running */#ifdef BSD43_DRIVER    lnStartOutput (ls->ls_if.if_unit);	/* tell chip about any pending output */#else    lnStartOutput (ls);#endif    return (0);    }/********************************************************************************* lnConfig - 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 lnConfig    (    FAST struct ls_softc  *ls     )    {    FAST ln_rmd	  *rmd;    FAST ln_tmd	  *tmd;    FAST char	  *buf;    FAST ln_ib	  *ib;    FAST int	   index;    int		   i;    rmd = ls->ls_rring;			/* receive message descriptor ring */    rmd = (ln_rmd *)(((int)rmd + 7) & ~7);	/* low 3 bits must be 000 */    ls->ls_rring = rmd;				/* fix softc as well */    sysWbFlush ();    buf = ls->rmd_ring.r_bufs;     for (i = 0; i < ls->ls_rsize; i++)        {        /* fill VIP10 dma table entry */	index = RBUF_INDEX + i;	pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(buf);	sysWbFlush ();	/* bits 15:00 of buffer address */	rmd->rbuf_ladr = (u_short) LNADDR(index, buf);	/* bits 23:16 of buffer address */	rmd->lnRMD1 = (u_short) ((u_int) (LNADDR(index, buf) >> 16) & 0xff);	rmd->rbuf_bcnt = -(ls->bufSize);/* neg of buffer byte count */	rmd->rbuf_mcnt = 0;		/* no message byte count yet */	rmd->lnRMD1 |= lnrmd1_OWN;	/* buffer now owned by LANCE */	sysWbFlush ();				/* make sure it gets out */	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;			/* LANCE will use at start of ring */    sysWbFlush ();    tmd = ls->ls_tring;			/* transmit message descriptor ring */    tmd = (ln_tmd *)(((int)tmd + 7) & ~7);	/* low 3 bits must be 000 */    ls->ls_tring = tmd;				/* fix softc as well */    sysWbFlush ();    buf = ls->tmd_ring.t_bufs;     for (i = 0; i < ls->ls_tsize; i++)        {	/* fill VIP10 dma table entry */	index = TBUF_INDEX + i;        pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(buf);	sysWbFlush ();	/* bits 15:00 of buffer address */	tmd->tbuf_ladr = (u_short) LNADDR(index, buf);	/* bits 23:16 of buffer address */	tmd->lnTMD1 = (u_short) ((u_int) (LNADDR(index, buf) >> 16) & 0xff);	tmd->tbuf_bcnt = 0;		/* no message byte count yet */	tmd->lnTMD3 = 0;		/* no error status yet */	tmd->lnTMD1 |= lntmd1_ENP;	/* buffer is end of packet */	tmd->lnTMD1 |= lntmd1_STP;	/* buffer is start of packet */	sysWbFlush ();				/* make sure it gets out */	tmd++;				/* step to next message descriptor */	buf += (ls->bufSize);		/* step to start of next buffer */	}    ls->ls_tindex = 0;			/* LANCE will use at start of ring */    ls->ls_dindex = 0;			/* buffer disposal will lag tindex */    sysWbFlush ();    ib = ls->ib;    /* fill VIP10 dma table entry for initialization block */    index = IBUF_INDEX;    pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(ib);    sysWbFlush ();    if (ls->ls_flags & LS_PROMISCUOUS_FLAG)        ib->lnIBMode = 0x8000;	/* chip will be in promiscuous receive mode */    else        ib->lnIBMode = 0;	/* chip will be in normal receive mode */    swab ((char *)ls->ls_enaddr, ib->lnIBPadr, 6);    /*     *  Fill VIP10 RMD Desc and Bufs. Two buffers are allocated to accomadate    *  the crossing page boundries.  RMD Desc and buffers should come right     *  after IB     */    index++;    pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(ls->ls_rring);    sysWbFlush ();    pEmap [EMAP_OFFSET(index + 1)] = (u_short) (EMAP_VALUE(ls->ls_rring) + 1);    sysWbFlush ();    ib->lnIBRdraLow = (u_short) LNADDR(index, ls->ls_rring);    ib->lnIBRdraHigh = (u_short) ((u_int) (LNADDR(index, ls->ls_rring) >> 16) 			& 0xff) | (ls->ls_rpo2 << 13);    sysWbFlush ();    index += 2;    pEmap [EMAP_OFFSET(index)] = (u_short) EMAP_VALUE(ls->ls_tring);    sysWbFlush ();    pEmap [EMAP_OFFSET(index + 1)] = (u_short) (EMAP_VALUE(ls->ls_tring) + 1);    sysWbFlush ();    ib->lnIBTdraLow = (u_short) LNADDR(index, ls->ls_tring);    ib->lnIBTdraHigh = (u_short) ((u_int) (LNADDR(index, ls->ls_tring) >> 16) 			& 0xff) | (ls->ls_tpo2 << 13);    sysWbFlush ();    }/********************************************************************************* lnInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL void lnInt    (    FAST struct ls_softc  *ls     )    {    FAST ln_rmd		*rmd;    FAST ln_tmd		*tmd;    FAST int 		*pDindex;    FAST int		*pTindex;    FAST int		*pTsize;    FAST ln_tmd		*pTring;    FAST u_short	stat;       if (!((stat = lnCsrIntRead (ls, 0)) & lncsr_INTR))        {        return;        }    /*     * enable interrupts, clear receive and/or transmit interrupts,      * and clear any errors that may be set.     */    lnCsrIntWrite (ls, 0, ((stat & 	    (lncsr_BABL | lncsr_CERR | lncsr_MISS | lncsr_MERR |	     lncsr_RINT | lncsr_TINT | lncsr_IDON)) | lncsr_INEA));    /*     * have task level handle csr0 errors;     */    if (stat & lncsr_ERR)        {	lnHandleCsr0Err (ls, stat);	}    /* have task level handle any input packets */    if ((stat & lncsr_RINT) && (stat & lncsr_RXON))	{	if ((rmd = lnGetFullRMD (ls)) != NULL)	    {	    /* discard error input ASAP - don't queue it */	    if (rmd->lnRMD1 & RMD_ERR) 		{		if (lnsgiLogCount && (ls->ls_if.if_ierrors % lnsgiLogCount) == 0)	            logMsg ("ln%d lnInt: ERROR rmd1=0x%x mcnt %d\n", 			    ls->ls_if.if_unit, rmd->lnRMD1 & 0xff00, 			    rmd->rbuf_mcnt, 0, 0, 0);		ls->ls_if.if_ierrors++;		ls->ls_rindex = (ls->ls_rindex + 1) & (ls->ls_rsize - 1);    		sysWbFlush ();				rmd->lnRMD1 &= ~RMD_ERR;		LN_RMD_GIVE_TO_LANCE (rmd); sysWbFlush ();		}	    else if ((ls->ls_flags & LS_RCV_HANDLING_FLAG) == 0)		{		ls->ls_flags |= LS_RCV_HANDLING_FLAG;		(void) netJobAdd ((FUNCPTR) lnHandleRecvInt, (int) ls, 				  0, 0, 0, 0);		}	    }	}    /*      * Did LANCE update any of the TMD's?     * If not then don't bother continuing with transmitter stuff      */        if (!(stat & lncsr_TINT))	{	/* common return path */        return;	}    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;        cacheClearEntry(tmd, sizeof(ln_tmd));	/* if the buffer is still owned by LANCE, don't touch it */	if (tmd->lnTMD1 & TMD_OWN)	    break;

⌨️ 快捷键说明

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