Exemplo n.º 1
0
Arquivo: netdrv.c Projeto: ariavie/bcm
LOCAL STATUS
NetdrvPollRcv(END_DEVICE * pDrvCtrl, /* device to be polled */
              M_BLK_ID     pMblk)    /* ptr to buffer */
{
    u_short stat;
    char* pPacket;
    int len;

    DRV_LOG (DRV_DEBUG_POLL_RX,
            "NetdrvPollRcv ....... Not Implemented\n", 1, 2, 3, 4, 5, 6);

    stat = NetdrvStatusRead(pDrvCtrl);

    

    if (!(stat & NETDRV_RINT)) {
        printf("\r\nNetdrvPollRcv no data");
        return (EAGAIN);
    }

    /* Get packet and  length from device buffer/descriptor */

    pPacket = NULL; /* DUMMY CODE */
    len = 64;       /* DUMMY CODE */

    /* Upper layer must provide a valid buffer. */

    if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT))) {
#ifdef BOOTROM_DEBUG
        printf("\r\nPRX bad mblk");
#endif

        return (EAGAIN);
    }

    

    

    END_ERR_ADD(&pDrvCtrl->end, MIB2_IN_UCAST, +1);

    
    bcopy (pPacket, pMblk->m_data, len);
    pMblk->mBlkHdr.mFlags |= M_PKTHDR; /* set the packet header */
    pMblk->mBlkHdr.mLen    = len;      /* set the data len */
    pMblk->mBlkPktHdr.len  = len;      /* set the total len */

    
#ifdef BOOTROM_DEBUG
    printf("\r\nNetdrvPollRcv OK");
#endif

    return (OK);
}
LOCAL STATUS mirrorEndPollSend
    (
    END_CTRL*   pDrvCtrl,
    M_BLK*      pMblk
    )
    {
    STATUS status;

    /* mirror 1 should not call this function */

    if (pDrvCtrl->unit != 0)
	return ERROR;

    /* call the poll routine in the real device */

    status = pDrvCtrl->pPhyEnd->pFuncTable->pollSend(pDrvCtrl->pPhyEnd, 
	                                             pMblk);

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

    return OK;
    }
Exemplo n.º 3
0
Arquivo: netdrv.c Projeto: ariavie/bcm
LOCAL STATUS
NetdrvPollSend(END_DEVICE* pDrvCtrl, /* device to be polled */
               M_BLK_ID    pMblk     /* packet to send */)
{
    int     len;
    u_short stat;

#ifdef BOOTROM_DEBUG
    printf("\r\nNetdrvPollSend");
#endif

    
    stat = NetdrvStatusRead(pDrvCtrl); /* dummy code */
    if((stat & NETDRV_TINT) == 0) {
        return ((STATUS) EAGAIN);
    }

    

    len = max(ETHERSMALL, pMblk->m_len);

    

    /* Bump the statistic counter. */

    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);

    /* Free the data if it was accepted by device */

    netMblkClFree (pMblk);

#ifdef BOOTROM_DEBUG
    printf("\r\nleaving NetdrvPollSend");
#endif

    return (OK);
}
Exemplo n.º 4
0
Arquivo: netdrv.c Projeto: ariavie/bcm
LOCAL STATUS
NetdrvSend(END_DEVICE * pDrvCtrl, M_BLK_ID pMblk)
{
    unsigned char  *pucPktData=NULL;
    uint32 len = 0;
    uint32 ulPort = -1;
    ULONG ulRet=OK;
    unsigned int unit = 0;
    int i;

    /* taskDelay(0); */

#ifdef BOOTROM_DEBUG
    PRINTF_DEBUG2("NetdrvSend\n"); /* DEL_ME */
#endif

    /* END_TX_SEM_TAKE(&pDrvCtrl->end, WAIT_FOREVER); */

    if (pMblk->mBlkPktHdr.len > NETDRV_CL_LEN - 4) {
        ulRet = ERROR;
        goto sendErr;
    }

    pucPktData = sal_dma_alloc(NETDRV_CL_LEN, "pucPktData");
    if (NULL==pucPktData) {
        ulRet = ERROR;
        goto sendErr;
    }

    /* memset(pucPktData, 0, NETDRV_CL_LEN); */

    len = (ULONG)netMblkToBufCopy(pMblk, pucPktData, NULL);
    len = max(ETHERSMALL, len);

    for (unit = 0; unit < _n_devices; unit++) {
        if (pkt_bcm_tx(unit, pucPktData, len) != 0) { /* Synchronous TX */
            printf("ERROR: fail to tx pkt unit %d\n", unit);
            ulRet = ERROR;
            goto sendErr;
        }
    }

    g_ulPktSend++;

    sendErr:

    netMblkClChainFree (pMblk);

    /* for the packet already sending, we don't want to free them */
    if (NULL!=pucPktData) {
        cacheDmaFree(pucPktData);
        pucPktData = NULL;
    }

    /* END_TX_SEM_GIVE(&pDrvCtrl->end); */

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

    return ulRet;
}
Exemplo n.º 5
0
Arquivo: netdrv.c Projeto: ariavie/bcm
/*
 * 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);
}
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.º 8
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);
}
Exemplo n.º 9
0
Arquivo: socend.c Projeto: ariavie/bcm
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);
	}
    }
}