Пример #1
0
LOCAL STATUS wdbEndPoll
    (
    void *	pDev
    )
    {
    long 		type;
    M_BLK_ID 		pMblk;
    WDB_END_PKT_DEV * 	pPktDev = pDev;
    LL_HDR_INFO  	llHdrInfo;
    int			mode = WDB_COMM_MODE_POLL; 
    END_OBJ * 		pEnd = PCOOKIE_TO_ENDOBJ(pPktDev->pCookie);

    /* Reset the size to the maximum. */

    pPktDev->pInBlk->mBlkHdr.mLen = pPktDev->pInBlk->pClBlk->clSize;
    pPktDev->pInBlk->mBlkHdr.mData = pPktDev->pInBlk->pClBlk->clNode.pClBuf;

#ifdef WDB_NPT_CAPABLE
    if (muxTkPollReceive (pPktDev->pCookie, pPktDev->pInBlk, NULL) == OK)
#else
    if (muxPollReceive (pPktDev->pCookie, pPktDev->pInBlk) == OK)
#endif /* WDB_NPT_CAPABLE */
	{
        if ((pMblk = mBlkGet (pEnd->pNetPool, M_DONTWAIT, MT_DATA)) == NULL)
            return (ERROR);

        /* duplicate the received mBlk so that wdbEndInt can free it */

        pMblk = netMblkDup (pPktDev->pInBlk, pMblk);

#ifndef WDB_NPT_CAPABLE
        if (muxPacketDataGet (pPktDev->pCookie, pMblk, &llHdrInfo) == ERROR)
	    {
	    return (ERROR);
	    }
#else
	if ((pEnd->mib2Tbl.ifType == M2_ifType_ethernet_csmacd) ||
	    (pEnd->mib2Tbl.ifType == M2_ifType_iso88023_csmacd))
	    {
	    if (endEtherPacketDataGet (pMblk, &llHdrInfo) == ERROR)
		{
		return (ERROR);
		}
	    }
	else
	    return ERROR;
#endif /* WDB_NPT_CAPABLE */

        type = llHdrInfo.pktType;

        if (wdbEndInt (pPktDev->pCookie, type, pMblk, &llHdrInfo,
                       (void *)&mode) == TRUE)
            return (OK);
        return (ERROR);
        }
    else
        {
        return (ERROR);
        }
    }
Пример #2
0
/*
 * Send the received packet to END driver
 */
int
NetdrvSendToEnd(bcm_pkt_t *pPkt)
{
    int         len;
    M_BLK_ID    pMblk;
    char*       pCluster = NULL;
    CL_BLK_ID   pClBlk;
    END_DEVICE  *pDrvCtrl = __netDriver;

    if (pDrvCtrl == NULL) {
        return ERROR;
    }

    /* Add one to our unicast data. */
    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);

    /*
     * We implicitly are loaning here, if copying is necessary this
     * step may be skipped, but the data must be copied before being
     * passed up to the protocols.
     */
    pCluster = netClusterGet (pDrvCtrl->end.pNetPool, pDrvCtrl->pClPoolId);

    if (pCluster == NULL) {
        DRV_LOG (1, "Cannot loan!\n",1,2,3,4,5,6);
        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
        goto cleanRXD;
    }

    /* Grab a cluster block to marry to the cluster we received. */
    if ((pClBlk = netClBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT)) == NULL) {
        netClFree (pDrvCtrl->end.pNetPool, (UCHAR *)pCluster);
        DRV_LOG (DRV_DEBUG_RX, "Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6);
        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
        goto cleanRXD;
    }

    /*
     * OK we've got a spare, let's get an M_BLK_ID and marry it to the
     * one in the ring.
     */
    if ((pMblk = mBlkGet (pDrvCtrl->end.pNetPool, M_DONTWAIT, MT_DATA)) == NULL) {
        netClBlkFree (pDrvCtrl->end.pNetPool, pClBlk);
        netClFree (pDrvCtrl->end.pNetPool, (UCHAR *)pCluster);
        DRV_LOG (DRV_DEBUG_RX, "Out of M Blocks!\n", 1, 2, 3, 4, 5, 6);
        END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_ERRS, +1);
        goto cleanRXD;
    }

    /* remove tag */
    len = pPkt->tot_len - 8;

    memcpy(pCluster + 2, (unsigned char *)(&(pPkt->_pkt_data.data[0])), 12);
    memcpy(pCluster + 14, (unsigned char *)(&(pPkt->_pkt_data.data[16])), len-12);

    /* Free buffer previously stolen */
    bcm_rx_free(pPkt->unit, pPkt->_pkt_data.data);

    /* Join the cluster to the MBlock */
    netClBlkJoin (pClBlk, pCluster, len, NULL, 0, 0, 0);
    netMblkClJoin (pMblk, pClBlk);

    pMblk->mBlkHdr.mLen = len;
    pMblk->mBlkHdr.mData += 2;
    pMblk->mBlkHdr.mFlags |= M_PKTHDR;
    pMblk->mBlkPktHdr.len = len;

    /* Send the packet to END driver */
    END_RCV_RTN_CALL(&__netDriver->end, pMblk);
    g_ulPktUp++;

    return OK;

    cleanRXD:
    return (ERROR);
}
Пример #3
0
MBUF_ID _mbufDup
    (
    MBUF_ID		mbufId,		/* mbuf ID to duplicate */
    MBUF_SEG		mbufSeg,	/* mbuf base for <offset> */
    int			offset,		/* relative byte offset */
    int			len		/* number of bytes to duplicate */
    )
    {
    MBUF_ID		mbufIdNew;	/* mbuf ID of duplicate */
    MBUF_SEG		mbufNew;	/* mbuf for duplicate */
    MBUF_SEG *		pMbufPrev;	/* mbuf prev to mbufNew */

    /* find the starting location for duplicate */

    if ((mbufSeg = _mbufSegFind (mbufId, mbufSeg, &offset)) == NULL)
        return (NULL);

    if (len < 0)				/* negative = rest of chain */
	len = INT_MAX;

    MBUF_ID_CREATE (mbufIdNew);			/* get ID for duplicate */
    if (mbufIdNew == NULL)
        return (NULL);

    pMbufPrev = &mbufIdNew->mbufHead;		/* init prev ptr to head */

    while (len && (mbufSeg != NULL))		/* while more to duplicate */
	{
	/* get mbuf for duplicate */
        if ( (mbufNew = mBlkGet (_pNetDpool, M_WAIT, mbufSeg->m_type)) == NULL)
	    {
	    /* release on fail */
	    
	    MBUF_ID_DELETE(mbufIdNew);		
	    return (NULL);
	    }

        mbufNew->m_len = min (len, (mbufSeg->m_len - offset));
        len -= mbufNew->m_len;			/* num to duplicate */

	/* copy the cluster header mbuf info to duplicate */
	mbufNew->m_data	= mtod (mbufSeg, char *)  + offset;
	mbufNew->m_flags	= mbufSeg->m_flags;
	mbufNew->m_ext	= mbufSeg->m_ext;

	/* bump share count */

	{
	int s = intLock ();
	++(mbufNew->m_extRefCnt);
	intUnlock (s);
	}
	    
	*pMbufPrev = mbufNew;			/* hook prev into duplicate */
        pMbufPrev = &mbufNew->m_next;		/* update prev mbuf ptr */
	mbufSeg = mbufSeg->m_next;		/* bump original chain */
	offset = 0;				/* no more offset */
	}

    return (mbufIdNew);				/* return ID of duplicate */
    }
Пример #4
0
MBUF_SEG _mbufInsertBuf
    (
    MBUF_ID		mbufId,		/* mbuf	ID which buffer is inserted */
    MBUF_SEG		mbufSeg,	/* mbuf base for <offset> */
    int			offset,		/* relative byte offset */
    caddr_t		buf,		/* user buffer for mbuf cluster */
    int			len,		/* number of bytes to insert */
    VOIDFUNCPTR		freeRtn,	/* user free routine */
    int			freeArg		/* argument to free routine */
    )
    {
    MBUF_ID		mbufIdNew;		/* mbuf ID containing <buf> */
    MBUF_DESC 		mbufDesc;		/* desc for <buf> cluster */
    MBUF_SEG		mbufNew;		/* mbuf for <buf> cluster */
    CL_BLK_ID		pClBlk;			/* pointer to cluster blk */
    int			lockKey;		/* int lock cookie */
    int			ix;			/* counter for list init */

    if (len <= 0)				/* have to insert some bytes */
        {
	errno = S_mbufLib_LENGTH_INVALID;
	return (NULL);
	}

    MBUF_ID_CREATE (mbufIdNew);			/* create new mbuf ID for buf */
    if (mbufIdNew == NULL)
	return (NULL);

    lockKey = intLock ();

    if ((mbufDesc = mbufDescHead) != NULL)	/* free list empty ? */
        {
        mbufDescHead = mbufDesc->mbufDescNext;	/* pop first desc off list */
        intUnlock (lockKey);
	}
    else					/* list is empty */
	{
        intUnlock (lockKey);

	if ((mbufDesc = (MBUF_DESC) KHEAP_ALLOC((sizeof (struct mbufDesc) *
	    MBUF_DESC_INC))) != NULL)		/* alloc more desc's */
            {
            for (ix = 0; ix < (MBUF_DESC_INC - 1); ix++)
                mbufDesc[ix].mbufDescNext = &mbufDesc[ix + 1];

            lockKey = intLock ();
            mbufDesc[ix].mbufDescNext = mbufDescHead;
            mbufDescHead = mbufDesc->mbufDescNext;/* hook head onto new list */
            intUnlock (lockKey);
	    }
        }

    if (mbufDesc == NULL)			/* able to get a new desc ? */
	{
        MBUF_ID_DELETE_EMPTY(mbufIdNew);
	return (NULL);
	}

    mbufDesc->buf = buf;

    /* get mbuf for cluster */
    
    if ( (mbufNew = mBlkGet (_pNetDpool, M_WAIT, MT_DATA)) == NULL)
        {
	/* release on fail */

	lockKey = intLock ();
	mbufDescHead = mbufDesc;
	intUnlock (lockKey);

	MBUF_ID_DELETE_EMPTY (mbufIdNew);		
	return (NULL);
	}

    pClBlk = clBlkGet (_pNetDpool, M_WAIT); 
    
    if (pClBlk == NULL)			/* out of cl Blks */
        {
        m_free (mbufNew);

	lockKey = intLock ();
	mbufDescHead = mbufDesc;
	intUnlock (lockKey);

	MBUF_ID_DELETE_EMPTY (mbufIdNew);		
	return (NULL);
        }

    mbufNew->pClBlk		= pClBlk;

    /* build <buf> into an mbuf cluster */
    mbufNew->m_data		= buf;
    mbufNew->m_len		= len;
    mbufNew->m_flags		|= M_EXT;
    mbufNew->m_extBuf		= buf;
    mbufNew->m_extSize		= len;
    mbufNew->m_extFreeRtn	= (FUNCPTR) _mbufBufFree;
    mbufNew->m_extRefCnt	= 1;
    mbufNew->m_extArg1		= (int) mbufDesc;
    mbufNew->m_extArg2		= (int) freeRtn;
    mbufNew->m_extArg3		= freeArg;

    mbufIdNew->mbufHead = mbufNew;		/* put cluster into new ID */

    /* insert the new mbuf ID with <buf> into <mbufId> */

    if ((mbufSeg = _mbufInsert (mbufId, mbufSeg, offset, mbufIdNew)) == NULL)
	{
        mbufNew->m_extArg2 = (int)NULL;		/* don't call freeRtn on fail */
        MBUF_ID_DELETE(mbufIdNew);
	}

    return (mbufSeg);				/* return inserted mbuf */
    }
Пример #5
0
void
socend_receive_netjob(int pi, int pckti, int pckt_size)
/*
 * Function: 	socend_receive_netjob
 * Purpose:	Called from netjob after packet arrives.
 * Parameters:	p - pointer to (se), cookied passed on registration
 *		pckpi - pointer to packet data (int form).
 *		pckt_size - received length of packet.
 * Returns:	Nothing
 */
{
    socend_t		*se = (socend_t *)pi;
    struct end_object 	*eo = &se->se_eo;
    void		*pckt = (void *)pckti;
    bcm_vlan_t		vid;
    CL_BLK_ID		cb = NULL;
    M_BLK_ID		mb = NULL;

    /* Check the DCB for errors */
#if defined(BROADCOM_DEBUG)			/* Only compile in for debug */
    if (LOG_CHECK(BSL_LS_SYS_END | BSL_INFO) &&
        LOG_CHECK(BSL_LS_SOC_PACKET | BSL_INFO)) {
	d_packet_format("socend RX", DECODE_ETHER, pckt, pckt_size, NULL);
    }
#endif /* BROADCOM_DEBUG */
    /*
     * Build Cluster - then attach to mblks, 1 for each interface that
     * should get the packet. Broadcast/Multicast packets go up all the stacks.
     *
     * For multicast, it should only go up stacks that have registered for that
     * address, but for now, this will allow multiple interfaces to work.
     */

    if ((NULL == (cb = netClBlkGet(eo->pNetPool, M_DONTWAIT)))) {
	if (mb) netMblkFree(eo->pNetPool, mb);
	netClFree(eo->pNetPool, pckt);	/* Free packet */
	END_ERR_ADD(eo, MIB2_IN_ERRS, +1);
	return;
    }

#if defined(__mips__)
    if (SOC_IS_ESW(se->se_unit)) 
    {
        seu_t *seu = &socend_seu[se->se_unit];
        void  *tmp;
	
        sal_memcpy((UINT8 *)seu->pkt_align_buf + 2, (UINT8 *)pckt, pckt_size);
	
        tmp = seu->pkt_align_buf;
        seu->pkt_align_buf = pckt;
        pckt = tmp;
    }
#endif /* __mips__ */

    /* 1 MBLK for each interface */

    if ((mb = mBlkGet(eo->pNetPool, M_DONTWAIT, MT_DATA))) {
	netClBlkJoin(cb, pckt, SOC_END_PK_SZ, NULL, 0, 0, 0);
	netMblkClJoin(mb, cb);
	mb->mBlkPktHdr.len = mb->mBlkHdr.mLen = pckt_size;
	mb->mBlkHdr.mFlags |= M_PKTHDR;
#if defined(__mips__)
        if (SOC_IS_ESW(se->se_unit)) {
            mb->mBlkHdr.mData +=2;
        }
#endif /* __mips__ */
	vid = VLAN_CTRL_ID(soc_ntohs(((enet_hdr_t *)mb->mBlkHdr.mData)->en_tag_ctrl));
        if (SOC_IS_ESW(se->se_unit)) {
            socend_untag(mb);		/* Untag packet for now */
        } else {
            robo_socend_untag(mb);		/* Untag packet for now */
        }
    } else {
	netClBlkFree(eo->pNetPool, cb);
	netClFree(eo->pNetPool, pckt);	/* Free packet */
	return;
    }

    {
	M_BLK_ID	tmb, fmb = mb;
	seu_t		*seu = &socend_seu[se->se_unit];
	/*
	 * Duplicate MBLK, and point to same cluster.
	 */
	for (se = seu->seu_devices; se != NULL; se = se->se_next) {

	    if (vid != se->se_vlan) {
		continue;
	    }

	    eo = &se->se_eo;

	    if (se->se_next != NULL) {
		tmb = mBlkGet(eo->pNetPool, M_DONTWAIT, MT_DATA);
		netMblkDup(mb, tmb);
	    } else {
		fmb = NULL;
		tmb = mb;
	    }

	    END_RCV_RTN_CALL(eo, tmb);
	}

	if (fmb) {
	    netMblkClFree(fmb);
	}
    }
}