⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsl_mcdmafec.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (!(pRbd->cbd_sc & BD_ENET_RX_EMPTY)) {		if ((pRbd->cbd_sc & BD_ENET_RX_LAST)		    && !(pRbd->cbd_sc & BD_ENET_RX_ERR)		    && ((pRbd->cbd_datlen - 4) > 14)) {			/* Get buffer address and size */			frame_length = pRbd->cbd_datlen - 4;			/* Fill the buffer and pass it to upper layers */			NetReceive((volatile uchar *)pRbd->cbd_bufaddr,				   frame_length);			len = frame_length;		}		/* Reset buffer descriptor as empty */		if ((info->rxIdx) == (PKTBUFSRX - 1))			pRbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);		else			pRbd->cbd_sc = BD_ENET_RX_EMPTY;		pRbd->cbd_datlen = PKTSIZE_ALIGN;		/* Now, we have an empty RxBD, restart the DMA receive task */		MCD_continDma(info->rxTask);		/* Increment BD count */		info->rxIdx = (info->rxIdx + 1) % PKTBUFSRX;	}	return len;}static void fec_set_hwaddr(volatile fecdma_t * fecp, u8 * mac){	u8 currByte;		/* byte for which to compute the CRC */	int byte;		/* loop - counter */	int bit;		/* loop - counter */	u32 crc = 0xffffffff;	/* initial value */	for (byte = 0; byte < 6; byte++) {		currByte = mac[byte];		for (bit = 0; bit < 8; bit++) {			if ((currByte & 0x01) ^ (crc & 0x01)) {				crc >>= 1;				crc = crc ^ 0xedb88320;			} else {				crc >>= 1;			}			currByte >>= 1;		}	}	crc = crc >> 26;	/* Set individual hash table register */	if (crc >= 32) {		fecp->ialr = (1 << (crc - 32));		fecp->iaur = 0;	} else {		fecp->ialr = 0;		fecp->iaur = (1 << crc);	}	/* Set physical address */	fecp->palr = (mac[0] << 24) + (mac[1] << 16) + (mac[2] << 8) + mac[3];	fecp->paur = (mac[4] << 24) + (mac[5] << 16) + 0x8808;	/* Clear multicast address hash table */	fecp->gaur = 0;	fecp->galr = 0;}static int fec_init(struct eth_device *dev, bd_t * bd){	struct fec_info_dma *info = dev->priv;	volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);	int i;#ifdef ET_DEBUG	printf("fec_init: iobase 0x%08x ...\n", info->iobase);#endif	fecpin_setclear(dev, 1);	fec_halt(dev);#if defined(CONFIG_CMD_MII) || defined (CONFIG_MII) || \	defined (CFG_DISCOVER_PHY)	mii_init();	set_fec_duplex_speed(fecp, bd, info->dup_spd);#else#ifndef CFG_DISCOVER_PHY	set_fec_duplex_speed(fecp, bd, (FECDUPLEX << 16) | FECSPEED);#endif				/* ifndef CFG_DISCOVER_PHY */#endif				/* CONFIG_CMD_MII || CONFIG_MII */	/* We use strictly polling mode only */	fecp->eimr = 0;	/* Clear any pending interrupt */	fecp->eir = 0xffffffff;	/* Set station address   */	if ((u32) fecp == CFG_FEC0_IOBASE) {		fec_set_hwaddr(fecp, bd->bi_enetaddr);	} else {		fec_set_hwaddr(fecp, bd->bi_enet1addr);	}	/* Set Opcode/Pause Duration Register */	fecp->opd = 0x00010020;	/* Setup Buffers and Buffer Desriptors */	info->rxIdx = 0;	info->txIdx = 0;	/* Setup Receiver Buffer Descriptors (13.14.24.18)	 * Settings:     Empty, Wrap */	for (i = 0; i < PKTBUFSRX; i++) {		info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;		info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN;		info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];	}	info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;	/* Setup Ethernet Transmitter Buffer Descriptors (13.14.24.19)	 * Settings:    Last, Tx CRC */	for (i = 0; i < CFG_TX_ETH_BUFFER; i++) {		info->txbd[i].cbd_sc = 0;		info->txbd[i].cbd_datlen = 0;		info->txbd[i].cbd_bufaddr = (uint) (&info->txbuf[0]);	}	info->txbd[CFG_TX_ETH_BUFFER - 1].cbd_sc |= BD_ENET_TX_WRAP;	info->usedTbdIdx = 0;	info->cleanTbdNum = CFG_TX_ETH_BUFFER;	/* Set Rx FIFO alarm and granularity value */	fecp->rfcr = 0x0c000000;	fecp->rfar = 0x0000030c;	/* Set Tx FIFO granularity value */	fecp->tfcr = FIFO_CTRL_FRAME | FIFO_CTRL_GR(6) | 0x00040000;	fecp->tfar = 0x00000080;	fecp->tfwr = 0x2;	fecp->ctcwr = 0x03000000;	/* Enable DMA receive task */	MCD_startDma(info->rxTask,	/* Dma channel */		     (s8 *) info->rxbd,	/*Source Address */		     0,		/* Source increment */		     (s8 *) (&fecp->rfdr),	/* dest */		     4,		/* dest increment */		     0,		/* DMA size */		     4,		/* xfer size */		     info->rxInit,	/* initiator */		     info->rxPri,	/* priority */		     (MCD_FECRX_DMA | MCD_TT_FLAGS_DEF),	/* Flags */		     (MCD_NO_CSUM | MCD_NO_BYTE_SWAP)	/* Function description */	    );	/* Enable DMA tx task with no ready buffer descriptors */	MCD_startDma(info->txTask,	/* Dma channel */		     (s8 *) info->txbd,	/*Source Address */		     0,		/* Source increment */		     (s8 *) (&fecp->tfdr),	/* dest */		     4,		/* dest incr */		     0,		/* DMA size */		     4,		/* xfer size */		     info->txInit,	/* initiator */		     info->txPri,	/* priority */		     (MCD_FECTX_DMA | MCD_TT_FLAGS_DEF),	/* Flags */		     (MCD_NO_CSUM | MCD_NO_BYTE_SWAP)	/* Function description */	    );	/* Now enable the transmit and receive processing */	fecp->ecr |= FEC_ECR_ETHER_EN;	return 1;}static void fec_halt(struct eth_device *dev){	struct fec_info_dma *info = dev->priv;	volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);	int counter = 0xffff;	/* issue graceful stop command to the FEC transmitter if necessary */	fecp->tcr |= FEC_TCR_GTS;	/* wait for graceful stop to register */	while ((counter--) && (!(fecp->eir & FEC_EIR_GRA))) ;	/* Disable DMA tasks */	MCD_killDma(info->txTask);	MCD_killDma(info->rxTask);;	/* Disable the Ethernet Controller */	fecp->ecr &= ~FEC_ECR_ETHER_EN;	/* Clear FIFO status registers */	fecp->rfsr &= FIFO_ERRSTAT;	fecp->tfsr &= FIFO_ERRSTAT;	fecp->frst = 0x01000000;	/* Issue a reset command to the FEC chip */	fecp->ecr |= FEC_ECR_RESET;	/* wait at least 20 clock cycles */	udelay(10000);#ifdef ET_DEBUG	printf("Ethernet task stopped\n");#endif}int mcdmafec_initialize(bd_t * bis){	struct eth_device *dev;	int i;#ifdef CFG_DMA_USE_INTSRAM	u32 tmp = CFG_INTSRAM + 0x2000;#endif	for (i = 0; i < sizeof(fec_info) / sizeof(fec_info[0]); i++) {		dev =		    (struct eth_device *)memalign(CFG_CACHELINE_SIZE,						  sizeof *dev);		if (dev == NULL)			hang();		memset(dev, 0, sizeof(*dev));		sprintf(dev->name, "FEC%d", fec_info[i].index);		dev->priv = &fec_info[i];		dev->init = fec_init;		dev->halt = fec_halt;		dev->send = fec_send;		dev->recv = fec_recv;		/* setup Receive and Transmit buffer descriptor */#ifdef CFG_DMA_USE_INTSRAM		fec_info[i].rxbd = (int)fec_info[i].rxbd + tmp;		tmp = fec_info[i].rxbd;		fec_info[i].txbd =		    (int)fec_info[i].txbd + tmp + (PKTBUFSRX * sizeof(cbd_t));		tmp = fec_info[i].txbd;		fec_info[i].txbuf =		    (int)fec_info[i].txbuf + tmp +		    (CFG_TX_ETH_BUFFER * sizeof(cbd_t));		tmp = fec_info[i].txbuf;#else		fec_info[i].rxbd =		    (cbd_t *) memalign(CFG_CACHELINE_SIZE,				       (PKTBUFSRX * sizeof(cbd_t)));		fec_info[i].txbd =		    (cbd_t *) memalign(CFG_CACHELINE_SIZE,				       (CFG_TX_ETH_BUFFER * sizeof(cbd_t)));		fec_info[i].txbuf =		    (char *)memalign(CFG_CACHELINE_SIZE, DBUF_LENGTH);#endif#ifdef ET_DEBUG		printf("rxbd %x txbd %x\n",		       (int)fec_info[i].rxbd, (int)fec_info[i].txbd);#endif		fec_info[i].phy_name = (char *)memalign(CFG_CACHELINE_SIZE, 32);		eth_register(dev);#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)		miiphy_register(dev->name,				mcffec_miiphy_read, mcffec_miiphy_write);#endif		if (i > 0)			fec_info[i - 1].next = &fec_info[i];	}	fec_info[i - 1].next = &fec_info[0];	/* default speed */	bis->bi_ethspeed = 10;	return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -