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

📄 if_bp.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    return (ERROR);	    }	}    pMemEnd = pMem + memSize;    pHdr = (BP_HEADER *) pMem;    /* initialize bp anchor region */    pBpAnchor->an_ready     = 0;		/* set bp not ready */    pBpAnchor->an_heartbeat = 0;		/* clear heartbeat */    pBpAnchor->an_pHdr      = KtoIval (pHdr, BP_HEADER *, pAnchor);    if (pMem + sizeof (BP_HEADER) > pMemEnd)	{	printf ("bp: bpInit out of memory!\n");	return (ERROR);	}    /* initialize bp header region */    pHdr->hdr_ready = 0;                /* set CPU region not ready */    pHdr->hdr_ncpu = BP_HTONS(NCPU);    /* set number of CPUs */    bcopy ((char *) bpEnetAdrs, (char *) pHdr->hdr_enetAdrs, 6);    /* initialize each CPU descriptor */    for (ix = 0; ix < MAXCPU; ++ix)	{	pCpu = &pHdr->hdr_cpuDesc[ix];	pCpu->cd_active      = FALSE;	pCpu->cd_cpuNum      = BP_HTONL(ix);	pCpu->cd_pInputRing  = NULL;	}    /* initialize free ring */    pMem += sizeof (BP_HEADER);    if ((pMem + sizeof (struct ring256) + NCPU * sizeof (struct ring32))								> pMemEnd)	{	printf ("bp: bpInit out of memory!\n");	return (ERROR);	}    ringinit ((pFreeRing = (RING *) pMem), 256);    pHdr->hdr_pFreeRing =  KtoIval (pFreeRing, RING *, pAnchor);    pMem += sizeof (struct ring256);    /* initialize each input ring */    for (ix = 0; ix < NCPU; ++ix)	{	ringinit ((RING *) pMem, 32);	pHdr->hdr_cpuDesc[ix].cd_pInputRing = KtoIval (pMem, RING *, pAnchor);	pMem += sizeof (struct ring32);	}    /* initialize as many buffer blocks as will fit in remaining shared memory*/    if ((pMem + sizeof (BUF_NODE) + BP_BUFSIZ) > pMemEnd)	{	printf ("bp: bpInit out of memory!\n");	return (ERROR);	}    while ((pMem + sizeof (BUF_NODE) + BP_BUFSIZ) <= pMemEnd)	{	((BUF_NODE *)pMem)->b_addr = KtoIval (pMem + sizeof (BUF_NODE),					      char*, pAnchor);        ((BUF_NODE *)pMem)->b_len = BP_BUFSIZ;	(void) ringput (pFreeRing, KtoIval (pMem, int, pAnchor));	pMem += sizeof (BUF_NODE) + BP_BUFSIZ;	npackets++;	}    if (DEBUG_OPTION_1)	{	printf ("bp: number of %d byte packets is %d\n", BP_BUFSIZ, npackets);	printf ("bp: %d bytes unused from 0x%x to 0x%x\n",		(int) (pMemEnd - pMem), 		(int) vir2phys (pMem), 		(int) vir2phys (pMemEnd));	}    /* mark bp as ready */    if (bpTasOK)	pHdr->hdr_ready = pBpAnchor->an_ready = BP_HTONL(BP_READY);    else	pHdr->hdr_ready = pBpAnchor->an_ready = BP_HTONL(BP_READY_SOFT_TAS);    /* start heartbeat */    bpHeartbeatRate = hz;#ifdef	UNIX    timeout (bpHeartbeat, (caddr_t) pAnchor, bpHeartbeatRate);#else	/* UNIX */    /* create watchdog timer for heartbeat */    if ((pBpAnchor->an_wdog = wdCreate ()) == NULL)	return (ERROR);    wdStart (pBpAnchor->an_wdog, bpHeartbeatRate, (FUNCPTR) bpHeartbeat,             (int) pAnchor);#endif	/* UNIX */    return (OK);    }/********************************************************************************* bpReset - mark a bp inactive** called from reboot and panic*/LOCAL void bpReset    (    FAST int unit    )    {    FAST BP_SOFTC *bs;    FAST BUF_NODE *pBufNode;#ifdef	UNIX    FAST struct mb_device *md;    if (unit >= NBP || (md = bpinfo[unit]) == 0 || md->md_alive == 0)	return;#endif	/* UNIX */    bs = BP_SOFTC_P [unit];    if (bs != NULL && bs->bs_pHdr != NULL)	{	/* turn off active flag in our CPU descriptor in the	 * shared header, then throw away anything on our input ring */	bs->bs_pHdr->hdr_cpuDesc[bs->bs_procNum].cd_active = FALSE;	while ( (pBufNode = (BUF_NODE *)ringget ( (RING *)bs->bs_pInputRing)))	    (void)ringput ( (RING *)bs->bs_pFreeRing, (int)pBufNode);	}    }/********************************************************************************* bpAlive - check for throbbing heartbeat** This routine is called for CPU 0 (master) as well as the rest.* The timeout is quick if the master can't see its own ticker.** RETURNS: OK or ERROR if unable to find anchor after 10 minutes*/LOCAL STATUS bpAlive    (    BP_SOFTC *bs    )    {    int readyValue;    int heartbeat;    FAST unsigned int oldBeat = 0;    FAST int countdown             = 10 * 60 * hz;	/* wait 10 minutes */    FAST BP_ANCHOR *pAnchor        = bs->bs_pAnchor;#ifdef	UNIX    int level = spl3 ();	/* find out priority level */    splx (level);#endif	/* UNIX */    if (bs->bs_procNum == 0)	countdown = 2 * hz;	/* don't wait around for self if master CPU */    while (--countdown > 0)	{	/* probe test:	 *  1) anchor must be readable (memory must be visable to us),	 *  2) anchor ready value must be BP_READY or BP_READY_SOFT_TAS,	 *  3) anchor heartbeat must be increasing.	 */#ifdef	UNIX	if (peek ((short *) &pAnchor->an_ready)     != -1 &&	    peek ((short *) &pAnchor->an_heartbeat) != -1)	    {	    readyValue = BP_NTOHL(pAnchor->an_ready);	    heartbeat  = (UINT)BP_NTOHL(pAnchor->an_heartbeat);#else	/* UNIX */	if (vxMemProbe ((char *) &pAnchor->an_ready,			 O_RDONLY, 4, (char *) &readyValue) == OK &&	    vxMemProbe ((char *) &pAnchor->an_heartbeat,			 O_RDONLY, 4, (char *) &heartbeat) == OK)	    {	    readyValue = BP_NTOHL(readyValue);	    heartbeat = (UINT)BP_NTOHL(heartbeat);#endif	/* UNIX */	    if ((countdown % 10) == 6)		{		printf ("\nbp: bpAlive ready = 0x%x, heartbeat = %d\n",			    readyValue, heartbeat);		}	    if (readyValue == BP_READY || readyValue == BP_READY_SOFT_TAS)		{		if (oldBeat == 0 || heartbeat <= oldBeat)		    oldBeat = heartbeat;		else		    {		    /* heartbeat increased, passed test */		    bpTasOK = readyValue == BP_READY;		    return (OK);		    }		}	    }	else if ((countdown % 10) == 8)	    printf ("\nbp: bpAlive bus error\n");#ifdef	UNIX	timeout (wakeup, (caddr_t)bs, 1);        sleep (bs, level);#else	/* UNIX */	taskDelay (hz);#endif	/* UNIX */	}#ifndef	UNIX    (void) errnoSet (S_iosLib_CONTROLLER_NOT_PRESENT);#endif	/* UNIX */    /* give up - didn't get initialized */    return (ERROR);    }/********************************************************************************* bpIfInit - initialize interface** RETURNS: OK or ERROR*/LOCAL STATUS bpIfInit    (    int unit    )    {    FAST CPU_DESC *pCpu;    FAST BP_SOFTC *bs = BP_SOFTC_P [unit];    FAST BP_HEADER *pHdr;    /* find the anchor and CPU descriptor */    pHdr = ItoKval (bs->bs_pAnchor->an_pHdr, BP_HEADER *, bs->bs_pAnchor);    bs->bs_pHdr = pHdr;#ifdef	UNIX    /* wait for shared memory to be initialized */    if (!BP_MASTER && bpAlive (bs) == ERROR)	return (ERROR);#endif	/* UNIX */    pCpu = &pHdr->hdr_cpuDesc [bs->bs_procNum];    bs->bs_pFreeRing = ItoKval (pHdr->hdr_pFreeRing, RING *, bs->bs_pAnchor);    bs->bs_pInputRing= ItoKval(pHdr->hdr_cpuDesc[bs->bs_procNum].cd_pInputRing,			       RING *, bs->bs_pAnchor);    /* fill in Ethernet address, which is the backplane Ethernet address with     * our processor number as the last byte. */#ifdef	UNIX    bcopy ((char *) pHdr->hdr_enetAdrs,	    (char *) bs->bs_enaddr.ether_addr_octet, 6);    bs->bs_enaddr.ether_addr_octet [4] = unit;    bs->bs_enaddr.ether_addr_octet [5] = (char) bs->bs_procNum;#else	/* UNIX */    bcopy ((char *) pHdr->hdr_enetAdrs, (char *) bs->bs_enaddr, 6);    bs->bs_enaddr [4] = unit;    bs->bs_enaddr [5] = (char) bs->bs_procNum;#endif	/* UNIX */    /* check that our input buffer was established     * (in case NCPU < our cpu < MAXCPU) */    if (pCpu->cd_pInputRing == NULL)	return (ERROR);    /* fill in our info in the CPU descriptor in shared memory */    pCpu->cd_unit = unit;	/* set our internal unit num */    /* tell others how to interrupt us */    pCpu->cd_intType = BP_HTONL(bs->bs_intType);    pCpu->cd_intArg1 = BP_HTONL(bs->bs_intArg1);    pCpu->cd_intArg2 = BP_HTONL(bs->bs_intArg2);    pCpu->cd_intArg3 = BP_HTONL(bs->bs_intArg3);    /* connect and enable our interprocessor interrupt */    if (DEBUG_OPTION_1)	printf ("bp%d: connecting...\n", unit);    if (bpConnect (bs, unit) != OK || bpIntEnable (bs) != OK)	return (ERROR);    /* tell others we're here now */    pCpu->cd_active = TRUE;    if ((bs->bs_if.if_flags & IFF_RUNNING) == 0)	bs->bs_if.if_flags |= IFF_UP | IFF_RUNNING;    return (OK);    }/********************************************************************************* bpintr - interrupt handler** RETURNS: N/A** NOMANUAL*/void bpintr    (    int unit    )    {    FAST BP_SOFTC *bs = BP_SOFTC_P [unit];    if (bs != NULL && bs->bs_pInputRing != NULL)	/* input ring exists? */	{#ifndef	UNIX	bpIntAck (bs);#endif	/* UNIX */	if (!bs->bs_readPending)	    {	    bs->bs_readPending = TRUE;#ifdef	UNIX	    bpReadAll (unit);#else	/* UNIX */	    (void) netJobAdd ((FUNCPTR)bpReadAll, unit, 0,0,0,0); /* read from input ring */#endif	/* UNIX */	    }	}    }/********************************************************************************* bpReadAll -*/LOCAL void bpReadAll    (    int unit    )    {    FAST BP_SOFTC *bs = BP_SOFTC_P [unit];    FAST BUF_NODE *pBufNode;    bs->bs_readPending = FALSE;    while ((pBufNode = (BUF_NODE *) ringget ((RING *) bs->bs_pInputRing)) != 0)	{#ifdef UNIX	bpRead (bs, ItoKval (pBufNode, BUF_NODE *, bs->bs_pAnchor));	(void) ringput (bs->bs_pFreeRing, (int) pBufNode);#else	/* UNIX */	if (bpRead (bs, ItoKval (pBufNode, BUF_NODE *, bs->bs_pAnchor),		    pBufNode) == OK)	    (void) ringput ((RING *) bs->bs_pFreeRing, (int) pBufNode);#endif	/* UNIX */	}    }/********************************************************************************* bpRead -** NOMANUAL*/#ifdef UNIXLOCAL void bpRead (bs, pBufNode)    BP_SOFTC *bs;    BUF_NODE *pBufNode;#else	/* UNIX */LOCAL STATUS bpRead    (    BP_SOFTC *bs,    BUF_NODE *pBufNode,    BUF_NODE *pBufNodeOrig    )#endif  /* UNIX */    {    FAST struct ether_header	*eh;    FAST struct mbuf 		*m;    int 			len;    int 			off;    FAST unsigned char 		*pData;    STATUS 			retval;#ifdef BSD43_DRIVER    u_short			ether_type;#endif    retval = OK;    bs->bs_if.if_ipackets++;	/* count input packets */    /* get length and pointer to packet */    len = (int) (BP_NTOHS (pBufNode->b_len));    eh = ItoKval (pBufNode->b_addr, struct ether_header *, bs->bs_pAnchor);#ifndef	UNIX    /* call input hook if any */    if ((etherInputHookRtn != NULL) &&	(* etherInputHookRtn) (&bs->bs_if, (char *)eh, BP_NTOHS(pBufNode->b_len)))	return (retval);	/* input hook has already processed packet */#endif	/* UNIX */    len -= SIZEOF_ETHERHEADER;    pData = ((unsigned char *) eh) + SIZEOF_ETHERHEADER;#ifdef	UNIX    check_trailer (eh, pData, &len, &off);    if (len == 0)	return;    m = copy_to_mbufs (pData, len, off);    if (m != NULL)	do_protocol (eh, m, &bs->bs_ac, len);    else        bs->bs_if.if_ierrors++;     /* bump error count */#else	/* UNIX */#ifdef BSD43_DRIVER    check_trailer (eh, pData, &len, &off, &bs->bs_if);    if (len == 0)	return (retval);    ether_type	= eh->ether_type;#endif    m = copy_to_mbufs (pData, len, off, &bs->bs_if);    if (m != NULL)#ifdef BSD43_DRIVER        do_protocol_with_type (ether_type, m, &bs->bs_ac, len);#else        do_protocol (eh, m, &bs->bs_ac, len);#endif    else        bs->bs_if.if_ierrors++;     /* bump error count */             return (retval);#endif	/* UNIX */    }/********************************************************************************* bpStart -** NOMANUAL*/#ifdef	UNIXLOCAL void bpStart (dev)    dev_t dev;#else	/* UNIX */#ifdef BSD43_DRIVERLOCAL void bpStart    (    int unit    )#elseLOCAL void bpStart    (    BP_SOFTC * 	bs    )#endif    /* BSD43_DRIVER */#endif  /* UNIX */    {

⌨️ 快捷键说明

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