Exemplo n.º 1
0
/*
 * bcm6352_init_dev: initialize Ethernet Switch device,
 * allocate Tx/Rx buffer descriptors pool, Tx control block pool.
 */
static int bcm6352_init_dev(bcm6352enet_softc *softc)
{
    unsigned long i, j;
    unsigned char *p = NULL;

    /* make sure emac clock is on */
    INTC->blkEnables |= (ESWITCH_CLK_EN | EPHY_CLK_EN);

    /* setup buffer/pointer relationships here */
    softc->nrRxBds = NR_RX_BDS;
    softc->rxBufLen = ENET_MAX_MTU_SIZE;

    /* init rx/tx dma channels */
    softc->dmaChannels = (DmaChannel *)(DMA_BASE);
    softc->rxDma = &softc->dmaChannels[EMAC_RX_CHAN];
    softc->txDma = &softc->dmaChannels[EMAC_TX_CHAN];

    p = (unsigned char *) (((uint32_t) softc->txBuf + 0x10) & ~0x0f);
    softc->txBufPtr = (unsigned char *)K0_TO_K1((uint32_t) p);

    p = (unsigned char *) (((uint32_t) softc->rxMem + 0x10) & ~0x0f);
    softc->rxBds = (DmaDesc *)K0_TO_K1((uint32_t) p);
    p += softc->nrRxBds * sizeof(DmaDesc);
    softc->rxBuffers = (unsigned char *) K0_TO_PHYS((uint32_t) p);

    /* initialize rx ring pointer variables. */
    softc->rxBdAssignPtr = softc->rxBdReadPtr = softc->rxBds;
    softc->rxFirstBdPtr = softc->rxBds;
    softc->rxLastBdPtr = softc->rxFirstBdPtr + softc->nrRxBds - 1;

    /* init the receive buffer descriptor ring */
    for (i = 0, j = (unsigned long) softc->rxBuffers; i < softc->nrRxBds;
        i++, j += softc->rxBufLen)
    {
        (softc->rxFirstBdPtr + i)->length = softc->rxBufLen;
        (softc->rxFirstBdPtr + i)->address = j;
        (softc->rxFirstBdPtr + i)->status = DMA_OWN;
    }
    softc->rxLastBdPtr->status = DMA_OWN | DMA_WRAP;

    /* init dma registers */
    init_dma(softc);

    /* init switch control registers */
    init_mii(softc);

    softc->rxDma->cfg |= DMA_ENABLE;

    /* if we reach this point, we've init'ed successfully */
    return 0;
}
Exemplo n.º 2
0
/*
========================================================================
Routine Description:
	Ikanos WLAN --> LAN transmit fast path function.

Arguments:
	pFrame			- the received packet (Ikanos packet format)

Return Value:
	None

Note:
	Ikanos platform supports only 8 VAPs
========================================================================
*/
static void IKANOS_WlanPktFromAp(
	IN apPreHeader_t		*pFrame)
{
	PRTMP_ADAPTER pAd;
    struct net_device *dev = NULL;
    struct sk_buff *skb;
    INT32 index;
    apPreHeader_t *apBuf = K0_TO_K1(pFrame);


	pAd = pIkanosAd;
    /*index = apBuf->specInfoElement; */
	/*dev = pAd->ApCfg.MBSSID[index].MSSIDDev; */
	index = GetSpecInfoIdxFromBssid(pAd, apBuf->specInfoElement);
	dev = get_netdev_from_bssid(pAd, apBuf->specInfoElement);
    if (dev == NULL)
    {
        printk("ikanos> %s: ERROR null device ***************\n", __FUNCTION__);
        return;
    } /* End of if */

    skb = (struct sk_buff *)translateApbuf2Mbuf(apBuf);
    if (NULL == skb)
    {
        printk("ikanos> %s: skb is null *********************\n", __FUNCTION__);
        return;
    } /* End of if */

    pAd->IkanosRxInfo[index].netdev = dev;
    pAd->IkanosRxInfo[index].fp = &IKANOS_WlanDataFramesTx;

    skb->dev = dev;
    skb->apFlowData.rxApId = IKANOS_PERAP_ID;
    /*skb->apFlowData.txHandle = &(txinforx[index]); */
    skb->apFlowData.rxHandle = &(pAd->IkanosRxInfo[index]);
    skb->protocol = eth_type_trans(skb, skb->dev);

#ifdef IKANOS_DEBUG
	printk("ikanos> rx no fp!\n"); /* debug use */
#endif /* IKANOS_DEBUG */

    netif_rx(skb);
    return;
} /* End of IKANOS_WlanPktFromAp */
Exemplo n.º 3
0
LOCAL void * cacheLsn2eMalloc
    (
    size_t bytes 
    )
    {
    void * pDmaBuffer;
    
#ifdef IS_KSEGM
    int    pageSize;

    /* check for non-memory mapped case */
    if (IS_KSEG0(cacheLsn2eMalloc))
	{
#endif
	int	allocBytes;
	void  * pBuffer;

        /* Round up the allocation size so that we can store a "back pointer"
         * to the allocated buffer, align the buffer on a cache line boundary
         * and pad the buffer to a cache line boundary.
         * sizeof(void *) 		for "back pointer"
         * _CACHE_ALIGN_SIZE-1	for cache line alignment
         * _CACHE_ALIGN_SIZE-1	for cache line padding
         */
        allocBytes = sizeof (void *) +
	  	    (_CACHE_ALIGN_SIZE - 1) +
		    bytes +
		    (_CACHE_ALIGN_SIZE - 1);

        if ((pBuffer = (void *)malloc (allocBytes)) == NULL)
	    return (NULL);

        /* Flush any data that may be still sitting in the cache */
	cacheLsn2eDCFlushInvalidate (pBuffer, allocBytes);

	pDmaBuffer = pBuffer;

	/* allocate space for the back pointer */
	pDmaBuffer = (void *)((int)pDmaBuffer + sizeof (void *));

	/* Now align to a cache line boundary */
	pDmaBuffer = (void *)CACHE_ROUND_UP (pDmaBuffer);

	/* Store "back pointer" in previous cache line using CACHED location */
	*(((void **)pDmaBuffer)-1) = pBuffer;

	return ((void *)K0_TO_K1(pDmaBuffer));
#ifdef IS_KSEGM
       	}
    
    /* memory-mapped case */

    if ((pageSize = VM_PAGE_SIZE_GET ()) == ERROR)
	return (NULL);

    /* make sure bytes is a multiple of pageSize */

    bytes = bytes / pageSize * pageSize + pageSize;

    pDmaBuffer = (void *)IOBUF_ALIGNED_ALLOC (bytes, pageSize);
    if (pDmaBuffer == NULL)
	return (NULL);

    VM_STATE_SET (NULL, pDmaBuffer, bytes,
		  MMU_ATTR_CACHE_MSK, MMU_ATTR_CACHE_OFF);

    return (pDmaBuffer);
#endif /* IS_KSEGM */
    }
Exemplo n.º 4
0
static int internal_open(bcmenet_softc * softc)
{
    int i;
    void *p;

    /* make sure emac clock is on */
    PERF->blkEnables |= EMAC_CLK_EN;

    /* init rx/tx dma channels */
    softc->dmaCtrl = (DmaRegs *)(EMAC_DMA_BASE);
    softc->rxDma = &softc->dmaCtrl->chcfg[EMAC_RX_CHAN];
    softc->txDma = &softc->dmaCtrl->chcfg[EMAC_TX_CHAN];

    p = KMALLOC( NR_TX_BDS * sizeof(DmaDesc), CACHE_ALIGN );
    if( p == NULL ) {
        xprintf( "BCM6348 : Failed to allocate txBds memory.\n" );
        return -1;
    }
    INVAL_RANGE(p, NR_TX_BDS * sizeof(DmaDesc));
    softc->txBds = (DmaDesc *)K0_TO_K1((uint32) p);

    p = KMALLOC( NR_RX_BDS * sizeof(DmaDesc), CACHE_ALIGN );
    if( p== NULL ) {
        xprintf( "BCM6348 : Failed to allocate rxBds memory.\n" );
        KFREE( (void *)(softc->txBds) );
        softc->txBds = NULL;
        return -1;
    }
    INVAL_RANGE(p, NR_RX_BDS * sizeof(DmaDesc));
    softc->rxBds = (DmaDesc *)K0_TO_K1((uint32) p);

    softc->rxBuffers = (uint32_t)KMALLOC( NR_RX_BDS * ENET_BUF_SIZE, CACHE_ALIGN );
    if( softc->rxBuffers == NULL ) {
        xprintf( "BCM6348 : Failed to allocate RxBuffer memory.\n" );
        KFREE( (void *)(softc->txBds) );
        softc->txBds = NULL;
        KFREE( (void *)(softc->rxBds) );
        softc->rxBds = NULL;
        return -1;
    }
    INVAL_RANGE(softc->rxBuffers, NR_RX_BDS * ENET_BUF_SIZE);

    softc->txBuffers = (uint32_t)KMALLOC( NR_TX_BDS * ENET_BUF_SIZE, CACHE_ALIGN );
    if( softc->txBuffers == NULL ) {
        xprintf( "BCM6348 : Failed to allocate txBuffer memory.\n" );
        KFREE( (void *)(softc->rxBuffers) );
        softc->rxBuffers = NULL;
        KFREE( (void *)(softc->txBds) );
        softc->txBds     = NULL;
        KFREE( (void *)(softc->rxBds) );
        softc->rxBds     = NULL;
        return -1;
    }
    INVAL_RANGE(softc->txBuffers, NR_TX_BDS * ENET_BUF_SIZE);

    /* Init the Receive Buffer Descriptor Ring. */
    softc->rxFirstBdPtr = softc->rxBdReadPtr = softc->rxBds;     
    softc->rxLastBdPtr = softc->rxBds + NR_RX_BDS - 1;

    for(i = 0; i < NR_RX_BDS; i++) {
        (softc->rxBds + i)->status  = DMA_OWN;
        (softc->rxBds + i)->length  = ENET_BUF_SIZE;
        (softc->rxBds + i)->address = softc->rxBuffers + i * ENET_BUF_SIZE;
        (softc->rxBds + i)->address = K1_TO_PHYS( (softc->rxBds + i)->address );
        softc->dmaCtrl->flowctl_ch1_alloc = 1;
    }
    softc->rxLastBdPtr->status |= DMA_WRAP;

    /* Init Transmit Buffer Descriptor Ring. */
    softc->txFirstBdPtr = softc->txNextBdPtr =  softc->txBds;
    softc->txLastBdPtr = softc->txBds + NR_TX_BDS - 1;

    for(i = 0; i < NR_TX_BDS; i++) {
        (softc->txBds + i)->status  = 0;
        (softc->txBds + i)->length  = 0;
        (softc->txBds + i)->address = softc->txBuffers + i * ENET_BUF_SIZE;
        (softc->txBds + i)->address = K1_TO_PHYS( (softc->txBds + i)->address );
    }
    softc->txLastBdPtr->status = DMA_WRAP;

    /* init dma registers */
    init_dma(softc);

    /* init enet control registers */
    if (init_emac(softc))
        return -1;

    getMacAddress(softc->hwaddr);

    bcm6348_write_mac_address( softc, softc->hwaddr);

    softc->rxDma->cfg |= DMA_ENABLE;

    return 0;
}