LOCAL void mirrorEndReceive
    (
    END_CTRL*   pDrvCtrl,       /* pointer to END_CTRL structure */
    M_BLK*      pMblk
    )
    { 
    UINT16 * pTmp;
    UINT16   enetAddr[3];

    LOG_MSG("mirrorEndReceive: unit: %d, ", 
	    (int)pDrvCtrl->unit, 
	    2, 3, 4, 5, 6);
    LOG_MSG("dst:%02X:%02X:%02X:%02X:%02X:%02X, ",
            *(UCHAR *)(pMblk->mBlkHdr.mData),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 1),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 2),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 3),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 4),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 5));
    LOG_MSG("src:%02X:%02X:%02X:%02X:%02X:%02X\n",
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 6),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 7),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 8),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 9),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 10),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 11));
        
   /* don't allow the packet through if in polling mode */

   if (pDrvCtrl->polling == TRUE)
       {
       netMblkClChainFree(pMblk);
       return;
       }

   /* if unit is not in promiscuous mode, filter packets to receive only
    * packets for our MAC address or broadcasts.
    */
    if (pDrvCtrl->promiscuous == FALSE)
        {
        pTmp = (UINT16 *)(pMblk->mBlkHdr.mData);
        if (((UINT32)(pTmp) & 0x01) == 0)
            {
            /* address is aligned on a 2 or 4 byte boundary */
            enetAddr[0] = pTmp[0];
            enetAddr[1] = pTmp[1];
            enetAddr[2] = pTmp[2];
            }
        else
            {
            /* address is aligned on a byte-boundary */
            bcopy((char *)pTmp, (char *)enetAddr, 6);
            }
            
        if ((MAC_ADDR_EQ(enetAddr, pDrvCtrl->enetAddr) == 0) &&
            (IS_BROADCAST(enetAddr) == 0) &&
            (isInMulticastList(pDrvCtrl, enetAddr) == FALSE))
            {
            LOG_MSG("Dest addr not my addr/broadcast/multicast - dropping!\n",
                    1, 2, 3, 4, 5, 6);
            netMblkClChainFree(pMblk);
            return;
            }
        }
   
    LOG_MSG("Sending up the packet to my network stack\n",
            1, 2, 3, 4, 5, 6);

    /* send up to protocol */
    END_RCV_RTN_CALL(&pDrvCtrl->endObject, pMblk);

    /* bump input packet counter */
    END_ERR_ADD(&pDrvCtrl->endObject, MIB2_IN_UCAST, +1);    
    }
LOCAL STATUS mirrorEndSend
    (
    END_CTRL*   pDrvCtrl,
    M_BLK*      pMblk
    )
    {
    int         otherHalfOfMirror;
    int status = OK;

    LOG_MSG("mirrorEndSend: unit: %d, pollMode: %d, ",
            (int)pDrvCtrl->unit, 
            (int)pDrvCtrl->polling, 
            4, 5, 6, 7);
    LOG_MSG("dst:%02X:%02X:%02X:%02X:%02X:%02X, ",
            *(UCHAR *)(pMblk->mBlkHdr.mData),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 1),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 2),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 3),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 4),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 5));
    LOG_MSG("src:%02X:%02X:%02X:%02X:%02X:%02X\n",
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 6),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 7),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 8),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 9),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 10),
            *((UCHAR *)(pMblk->mBlkHdr.mData) + 11));

    if (pDrvCtrl->polling == TRUE)
        {
        netMblkClChainFree (pMblk); /* free the given mBlk chain */
        return ERROR;
        }

    otherHalfOfMirror = pDrvCtrl->unit ^ 1;     /* 0->1, 1->0 */

    if (channelState[otherHalfOfMirror] == CHANNEL_UP)
        {
        /* other half of mirror is up, send packet there */

       
	if (pDrvCtrl->unit == MIRROR_STACK_UNIT_NUM)
            mirrorSendStatus = OK;

        /*
         * In the previous version of the Bridge, calling mirrorEndReceive
         * directly caused deadlock when bridge tries to flood multicasts
         * outgoing from local stack. One way to avoid the deadlock is to
         * call mirrorEndReceive from tNetTask by using netJobAdd. But this
         * causes performance hit, and also overloads the netJob ring buffer.
         *
         * The better solution is to call mirrorEndReceive directly, and
         * avoid deadlock by not taking the bridge port list semaphore when
         * flooding packets to all bridge ports. Taking this semaphore was
         * previously thought necessary to guard against removal of a bridge
         * port when the bridge is flooding packets to that port. The 
         * possibility of this occurring is very small, and can be avoided
         * if the user makes sure the bridge port is free of incoming and
         * outgoing traffic before removing the bridge port.
         */

        mirrorEndReceive(&drvCtrl[otherHalfOfMirror], pMblk);

        if (pDrvCtrl->unit == MIRROR_STACK_UNIT_NUM)
            status = mirrorSendStatus;
        }
    else 
        {
        /* other half of mirror is not up, toss the packet */

        netMblkClChainFree(pMblk);
        }

    /* Bump the statistic counter. */
    END_ERR_ADD(&pDrvCtrl->endObject, MIB2_OUT_UCAST, +1);

    return status;
    }
Exemplo n.º 3
0
Arquivo: vx_osl.c Projeto: ariavie/bcm
/* Free the packet. Free the packettags from the chained packets */
void
osl_pktfree(M_BLK_ID m) /* PED: remove osh parameter */
{
	netMblkClChainFree(m);
}
Exemplo n.º 4
0
Arquivo: vx_osl.c Projeto: ariavie/bcm
void
osl_pktfree(void *drv, M_BLK_ID m, bool send)
{
	netMblkClChainFree(m);
}
Exemplo n.º 5
0
Arquivo: socend.c Projeto: ariavie/bcm
STATUS
socend_send(_END_OBJ_PAR *p, M_BLK_ID mb)
/*
 * Function: 	socend_send
 * Purpose:	SENS send packet interface to SOC device.
 * Parameters:	p - pointer to VxWorks end_obj structure for device
 *		mb - mBlk containing packet.
 * Returns:	OK/ERROR
 *
 * Notes: Since since we don't have scatter/gather capability right
 *	  now, we must copy up the data into one clustered buffer.
 *	  If Possible, we simply hand off the buffer.
 */
{
    int			rv;
    struct end_object 	*eo = (struct end_object *)p;
    socend_t 		*se = (socend_t *)eo->devObject.pDevice;
    char		*packet;
    int			l;
    enet_hdr_t		*eh;
    void *cookie;
    bcm_pkt_t *pkt;

    if (NULL == (pkt = sal_alloc(sizeof(bcm_pkt_t), "bcm pkt"))) {
        return(ENOMEM);
    }

    /*
     * If there is more than one cluster, we must allocate another
     * buffer and copy the data.
     *
     * Note: Requires entire ethernet header to be in first mblk.
     */

    if (mb->mBlkHdr.mNext|| !ENET_TAGGED((enet_hdr_t *)mb->mBlkHdr.mData)) {
        if (SOC_IS_ESW(se->se_unit)) {
            socend_packet_alloc(se->se_unit,SOC_END_PK_SZ, 0, (void*)&packet);
        } else {
            packet = soc_cm_salloc(se->se_unit, SOC_END_PK_SZ, 
                            "SOCEND_TX");
        }
        if (NULL == (packet)) {
            END_ERR_ADD(eo, MIB2_OUT_ERRS, +1);
            netMblkClChainFree(mb);
            return(ENOMEM);
        }

	cookie = NULL;
	/*
	 * If packet is not tagged, build a tag now.
	 */
	eh = (enet_hdr_t *)packet;
	if (!ENET_TAGGED((enet_hdr_t *)mb->mBlkHdr.mData)) {

	  
	  /* Set COS to default here */
	    l = ENET_TAG_SIZE +
		netMblkToBufCopy(mb, packet + ENET_TAG_SIZE, NULL);
	    /* Copy MAC addresses */
	    sal_memcpy(eh, mb->mBlkHdr.mData, sizeof(sal_mac_addr_t) * 2);

	    /* Set VLAN info */
	    eh->en_tag_tpid = htons(ENET_DEFAULT_TPID);
	    eh->en_tag_ctrl = htons(VLAN_CTRL(0,0,se->se_vlan));
	    eh->en_tag_len  =
		((enet_hdr_t *)mb->mBlkHdr.mData)->en_untagged_len;
	} else {
	    /* Just copy entire packet */
	  
	  /* Extract priority and map to COS here */
	    l = netMblkToBufCopy(mb, packet, NULL);
	}

	if (set_target_broadcast &&
	    sal_memcmp(eh->en_dhost, eh->en_shost, 6) == 0) {
	    sal_memcpy(eh->en_dhost, mac_ones, 6);
	}
	netMblkClChainFree(mb);		/* Free MBLK */
    } else {
	l = mb->mBlkHdr.mLen;
	packet = mb->mBlkHdr.mData;
	cookie = (void *)mb;
    }

#if defined(BROADCOM_DEBUG)
    if (LOG_CHECK(BSL_LS_SYS_END | BSL_INFO) &&
        LOG_CHECK(BSL_LS_SOC_PACKET | BSL_INFO)) {
	d_packet_format("socend TX", DECODE_ETHER, packet, l, NULL);
    }
#endif /* defined(BROADCOM_DEBUG) */

    if (snoop_ip_tx != NULL) {
	snoop_ip_tx(se->se_unit, packet, l);
    }

    sal_memset(pkt, 0, sizeof(bcm_pkt_t));
    pkt->pkt_data = &(pkt->_pkt_data);
    pkt->_pkt_data.len = l;
    pkt->_pkt_data.data = (uint8 *)packet;
    pkt->blk_count = 1;
    pkt->unit = se->se_unit;
    pkt->pkt_len = l;
    SOC_PBMP_CLEAR(pkt->tx_pbmp);
    SOC_PBMP_CLEAR(pkt->tx_upbmp);
    SOC_PBMP_CLEAR(pkt->tx_l3pbmp);

    /* get tx_pbmp, tx_upbmp */
    eh = (enet_hdr_t *)packet;
    rv = _socend_l2_lookup(se->se_unit,
                      eh->en_dhost,
                      VLAN_CTRL_ID(se->se_vlan),
                      pkt);
    if(rv == ERROR){
        LOG_CLI((BSL_META("socend_send : can't get egress port(s) by _socend_l2_lookup.\n")));
        return(ERROR);
        }

    pkt->cookie = cookie;
    pkt->call_back = socend_send_done;
    pkt->flags &= ~BCM_TX_CRC_FLD;
    pkt->flags |= BCM_TX_CRC_APPEND;

    if ((rv = bcm_tx(se->se_unit, pkt, cookie)) != BCM_E_NONE) {
        LOG_ERROR(BSL_LS_SOC_COMMON,
                  (BSL_META("bcm_tx failed: Unit %d: %s\n"),
                   se->se_unit, bcm_errmsg(rv)));
        return(ERROR);
    }

    return(OK);
}