From 98f181be8e400434698fd89b13e04dbda9e8935d Mon Sep 17 00:00:00 2001 From: Jason Jin Date: Thu, 26 Jul 2012 15:16:42 +0800 Subject: Add Vybrid ENET support Signed-off-by: TsiChung Liew --- arch/arm/include/asm/fec.h | 302 +++++++++++++++++++++++++++++++++++++++++++++ drivers/net/mcffec.c | 18 ++- drivers/net/mcfmii.c | 4 +- 3 files changed, 319 insertions(+), 5 deletions(-) create mode 100644 arch/arm/include/asm/fec.h diff --git a/arch/arm/include/asm/fec.h b/arch/arm/include/asm/fec.h new file mode 100644 index 0000000000..ca3c3e283b --- /dev/null +++ b/arch/arm/include/asm/fec.h @@ -0,0 +1,302 @@ +/* + * fec.h -- Fast Ethernet Controller definitions + * + * Some definitions copied from commproc.h for MPC8xx: + * MPC8xx Communication Processor Module. + * + * Add FEC Structure and definitions + * Copyright 2004-2007,2012 Freescale Semiconductor, Inc. + * + * 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 + */ + +#ifndef fec_h +#define fec_h + +/* Buffer descriptors used FEC.*/ +typedef struct cpm_buf_desc { + ushort cbd_datlen; /* Data length in buffer */ + ushort cbd_sc; /* Status and Control */ + uint cbd_bufaddr; /* Buffer address in host memory */ +} cbd_t; + +#define BD_SC_EMPTY ((ushort)0x8000) /* Receive is empty */ +#define BD_SC_READY ((ushort)0x8000) /* Transmit is ready */ +#define BD_SC_WRAP ((ushort)0x2000) /* Last buffer descriptor */ +#define BD_SC_INTRPT ((ushort)0x1000) /* Interrupt on change */ +#define BD_SC_LAST ((ushort)0x0800) /* Last buffer in frame */ +#define BD_SC_TC ((ushort)0x0400) /* Transmit CRC */ +#define BD_SC_CM ((ushort)0x0200) /* Continous mode */ +#define BD_SC_ID ((ushort)0x0100) /* Rec'd too many idles */ +#define BD_SC_P ((ushort)0x0100) /* xmt preamble */ +#define BD_SC_BR ((ushort)0x0020) /* Break received */ +#define BD_SC_FR ((ushort)0x0010) /* Framing error */ +#define BD_SC_PR ((ushort)0x0008) /* Parity error */ +#define BD_SC_OV ((ushort)0x0002) /* Overrun */ +#define BD_SC_CD ((ushort)0x0001) /* Carrier Detect lost */ + +/* Buffer descriptor control/status used by Ethernet receive.*/ +#define BD_ENET_RX_EMPTY ((ushort)0x8000) +#define BD_ENET_RX_RO1 ((ushort)0x4000) +#define BD_ENET_RX_WRAP ((ushort)0x2000) +#define BD_ENET_RX_INTR ((ushort)0x1000) +#define BD_ENET_RX_RO2 BD_ENET_RX_INTR +#define BD_ENET_RX_LAST ((ushort)0x0800) +#define BD_ENET_RX_FIRST ((ushort)0x0400) +#define BD_ENET_RX_MISS ((ushort)0x0100) +#define BD_ENET_RX_BC ((ushort)0x0080) +#define BD_ENET_RX_MC ((ushort)0x0040) +#define BD_ENET_RX_LG ((ushort)0x0020) +#define BD_ENET_RX_NO ((ushort)0x0010) +#define BD_ENET_RX_SH ((ushort)0x0008) +#define BD_ENET_RX_CR ((ushort)0x0004) +#define BD_ENET_RX_OV ((ushort)0x0002) +#define BD_ENET_RX_CL ((ushort)0x0001) +#define BD_ENET_RX_TR BD_ENET_RX_CL +#define BD_ENET_RX_STATS ((ushort)0x013f) /* All status bits */ + +/* Buffer descriptor control/status used by Ethernet transmit.*/ +#define BD_ENET_TX_READY ((ushort)0x8000) +#define BD_ENET_TX_PAD ((ushort)0x4000) +#define BD_ENET_TX_TO1 BD_ENET_TX_PAD +#define BD_ENET_TX_WRAP ((ushort)0x2000) +#define BD_ENET_TX_INTR ((ushort)0x1000) +#define BD_ENET_TX_TO2 BD_ENET_TX_INTR_ +#define BD_ENET_TX_LAST ((ushort)0x0800) +#define BD_ENET_TX_TC ((ushort)0x0400) +#define BD_ENET_TX_DEF ((ushort)0x0200) +#define BD_ENET_TX_ABC BD_ENET_TX_DEF +#define BD_ENET_TX_HB ((ushort)0x0100) +#define BD_ENET_TX_LC ((ushort)0x0080) +#define BD_ENET_TX_RL ((ushort)0x0040) +#define BD_ENET_TX_RCMASK ((ushort)0x003c) +#define BD_ENET_TX_UN ((ushort)0x0002) +#define BD_ENET_TX_CSL ((ushort)0x0001) +#define BD_ENET_TX_STATS ((ushort)0x03ff) /* All status bits */ + +/* FEC private information */ +struct fec_info_s { + int index; + u32 iobase; + u32 pinmux; + u32 miibase; + int phy_addr; + int dup_spd; + char *phy_name; + int phyname_init; + cbd_t *rxbd; /* Rx BD */ + cbd_t *txbd; /* Tx BD */ + uint rxIdx; + uint txIdx; + char *txbuf; + int initialized; + struct fec_info_s *next; +}; + +#ifdef CONFIG_MCFFEC +/* Register read/write struct */ +typedef struct fec { + u8 resv0[0x4]; + u32 eir; + u32 eimr; + u8 resv1[0x4]; + u32 rdar; + u32 tdar; + u8 resv2[0xC]; + u32 ecr; + u8 resv3[0x18]; + u32 mmfr; + u32 mscr; + u8 resv4[0x1C]; + u32 mibc; + u8 resv5[0x1C]; + u32 rcr; + u8 resv6[0x3C]; + u32 tcr; + u8 resv7[0x1C]; + u32 palr; + u32 paur; + u32 opd; + u8 resv8[0x28]; + u32 iaur; + u32 ialr; + u32 gaur; + u32 galr; + u8 resv9[0x1C]; + u32 tfwr; + u8 resv10[0x4]; + u32 frbr; + u32 frsr; + u8 resv11[0x2C]; + u32 erdsr; + u32 etdsr; + u32 emrbr; + u8 resv12[0x74]; + + u32 rmon_t_drop; + u32 rmon_t_packets; + u32 rmon_t_bc_pkt; + u32 rmon_t_mc_pkt; + u32 rmon_t_crc_align; + u32 rmon_t_undersize; + u32 rmon_t_oversize; + u32 rmon_t_frag; + u32 rmon_t_jab; + u32 rmon_t_col; + u32 rmon_t_p64; + u32 rmon_t_p65to127; + u32 rmon_t_p128to255; + u32 rmon_t_p256to511; + u32 rmon_t_p512to1023; + u32 rmon_t_p1024to2047; + u32 rmon_t_p_gte2048; + u32 rmon_t_octets; + + u32 ieee_t_drop; + u32 ieee_t_frame_ok; + u32 ieee_t_1col; + u32 ieee_t_mcol; + u32 ieee_t_def; + u32 ieee_t_lcol; + u32 ieee_t_excol; + u32 ieee_t_macerr; + u32 ieee_t_cserr; + u32 ieee_t_sqe; + u32 ieee_t_fdxfc; + u32 ieee_t_octets_ok; + u8 resv13[0x8]; + + u32 rmon_r_drop; + u32 rmon_r_packets; + u32 rmon_r_bc_pkt; + u32 rmon_r_mc_pkt; + u32 rmon_r_crc_align; + u32 rmon_r_undersize; + u32 rmon_r_oversize; + u32 rmon_r_frag; + u32 rmon_r_jab; + u32 rmon_r_resvd_0; + u32 rmon_r_p64; + u32 rmon_r_p65to127; + u32 rmon_r_p128to255; + u32 rmon_r_p256to511; + u32 rmon_r_p512to1023; + u32 rmon_r_p1024to2047; + u32 rmon_r_p_gte2048; + u32 rmon_r_octets; + + u32 ieee_r_drop; + u32 ieee_r_frame_ok; + u32 ieee_r_crc; + u32 ieee_r_align; + u32 ieee_r_macerr; + u32 ieee_r_fdxfc; + u32 ieee_r_octets_ok; +} fec_t; +#endif /* CONFIG_MCFFEC */ + +#define FEC_EIR_CLEAR_ALL (0xFFF80000) +#define FEC_EIR_HBERR (0x80000000) +#define FEC_EIR_BABR (0x40000000) +#define FEC_EIR_BABT (0x20000000) +#define FEC_EIR_GRA (0x10000000) +#define FEC_EIR_TXF (0x08000000) +#define FEC_EIR_TXB (0x04000000) +#define FEC_EIR_RXF (0x02000000) +#define FEC_EIR_RXB (0x01000000) +#define FEC_EIR_MII (0x00800000) +#define FEC_EIR_EBERR (0x00400000) +#define FEC_EIR_LC (0x00200000) +#define FEC_EIR_RL (0x00100000) +#define FEC_EIR_UN (0x00080000) + +#define FEC_RDAR_R_DES_ACTIVE (0x01000000) + +#define FEC_TDAR_X_DES_ACTIVE (0x01000000) + +#define FEC_ECR_ETHER_EN (0x00000002) +#define FEC_ECR_RESET (0x00000001) + +#define FEC_MMFR_DATA(x) (((x)&0xFFFF)) +#define FEC_MMFR_ST(x) (((x)&0x03)<<30) +#define FEC_MMFR_ST_01 (0x40000000) +#define FEC_MMFR_OP_RD (0x20000000) +#define FEC_MMFR_OP_WR (0x10000000) +#define FEC_MMFR_PA(x) (((x)&0x1F)<<23) +#define FEC_MMFR_RA(x) (((x)&0x1F)<<18) +#define FEC_MMFR_TA(x) (((x)&0x03)<<16) +#define FEC_MMFR_TA_10 (0x00020000) + +#define FEC_MSCR_DIS_PREAMBLE (0x00000080) +#define FEC_MSCR_MII_SPEED(x) (((x)&0x3F)<<1) + +#define FEC_MIBC_MIB_DISABLE (0x80000000) +#define FEC_MIBC_MIB_IDLE (0x40000000) + +#define FEC_RCR_MAX_FL(x) (((x)&0x7FF)<<16) +#define FEC_RCR_FCE (0x00000020) +#define FEC_RCR_BC_REJ (0x00000010) +#define FEC_RCR_PROM (0x00000008) +#define FEC_RCR_MII_MODE (0x00000004) +#define FEC_RCR_DRT (0x00000002) +#define FEC_RCR_LOOP (0x00000001) + +#define FEC_TCR_RFC_PAUSE (0x00000010) +#define FEC_TCR_TFC_PAUSE (0x00000008) +#define FEC_TCR_FDEN (0x00000004) +#define FEC_TCR_HBC (0x00000002) +#define FEC_TCR_GTS (0x00000001) + +#define FEC_PAUR_PADDR2(x) (((x)&0xFFFF)<<16) +#define FEC_PAUR_TYPE(x) ((x)&0xFFFF) + +#define FEC_OPD_PAUSE_DUR(x) (((x)&0x0000FFFF)<<0) +#define FEC_OPD_OPCODE(x) (((x)&0x0000FFFF)<<16) + +#define FEC_TFWR_X_WMRK(x) ((x)&0x03) +#define FEC_TFWR_X_WMRK_64 (0x01) +#define FEC_TFWR_X_WMRK_128 (0x02) +#define FEC_TFWR_X_WMRK_192 (0x03) + +#define FEC_FRBR_R_BOUND(x) (((x)&0xFF)<<2) + +#define FEC_FRSR_R_FSTART(x) (((x)&0xFF)<<2) + +#define FEC_ERDSR_R_DES_START(x) (((x)&0x3FFFFFFF)<<2) + +#define FEC_ETDSR_X_DES_START(x) (((x)&0x3FFFFFFF)<<2) + +#define FEC_EMRBR_R_BUF_SIZE(x) (((x)&0x7F)<<4) + +#define FEC_RESET_DELAY 100 +#define FEC_RX_TOUT 100 + +int fecpin_setclear(struct eth_device *dev, int setclear); + +#ifdef CONFIG_SYS_DISCOVER_PHY +void __mii_init(void); +uint mii_send(uint mii_cmd); +int mii_discover_phy(struct eth_device *dev); +int mcffec_miiphy_read(const char *devname, unsigned char addr, + unsigned char reg, unsigned short *value); +int mcffec_miiphy_write(const char *devname, unsigned char addr, + unsigned char reg, unsigned short value); +#endif + +#endif /* fec_h */ diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c index a08ff278bf..1f59794102 100644 --- a/drivers/net/mcffec.c +++ b/drivers/net/mcffec.c @@ -33,7 +33,11 @@ #include #include +#ifdef CONFIG_COLDFIRE #include +#endif +#ifdef CONFIG_VYBRID +#endif #undef ET_DEBUG #undef MII_DEBUG @@ -116,7 +120,7 @@ void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd) } if ((dup_spd & 0xFFFF) == _100BASET) { -#ifdef CONFIG_MCF5445x +#if defined(CONFIG_MCF5445x) || defined(CONFIG_VYBRID) fecp->rcr &= ~0x200; /* disabled 10T base */ #endif #ifdef MII_DEBUG @@ -124,7 +128,7 @@ void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd) #endif bd->bi_ethspeed = 100; } else { -#ifdef CONFIG_MCF5445x +#if defined(CONFIG_MCF5445x) || defined(CONFIG_VYBRID) fecp->rcr |= 0x200; /* enabled 10T base */ #endif #ifdef MII_DEBUG @@ -182,7 +186,7 @@ int fec_send(struct eth_device *dev, volatile void *packet, int length) j = 0; while ((info->txbd[info->txIdx].cbd_sc & BD_ENET_TX_READY) && (j < MCFFEC_TOUT_LOOP)) { - udelay(1); + udelay(10); j++; } if (j >= MCFFEC_TOUT_LOOP) { @@ -515,7 +519,12 @@ int fec_init(struct eth_device *dev, bd_t * bd) fecp->etdsr = (unsigned int)(&info->txbd[0]); /* Now enable the transmit and receive processing */ +#ifdef CONFIG_VYBRID + /*Big Endian*/ + fecp->ecr |= FEC_ECR_ETHER_EN | 0x100; +#else fecp->ecr |= FEC_ECR_ETHER_EN; +#endif /* And last, try to fill Rx Buffer Descriptors */ fecp->rdar = 0x01000000; /* Descriptor polling active */ @@ -621,6 +630,7 @@ int mcffec_initialize(bd_t * bis) /* default speed */ bis->bi_ethspeed = 10; - + /*Ugly workaround for FEC to work in kernel, TODO Jason*/ + mii_init(); return 0; } diff --git a/drivers/net/mcfmii.c b/drivers/net/mcfmii.c index 471c5efea1..63f1fd98ad 100644 --- a/drivers/net/mcfmii.c +++ b/drivers/net/mcfmii.c @@ -31,7 +31,9 @@ #else #include #endif +#ifdef CONFIG_COLDFIRE #include +#endif DECLARE_GLOBAL_DATA_PTR; @@ -83,6 +85,7 @@ phy_info_t phyinfo[] = { {0x20005CE1, "N83640"}, /* National 83640 */ {0x20005C90, "N83848"}, /* National 83848 */ {0x20005CA2, "N83849"}, /* National 83849 */ + {0x0007C0F1, "SMSC8720A"}, /* SMSC 8720a */ {0x01814400, "QS6612"}, /* QS6612 */ #if defined(CONFIG_SYS_UNSPEC_PHYID) && defined(CONFIG_SYS_UNSPEC_STRID) {CONFIG_SYS_UNSPEC_PHYID, CONFIG_SYS_UNSPEC_STRID}, @@ -122,7 +125,6 @@ uint mii_send(uint mii_cmd) info = dev->priv; ep = (FEC_T *) info->miibase; - ep->mmfr = mii_cmd; /* command to phy */ /* wait for mii complete */ -- cgit v1.2.3