/* * 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; }
/* ======================================================================== 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 */
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 */ }
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; }