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

📄 fsl_mcdmafec.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2000-2004 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * (C) Copyright 2007 Freescale Semiconductor, Inc. * TsiChung Liew (Tsi-Chung.Liew@freescale.com) * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#include <common.h>#include <malloc.h>#include <command.h>#include <config.h>#include <net.h>#include <miiphy.h>#undef	ET_DEBUG#undef	MII_DEBUG/* Ethernet Transmit and Receive Buffers */#define DBUF_LENGTH		1520#define PKT_MAXBUF_SIZE		1518#define PKT_MINBUF_SIZE		64#define PKT_MAXBLR_SIZE		1536#define LAST_PKTBUFSRX		PKTBUFSRX - 1#define BD_ENET_RX_W_E		(BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY)#define BD_ENET_TX_RDY_LST	(BD_ENET_TX_READY | BD_ENET_TX_LAST)#define FIFO_ERRSTAT		(FIFO_STAT_RXW | FIFO_STAT_UF | FIFO_STAT_OF)/* RxBD bits definitions */#define BD_ENET_RX_ERR	(BD_ENET_RX_LG | BD_ENET_RX_NO | BD_ENET_RX_CR | \			 BD_ENET_RX_OV | BD_ENET_RX_TR)#include <asm/immap.h>#include <asm/fsl_mcdmafec.h>#include "MCD_dma.h"DECLARE_GLOBAL_DATA_PTR;struct fec_info_dma fec_info[] = {#ifdef CFG_FEC0_IOBASE	{	 0,			/* index */	 CFG_FEC0_IOBASE,	/* io base */	 CFG_FEC0_PINMUX,	/* gpio pin muxing */	 CFG_FEC0_MIIBASE,	/* mii base */	 -1,			/* phy_addr */	 0,			/* duplex and speed */	 0,			/* phy name */	 0,			/* phyname init */	 0,			/* RX BD */	 0,			/* TX BD */	 0,			/* rx Index */	 0,			/* tx Index */	 0,			/* tx buffer */	 0,			/* initialized flag */	 (struct fec_info_dma *)-1,	/* next */	 FEC0_RX_TASK,		/* rxTask */	 FEC0_TX_TASK,		/* txTask */	 FEC0_RX_PRIORITY,	/* rxPri */	 FEC0_TX_PRIORITY,	/* txPri */	 FEC0_RX_INIT,		/* rxInit */	 FEC0_TX_INIT,		/* txInit */	 0,			/* usedTbdIndex */	 0,			/* cleanTbdNum */	 },#endif#ifdef CFG_FEC1_IOBASE	{	 1,			/* index */	 CFG_FEC1_IOBASE,	/* io base */	 CFG_FEC1_PINMUX,	/* gpio pin muxing */	 CFG_FEC1_MIIBASE,	/* mii base */	 -1,			/* phy_addr */	 0,			/* duplex and speed */	 0,			/* phy name */	 0,			/* phy name init */#ifdef CFG_DMA_USE_INTSRAM	 DBUF_LENGTH,		/* RX BD */#else	 0,			/* RX BD */#endif	 0,			/* TX BD */	 0,			/* rx Index */	 0,			/* tx Index */	 0,			/* tx buffer */	 0,			/* initialized flag */	 (struct fec_info_dma *)-1,	/* next */	 FEC1_RX_TASK,		/* rxTask */	 FEC1_TX_TASK,		/* txTask */	 FEC1_RX_PRIORITY,	/* rxPri */	 FEC1_TX_PRIORITY,	/* txPri */	 FEC1_RX_INIT,		/* rxInit */	 FEC1_TX_INIT,		/* txInit */	 0,			/* usedTbdIndex */	 0,			/* cleanTbdNum */	 }#endif};static int fec_send(struct eth_device *dev, volatile void *packet, int length);static int fec_recv(struct eth_device *dev);static int fec_init(struct eth_device *dev, bd_t * bd);static void fec_halt(struct eth_device *dev);#ifdef ET_DEBUGstatic void dbg_fec_regs(struct eth_device *dev){	struct fec_info_dma *info = dev->priv;	volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);	printf("=====\n");	printf("ievent       %x - %x\n", (int)&fecp->eir, fecp->eir);	printf("imask        %x - %x\n", (int)&fecp->eimr, fecp->eimr);	printf("ecntrl       %x - %x\n", (int)&fecp->ecr, fecp->ecr);	printf("mii_mframe   %x - %x\n", (int)&fecp->mmfr, fecp->mmfr);	printf("mii_speed    %x - %x\n", (int)&fecp->mscr, fecp->mscr);	printf("mii_ctrlstat %x - %x\n", (int)&fecp->mibc, fecp->mibc);	printf("r_cntrl      %x - %x\n", (int)&fecp->rcr, fecp->rcr);	printf("r hash       %x - %x\n", (int)&fecp->rhr, fecp->rhr);	printf("x_cntrl      %x - %x\n", (int)&fecp->tcr, fecp->tcr);	printf("padr_l       %x - %x\n", (int)&fecp->palr, fecp->palr);	printf("padr_u       %x - %x\n", (int)&fecp->paur, fecp->paur);	printf("op_pause     %x - %x\n", (int)&fecp->opd, fecp->opd);	printf("iadr_u       %x - %x\n", (int)&fecp->iaur, fecp->iaur);	printf("iadr_l       %x - %x\n", (int)&fecp->ialr, fecp->ialr);	printf("gadr_u       %x - %x\n", (int)&fecp->gaur, fecp->gaur);	printf("gadr_l       %x - %x\n", (int)&fecp->galr, fecp->galr);	printf("x_wmrk       %x - %x\n", (int)&fecp->tfwr, fecp->tfwr);	printf("r_fdata      %x - %x\n", (int)&fecp->rfdr, fecp->rfdr);	printf("r_fstat      %x - %x\n", (int)&fecp->rfsr, fecp->rfsr);	printf("r_fctrl      %x - %x\n", (int)&fecp->rfcr, fecp->rfcr);	printf("r_flrfp      %x - %x\n", (int)&fecp->rlrfp, fecp->rlrfp);	printf("r_flwfp      %x - %x\n", (int)&fecp->rlwfp, fecp->rlwfp);	printf("r_frfar      %x - %x\n", (int)&fecp->rfar, fecp->rfar);	printf("r_frfrp      %x - %x\n", (int)&fecp->rfrp, fecp->rfrp);	printf("r_frfwp      %x - %x\n", (int)&fecp->rfwp, fecp->rfwp);	printf("t_fdata      %x - %x\n", (int)&fecp->tfdr, fecp->tfdr);	printf("t_fstat      %x - %x\n", (int)&fecp->tfsr, fecp->tfsr);	printf("t_fctrl      %x - %x\n", (int)&fecp->tfcr, fecp->tfcr);	printf("t_flrfp      %x - %x\n", (int)&fecp->tlrfp, fecp->tlrfp);	printf("t_flwfp      %x - %x\n", (int)&fecp->tlwfp, fecp->tlwfp);	printf("t_ftfar      %x - %x\n", (int)&fecp->tfar, fecp->tfar);	printf("t_ftfrp      %x - %x\n", (int)&fecp->tfrp, fecp->tfrp);	printf("t_ftfwp      %x - %x\n", (int)&fecp->tfwp, fecp->tfwp);	printf("frst         %x - %x\n", (int)&fecp->frst, fecp->frst);	printf("ctcwr        %x - %x\n", (int)&fecp->ctcwr, fecp->ctcwr);}#endifstatic void set_fec_duplex_speed(volatile fecdma_t * fecp, bd_t * bd,				 int dup_spd){	if ((dup_spd >> 16) == FULL) {		/* Set maximum frame length */		fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) | FEC_RCR_MII_MODE |		    FEC_RCR_PROM | 0x100;		fecp->tcr = FEC_TCR_FDEN;	} else {		/* Half duplex mode */		fecp->rcr = FEC_RCR_MAX_FL(PKT_MAXBUF_SIZE) |		    FEC_RCR_MII_MODE | FEC_RCR_DRT;		fecp->tcr &= ~FEC_TCR_FDEN;	}	if ((dup_spd & 0xFFFF) == _100BASET) {#ifdef MII_DEBUG		printf("100Mbps\n");#endif		bd->bi_ethspeed = 100;	} else {#ifdef MII_DEBUG		printf("10Mbps\n");#endif		bd->bi_ethspeed = 10;	}}static int fec_send(struct eth_device *dev, volatile void *packet, int length){	struct fec_info_dma *info = dev->priv;	cbd_t *pTbd, *pUsedTbd;	u16 phyStatus;	miiphy_read(dev->name, info->phy_addr, PHY_BMSR, &phyStatus);	/* process all the consumed TBDs */	while (info->cleanTbdNum < CFG_TX_ETH_BUFFER) {		pUsedTbd = &info->txbd[info->usedTbdIdx];		if (pUsedTbd->cbd_sc & BD_ENET_TX_READY) {#ifdef ET_DEBUG			printf("Cannot clean TBD %d, in use\n",			       info->cleanTbdNum);#endif			return 0;		}		/* clean this buffer descriptor */		if (info->usedTbdIdx == (CFG_TX_ETH_BUFFER - 1))			pUsedTbd->cbd_sc = BD_ENET_TX_WRAP;		else			pUsedTbd->cbd_sc = 0;		/* update some indeces for a correct handling of the TBD ring */		info->cleanTbdNum++;		info->usedTbdIdx = (info->usedTbdIdx + 1) % CFG_TX_ETH_BUFFER;	}	/* Check for valid length of data. */	if ((length > 1500) || (length <= 0)) {		return -1;	}	/* Check the number of vacant TxBDs. */	if (info->cleanTbdNum < 1) {		printf("No available TxBDs ...\n");		return -1;	}	/* Get the first TxBD to send the mac header */	pTbd = &info->txbd[info->txIdx];	pTbd->cbd_datlen = length;	pTbd->cbd_bufaddr = (u32) packet;	pTbd->cbd_sc |= BD_ENET_TX_LAST | BD_ENET_TX_TC | BD_ENET_TX_READY;	info->txIdx = (info->txIdx + 1) % CFG_TX_ETH_BUFFER;	/* Enable DMA transmit task */	MCD_continDma(info->txTask);	info->cleanTbdNum -= 1;	/* wait until frame is sent . */	while (pTbd->cbd_sc & BD_ENET_TX_READY) {		udelay(10);	}	return (int)(info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_STATS);}static int fec_recv(struct eth_device *dev){	struct fec_info_dma *info = dev->priv;	volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);	cbd_t *pRbd = &info->rxbd[info->rxIdx];	u32 ievent;	int frame_length, len = 0;	/* Check if any critical events have happened */	ievent = fecp->eir;	if (ievent != 0) {		fecp->eir = ievent;		if (ievent & (FEC_EIR_BABT | FEC_EIR_TXERR | FEC_EIR_RXERR)) {			printf("fec_recv: error\n");			fec_halt(dev);			fec_init(dev, NULL);			return 0;		}		if (ievent & FEC_EIR_HBERR) {			/* Heartbeat error */			fecp->tcr |= FEC_TCR_GTS;		}		if (ievent & FEC_EIR_GRA) {			/* Graceful stop complete */			if (fecp->tcr & FEC_TCR_GTS) {				printf("fec_recv: tcr_gts\n");				fec_halt(dev);				fecp->tcr &= ~FEC_TCR_GTS;				fec_init(dev, NULL);			}		}	}

⌨️ 快捷键说明

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