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

📄 if_sm.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 2 页
字号:
            }    	else    	    {	    pEaddr = etherAddrPtr (pEh->ether_dhost);            if (xs->masterAddr != 0)		/* sequential addressing */		{		destCPU = ((pEaddr [3] << 16)|(pEaddr [4] << 8)| pEaddr [5]) -		          xs->masterAddr;		}	    else		destCPU = pEaddr [5];            /* receive packets sent to self */    	    if (destCPU == xs->smPktDesc.smDesc.cpuNum)    		{    		smIfRecv (xs, pPkt, &retBuffer);                if (retBuffer)                    (void) smPktFreePut (&xs->smPktDesc, (SM_PKT *)pPkt);                continue;                 /* don't use SM to send to self */    		}    	    }  	if (smIfVerbose)	    {	    printf ("smIfStartOutput: [0x%x] len:%d src:%s ", pEh->ether_type,		    len, ether_sprintf (etherAddrPtr (pEh->ether_shost)));	    printf ("dst:%s cpu [%d]\n",		    ether_sprintf (etherAddrPtr (pEh->ether_dhost)), destCPU);	    }	xs->xs_if.if_opackets++;	        	if (smPktSend (&xs->smPktDesc, (SM_PKT *)pPkt, destCPU) == ERROR)    	    {	    if (smIfVerbose)	    	printf ("smIfStartOutput:smPktSend failed 0x%x\n", errno);    	    xs->xs_if.if_oerrors++;	    xs->xs_if.if_opackets--;	    /*	     * need to return shared memory packet on error,	     * unless it's a incomplete broadcast error.	     */    	    if (errno != S_smPktLib_INCOMPLETE_BROADCAST)    		(void) smPktFreePut (&xs->smPktDesc, (SM_PKT *)pPkt);    	    }    	}    }/******************************************************************************** smIfReset - reset the backplane interface** smIfReset resets the interface.  This gets called when the system* receives a reset.  Basically this routine cleans up the state and marks* the interface as inactive before it goes away.** RETURNS: N/A** NOMANUAL*/LOCAL void smIfReset    (    int  unit				/* unit number */    )    {    SM_SOFTC * xs = UNIT_TO_SOFTC (unit);	/* softc pointer */    int        spl;				/* spl level 	 */    if (!deviceValid (unit))    	return;    /* detach from network */    spl = splimp ();    xs->xs_if.if_flags &= ~IFF_RUNNING;    if_down (&xs->xs_if);    splx (spl);    /* detach from shared mem */    (void) smPktDetach (&xs->smPktDesc, SM_FLUSH);    }/******************************************************************************** smIfIoctl - process an ioctl request** smIfIoctl gets called to perform a control operation on the backplane network* interface.  The implemented commands include: SIOCSIFADDR (set interface* address) SIOCSIFFLAGS (set interface flags), SIOCGIFADDR get (link-level)* interface address.** RETURNS: OK if successful, otherwise errno.** NOMANUAL*/LOCAL int smIfIoctl    (    struct ifnet * pIf,		/* interface pointer */    UINT	   cmd,		/* ioctl command */    caddr_t 	   data		/* command data */    )    {    struct ifreq * pIfr;		/* if request */    int		   retVal = OK;		/* error value */    int		   spl    = splimp ();	/* spl level */    SM_SOFTC *	   xs     = UNIT_TO_SOFTC (pIf->if_unit);    struct in_addr ipAddr;		/* address passed */    struct in_addr expAddr;		/* expected address */    char	   netString[32];    pIfr = (struct ifreq *) data;    switch (cmd)        {        case SIOCSIFADDR:			/* set interface address */    	    retVal = set_if_addr (pIf, data, etherAddrPtr (xs->xs_enaddr));	    if ((retVal == OK) && (xs->masterAddr != 0))		{	    	/*	    	 * We validate address after set_if_addr because	         * shared memory must be up (smPktAttach) before master	     	 * address can be determined.	     	 */		ipAddr = ((struct in_ifaddr *) data)->ia_addr.sin_addr;	    	expAddr.s_addr = htonl (				 ntohl (xs->smPktDesc.hdrLocalAdrs->reserved1)+			  	 xs->smPktDesc.smDesc.cpuNum);	    	if (expAddr.s_addr != ipAddr.s_addr)		    {		    inet_ntoa_b (expAddr, netString);	            printf ("Seqential addressing enabled - expected address:"			    "%s\n", netString);		    smIfReset (pIf->if_unit);	    	    retVal = ERROR;	            }	        }    	    break;	case SIOCSIFFLAGS:			/* set interface flags */    	    if (pIf->if_flags & IFF_UP)		smIfInit (pIf->if_unit);	    break;        case SIOCGIFADDR:			/* get link level address */	    bcopy ((caddr_t) etherAddrPtr (xs->xs_enaddr),		   (caddr_t)(pIfr->ifr_addr.sa_data), sizeof (xs->xs_enaddr));            break;	case SIOCADDMULTI:	case SIOCDELMULTI:	    if (pIfr == 0)		{		retVal = EINVAL; 		/* invalid argument passed */		break;		}	    switch (pIfr->ifr_addr.sa_family)		{#ifdef INET		case AF_INET:			/* do nothing */		    break;#endif		default:		    retVal = EAFNOSUPPORT;		    break;		}	    break;    	default:	    if (smIfVerbose)		printf ("smIfIoctl: [0x%x] command not implemented\n", cmd);    	    retVal = EINVAL;	}    (void) splx (spl);    return (retVal);    }/******************************************************************************** smIfInput - handle an input packet** smIfInput gets called from the OS specific interrupt handling routine* to process a shared memory input packet.  It calls smPktRecv to obtain* the packets from shared memory and then calls smIfRecv to process the* packet and pass it up to the network modules.** RETURNS: N/A** NOMANUAL*/void smIfInput    (    SM_SOFTC * xs		/* softc pointer */    )    {    SM_PKT *   pPkt;		/* shared memory packet */    int        status;		/* status */    BOOL       retBuffer;	/* return packet */    int        cpuNum;		/* my cpu number */    cpuNum = xs->smPktDesc.smDesc.cpuNum;    do	{	xs->taskRecvActive = TRUE;    	while (((status = smPktRecv (&xs->smPktDesc, &pPkt)) == OK) &&    	       (pPkt != NULL))	    {    	    smIfRecv (xs, pPkt, &retBuffer);	    if (retBuffer)		(void) smPktFreePut (&xs->smPktDesc, pPkt);	    }	if (status == ERROR)	    {	    xs->xs_if.if_ierrors++;	    if (smIfVerbose)	        printf ("smIfInput:error receiving packet 0x%x\n", errno);	    }	xs->taskRecvActive = FALSE;	} while ((xs->smPktDesc.status == SM_CPU_ATTACHED) &&	         (smIfInputCount (xs, cpuNum) > 0));    }/******************************************************************************** smIfRecv - process shared memory input packet** smIfRecv is called once per packet that arrives.  It calls check_trailer* to process trailers.  Copies that packet into an mbuf chain (if buffer* loaning is not set).  Then passes the packet to the network layer by calling* do_protocol.** RETURNS: N/A** NOMANUAL*/LOCAL void smIfRecv    (    SM_SOFTC *        xs,		/* softc pointer */    SM_PKT volatile * pPkt,		/* packet */    BOOL *            retBuffer		/* kept buffer */    )    {    struct ether_header * pEh;		/* ethernet header */    int			  len;		/* length */    u_char *		  pData;	/* pointer to data */    struct mbuf *	  pMbuf = NULL;	/* mbuf pointer */    *retBuffer = TRUE;    		/* return buffer by default */    CACHE_PIPE_FLUSH ();		/* CACHE FLUSH   [SPR 68334] */    len = pPkt->header.nBytes;		/* PCI bug       [SPR 68844] */    len = pPkt->header.nBytes;    pEh = (struct ether_header *) pPkt->data;    if (inputHook (&xs->xs_if, (char *) pEh, len))	return;    if (len < SIZEOF_ETHERHEADER)	{	if (smIfVerbose)	    printf ("smIfRecv:invalid packet len %d\n", len);	xs->xs_if.if_ierrors++;	return;					/* invalid packet size */	}    if (smIfVerbose)				/* debugging aide */	{        printf ("smIfRecv [0x%x] len: %d src:%s ", ntohs (pEh->ether_type), len,	        ether_sprintf (etherAddrPtr (pEh->ether_shost)));	printf ("dst:%s\n", ether_sprintf (etherAddrPtr (pEh->ether_dhost)));	}    len -= SIZEOF_ETHERHEADER;			/* adj. for enet header */    pData = ((unsigned char *) pEh) + SIZEOF_ETHERHEADER;    if (len == 0)	return;					/* packet with no data */    /*     * try to build a loaned mbuf cluster (if buffering loaning is enabled,     * there are loan buffers available, the packet doesn't use     * trailers, and the packet is big enough).  Otherwise copy it     * to an mbuf.     */    if ((xs->bufFree > 0) && (USE_CLUSTER (len)))  	{	if ((pMbuf = loanBuild (xs, pPkt, pData, len)) != NULL)  	    {	    xs->bufFree--;	    *retBuffer = FALSE;	    }	}    if (pMbuf == NULL)	{    	if ((pMbuf = (struct mbuf *)		     copyToMbufs (pData, len, 0, &xs->xs_if)) == NULL)	    return;    	}    do_protocol (pEh, pMbuf, &xs->xs_ac, len);    xs->xs_if.if_ipackets++;    }/******************************************************************************** smIfLoanReturn - return shared memory packet to shared memory pool** smPktReturn gets called from the network modules to return the loaned* shared memory buffer once the network code has finished with it.  It gets* called with the spl semaphore taken.** RETURNS: N/A** NOMANUAL*/void smIfLoanReturn    (    SM_SOFTC * xs,            /* softc pointer */    SM_PKT *   pPkt           /* shared memory packet */    )    {    if (smPktFreePut (&xs->smPktDesc, pPkt) == ERROR)	return;    xs->bufFree++;    }/******************************************************************************** smIfHwAddrSet - set hardware address** This routine sets the hardware address associated with the backplane * interface specified by <unit>.** RETURNS: N/A** NOMANUAL*/LOCAL void smIfHwAddrSet    (    int  unit 		/* unit number */    )    {    u_char * 	     pEaddr;			/* ethernet address */    u_long	     addr;			/* address */    int              tmp;			/* temp storage */    SM_PKT_MEM_HDR volatile * pSmPktHdr;	/* packet header */    SM_SOFTC *       xs = UNIT_TO_SOFTC (unit); /* softc pointer */    pEaddr = etherAddrPtr(xs->xs_enaddr);    bzero ((caddr_t)pEaddr, 6);		/* fill in ethernet address */    pEaddr [0] = 0x00;    pEaddr [1] = 0x02;    pEaddr [2] = 0xE2;    pSmPktHdr = (SM_PKT_MEM_HDR volatile *)xs->smPktDesc.hdrLocalAdrs;    CACHE_PIPE_FLUSH ();		/* CACHE FLUSH   [SPR 68334] */    tmp = pSmPktHdr->reserved1;		/* PCI bug       [SPR 68844] */    if (pSmPktHdr->reserved1 != 0)		/* sequential addressing */	{	/*	 * The backplane hw address consists of	 * { 0x00, 0x02, 0xE2, ip[1], ip[2], ip[3] }.	 * where ip is the lower three bytes of	 * the IP interface address.	 */	xs->masterAddr = ntohl (pSmPktHdr->reserved1) & 0x00ffffff;	addr = xs->masterAddr + xs->smPktDesc.smDesc.cpuNum;	pEaddr [3] = (u_char)((addr >> 16) & 0xff);	pEaddr [4] = (u_char)((addr >> 8)  & 0xff);	pEaddr [5] = (u_char)(addr & 0xff);	}    else	{    	/*    	 * Backplane hw address consists of     	 * { 0x00, 0x02, 0xE2, 0x00, unit, cpu }.     	 */	pEaddr [4] =  (u_char)unit;	pEaddr [5] =  (u_char)xs->smPktDesc.smDesc.cpuNum;	}    if (smIfVerbose)	printf ("hw address:%s\n", ether_sprintf (pEaddr));    }

⌨️ 快捷键说明

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