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

📄 if_bp.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    u_char 	bs_ivec;#endif	/* UNIX */    } BP_SOFTC;#ifdef	UNIXextern struct mb_driver bpdriver;struct mb_device *bpinfo[NBP];LOCAL BP_SOFTC bp_softc [NBP];#define	BP_SOFTC_P	&bp_softc#define	dbgprintf	printf#define	sysProcNumGet()	(bp_procnum)FUNCPTR bpProbeType;LOCAL char *cpudesc_vaddr [MAXCPU];#else	/* UNIX *//* bpPollTask parameters */int bpPollTaskId;int bpPollTaskOptions	= VX_SUPERVISOR_MODE | VX_UNBREAKABLE;int bpPollTaskStackSize	= 2000;int bpPollTaskPriority	= 250;LOCAL BP_SOFTC *bp_softc[NBP];#define	BP_SOFTC_P	bp_softc#define	dbgprintf	logMsgint bpProbeType;#endif	/* UNIX */LOCAL  BOOL vxTasac ();/* * the default TAS, use undef if you dont like it */#define TAS(x) 	(bpTasOK ? sysBusTas (x) : vxTasac (x))#if     (CPU_FAMILY==MIPS)#define TAS_CLEAR(x)    (bpTasOK ? sysBusClearTas (&(x)) : ((x)=0))#endif  /* CPU_FAMILY==MIPS */#if 	CPU_FAMILY==SPARCIMPORT BOOL vxTas ();IMPORT BOOL sysBusTas ();FUNCPTR         bpTasRtn = vxTasac;  /* Test-and-Set Routine */#undef TAS(x)#define TAS(x)  (*bpTasRtn)(x)/********************************************************************************* bpTas - determine backplane test-and-set macro TAS(x)** NOMANUAL*/void bpTas (bp_tas, bp_off_board, bp_target)    BOOL bp_tas;	/* BP_TAS */    BOOL bp_off_board;	/* BP_OFF_BOARD */    int  bp_target;	/* target id */    {    if (!bp_tas)      bpTasRtn = vxTasac;       /* software TAS */    else	{	/* hardware TAS */	if (bp_target == 0x1E)	    {	    /* Sun-1E */	    if (bp_off_board)		bpTasRtn = vxTas;	    else		bpTasRtn = sysBusTas;	    }	else	    {	    if (bp_off_board)		bpTasRtn = sysBusTas;	    else		bpTasRtn = vxTas;	    }	}    }#endif	/* CPU_FAMILY==SPARC */#ifdef	UNIX#define intLock		spl7#define intUnlock	splx#endif	/* UNIX */#define	DELAY_COUNT	5000	/* how high to count when waiting on TAS */#ifdef	UNIXIMPORT int bpParity;IMPORT int bpDebug;	/* flags: 1-usage, 2-dropped packets */#else	/* UNIX */int bpParity = FALSE;int bpDebug;		/* flags: 1-usage, 2-dropped packets */#endif	/* UNIX */#define	DEBUG_OPTION_1	(bpDebug & 0x1)#define	DEBUG_OPTION_2	(bpDebug & 0x2)#define	DEBUG_OPTION_3	(bpDebug & 0x4)#define	DEBUG_OPTION_4	(bpDebug & 0x8)#define DEBUG_OPTION_5	(bpDebug & 0x10)			/*  0, 0, 0, 0, unit, host */u_char bpEnetAdrs [6]	= { 0, 0, 0, 0, 0, 0 };/* local variables */LOCAL BOOL bpTasOK;		/* whether hardward can do test-and-set */LOCAL int bpHeartbeatRate;int bpBitBucket;		/* spare change *//* forward declarations */void bpPollTask ();void bpintr ();/* forward static functions */static void bpReset (int unit);static STATUS bpAlive (BP_SOFTC *bs);static STATUS bpIfInit (int unit);static void bpReadAll (int unit);static STATUS bpRead (BP_SOFTC *bs, BUF_NODE *pBufNode, BUF_NODE		*pBufNodeOrig);#if defined BSD43_DRIVER || defined (UNIX)static void bpStart (int unit);static int bpOutput (struct ifnet *ifp, struct mbuf *m0, struct sockaddr		*dst);#elsestatic void bpStart (BP_SOFTC * 	bs);#endifstatic STATUS bpPut (BP_SOFTC *bs, struct mbuf *m);static void bpXmit (BP_SOFTC *bs, BUF_NODE *pBufNode, int destProcNum, int		srcProcNum);static void bpIntAck (BP_SOFTC *bs);static STATUS bpConnect (BP_SOFTC *bs, int unit);static STATUS bpIntEnable (BP_SOFTC *bs);static void bpIntGen (CPU_DESC *pCpu, int srcProcNum);static void bpHeartbeat (BP_ANCHOR *pAnchor);static int bpSizeMem (caddr_t memAdrs, int memSize);static int bpIoctl (struct ifnet *ifp, int cmd, caddr_t data);static void ringinit (RING *rp, short size);#if CPU==R3000static int ringput ();static int ringget ();#elsestatic int ringput (RING *rp, int v);static int ringget (RING *rp);#endifstatic int ringcount (RING *pRing);static BOOL vxTasac (char *address);#ifdef	UNIXLOCAL void	bpRead ();#else	/* UNIX */LOCAL STATUS	bpRead ();#endif	/* UNIX */#ifdef	UNIX/********************************************************************************* bpattach - attach the `bp' interface to the network** Make the `bp' interface available by filling in the network interface record.* The system will initialize the interface when it is ready to accept packets.** RETURNS: N/A** NOMANUAL*/void bpattach (md)    struct mb_device *md;    {    int unit          = md->md_unit;    FAST BP_SOFTC *bs = BP_SOFTC_P [unit];    struct ifnet *ifp = &bs->bs_if;    bs->bs_procNum = bp_procnum;    bs->bs_intType = bp_int_type;    bs->bs_intArg1 = bp_int_arg1;    bs->bs_intArg2 = bp_int_arg2;    bs->bs_intArg3 = bp_int_arg3;    bs->bs_addr = md->md_addr;    bs->bs_ivec = md->md_intr->v_vec;    ether_attach (ifp, unit, "bp", bpIfInit, bpIoctl, bpOutput,                  (FUNCPTR)bpReset);    ifp->if_mtu = bp_mtu;    bzero ((char*) cpudesc_vaddr, sizeof (cpudesc_vaddr));    }/********************************************************************************* bpPoke - map in physical memory and write value to address** This routine is used to map in CPU boards' mailboxes.* An array up to MAXCPU is kept so that a mailbox is* only mapped in once per CPU.*/LOCAL void bpPoke (addr, type, value, cpuNum)    char *addr;		/* physical address */    int type;		/* mailbox size + read/write */    int value;		/* value to write */    int cpuNum;		/* which CPU */    {    char *vaddr;		/* virtual address */    int kmx;			/* kernel map index */    int numClicks;    /* int numBytes; */    int addrOffset;    if (cpuNum < 0 && cpuNum > MAXCPU)	{	printf ("bp: bpPoke invalid cpu #%d\n", cpuNum);	return;	}    if ((vaddr = cpudesc_vaddr [cpuNum]) == 0)	{	numClicks = btoc (sizeof (int));	/* numBytes = ctob (numClicks); */	addrOffset = (int)(addr - ptob (btop (addr)));	/* get some virtual address space */	if ((kmx = rmalloc (kernelmap, numClicks)) == 0)	    {	    printf ("bp: no kernelmap for bp mailbox\n");	    panic ("bpPoke");	    }	vaddr = (char *)kmxtob (kmx);	mapin (&Usrptmap [kmx], btop (vaddr), btop (addr) | PGT_VME_D16,		numClicks, PG_V | PG_KW);	cpudesc_vaddr [cpuNum] = vaddr += addrOffset;	if (DEBUG_OPTION_1)	    printf ("\nbp: cpu #%d mailbox addr = 0x%x, vaddr = 0x%x\n",		    cpuNum, (int)addr, (int)vaddr);	}    switch (type)	{	case BP_INT_MAILBOX_1: *(char  *) vaddr = value; break;	case BP_INT_MAILBOX_2: *(short *) vaddr = value; break;	case BP_INT_MAILBOX_4: *(long  *) vaddr = value; break;	case BP_INT_MAILBOX_R1: value = *(char  *) vaddr; break;	case BP_INT_MAILBOX_R2: value = *(short *) vaddr; break;	case BP_INT_MAILBOX_R4: value = *(long  *) vaddr; break;	default: printf ("bp: bpPoke - bad mailbox type 0x%x\n", type); break;	}#ifdef	MAP_OUT    /* example of mapping out memory */    cpudesc_vaddr [cpuNum] = 0;    mapout (&Usrptmap [kmx], numClicks, kmx);    rmfree (kernelmap, numClicks, kmx);#endif	/* MAP_OUT */    }/********************************************************************************* bpProbe - probe for backplane memory** RETURNS:* The amount of memory available, or 0 if error.** NOMANUAL*/int bpProbe (addr, unit)    caddr_t addr;	/* address of backplane memory */    int unit;		/* device number */    {    int memSize = bp_mem_size;    FAST BP_SOFTC *bs = BP_SOFTC_P [unit];    extern int peek (), pokec ();    if (BP_MASTER)	bpProbeType = bpParity ? pokec : peek;    else	bpProbeType = peek;    if (DEBUG_OPTION_1)	printf ("bp%d: debugging on (level = 0x%x)\n", unit, bpDebug);    /* anchor is at the start of shared memory */    bs->bs_pAnchor = (BP_ANCHOR *) addr;    if ((*bpProbeType) (addr, 0) == -1)	{	printf ("bp%d: shared memory not present at 0x%x (0x%x)\n",		unit, (int)bs->bs_pAnchor,(int)vir2phys((char*)bs->bs_pAnchor));	return (0);	}    if (BP_MASTER &&	bpInit ((char*)bs->bs_pAnchor, addr, memSize, bp_tas) == ERROR)	{	printf ("bp%d: bpProbe cannot initialize anchor!\n", unit);	return (0);	}    if (DEBUG_OPTION_1)	printf ("bp%d: shared memory size is %d bytes, at 0x%x (0x%x)\n", unit,	     memSize,(int)bs->bs_pAnchor, (int)vir2phys((char*)bs->bs_pAnchor));    return (memSize);    }#else	/* UNIX *//********************************************************************************* bpattach - publish the `bp' network interface and initialize the driver and device** This routine attaches a `bp' interface to the network, if the* interface exists.  This routine makes the interface available by filling in* the network interface record.  The system will initialize the interface* when it is ready to accept packets.** RETURN: OK or ERROR.*/STATUS bpattach    (    int unit,           /* backplane unit number */    char *pAnchor,      /* bus pointer to bp anchor */    int procNum,        /* processor number in backplane */    int intType,        /* interrupt type: poll, bus, mailbox */    int intArg1,        /* as per interrupt type */    int intArg2,        /* as per interrupt type */    int intArg3         /* as per interrupt type */    )    {    FAST BP_SOFTC *bs;    FAST struct ifnet *ifp;    FAST BP_ANCHOR *pBpAnchor = (BP_ANCHOR *) pAnchor;    if (procNum == 0)	bpProbeType = bpParity ? O_WRONLY : O_RDONLY;    else	bpProbeType = O_RDONLY;    /* allocate bp_softc structure */    if ((bs = (BP_SOFTC *) malloc (sizeof (BP_SOFTC))) == NULL)	return (ERROR);    bp_softc [unit] = bs;	/* XXX check if non-zero for re-attach? */    ifp = &bs->bs_if;    /* initialize the interface structure */    bzero ((char *) bs, sizeof (BP_SOFTC));    bs->bs_pAnchor = pBpAnchor;    bs->bs_procNum = procNum;    bs->bs_intType = intType;    bs->bs_intArg1 = intArg1;    bs->bs_intArg2 = intArg2;    bs->bs_intArg3 = intArg3;    /* wait for shared memory to be initialized; master CPU does sanity check */    if (bpAlive (bs) == ERROR)	{	(void) free ((void *) bs);	return (ERROR);	}    if (bpDebug != 0)	{	printf ("bp%d: debugging on (level = 0x%x)\n", unit, bpDebug);	printf ("bpattach: anchor CPU can%s do real TAS.\n",		bpTasOK ? "" : "not");	}#ifdef BSD43_DRIVER    ether_attach (ifp, unit, "bp", bpIfInit, bpIoctl, bpOutput,                  (FUNCPTR)bpReset);#else    ether_attach (                 ifp,                 unit,                 "bp",                 (FUNCPTR) bpIfInit,                 (FUNCPTR) bpIoctl,                 (FUNCPTR) ether_output,                 (FUNCPTR) bpReset                 );    ifp->if_start = (FUNCPTR)bpStart;#endif    ifp->if_mtu = bp_mtu;    if (bpIfInit (unit) == ERROR)        {        (void) free ((void *) bs);        return (ERROR);        }    return (OK);    }#endif	/* UNIX *//********************************************************************************* bpInit - initialize the backplane anchor** This routine initializes the backplane anchor.  Typically, <pAnchor> and* <pMem> both point to the same block of shared memory.  If the first* processor is dual-porting its memory, then, by convention, the anchor is* at 0x600 (only 16 bytes are required) and the start of memory <pMem> is* dynamically allocated by using the value NONE (-1).  <memSize> should be at* least 64 Kbytes.  The <tasOK> parameter is provided for CPUs that do* not support the test-and-set instruction.  If the system includes any* test-and-set deficient CPUs, then all CPUs must use the software* "test-and-set".** RETURNS:* OK, or ERROR if data structures cannot be set up or memory is insufficient.*/STATUS bpInit    (    FAST char *pAnchor, /* backplane anchor address */    FAST char *pMem,    /* start of backplane shared memory, NONE = alloc */    int memSize,        /* no. bytes in bp shared memory, 0 = 0x100000 */    BOOL tasOK          /* TRUE = hardware can do test-and-set */    )    {    FAST BP_ANCHOR *pBpAnchor = (BP_ANCHOR *) pAnchor;    FAST RING *pFreeRing;    FAST int ix;    FAST char *pMemEnd;	/* end of backplane shared memory */    FAST CPU_DESC *pCpu;    FAST BP_HEADER *pHdr;    int npackets = 0;    memSize = (memSize == 0) ? 0x100000 : memSize;    bpTasOK = tasOK;    /* if bp header specified, probe it, otherwise malloc it */    if (pMem != (char *) NONE)	{	memSize = min (memSize, bpSizeMem (pMem, memSize));	if (memSize == 0)	    {	    printf ("bp: no shared memory at address 0x%x\n", (int)pMem);	    return (ERROR);	    }	/* if anchor is at start of shared region, skip over it */	if (pMem == pAnchor)	    {	    pMem    += sizeof (BP_ANCHOR);	    memSize -= sizeof (BP_ANCHOR);	    }	}    else	{#ifndef	UNIX#if	((CPU_FAMILY==MIPS) || (CPU_FAMILY==SH))	if ((pMem = (char *) cacheDmaMalloc ((unsigned) memSize)) == NULL)#else	/* CPU_FAMILY==MIPS || CPU_FAMILY==SH */        if ((pMem = (char *) malloc ((unsigned) memSize)) == NULL)#endif	/* CPU_FAMILY==MIPS || CPU_FAMILY==SH */#endif	/* UNIX */	    {	    printf ("bp: can't allocate shared memory\n");

⌨️ 快捷键说明

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