📄 fsl_mcdmafec.c
字号:
/* * (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 + -