📄 bcm1250macend.c
字号:
DRV_LOG (DRV_DEBUG_LOAD, "sbe%d - bcm1250MacMemInit() complete\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); return OK; }/********************************************************************************* bcm1250MacDmaInit - Initialize DMA data structure and hardware registers** This routine initializes the DMA data structure. It allocates and* initializes memory for the DMA buffer descriptors, the buffer pointer* table, and the buffer type table. The buffer type table is only used* in the transmit direction. The variables used to manage the ring of* buffers and descriptors are also initialized in this routine. Finally,* the address of the DMA registers are initialized, and the config and buffer* descriptor base registers are initialized.** RETURNS: OK, or ERROR*/LOCAL STATUS bcm1250MacDmaInit ( ETH_MAC_DMA * pDma, /* ethernet DMA struct to be initialized */ MAC_REG dmaBaseAdr, /* base address of DMA registers */ int xmit /* 1 if transmit direction, 0 for receive */ ) { int dscr; /* DMA buffer descriptor index */ DRV_LOG (DRV_DEBUG_LOAD, "DMA init start\n", 1, 2, 3, 4, 5, 6); /* allocate memory for DMA buffer descriptor rings */ pDma->pDscrTable = (ETH_DMA_DSCR *)memalign (CACHELINESIZE, pDma->maxDescr * sizeof (ETH_DMA_DSCR)); if (pDma->pDscrTable == (ETH_DMA_DSCR *)NULL) { DRV_LOG (DRV_DEBUG_LOAD, "pDscrTable alloc failed\n", 1, 2, 3, 4, 5, 6); return (ERROR); } bzero ((char *)pDma->pDscrTable, (pDma->maxDescr * sizeof (ETH_DMA_DSCR))); /* * For transmit only, allocate and initialize a table of pointers to buffers * and a table of buffers types. */ if (xmit == 1) { pDma->bufTable = (TX_BUF_TABLE *)malloc (pDma->maxDescr * sizeof (TX_BUF_TABLE)); if (pDma->bufTable == (TX_BUF_TABLE *)NULL) { DRV_LOG (DRV_DEBUG_LOAD, "bufTable alloc failed.\n", 1, 2, 3, 4, 5, 6); return (ERROR); } for (dscr = 0; dscr < pDma->maxDescr; dscr++) { pDma->bufTable[dscr].pBuf = (char *)NULL; pDma->bufTable[dscr].type = BUF_TYPE_NONE; } } /* Initialize ring management variables */ pDma->tailIndex = 0; pDma->headIndex = 0; pDma->ringCount = 0; /* Transmitter is not blocked */ pDma->txBlocked = FALSE; /* Initialize register addresses */ pDma->regConfig0 = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_CONFIG0) + dmaBaseAdr; pDma->regConfig1 = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_CONFIG1) + dmaBaseAdr; pDma->regDscrBase = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_DSCR_BASE) + dmaBaseAdr; pDma->regDscrCnt = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_DSCR_CNT) + dmaBaseAdr; pDma->regCurDscr = R_MAC_DMA_REGISTER (xmit, 0, R_MAC_DMA_CUR_DSCRADDR) + dmaBaseAdr; DRV_LOG (DRV_DEBUG_LOAD, "set regs, dscrbase and config0/maxdscr\n", 1, 2, 3, 4, 5, 6); /* Initialize config registers and buffer descriptor base register */ ETH_DMA_REG_WRITE (pDma->regConfig1, 0); ETH_DMA_REG_WRITE (pDma->regDscrBase, (UINT32)(KVTOPHYS (pDma->pDscrTable))); ETH_DMA_REG_WRITE (pDma->regConfig0, V_DMA_RINGSZ (pDma->maxDescr)); DRV_LOG (DRV_DEBUG_LOAD, "DMA init complete\n", 1, 2, 3, 4, 5, 6); return (OK); }/********************************************************************************* bcm1250MacUnload - unload a driver from the system** This routine first brings down the device, and then frees any memory* allocated by the driver in the load function. The controller structure* should be freed by the calling function.** RETURNS: OK, always.*/LOCAL STATUS bcm1250MacUnload ( DRV_CTRL * pDrvCtrl /* driver control structure */ ) { ETH_MAC_DMA * pDma; /* ethernet DMA structure */ DRV_LOG (DRV_DEBUG_LOAD, "EndUnload ...\n", 1, 2, 3, 4, 5, 6); /* deallocate lists */ END_OBJ_UNLOAD (&pDrvCtrl->endObj); pDma = &pDrvCtrl->rxDma; /* Free the RX DMA buffer descriptors. */ if (pDma->pDscrTable) free (pDma->pDscrTable); pDma = &pDrvCtrl->txDma; /* Free the TX buffer table. */ if (pDma->bufTable) free (pDma->bufTable); /* Free the TX DMA buffer descriptors. */ if (pDma->pDscrTable) free (pDma->pDscrTable); /* Free the mBlk/clBlk memory. */ if (pDrvCtrl->mClBlkBase) free (pDrvCtrl->mClBlkBase); /* Free the cluster buffer memory. */ if (pDrvCtrl->bufBase) free (pDrvCtrl->bufBase); /* Free the memory allocated for driver pool structure */ if (pDrvCtrl->endObj.pNetPool != (NET_POOL *)NULL) free (pDrvCtrl->endObj.pNetPool); return (OK); }/********************************************************************************* bcm1250MacStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR*/LOCAL STATUS bcm1250MacStart ( DRV_CTRL * pDrvCtrl /* driver control structure */ ) { UINT64 macAddr; /* 64 bit ethernet MAC address */ STATUS rtv; /* function return value */ int idx; MAC_REG port; char enetAddr[6]; /* 6 byte ethernet MAC address */ ETH_MAC_DMA * pDma; /* ethernet DMA structure */ int ix; char * pBuf = (char *)NULL; ETH_DMA_DSCR * pDscr; /* DMA buffer descriptor */ DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart enter ......\n", 1, 2, 3, 4, 5, 6); /* reset */ ETH_MAC_REG_WRITE (pDrvCtrl->regMacEnable, 0); /* get mac addr */ sysBcm1250MacEnetAddrGet (pDrvCtrl->unit, &enetAddr[0]); macAddr = bcm1250MacAddr2Reg ((unsigned char *)enetAddr); DRV_LOG (DRV_DEBUG_IOCTL, "macAddr=0x%08x%08x\n", (int)(macAddr >> 32), macAddr, 3, 4, 5, 6); /* set its own hw addr */ ETH_MAC_REG_WRITE (R_MAC_ETHERNET_ADDR, 0); /* clear hash table */ port = R_MAC_HASH_BASE; for (idx = 0; idx < MAC_HASH_COUNT; idx++) { ETH_MAC_REG_WRITE (port, 0); port += sizeof (UINT64); } /* clear exact match addr table */ port = R_MAC_ADDR_BASE; for (idx = 0; idx < MAC_ADDR_COUNT; idx++) { ETH_MAC_REG_WRITE (port, 0); port += sizeof (UINT64); } /* always interested in packets addressed to self */ ETH_MAC_REG_WRITE (R_MAC_ADDR_BASE, macAddr); /* reset channel map register to only use channel 0!!! */ port = R_MAC_CHUP0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { ETH_MAC_REG_WRITE (port, 0); port += sizeof (UINT64); } port = R_MAC_CHLO0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { ETH_MAC_REG_WRITE (port, 0); port += sizeof (UINT64); } /* clear rx filter */ ETH_MAC_REG_WRITE (pDrvCtrl->regRxFilter, 0); /* no interrupt yet */ ETH_MAC_REG_WRITE (pDrvCtrl->regImr, 0); /* setup frame cfg */ ETH_MAC_REG_WRITE (pDrvCtrl->regFrameCfg, V_MAC_MIN_FRAMESZ_DEFAULT | V_MAC_MAX_FRAMESZ_DEFAULT | V_MAC_BACKOFF_SEL (1) ); /* setup fifo cfg */ ETH_MAC_REG_WRITE (pDrvCtrl->regFifoCfg, V_MAC_TX_WR_THRSH (4) | /* Must be '4' or '8' */ V_MAC_TX_RD_THRSH (4) | V_MAC_TX_RL_THRSH (4) | V_MAC_RX_PL_THRSH (4) | V_MAC_RX_RD_THRSH (4) | /* Must be '4' */ V_MAC_RX_PL_THRSH (4) | V_MAC_RX_RL_THRSH (8)); /* setup the main config reg */ ETH_MAC_REG_WRITE (pDrvCtrl->regMacCfg, M_MAC_RETRY_EN | M_MAC_TX_HOLD_SOP_EN | V_MAC_TX_PAUSE_CNT_16K | V_MAC_SPEED_SEL_100MBPS | M_MAC_AP_STAT_EN | M_MAC_FAST_SYNC | M_MAC_SS_EN | V_MAC_IPHDR_OFFSET (14)); /* Set interface's speed, duplex, and flow control */ (void)bcm1250MacSetConfig (pDrvCtrl, pDrvCtrl->macSpeed, pDrvCtrl->macDuplex, pDrvCtrl->macFc); /* init rx dma's descrs */ DRV_LOG (DRV_DEBUG_LOAD, "rxDMA ch#0 init\n", 1, 2, 3, 4, 5, 6); pDma = &(pDrvCtrl->rxDma); /* Initialize all receive DMA buffer descriptors. */ for (ix = 0; ix < pDma->maxDescr; ix++) { /* Allocate a cluster */ pBuf = (char *)NET_BUF_ALLOC (); if (pBuf == (char *)NULL) { DRV_LOG (DRV_DEBUG_LOAD, "bcm1250Mac - netClusterGet failed\n", 1, 2, 3, 4, 5, 6); return (ERROR); } /* point to next buffer descriptor. */ pDscr = &pDma->pDscrTable[pDma->tailIndex]; /* initialize descriptor to receive into the cluster */ pDscr->dscr_a = (UINT64)((UINT32)KVTOPHYS (pBuf)) | V_DMA_DSCRA_A_SIZE (MAX_FRAME_CACHE_BLKS) | M_DMA_DSCRA_INTERRUPT | VXW_RCV_BUF_OFFSET; pDscr->dscr_b = 0; /* give desc to the hw */ ETH_DMA_REG_WRITE (pDma->regDscrCnt, 1); /* Advance ring management variables */ pDma->tailIndex = (pDma->tailIndex + 1) % pDma->maxDescr; pDma->ringCount++; DRV_LOG (DRV_DEBUG_LOAD, "set reg, dscrcnt\n", 1, 2, 3, 4, 5, 6); DRV_LOG (DRV_DEBUG_LOAD, "descA manual read 0x%08x%08x\n", (pDscr->dscr_a) >> 32, pDscr->dscr_a, 3, 4, 5, 6); DRV_LOG (DRV_DEBUG_LOAD, "descB manual read 0x%08x%08x\n", (pDscr->dscr_b) >> 32, pDscr->dscr_b, 3, 4, 5, 6); } /* enable transmit and receive interrupts for channel 0 */ ETH_MAC_REG_WRITE (pDrvCtrl->regMacEnable, M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0 | M_MAC_RX_ENABLE | M_MAC_TX_ENABLE); DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart: enabled\n", 1, 2, 3, 4, 5, 6); /* connect interrupt handler */ rtv = bcm1250IntConnect (pDrvCtrl->intSource, pDrvCtrl->iVecNum, bcm1250MacInt, (int) pDrvCtrl); if (rtv == ERROR) return (ERROR); DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart connect int\n", 1, 2, 3, 4, 5, 6); /* unmask the mac interrupt */ ETH_MAC_REG_WRITE (pDrvCtrl->regImr, (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)); DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart, set intr mask\n", 1, 2, 3, 4, 5, 6); /* set rxfilter */ ETH_MAC_REG_WRITE (pDrvCtrl->regRxFilter, M_MAC_UCAST_EN | M_MAC_BCAST_EN); /* set flags to indicate interface is up */ END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart, interface up\n", 1, 2, 3, 4, 5, 6); /* enable interrupts */ (void)bcm1250IntEnable (pDrvCtrl->intSource); DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart: enable interrupt\n", 1, 2, 3, 4, 5, 6); DRV_LOG (DRV_DEBUG_IOCTL, "bcm1250MacStart done\n", 1, 2, 3, 4, 5, 6); return OK; }/********************************************************************************* bcm1250MacStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK.*/LOCAL STATUS bcm1250MacStop ( DRV_CTRL * pDrvCtrl /* driver control structure */ ) { DRV_LOG (DRV_DEBUG_LOAD, "bcm1250MacStop enter ......\n", 1, 2, 3, 4, 5, 6); /* mark the interface as down */ END_FLAGS_CLR (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING)); /* disable mac interrupts */ ETH_MAC_REG_WRITE (pDrvCtrl->regImr, 0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -