From 567fb852178dbf59529d7301620a3f3732a4b02d Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Thu, 8 May 2008 22:52:09 +0200 Subject: Fix @ -> substitution When applying the AT91CAP9 patches upstream, something transformed the '@' character into the ' ' sequence. The patch below restores the original form in all the places where it has been modified (the AT91CAP9 files, the AT91SAM9260 files which were copied from AT91CAP9, and a couple of other files where the ' ' sequence was present). Signed-off-by: Stelian Pop Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/net/smc911x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index d22c889..c17dcf4 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -1,7 +1,7 @@ /* * SMSC LAN9[12]1[567] Network driver * - * (c) 2007 Pengutronix, Sascha Hauer pengutronix.de> + * (c) 2007 Pengutronix, Sascha Hauer * * See file CREDITS for list of people who contributed to this * project. -- cgit v1.1 From d99a8ff66d8ae87e5c87590ed2e4ead629540607 Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Thu, 8 May 2008 20:52:22 +0200 Subject: AT91SAM9261EK support This patch adds support for the AT91SAM9261 chip and the AT91SAM9261EK board. Signed-off-by: Stelian Pop Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/net/dm9000x.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 6131b5c..db6d3bd 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -300,8 +300,10 @@ eth_init(bd_t * bd) DM9000_iow(DM9000_ISR, 0x0f); /* Clear interrupt status */ /* Set Node address */ +#ifndef CONFIG_AT91SAM9261EK for (i = 0; i < 6; i++) ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i); +#endif if (is_zero_ether_addr(bd->bi_enetaddr) || is_multicast_ether_addr(bd->bi_enetaddr)) { -- cgit v1.1 From 8e429b3eee23927c1222679f6b6f53667b21595c Mon Sep 17 00:00:00 2001 From: Stelian Pop Date: Thu, 8 May 2008 18:52:23 +0200 Subject: AT91SAM9263EK support This patch adds support for the AT91SAM9263 chip and the AT91SAM9263EK board. Signed-off-by: Stelian Pop Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- drivers/net/macb.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/macb.c b/drivers/net/macb.c index 703784e..e5733f6 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -417,13 +417,15 @@ static int macb_init(struct eth_device *netdev, bd_t *bd) /* choose RMII or MII mode. This depends on the board */ #ifdef CONFIG_RMII -#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) +#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ + defined(CONFIG_AT91SAM9263) macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN)); #else macb_writel(macb, USRIO, 0); #endif #else -#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) +#if defined(CONFIG_AT91CAP9) || defined(CONFIG_AT91SAM9260) || \ + defined(CONFIG_AT91SAM9263) macb_writel(macb, USRIO, MACB_BIT(CLKEN)); #else macb_writel(macb, USRIO, MACB_BIT(MII)); -- cgit v1.1 From 557b377d8bfc8b833b6e749457bcdfa298331a24 Mon Sep 17 00:00:00 2001 From: Jens Gehrlein Date: Mon, 5 May 2008 14:06:11 +0200 Subject: smc911x: add 16 bit support Signed-off-by: Jens Gehrlein Signed-off-by: Ben Warren --- drivers/net/smc911x.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 5302cb5..6d93bf0 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -30,6 +30,12 @@ #include #include +#if defined (CONFIG_DRIVER_SMC911X_32_BIT) && \ + defined (CONFIG_DRIVER_SMC911X_16_BIT) +#error "SMC911X: Only one of CONFIG_DRIVER_SMC911X_32_BIT and \ + CONFIG_DRIVER_SMC911X_16_BIT shall be set" +#endif + #ifdef CONFIG_DRIVER_SMC911X_32_BIT static inline u32 reg_read(u32 addr) { @@ -39,9 +45,20 @@ static inline void reg_write(u32 addr, u32 val) { *(volatile u32*)addr = val; } +#elif CONFIG_DRIVER_SMC911X_16_BIT +static inline u32 reg_read(u32 addr) +{ + volatile u16 *addr_16 = (u16 *)addr; + return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16)); +} +static inline void reg_write(u32 addr, u32 val) +{ + *(volatile u16*)addr = (u16)val; + *(volatile u16*)(addr + 2) = (u16)(val >> 16); +} #else -#error "SMC911X: Only 32-bit bus is supported" -#endif +#error "SMC911X: undefined bus width" +#endif /* CONFIG_DRIVER_SMC911X_16_BIT */ #define mdelay(n) udelay((n)*1000) -- cgit v1.1 From 290ef6436838b1cc013bd67e0e0495c9eb3e23c0 Mon Sep 17 00:00:00 2001 From: Ron Madrid Date: Fri, 23 May 2008 15:37:05 -0700 Subject: Add Marvell 88E1118 support for TSEC Signed-off-by: Ron Madrid Signed-off-by: Ben Warren --- drivers/net/tsec.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index c7af930..397ae71 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -1128,6 +1128,36 @@ struct phy_info phy_info_M88E1111S = { }, }; +struct phy_info phy_info_M88E1118 = { + 0x01410e1, + "Marvell 88E1118", + 4, + (struct phy_cmd[]){ /* config */ + /* Reset and configure the PHY */ + {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, + {0x16, 0x0002, NULL}, /* Change Page Number */ + {0x15, 0x1070, NULL}, /* Delay RGMII TX and RX */ + {MIIM_GBIT_CONTROL, MIIM_GBIT_CONTROL_INIT, NULL}, + {MIIM_ANAR, MIIM_ANAR_INIT, NULL}, + {MIIM_CONTROL, MIIM_CONTROL_RESET, NULL}, + {MIIM_CONTROL, MIIM_CONTROL_INIT, &mii_cr_init}, + {miim_end,} + }, + (struct phy_cmd[]){ /* startup */ + {0x16, 0x0000, NULL}, /* Change Page Number */ + /* Status is read once to clear old link state */ + {MIIM_STATUS, miim_read, NULL}, + /* Auto-negotiate */ + /* Read the status */ + {MIIM_88E1011_PHY_STATUS, miim_read, + &mii_parse_88E1011_psr}, + {miim_end,} + }, + (struct phy_cmd[]){ /* shutdown */ + {miim_end,} + }, +}; + static unsigned int m88e1145_setmode(uint mii_reg, struct tsec_private *priv) { uint mii_data = read_phy_reg(priv, mii_reg); @@ -1492,6 +1522,7 @@ struct phy_info *phy_info[] = { &phy_info_BCM5464S, &phy_info_M88E1011S, &phy_info_M88E1111S, + &phy_info_M88E1118, &phy_info_M88E1145, &phy_info_M88E1149S, &phy_info_dm9161, -- cgit v1.1 From ff36fbb2e7583fb808eef773f511489c7a9c2df3 Mon Sep 17 00:00:00 2001 From: TsiChung Liew Date: Wed, 28 May 2008 13:06:25 -0500 Subject: ColdFire: Add 10 base ethernet support for mcf5445x Signed-off-by: TsiChung Liew Signed-off-by: Ben Warren --- drivers/net/mcffec.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c index 5ab4726..8d4e248 100644 --- a/drivers/net/mcffec.c +++ b/drivers/net/mcffec.c @@ -125,11 +125,17 @@ void setFecDuplexSpeed(volatile fec_t * fecp, bd_t * bd, int dup_spd) } if ((dup_spd & 0xFFFF) == _100BASET) { +#ifdef CONFIG_MCF5445x + fecp->rcr &= ~0x200; /* disabled 10T base */ +#endif #ifdef MII_DEBUG printf("100Mbps\n"); #endif bd->bi_ethspeed = 100; } else { +#ifdef CONFIG_MCF5445x + fecp->rcr |= 0x200; /* enabled 10T base */ +#endif #ifdef MII_DEBUG printf("10Mbps\n"); #endif -- cgit v1.1 From aa3b8bf9c30065bb2ea852799d32db5020598495 Mon Sep 17 00:00:00 2001 From: Wolfgang Grandegger Date: Wed, 28 May 2008 19:55:19 +0200 Subject: E1000: Add support for the 82541GI LF Intel Pro 1000 GT Desktop Adapter Signed-off-by: Wolfgang Grandegger Signed-off-by: Ben Warren --- drivers/net/e1000.c | 2 ++ drivers/net/e1000.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index c53c226..40a781f 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -83,6 +83,7 @@ static struct pci_device_id supported[] = { {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM_LOM}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541ER}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82541GI_LF}, }; /* Function forward declarations */ @@ -646,6 +647,7 @@ e1000_set_mac_type(struct e1000_hw *hw) hw->mac_type = e1000_82546; break; case E1000_DEV_ID_82541ER: + case E1000_DEV_ID_82541GI_LF: hw->mac_type = e1000_82541_rev_2; break; default: diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 851467d..23b2eb9 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -222,7 +222,8 @@ struct e1000_phy_stats { #define E1000_DEV_ID_82546EB_COPPER 0x1010 #define E1000_DEV_ID_82546EB_FIBER 0x1012 #define E1000_DEV_ID_82541ER 0x1078 -#define NUM_DEV_IDS 14 +#define E1000_DEV_ID_82541GI_LF 0x107C +#define NUM_DEV_IDS 15 #define NODE_ADDRESS_SIZE 6 #define ETH_LENGTH_OF_ADDRESS 6 -- cgit v1.1 From a101361bfe23c120321e45d114c0603b8e0763e9 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Tue, 3 Jun 2008 15:26:21 +0200 Subject: DM9000: Add data bus-width auto detection. The U-boot DM9000x driver contains a compile time bus-width definition for the databus connected to the network controller. This compile check makes the code unclear, inflexible and is unneccessary. It can be asked to the network controller what its bus-width is by reading bits 6 and 7 of the interrupt status register. The linux kernel already uses a runtime mechanism to determine this bus-width, so the implementation below looks somewhat like that implementation. This change has been tested with DM9000A, DM9000E, DM9000EP. Signed-off-by: Remy Bohmer Signed-off-by: Ben Warren --- drivers/net/dm9000x.c | 187 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 129 insertions(+), 58 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 01e2f14..0a2ce68 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -36,7 +36,13 @@ v1.2 03/18/2003 Weilun Huang : -------------------------------------- - 12/15/2003 Initial port to u-boot by Sascha Hauer + 12/15/2003 Initial port to u-boot by + Sascha Hauer + + 06/03/2008 Remy Bohmer + - Added autodetect of databus width. + These changes are tested with DM9000{A,EP,E} together + with a 200MHz Atmel AT91SAM92161 core TODO: Homerun NIC and longrun NIC are not functional, only internal at the moment. @@ -84,8 +90,11 @@ typedef struct board_info { u8 device_wait_reset; /* device state */ u8 nic_type; /* NIC type */ unsigned char srom[128]; -} board_info_t; -board_info_t dmfe_info; + void (*outblk)(void *data_ptr, int count); + void (*inblk)(void *data_ptr, int count); + void (*rx_status)(u16 *RxStatus, u16 *RxLen); + } board_info_t; +static board_info_t dm9000_info; /* For module input parameter */ static int media_mode = DM9000_AUTO; @@ -127,7 +136,81 @@ dump_regs(void) DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(ISR)); DM9000_DBG("\n"); } -#endif /* */ +#endif + +static void dm9000_outblk_8bit(void *data_ptr, int count) +{ + int i; + for (i = 0; i < count; i++) + DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA); +} + +static void dm9000_outblk_16bit(void *data_ptr, int count) +{ + int i; + u32 tmplen = (count + 1) / 2; + + for (i = 0; i < tmplen; i++) + DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); +} +static void dm9000_outblk_32bit(void *data_ptr, int count) +{ + int i; + u32 tmplen = (count + 3) / 4; + + for (i = 0; i < tmplen; i++) + DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA); +} + +static void dm9000_inblk_8bit(void *data_ptr, int count) +{ + int i; + for (i = 0; i < count; i++) + ((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA); +} + +static void dm9000_inblk_16bit(void *data_ptr, int count) +{ + int i; + u32 tmplen = (count + 1) / 2; + + for (i = 0; i < tmplen; i++) + ((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA); +} +static void dm9000_inblk_32bit(void *data_ptr, int count) +{ + int i; + u32 tmplen = (count + 3) / 4; + + for (i = 0; i < tmplen; i++) + ((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA); +} + +static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen) +{ + u32 tmpdata = DM9000_inl(DM9000_DATA); + + DM9000_outb(DM9000_MRCMD, DM9000_IO); + + *RxStatus = tmpdata; + *RxLen = tmpdata >> 16; +} + +static void dm9000_rx_status_16bit(u16 *RxStatus, u16 *RxLen) +{ + DM9000_outb(DM9000_MRCMD, DM9000_IO); + + *RxStatus = DM9000_inw(DM9000_DATA); + *RxLen = DM9000_inw(DM9000_DATA); +} + +static void dm9000_rx_status_8bit(u16 *RxStatus, u16 *RxLen) +{ + DM9000_outb(DM9000_MRCMD, DM9000_IO); + + *RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8); + *RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8); +} /* Search DM9000 board, allocate space and register it @@ -236,7 +319,7 @@ program_dm9802(void) static void identify_nic(void) { - struct board_info *db = &dmfe_info; /* Point a board information structure */ + struct board_info *db = &dm9000_info; u16 phy_reg3; DM9000_iow(DM9000_NCR, NCR_EXT_PHY); phy_reg3 = phy_read(3); @@ -274,12 +357,46 @@ int eth_init(bd_t * bd) { int i, oft, lnk; + u8 io_mode; + struct board_info *db = &dm9000_info; + DM9000_DBG("eth_init()\n"); /* RESET device */ dm9000_reset(); dm9000_probe(); + /* Auto-detect 8/16/32 bit mode, ISR Bit 6+7 indicate bus width */ + io_mode = DM9000_ior(DM9000_ISR) >> 6; + + switch (io_mode) { + case 0x0: /* 16-bit mode */ + printf("DM9000: running in 16 bit mode\n"); + db->outblk = dm9000_outblk_16bit; + db->inblk = dm9000_inblk_16bit; + db->rx_status = dm9000_rx_status_16bit; + break; + case 0x01: /* 32-bit mode */ + printf("DM9000: running in 32 bit mode\n"); + db->outblk = dm9000_outblk_32bit; + db->inblk = dm9000_inblk_32bit; + db->rx_status = dm9000_rx_status_32bit; + break; + case 0x02: /* 8 bit mode */ + printf("DM9000: running in 8 bit mode\n"); + db->outblk = dm9000_outblk_8bit; + db->inblk = dm9000_inblk_8bit; + db->rx_status = dm9000_rx_status_8bit; + break; + default: + /* Assume 8 bit mode, will probably not work anyway */ + printf("DM9000: Undefined IO-mode:0x%x\n", io_mode); + db->outblk = dm9000_outblk_8bit; + db->inblk = dm9000_inblk_8bit; + db->rx_status = dm9000_rx_status_8bit; + break; + } + /* NIC Type: FASTETHER, HOMERUN, LONGRUN */ identify_nic(); @@ -377,6 +494,8 @@ eth_send(volatile void *packet, int length) char *data_ptr; u32 tmplen, i; int tmo; + struct board_info *db = &dm9000_info; + DM9000_DBG("eth_send: length: %d\n", length); for (i = 0; i < length; i++) { if (i % 8 == 0) @@ -388,24 +507,8 @@ eth_send(volatile void *packet, int length) data_ptr = (char *) packet; DM9000_outb(DM9000_MWCMD, DM9000_IO); -#ifdef CONFIG_DM9000_USE_8BIT - /* Byte mode */ - for (i = 0; i < length; i++) - DM9000_outb((data_ptr[i] & 0xff), DM9000_DATA); - -#endif /* */ -#ifdef CONFIG_DM9000_USE_16BIT - tmplen = (length + 1) / 2; - for (i = 0; i < tmplen; i++) - DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); - -#endif /* */ -#ifdef CONFIG_DM9000_USE_32BIT - tmplen = (length + 3) / 4; - for (i = 0; i < tmplen; i++) - DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA); - -#endif /* */ + /* push the data to the TX-fifo */ + (db->outblk)(data_ptr, length); /* Set TX length to DM9000 */ DM9000_iow(DM9000_TXPLL, length & 0xff); @@ -450,10 +553,7 @@ eth_rx(void) { u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0]; u16 RxStatus, RxLen = 0; - u32 tmplen, i; -#ifdef CONFIG_DM9000_USE_32BIT - u32 tmpdata; -#endif + struct board_info *db = &dm9000_info; /* Check packet ready or not */ DM9000_ior(DM9000_MRCMDX); /* Dummy read */ @@ -472,43 +572,14 @@ eth_rx(void) /* A packet ready now & Get status/length */ DM9000_outb(DM9000_MRCMD, DM9000_IO); -#ifdef CONFIG_DM9000_USE_8BIT - RxStatus = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8); - RxLen = DM9000_inb(DM9000_DATA) + (DM9000_inb(DM9000_DATA) << 8); + (db->rx_status)(&RxStatus, &RxLen); -#endif /* */ -#ifdef CONFIG_DM9000_USE_16BIT - RxStatus = DM9000_inw(DM9000_DATA); - RxLen = DM9000_inw(DM9000_DATA); - -#endif /* */ -#ifdef CONFIG_DM9000_USE_32BIT - tmpdata = DM9000_inl(DM9000_DATA); - RxStatus = tmpdata; - RxLen = tmpdata >> 16; - -#endif /* */ DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); /* Move data from DM9000 */ /* Read received packet from RX SRAM */ -#ifdef CONFIG_DM9000_USE_8BIT - for (i = 0; i < RxLen; i++) - rdptr[i] = DM9000_inb(DM9000_DATA); - -#endif /* */ -#ifdef CONFIG_DM9000_USE_16BIT - tmplen = (RxLen + 1) / 2; - for (i = 0; i < tmplen; i++) - ((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA); + (db->inblk)(rdptr, RxLen); -#endif /* */ -#ifdef CONFIG_DM9000_USE_32BIT - tmplen = (RxLen + 3) / 4; - for (i = 0; i < tmplen; i++) - ((u32 *) rdptr)[i] = DM9000_inl(DM9000_DATA); - -#endif /* */ if ((RxStatus & 0xbf00) || (RxLen < 0x40) || (RxLen > DM9000_PKT_MAX)) { if (RxStatus & 0x100) { -- cgit v1.1 From 134e266253c02a7832560da59d394989c4f64453 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Tue, 3 Jun 2008 15:26:22 +0200 Subject: DM9000: repair debug logging It seems that the debugging code of the DM9000x driver in U-boot has not been compiled for a long time, because it cannot compile... Also rearranged some loglines to get more useful info while debugging. Signed-off-by: Remy Bohmer Signed-off-by: Ben Warren --- drivers/net/dm9000x.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 0a2ce68..05d07f3 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -41,6 +41,7 @@ v1.2 03/18/2003 Weilun Huang : 06/03/2008 Remy Bohmer - Added autodetect of databus width. + - Made debug code compile again. These changes are tested with DM9000{A,EP,E} together with a 200MHz Atmel AT91SAM92161 core @@ -65,10 +66,22 @@ TODO: Homerun NIC and longrun NIC are not functional, only internal at the /* #define CONFIG_DM9000_DEBUG */ #ifdef CONFIG_DM9000_DEBUG -#define DM9000_DBG(fmt,args...) printf(fmt ,##args) -#else /* */ +#define DM9000_DBG(fmt,args...) printf(fmt, ##args) +#define DM9000_DMP_PACKET(func,packet,length) \ + do { \ + int i; \ + printf(func ": length: %d\n", length); \ + for (i = 0; i < length; i++) { \ + if (i % 8 == 0) \ + printf("\n%s: %02x: ", func, i); \ + printf("%02x ", ((unsigned char *) packet)[i]); \ + } printf("\n"); \ + } while(0) +#else #define DM9000_DBG(fmt,args...) -#endif /* */ +#define DM9000_DMP_PACKET(func,packet,length) +#endif + enum DM9000_PHY_mode { DM9000_10MHD = 0, DM9000_100MHD = 1, DM9000_10MFD = 4, DM9000_100MFD = 5, DM9000_AUTO = 8, DM9000_1M_HPNA = 0x10 @@ -133,7 +146,7 @@ dump_regs(void) DM9000_DBG("TSRII (0x04): %02x\n", DM9000_ior(4)); DM9000_DBG("RCR (0x05): %02x\n", DM9000_ior(5)); DM9000_DBG("RSR (0x06): %02x\n", DM9000_ior(6)); - DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(ISR)); + DM9000_DBG("ISR (0xFE): %02x\n", DM9000_ior(DM9000_ISR)); DM9000_DBG("\n"); } #endif @@ -496,12 +509,7 @@ eth_send(volatile void *packet, int length) int tmo; struct board_info *db = &dm9000_info; - DM9000_DBG("eth_send: length: %d\n", length); - for (i = 0; i < length; i++) { - if (i % 8 == 0) - DM9000_DBG("\nSend: 02x: ", i); - DM9000_DBG("%02x ", ((unsigned char *) packet)[i]); - } DM9000_DBG("\n"); + DM9000_DMP_PACKET("eth_send", packet, length); /* Move data to DM9000 TX RAM */ data_ptr = (char *) packet; @@ -596,6 +604,7 @@ eth_rx(void) dm9000_reset(); } } else { + DM9000_DMP_PACKET("eth_rx", rdptr, RxLen); /* Pass to upper layer */ DM9000_DBG("passing packet to upper layer\n"); @@ -666,7 +675,7 @@ phy_read(int reg) val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL); /* The read data keeps on REG_0D & REG_0E */ - DM9000_DBG("phy_read(%d): %d\n", reg, val); + DM9000_DBG("phy_read(0x%x): 0x%x\n", reg, val); return val; } @@ -686,6 +695,6 @@ phy_write(int reg, u16 value) DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */ udelay(500); /* Wait write complete */ DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */ - DM9000_DBG("phy_write(reg:%d, value:%d)\n", reg, value); + DM9000_DBG("phy_write(reg:0x%x, value:0x%x)\n", reg, value); } #endif /* CONFIG_DRIVER_DM9000 */ -- cgit v1.1 From acba31847fad9ae40708cc2c9f3a634ec35f3416 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Tue, 3 Jun 2008 15:26:23 +0200 Subject: DM9000: improve eth_send() routine The eth_send routine of the U-boot DM9000x driver does not match the DM9000 or DM9000A application notes/programming guides. This change improves the stability of the DM9000A network controller. This change has been tested with DM9000A, DM9000E, DM9000EP. Signed-off-by: Remy Bohmer Signed-off-by: Ben Warren --- drivers/net/dm9000x.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 05d07f3..c6c24dd 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -42,6 +42,9 @@ v1.2 03/18/2003 Weilun Huang : 06/03/2008 Remy Bohmer - Added autodetect of databus width. - Made debug code compile again. + - Adapt eth_send such that it matches the DM9000* + application notes. Needed to make it work properly + for DM9000A. These changes are tested with DM9000{A,EP,E} together with a 200MHz Atmel AT91SAM92161 core @@ -505,15 +508,16 @@ int eth_send(volatile void *packet, int length) { char *data_ptr; - u32 tmplen, i; int tmo; struct board_info *db = &dm9000_info; DM9000_DMP_PACKET("eth_send", packet, length); + DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ + /* Move data to DM9000 TX RAM */ data_ptr = (char *) packet; - DM9000_outb(DM9000_MWCMD, DM9000_IO); + DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */ /* push the data to the TX-fifo */ (db->outblk)(data_ptr, length); @@ -523,16 +527,19 @@ eth_send(volatile void *packet, int length) DM9000_iow(DM9000_TXPLH, (length >> 8) & 0xff); /* Issue TX polling command */ - DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ + DM9000_iow(DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ /* wait for end of transmission */ tmo = get_timer(0) + 5 * CFG_HZ; - while (DM9000_ior(DM9000_TCR) & TCR_TXREQ) { + while ( !(DM9000_ior(DM9000_NSR) & (NSR_TX1END | NSR_TX2END)) || + !(DM9000_ior(DM9000_ISR) & IMR_PTM) ) { if (get_timer(0) >= tmo) { printf("transmission timeout\n"); break; } } + DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ + DM9000_DBG("transmit done\n\n"); return 0; } -- cgit v1.1 From fbcb7ece0ea1e364180f1cf963e0fa0ce7f6560d Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Tue, 3 Jun 2008 15:26:24 +0200 Subject: DM9000: Improve eth_reset() routine According to the application notes of the DM9000 v1.22 chapter 5.2 bullet 2, the reset procedure must be done twice to properly reset the DM9000 by means of software. This errata is not needed anymore for the DM9000A, but it does not bother it. This change has been tested with DM9000A, DM9000E, DM9000EP. Signed-off-by: Remy Bohmer Signed-off-by: Ben Warren --- drivers/net/dm9000x.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index c6c24dd..5b00e95 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -45,6 +45,8 @@ v1.2 03/18/2003 Weilun Huang : - Adapt eth_send such that it matches the DM9000* application notes. Needed to make it work properly for DM9000A. + - Adapted reset procedure to match DM9000 application + notes (i.e. double reset) These changes are tested with DM9000{A,EP,E} together with a 200MHz Atmel AT91SAM92161 core @@ -362,9 +364,35 @@ identify_nic(void) static void dm9000_reset(void) { - DM9000_DBG("resetting\n"); - DM9000_iow(DM9000_NCR, NCR_RST); - udelay(1000); /* delay 1ms */ + DM9000_DBG("resetting DM9000\n"); + + /* Reset DM9000, + see DM9000 Application Notes V1.22 Jun 11, 2004 page 29 */ + + /* DEBUG: Make all GPIO pins outputs */ + DM9000_iow(DM9000_GPCR, 0x0F); + /* Step 1: Power internal PHY by writing 0 to GPIO0 pin */ + DM9000_iow(DM9000_GPR, 0); + /* Step 2: Software reset */ + DM9000_iow(DM9000_NCR, 3); + + do { + DM9000_DBG("resetting the DM9000, 1st reset\n"); + udelay(25); /* Wait at least 20 us */ + } while (DM9000_ior(DM9000_NCR) & 1); + + DM9000_iow(DM9000_NCR, 0); + DM9000_iow(DM9000_NCR, 3); /* Issue a second reset */ + + do { + DM9000_DBG("resetting the DM9000, 2nd reset\n"); + udelay(25); /* Wait at least 20 us */ + } while (DM9000_ior(DM9000_NCR) & 1); + + /* Check whether the ethernet controller is present */ + if ((DM9000_ior(DM9000_PIDL) != 0x0) || + (DM9000_ior(DM9000_PIDH) != 0x90)) + printf("ERROR: resetting DM9000 -> not responding\n"); } /* Initilize dm9000 board -- cgit v1.1 From 850ba7555dbd4ca8d14fc475b864d534797adab3 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Tue, 3 Jun 2008 15:26:25 +0200 Subject: DM9000: Make driver work properly for DM9000A The DM9000A network controller does not work with the U-boot DM9000x driver. Analysis showed that many incoming packets are lost. The DM9000A Application Notes V1.20 (section 5.6.1) recommend that the poll to check for a valid rx packet be done on the interrupt status register, not directly by performing the dummy read and the rx status check as is currently the case in the u-boot driver. When the recommended poll is done as suggested the driver starts working correctly on 10Mbit/HD, but on 100MBit/FD packets come in faster so that there can be more than 1 package in the fifo at the same time. The driver must perform the rx-status check in a loop and read and handle all packages until there is no more left _after_ the interrupt RX flag is set. This change has been tested with DM9000A, DM9000E, DM9000EP. Signed-off-by: Remy Bohmer Signed-off-by: Ben Warren --- drivers/net/dm9000x.c | 93 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 39 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 5b00e95..08248f4 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -40,6 +40,10 @@ v1.2 03/18/2003 Weilun Huang : Sascha Hauer 06/03/2008 Remy Bohmer + - Fixed the driver to work with DM9000A. + (check on ISR receive status bit before reading the + FIFO as described in DM9000 programming guide and + application notes) - Added autodetect of databus width. - Made debug code compile again. - Adapt eth_send such that it matches the DM9000* @@ -598,53 +602,64 @@ eth_rx(void) u16 RxStatus, RxLen = 0; struct board_info *db = &dm9000_info; - /* Check packet ready or not */ - DM9000_ior(DM9000_MRCMDX); /* Dummy read */ - rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */ - if (rxbyte == 0) + /* Check packet ready or not, we must check + the ISR status first for DM9000A */ + if (!(DM9000_ior(DM9000_ISR) & 0x01)) /* Rx-ISR bit must be set. */ return 0; - /* Status check: this byte must be 0 or 1 */ - if (rxbyte > 1) { - DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */ - DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */ - DM9000_DBG("rx status check: %d\n", rxbyte); - } - DM9000_DBG("receiving packet\n"); + DM9000_iow(DM9000_ISR, 0x01); /* clear PR status latched in bit 0 */ - /* A packet ready now & Get status/length */ - DM9000_outb(DM9000_MRCMD, DM9000_IO); + /* There is _at least_ 1 package in the fifo, read them all */ + for (;;) { + DM9000_ior(DM9000_MRCMDX); /* Dummy read */ - (db->rx_status)(&RxStatus, &RxLen); + /* Get most updated data */ + rxbyte = DM9000_inb(DM9000_DATA); - DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); + /* Status check: this byte must be 0 or 1 */ + if (rxbyte > DM9000_PKT_RDY) { + DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */ + DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */ + printf("DM9000 error: status check fail: 0x%x\n", + rxbyte); + return 0; + } - /* Move data from DM9000 */ - /* Read received packet from RX SRAM */ - (db->inblk)(rdptr, RxLen); + if (rxbyte != DM9000_PKT_RDY) + return 0; /* No packet received, ignore */ + + DM9000_DBG("receiving packet\n"); + + /* A packet ready now & Get status/length */ + (db->rx_status)(&RxStatus, &RxLen); + + DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen); + + /* Move data from DM9000 */ + /* Read received packet from RX SRAM */ + (db->inblk)(rdptr, RxLen); + + if ((RxStatus & 0xbf00) || (RxLen < 0x40) + || (RxLen > DM9000_PKT_MAX)) { + if (RxStatus & 0x100) { + printf("rx fifo error\n"); + } + if (RxStatus & 0x200) { + printf("rx crc error\n"); + } + if (RxStatus & 0x8000) { + printf("rx length error\n"); + } + if (RxLen > DM9000_PKT_MAX) { + printf("rx length too big\n"); + dm9000_reset(); + } + } else { + DM9000_DMP_PACKET("eth_rx", rdptr, RxLen); - if ((RxStatus & 0xbf00) || (RxLen < 0x40) - || (RxLen > DM9000_PKT_MAX)) { - if (RxStatus & 0x100) { - printf("rx fifo error\n"); + DM9000_DBG("passing packet to upper layer\n"); + NetReceive(NetRxPackets[0], RxLen); } - if (RxStatus & 0x200) { - printf("rx crc error\n"); - } - if (RxStatus & 0x8000) { - printf("rx length error\n"); - } - if (RxLen > DM9000_PKT_MAX) { - printf("rx length too big\n"); - dm9000_reset(); - } - } else { - DM9000_DMP_PACKET("eth_rx", rdptr, RxLen); - - /* Pass to upper layer */ - DM9000_DBG("passing packet to upper layer\n"); - NetReceive(NetRxPackets[0], RxLen); - return RxLen; } return 0; } -- cgit v1.1 From 98291e2e689096420465074cce926b226d2e71b4 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Tue, 3 Jun 2008 15:26:26 +0200 Subject: DM9000: Some minor code cleanups Some lines of the U-boot DM9000x driver are longer than 80 characters, or need some other minor cleanup. Signed-off-by: Remy Bohmer Signed-off-by: Ben Warren --- drivers/net/dm9000x.c | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 08248f4..2945995 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -51,6 +51,7 @@ v1.2 03/18/2003 Weilun Huang : for DM9000A. - Adapted reset procedure to match DM9000 application notes (i.e. double reset) + - some minor code cleanups These changes are tested with DM9000{A,EP,E} together with a 200MHz Atmel AT91SAM92161 core @@ -115,7 +116,7 @@ typedef struct board_info { void (*outblk)(void *data_ptr, int count); void (*inblk)(void *data_ptr, int count); void (*rx_status)(u16 *RxStatus, u16 *RxLen); - } board_info_t; +} board_info_t; static board_info_t dm9000_info; /* For module input parameter */ @@ -454,15 +455,22 @@ eth_init(bd_t * bd) /* Set PHY */ set_PHY_mode(); - /* Program operating register */ - DM9000_iow(DM9000_NCR, 0x0); /* only intern phy supported by now */ - DM9000_iow(DM9000_TCR, 0); /* TX Polling clear */ - DM9000_iow(DM9000_BPTR, 0x3f); /* Less 3Kb, 200us */ - DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); /* Flow Control : High/Low Water */ - DM9000_iow(DM9000_FCR, 0x0); /* SH FIXME: This looks strange! Flow Control */ - DM9000_iow(DM9000_SMCR, 0); /* Special Mode */ - DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); /* clear TX status */ - DM9000_iow(DM9000_ISR, 0x0f); /* Clear interrupt status */ + /* Program operating register, only intern phy supported by now */ + DM9000_iow(DM9000_NCR, 0x0); + /* TX Polling clear */ + DM9000_iow(DM9000_TCR, 0); + /* Less 3Kb, 200us */ + DM9000_iow(DM9000_BPTR, 0x3f); + /* Flow Control : High/Low Water */ + DM9000_iow(DM9000_FCTR, FCTR_HWOT(3) | FCTR_LWOT(8)); + /* SH FIXME: This looks strange! Flow Control */ + DM9000_iow(DM9000_FCR, 0x0); + /* Special Mode */ + DM9000_iow(DM9000_SMCR, 0); + /* clear TX status */ + DM9000_iow(DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END); + /* Clear interrupt status */ + DM9000_iow(DM9000_ISR, 0x0f); /* Set Node address */ for (i = 0; i < 6; i++) @@ -496,8 +504,11 @@ eth_init(bd_t * bd) DM9000_DBG("\n"); /* Activate DM9000 */ - DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); /* RX enable */ - DM9000_iow(DM9000_IMR, IMR_PAR); /* Enable TX/RX interrupt mask */ + /* RX enable */ + DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN); + /* Enable TX/RX interrupt mask */ + DM9000_iow(DM9000_IMR, IMR_PAR); + i = 0; while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */ udelay(1000); @@ -720,7 +731,7 @@ phy_read(int reg) /* Fill the phyxcer register into REG_0C */ DM9000_iow(DM9000_EPAR, DM9000_PHY | reg); DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */ - udelay(100); /* Wait read complete */ + udelay(100); /* Wait read complete */ DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */ val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL); @@ -743,8 +754,8 @@ phy_write(int reg, u16 value) DM9000_iow(DM9000_EPDRL, (value & 0xff)); DM9000_iow(DM9000_EPDRH, ((value >> 8) & 0xff)); DM9000_iow(DM9000_EPCR, 0xa); /* Issue phyxcer write command */ - udelay(500); /* Wait write complete */ + udelay(500); /* Wait write complete */ DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */ DM9000_DBG("phy_write(reg:0x%x, value:0x%x)\n", reg, value); } -#endif /* CONFIG_DRIVER_DM9000 */ +#endif /* CONFIG_DRIVER_DM9000 */ -- cgit v1.1 From d6ee5fa40c26970d39990c6fc4a2f20a97822650 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Wed, 4 Jun 2008 10:47:25 +0200 Subject: Fix order for reading rx-status registers in 32bit mode of DM9000 A last minute cleanup before submitting the DM9000A patch series yesterday introduced a bug in reading the rx-status registers in 32bit mode only. This patch repairs this. Signed-off-by: Remy Bohmer Signed-off-by: Ben Warren --- drivers/net/dm9000x.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 2945995..6f3ddf0 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -211,10 +211,11 @@ static void dm9000_inblk_32bit(void *data_ptr, int count) static void dm9000_rx_status_32bit(u16 *RxStatus, u16 *RxLen) { - u32 tmpdata = DM9000_inl(DM9000_DATA); + u32 tmpdata; DM9000_outb(DM9000_MRCMD, DM9000_IO); + tmpdata = DM9000_inl(DM9000_DATA); *RxStatus = tmpdata; *RxLen = tmpdata >> 16; } -- cgit v1.1 From 7daf2ebe9196dd67131a06d85049c3a8a08ca413 Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Thu, 5 Jun 2008 22:29:00 +0900 Subject: [MIPS] Update header - Fix traditional KSEG names - Replace PHYSADDR with CPHYSADDR Signed-off-by: Shinya Kuribayashi --- drivers/net/inca-ip_sw.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/inca-ip_sw.c b/drivers/net/inca-ip_sw.c index e4aaed6..a079b60 100644 --- a/drivers/net/inca-ip_sw.c +++ b/drivers/net/inca-ip_sw.c @@ -234,7 +234,7 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis) /* Initialize the descriptor rings. */ for (i = 0; i < NUM_RX_DESC; i++) { - inca_rx_descriptor_t * rx_desc = KSEG1ADDR(&rx_ring[i]); + inca_rx_descriptor_t * rx_desc = (inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[i]); memset(rx_desc, 0, sizeof(rx_ring[i])); /* Set maximum size of receive buffer. @@ -252,14 +252,14 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis) /* Let the last descriptor point to the first * one. */ - rx_desc->nextRxDescPtr = KSEG1ADDR((u32)rx_ring); + rx_desc->nextRxDescPtr = (u32)CKSEG1ADDR(rx_ring); } else { /* Set the address of the next descriptor. */ - rx_desc->nextRxDescPtr = (u32)KSEG1ADDR(&rx_ring[i+1]); + rx_desc->nextRxDescPtr = (u32)CKSEG1ADDR(&rx_ring[i+1]); } - rx_desc->RxDataPtr = (u32)KSEG1ADDR(NetRxPackets[i]); + rx_desc->RxDataPtr = (u32)CKSEG1ADDR(NetRxPackets[i]); } #if 0 @@ -268,7 +268,7 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis) #endif for (i = 0; i < NUM_TX_DESC; i++) { - inca_tx_descriptor_t * tx_desc = KSEG1ADDR(&tx_ring[i]); + inca_tx_descriptor_t * tx_desc = (inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[i]); memset(tx_desc, 0, sizeof(tx_ring[i])); @@ -282,11 +282,11 @@ static int inca_switch_init(struct eth_device *dev, bd_t * bis) /* Let the last descriptor point to the * first one. */ - tx_desc->nextTxDescPtr = KSEG1ADDR((u32)tx_ring); + tx_desc->nextTxDescPtr = (u32)CKSEG1ADDR(tx_ring); } else { /* Set the address of the next descriptor. */ - tx_desc->nextTxDescPtr = (u32)KSEG1ADDR(&tx_ring[i+1]); + tx_desc->nextTxDescPtr = (u32)CKSEG1ADDR(&tx_ring[i+1]); } } @@ -346,7 +346,7 @@ static int inca_switch_send(struct eth_device *dev, volatile void *packet, int l int res = -1; u32 command; u32 regValue; - inca_tx_descriptor_t * tx_desc = KSEG1ADDR(&tx_ring[tx_new]); + inca_tx_descriptor_t * tx_desc = (inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_new]); #if 0 printf("Entered inca_switch_send()\n"); @@ -365,7 +365,7 @@ static int inca_switch_send(struct eth_device *dev, volatile void *packet, int l } if (tx_old_hold >= 0) { - KSEG1ADDR(&tx_ring[tx_old_hold])->params.field.HOLD = 1; + ((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_old_hold]))->params.field.HOLD = 1; } tx_old_hold = tx_hold; @@ -376,7 +376,7 @@ static int inca_switch_send(struct eth_device *dev, volatile void *packet, int l tx_desc->TxDataPtr = (u32)packet; tx_desc->params.field.NBA = length; - KSEG1ADDR(&tx_ring[tx_hold])->params.field.HOLD = 0; + ((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_hold]))->params.field.HOLD = 0; tx_hold = tx_new; tx_new = (tx_new + 1) % NUM_TX_DESC; @@ -397,7 +397,7 @@ static int inca_switch_send(struct eth_device *dev, volatile void *packet, int l DMA_WRITE_REG(INCA_IP_DMA_DMA_TXCCR0, regValue); #if 1 - for(i = 0; KSEG1ADDR(&tx_ring[tx_hold])->C == 0; i++) { + for(i = 0; ((inca_tx_descriptor_t *)CKSEG1ADDR(&tx_ring[tx_hold]))->C == 0; i++) { if (i >= TOUT_LOOP) { printf("%s: tx buffer not ready\n", dev->name); goto Done; @@ -423,7 +423,7 @@ static int inca_switch_recv(struct eth_device *dev) #endif for (;;) { - rx_desc = KSEG1ADDR(&rx_ring[rx_new]); + rx_desc = (inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[rx_new]); if (rx_desc->status.field.C == 0) { break; @@ -456,7 +456,7 @@ static int inca_switch_recv(struct eth_device *dev) #if 0 printf("Received %d bytes\n", length); #endif - NetReceive((void*)KSEG1ADDR(NetRxPackets[rx_new]), length - 4); + NetReceive((void*)CKSEG1ADDR(NetRxPackets[rx_new]), length - 4); } else { #if 1 printf("Zero length!!!\n"); @@ -464,7 +464,7 @@ static int inca_switch_recv(struct eth_device *dev) } - KSEG1ADDR(&rx_ring[rx_hold])->params.field.HOLD = 0; + ((inca_rx_descriptor_t *)CKSEG1ADDR(&rx_ring[rx_hold]))->params.field.HOLD = 0; rx_hold = rx_new; -- cgit v1.1 From 0e38c938ed4bcadb4f4fc1419a541431e94fc202 Mon Sep 17 00:00:00 2001 From: Remy Bohmer Date: Thu, 5 Jun 2008 13:03:36 +0200 Subject: DM9000 fix status check fail 0x6d error for trizeps board According to the Application Notes of the DM9000, only the 2 bits 0:1 of the status byte need to be checked to identify a valid packet in the fifo But, The several different Application Notes do not all speak the same language on these bits. They do not disagree, but only 1 Application Note noted explicitly that only these 2 bits need to be checked. Even the datasheets do not mention anything about these 2 bits. Because the old code, and the kernel check the whole byte, I left this piece untouched. However, I tested all board/DM9000[A|E|EP] devices with this 2 bit check, so it should work. Notice, that the 2nd iteration through this receive loop (when a 2nd packet is in the fifo) is much shorter now, compared to the older U-boot driver code, so that we can maybe run into a hardware condition now that was never seen before, or maybe was seen very unfrequently. Additionaly added a cleanup of a stack variable. Signed-off-by: Remy Bohmer Signed-off-by: Ben Warren --- drivers/net/dm9000x.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index 6f3ddf0..c2144d9 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -113,7 +113,7 @@ typedef struct board_info { u8 device_wait_reset; /* device state */ u8 nic_type; /* NIC type */ unsigned char srom[128]; - void (*outblk)(void *data_ptr, int count); + void (*outblk)(volatile void *data_ptr, int count); void (*inblk)(void *data_ptr, int count); void (*rx_status)(u16 *RxStatus, u16 *RxLen); } board_info_t; @@ -161,14 +161,14 @@ dump_regs(void) } #endif -static void dm9000_outblk_8bit(void *data_ptr, int count) +static void dm9000_outblk_8bit(volatile void *data_ptr, int count) { int i; for (i = 0; i < count; i++) DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA); } -static void dm9000_outblk_16bit(void *data_ptr, int count) +static void dm9000_outblk_16bit(volatile void *data_ptr, int count) { int i; u32 tmplen = (count + 1) / 2; @@ -176,7 +176,7 @@ static void dm9000_outblk_16bit(void *data_ptr, int count) for (i = 0; i < tmplen; i++) DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA); } -static void dm9000_outblk_32bit(void *data_ptr, int count) +static void dm9000_outblk_32bit(volatile void *data_ptr, int count) { int i; u32 tmplen = (count + 3) / 4; @@ -551,7 +551,6 @@ eth_init(bd_t * bd) int eth_send(volatile void *packet, int length) { - char *data_ptr; int tmo; struct board_info *db = &dm9000_info; @@ -560,11 +559,10 @@ eth_send(volatile void *packet, int length) DM9000_iow(DM9000_ISR, IMR_PTM); /* Clear Tx bit in ISR */ /* Move data to DM9000 TX RAM */ - data_ptr = (char *) packet; DM9000_outb(DM9000_MWCMD, DM9000_IO); /* Prepare for TX-data */ /* push the data to the TX-fifo */ - (db->outblk)(data_ptr, length); + (db->outblk)(packet, length); /* Set TX length to DM9000 */ DM9000_iow(DM9000_TXPLL, length & 0xff); @@ -625,8 +623,9 @@ eth_rx(void) for (;;) { DM9000_ior(DM9000_MRCMDX); /* Dummy read */ - /* Get most updated data */ - rxbyte = DM9000_inb(DM9000_DATA); + /* Get most updated data, + only look at bits 0:1, See application notes DM9000 */ + rxbyte = DM9000_inb(DM9000_DATA) & 0x03; /* Status check: this byte must be 0 or 1 */ if (rxbyte > DM9000_PKT_RDY) { -- cgit v1.1 From 3b904ccb93c3196727e2e9870cb1df903cab19ad Mon Sep 17 00:00:00 2001 From: Shinya Kuribayashi Date: Mon, 9 Jun 2008 23:37:44 +0900 Subject: net: Conditional COBJS inclusion of network drivers Replace COBJS-y with appropriate driver config names. Signed-off-by: Shinya Kuribayashi Signed-off-by: Ben Warren --- drivers/net/3c589.c | 5 ---- drivers/net/Makefile | 66 +++++++++++++++++++++++----------------------- drivers/net/bcm570x.c | 5 ---- drivers/net/cs8900.c | 8 ------ drivers/net/dc2114x.c | 6 ----- drivers/net/dm9000x.c | 3 --- drivers/net/e1000.c | 5 ---- drivers/net/eepro100.c | 5 ---- drivers/net/enc28j60.c | 3 --- drivers/net/fsl_mcdmafec.c | 5 ---- drivers/net/inca-ip_sw.c | 5 ---- drivers/net/ks8695eth.c | 4 --- drivers/net/lan91c96.c | 9 ------- drivers/net/macb.c | 5 ---- drivers/net/mcffec.c | 7 ----- drivers/net/natsemi.c | 5 ---- drivers/net/netarm_eth.c | 8 ------ drivers/net/netconsole.c | 5 ---- drivers/net/ns7520_eth.c | 5 ---- drivers/net/ns8382x.c | 5 ---- drivers/net/ns9750_eth.c | 4 --- drivers/net/pcnet.c | 4 --- drivers/net/plb2800_eth.c | 6 ----- drivers/net/rtl8019.c | 8 ------ drivers/net/rtl8139.c | 4 --- drivers/net/rtl8169.c | 5 ---- drivers/net/s3c4510b_eth.c | 5 ---- drivers/net/smc91111.c | 3 --- drivers/net/smc911x.c | 5 ---- drivers/net/tigon3.c | 5 +--- drivers/net/tsec.c | 3 --- drivers/net/tsi108_eth.c | 5 ---- drivers/net/uli526x.c | 4 --- drivers/net/vsc7385.c | 5 ---- 34 files changed, 34 insertions(+), 201 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/3c589.c b/drivers/net/3c589.c index 3f1e770..0cf8dff 100644 --- a/drivers/net/3c589.c +++ b/drivers/net/3c589.c @@ -26,8 +26,6 @@ #include #include -#ifdef CONFIG_DRIVER_3C589 - #include "3c589.h" @@ -514,6 +512,3 @@ int eth_send(volatile void *packet, int length) { return length; } - - -#endif /* CONFIG_DRIVER_3C589 */ diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 5b031c9..84be288 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -25,45 +25,45 @@ include $(TOPDIR)/config.mk LIB := $(obj)libnet.a -COBJS-y += 3c589.o -COBJS-y += bcm570x.o bcm570x_autoneg.o 5701rls.o +COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o +COBJS-$(CONFIG_BCM570x) += bcm570x.o bcm570x_autoneg.o 5701rls.o COBJS-$(CONFIG_BFIN_MAC) += bfin_mac.o -COBJS-y += cs8900.o -COBJS-y += dc2114x.o -COBJS-y += dm9000x.o -COBJS-y += e1000.o -COBJS-y += eepro100.o -COBJS-y += enc28j60.o -COBJS-y += fsl_mcdmafec.o +COBJS-$(CONFIG_DRIVER_CS8900) += cs8900.o +COBJS-$(CONFIG_TULIP) += dc2114x.o +COBJS-$(CONFIG_DRIVER_DM9000) += dm9000x.o +COBJS-$(CONFIG_E1000) += e1000.o +COBJS-$(CONFIG_EEPRO100) += eepro100.o +COBJS-$(CONFIG_ENC28J60) += enc28j60.o +COBJS-$(CONFIG_FSLDMAFEC) += fsl_mcdmafec.o COBJS-$(CONFIG_GRETH) += greth.o -COBJS-y += inca-ip_sw.o -COBJS-y += ks8695eth.o -COBJS-y += lan91c96.o -COBJS-y += macb.o -COBJS-y += mcffec.o -COBJS-y += natsemi.o +COBJS-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o +COBJS-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o +COBJS-$(CONFIG_DRIVER_LAN91C96) += lan91c96.o +COBJS-$(CONFIG_MACB) += macb.o +COBJS-$(CONFIG_MCFFEC) += mcffec.o +COBJS-$(CONFIG_NATSEMI) += natsemi.o ifeq ($(CONFIG_DRIVER_NE2000),y) COBJS-y += ne2000.o COBJS-$(CONFIG_DRIVER_AX88796L) += ax88796.o endif -COBJS-y += netarm_eth.o -COBJS-y += netconsole.o -COBJS-y += ns7520_eth.o -COBJS-y += ns8382x.o -COBJS-y += ns9750_eth.o -COBJS-y += pcnet.o -COBJS-y += plb2800_eth.o -COBJS-y += rtl8019.o -COBJS-y += rtl8139.o -COBJS-y += rtl8169.o -COBJS-y += s3c4510b_eth.o -COBJS-y += smc91111.o -COBJS-y += smc911x.o -COBJS-y += tigon3.o -COBJS-y += tsec.o -COBJS-y += tsi108_eth.o -COBJS-y += uli526x.o -COBJS-y += vsc7385.o +COBJS-$(CONFIG_DRIVER_NETARMETH) += netarm_eth.o +COBJS-$(CONFIG_NETCONSOLE) += netconsole.o +COBJS-$(CONFIG_DRIVER_NS7520_ETHERNET) += ns7520_eth.o +COBJS-$(CONFIG_NS8382X) += ns8382x.o +COBJS-$(CONFIG_DRIVER_NS9750_ETHERNET) += ns9750_eth.o +COBJS-$(CONFIG_PCNET) += pcnet.o +COBJS-$(CONFIG_PLB2800_ETHER) += plb2800_eth.o +COBJS-$(CONFIG_DRIVER_RTL8019) += rtl8019.o +COBJS-$(CONFIG_RTL8139) += rtl8139.o +COBJS-$(CONFIG_RTL8169) += rtl8169.o +COBJS-$(CONFIG_DRIVER_S3C4510_ETH) += s3c4510b_eth.o +COBJS-$(CONFIG_DRIVER_SMC91111) += smc91111.o +COBJS-$(CONFIG_DRIVER_SMC911X) += smc911x.o +COBJS-$(CONFIG_TIGON3) += tigon3.o bcm570x_autoneg.o 5701rls.o +COBJS-$(CONFIG_TSEC_ENET) += tsec.o +COBJS-$(CONFIG_TSI108_ETH) += tsi108_eth.o +COBJS-$(CONFIG_ULI526X) += uli526x.o +COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o diff --git a/drivers/net/bcm570x.c b/drivers/net/bcm570x.c index 5ad31d1..6b28b95 100644 --- a/drivers/net/bcm570x.c +++ b/drivers/net/bcm570x.c @@ -6,9 +6,6 @@ #include -#if defined(CONFIG_CMD_NET) \ - && (!defined(CONFIG_NET_MULTI)) && defined(CONFIG_BCM570x) - #ifdef CONFIG_BMW #include #endif @@ -1599,5 +1596,3 @@ PQQ_ENTRY QQ_GetTail (PQQ_CONTAINER pQueue, unsigned int Idx) return pQueue->Array[Idx]; } - -#endif diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c index 458b517..ae1983a 100644 --- a/drivers/net/cs8900.c +++ b/drivers/net/cs8900.c @@ -41,10 +41,6 @@ #include "cs8900.h" #include -#ifdef CONFIG_DRIVER_CS8900 - -#if defined(CONFIG_CMD_NET) - #undef DEBUG /* packet page register access functions */ @@ -315,7 +311,3 @@ int cs8900_e2prom_write(unsigned char addr, unsigned short value) return 0; } - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_CS8900 */ diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c index 1d728d8..8117239 100644 --- a/drivers/net/dc2114x.c +++ b/drivers/net/dc2114x.c @@ -19,10 +19,6 @@ */ #include - -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_TULIP) - #include #include #include @@ -766,5 +762,3 @@ static void update_srom(struct eth_device *dev, bd_t *bis) } } #endif /* UPDATE_SROM */ - -#endif diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index fa95a73..844fb76 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -64,8 +64,6 @@ TODO: Homerun NIC and longrun NIC are not functional, only internal at the #include #include -#ifdef CONFIG_DRIVER_DM9000 - #include "dm9000x.h" /* Board/System/Debug information/definition ---------------- */ @@ -760,4 +758,3 @@ phy_write(int reg, u16 value) DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer write command */ DM9000_DBG("phy_write(reg:0x%x, value:0x%x)\n", reg, value); } -#endif /* CONFIG_DRIVER_DM9000 */ diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 40a781f..c31029a 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -44,9 +44,6 @@ tested on both gig copper and gig fiber boards #include "e1000.h" -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_E1000) - #define TOUT_LOOP 100000 #undef virt_to_bus @@ -3061,5 +3058,3 @@ e1000_initialize(bd_t * bis) } return 1; } - -#endif diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index 96ed271..9de0fb5 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -30,9 +30,6 @@ #undef DEBUG -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_EEPRO100) - /* Ethernet chip registers. */ #define SCBStatus 0 /* Rx/Command Unit Status *Word* */ @@ -944,5 +941,3 @@ static void read_hw_addr (struct eth_device *dev, bd_t * bis) #endif } } - -#endif diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c index 98303ac..5c24b0d 100644 --- a/drivers/net/enc28j60.c +++ b/drivers/net/enc28j60.c @@ -17,7 +17,6 @@ #include #include -#ifdef CONFIG_ENC28J60 #include #include #include @@ -979,5 +978,3 @@ static void phyWrite(unsigned char addr, unsigned short data) } } } - -#endif /* CONFIG_ENC28J60 */ diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c index 2ef91f2..f2bdba6 100644 --- a/drivers/net/fsl_mcdmafec.c +++ b/drivers/net/fsl_mcdmafec.c @@ -31,7 +31,6 @@ #include #include -#ifdef CONFIG_FSLDMAFEC #undef ET_DEBUG #undef MII_DEBUG @@ -49,7 +48,6 @@ #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) -#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) #include #include @@ -586,6 +584,3 @@ int mcdmafec_initialize(bd_t * bis) return 1; } - -#endif /* CONFIG_CMD_NET && CONFIG_NET_MULTI */ -#endif /* CONFIG_FSLDMAFEC */ diff --git a/drivers/net/inca-ip_sw.c b/drivers/net/inca-ip_sw.c index e4aaed6..ffdd1f3 100644 --- a/drivers/net/inca-ip_sw.c +++ b/drivers/net/inca-ip_sw.c @@ -26,9 +26,6 @@ #include -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_INCA_IP_SWITCH) - #include #include #include @@ -813,5 +810,3 @@ Fail: return -1; } #endif /* CONFIG_INCA_IP_SWITCH_AMDIX */ - -#endif diff --git a/drivers/net/ks8695eth.c b/drivers/net/ks8695eth.c index b598dd7..7f3e0c2 100644 --- a/drivers/net/ks8695eth.c +++ b/drivers/net/ks8695eth.c @@ -21,8 +21,6 @@ /****************************************************************************/ #include - -#ifdef CONFIG_DRIVER_KS8695ETH #include #include #include @@ -234,5 +232,3 @@ int eth_send(volatile void *packet, int len) return len; } - -#endif /* CONFIG_DRIVER_KS8695ETH */ diff --git a/drivers/net/lan91c96.c b/drivers/net/lan91c96.c index 51cfb7e..c23a400 100644 --- a/drivers/net/lan91c96.c +++ b/drivers/net/lan91c96.c @@ -63,10 +63,6 @@ #include "lan91c96.h" #include -#ifdef CONFIG_DRIVER_LAN91C96 - -#if defined(CONFIG_CMD_NET) - /*------------------------------------------------------------------------ * * Configuration options, for the experienced user to change. @@ -865,9 +861,6 @@ static int smc_hw_init () } #endif /* 0 */ -#endif /* CONFIG_CMD_NET */ - - /* smc_get_ethaddr (bd_t * bd) * * This checks both the environment and the ROM for an ethernet address. If @@ -963,5 +956,3 @@ int get_rom_mac (unsigned char *v_rom_mac) return (1); #endif } - -#endif /* CONFIG_DRIVER_LAN91C96 */ diff --git a/drivers/net/macb.c b/drivers/net/macb.c index e5733f6..aa39284 100644 --- a/drivers/net/macb.c +++ b/drivers/net/macb.c @@ -17,9 +17,6 @@ */ #include -#if defined(CONFIG_MACB) \ - && (defined(CONFIG_CMD_NET) || defined(CONFIG_CMD_MII)) - /* * The u-boot networking stack is a little weird. It seems like the * networking core allocates receive buffers up front without any @@ -593,5 +590,3 @@ int miiphy_write(unsigned char addr, unsigned char reg, unsigned short value) } #endif - -#endif /* CONFIG_MACB */ diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c index 8d4e248..58ed5e3 100644 --- a/drivers/net/mcffec.c +++ b/drivers/net/mcffec.c @@ -27,8 +27,6 @@ #include #include -#ifdef CONFIG_MCFFEC - #include #include @@ -51,8 +49,6 @@ DECLARE_GLOBAL_DATA_PTR; -#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) - struct fec_info_s fec_info[] = { #ifdef CFG_FEC0_IOBASE { @@ -605,6 +601,3 @@ int mcffec_initialize(bd_t * bis) return 1; } - -#endif /* CONFIG_CMD_NET, FEC_ENET & NET_MULTI */ -#endif /* CONFIG_MCFFEC */ diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index a523959..4aee048 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -56,9 +56,6 @@ #include #include -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_NATSEMI) - /* defines */ #define EEPROM_SIZE 0xb /*12 16-bit chunks, or 24 bytes*/ @@ -878,5 +875,3 @@ natsemi_disable(struct eth_device *dev) /* Restore PME enable bit */ OUTL(dev, SavedClkRun, ClkRun); } - -#endif diff --git a/drivers/net/netarm_eth.c b/drivers/net/netarm_eth.c index ecf45dc..c011809 100644 --- a/drivers/net/netarm_eth.c +++ b/drivers/net/netarm_eth.c @@ -22,15 +22,11 @@ #include - -#ifdef CONFIG_DRIVER_NETARMETH #include #include #include "netarm_eth.h" #include -#if defined(CONFIG_CMD_NET) - static int na_mii_poll_busy (void); static void na_get_mac_addr (void) @@ -352,7 +348,3 @@ extern int eth_send (volatile void *packet, int length) printf ("eth_send timeout\n"); return 1; } - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_NETARMETH */ diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 69089f9..b2ee5ea 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -22,9 +22,6 @@ */ #include - -#ifdef CONFIG_NETCONSOLE - #include #include #include @@ -263,5 +260,3 @@ int drv_nc_init (void) return (rc == 0) ? 1 : rc; } - -#endif /* CONFIG_NETCONSOLE */ diff --git a/drivers/net/ns7520_eth.c b/drivers/net/ns7520_eth.c index a5a20df..37411df 100644 --- a/drivers/net/ns7520_eth.c +++ b/drivers/net/ns7520_eth.c @@ -15,8 +15,6 @@ #include -#if defined(CONFIG_DRIVER_NS7520_ETHERNET) - #include /* NetSendPacket */ #include #include @@ -846,14 +844,11 @@ extern int ns7520_miiphy_write(char *devname, unsigned char const addr, return (ret); } #endif /* defined(CONFIG_MII) */ -#endif /* CONFIG_DRIVER_NS7520_ETHERNET */ int ns7520_miiphy_initialize(bd_t *bis) { -#if defined(CONFIG_DRIVER_NS7520_ETHERNET) #if defined(CONFIG_MII) miiphy_register("ns7520phy", ns7520_miiphy_read, ns7520_miiphy_write); #endif -#endif return 0; } diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c index c807dd4..0b9a3ae 100644 --- a/drivers/net/ns8382x.c +++ b/drivers/net/ns8382x.c @@ -56,9 +56,6 @@ #include #include -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_NS8382X) - /* defines */ #define DSIZE 0x00000FFF #define ETH_ALEN 6 @@ -859,5 +856,3 @@ ns8382x_disable(struct eth_device *dev) /* Restore PME enable bit */ OUTL(dev, SavedClkRun, ClkRun); } - -#endif diff --git a/drivers/net/ns9750_eth.c b/drivers/net/ns9750_eth.c index 067ff8e..0559710 100644 --- a/drivers/net/ns9750_eth.c +++ b/drivers/net/ns9750_eth.c @@ -37,8 +37,6 @@ #include "ns9750_eth.h" /* for Ethernet and PHY */ -#ifdef CONFIG_DRIVER_NS9750_ETHERNET - /* some definition to make transistion to linux easier */ #define NS9750_DRIVER_NAME "eth" @@ -793,5 +791,3 @@ static unsigned int ns9750_mii_poll_busy (void) return unTimeout; } - -#endif /* CONFIG_DRIVER_NS9750_ETHERNET */ diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index aa04e8f..a4f0214 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -45,9 +45,6 @@ #define PCNET_DEBUG2(fmt,args...) #endif -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_PCNET) - #if !defined(CONF_PCNET_79C973) && defined(CONF_PCNET_79C975) #error "Macro for PCnet chip version is not defined!" #endif @@ -537,4 +534,3 @@ static void pcnet_halt (struct eth_device *dev) printf ("%s: TIMEOUT: controller reset failed\n", dev->name); } } -#endif diff --git a/drivers/net/plb2800_eth.c b/drivers/net/plb2800_eth.c index b8cc57a..dad842c 100644 --- a/drivers/net/plb2800_eth.c +++ b/drivers/net/plb2800_eth.c @@ -24,10 +24,6 @@ */ #include - -#if defined(CONFIG_CMD_NET) \ - && defined(CONFIG_NET_MULTI) && defined(CONFIG_PLB2800_ETHER) - #include #include #include @@ -392,5 +388,3 @@ static unsigned char * plb2800_get_mac_addr(void) return addr; } - -#endif /* CONFIG_PLB2800_ETHER */ diff --git a/drivers/net/rtl8019.c b/drivers/net/rtl8019.c index 9d62cab..3ddf917 100644 --- a/drivers/net/rtl8019.c +++ b/drivers/net/rtl8019.c @@ -32,10 +32,6 @@ #include "rtl8019.h" #include -#ifdef CONFIG_DRIVER_RTL8019 - -#if defined(CONFIG_CMD_NET) - /* packet page register access functions */ static unsigned char get_reg (unsigned int regno) @@ -271,7 +267,3 @@ extern int eth_send (volatile void *packet, int length) return 0; } - -#endif /* CONFIG_CMD_NET */ - -#endif /* CONFIG_DRIVER_RTL8019 */ diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 097f684..4fd20ac 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -77,9 +77,6 @@ #include #include -#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ - defined(CONFIG_RTL8139) - #define RTL_TIMEOUT 100000 #define ETH_FRAME_LEN 1514 @@ -545,4 +542,3 @@ static void rtl_disable(struct eth_device *dev) udelay (100); /* wait 100us */ } } -#endif diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 6c4c9ff..7423bc0 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -58,9 +58,6 @@ #include #include -#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ - defined(CONFIG_RTL8169) - #undef DEBUG_RTL8169 #undef DEBUG_RTL8169_TX #undef DEBUG_RTL8169_RX @@ -887,5 +884,3 @@ int rtl8169_initialize(bd_t *bis) } return card_number; } - -#endif diff --git a/drivers/net/s3c4510b_eth.c b/drivers/net/s3c4510b_eth.c index 3d9066a..6dcb244 100644 --- a/drivers/net/s3c4510b_eth.c +++ b/drivers/net/s3c4510b_eth.c @@ -25,9 +25,6 @@ */ #include - -#ifdef CONFIG_DRIVER_S3C4510_ETH - #include #include #include @@ -242,5 +239,3 @@ void eth_halt(void) /* disable MAC */ PUT_REG( REG_MACCON, ETH_HaltReg); } - -#endif diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c index 8061f12..e8b235b 100644 --- a/drivers/net/smc91111.c +++ b/drivers/net/smc91111.c @@ -65,8 +65,6 @@ #include "smc91111.h" #include -#ifdef CONFIG_DRIVER_SMC91111 - /* Use power-down feature of the chip */ #define POWER_DOWN 0 @@ -1620,4 +1618,3 @@ int get_rom_mac (uchar *v_rom_mac) return (valid_mac ? 1 : 0); #endif } -#endif /* CONFIG_DRIVER_SMC91111 */ diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 6d93bf0..7555cb9 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -23,9 +23,6 @@ */ #include - -#ifdef CONFIG_DRIVER_SMC911X - #include #include #include @@ -699,5 +696,3 @@ int eth_rx(void) return 0; } - -#endif /* CONFIG_DRIVER_SMC911X */ diff --git a/drivers/net/tigon3.c b/drivers/net/tigon3.c index 5f6a4ec..ab448b0 100644 --- a/drivers/net/tigon3.c +++ b/drivers/net/tigon3.c @@ -12,8 +12,7 @@ /******************************************************************************/ #include #include -#if defined(CONFIG_CMD_NET) && !defined(CONFIG_NET_MULTI) && \ - defined(CONFIG_TIGON3) + #ifdef CONFIG_BMW #include #endif @@ -5695,5 +5694,3 @@ LM_DmaTest (PLM_DEVICE_BLOCK pDevice, PLM_UINT8 pBufferVirt, } return LM_STATUS_SUCCESS; } - -#endif diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index 397ae71..6e0f2c6 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -17,7 +17,6 @@ #include #include -#if defined(CONFIG_TSEC_ENET) #include "tsec.h" #include "miiphy.h" @@ -1741,5 +1740,3 @@ tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) return 0; } #endif /* Multicast TFTP ? */ - -#endif /* CONFIG_TSEC_ENET */ diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c index a09115e..57c0dc3 100644 --- a/drivers/net/tsi108_eth.c +++ b/drivers/net/tsi108_eth.c @@ -27,9 +27,6 @@ #include -#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) \ - && defined(CONFIG_TSI108_ETH) - #if !defined(CONFIG_TSI108_ETH_NUM_PORTS) || (CONFIG_TSI108_ETH_NUM_PORTS > 2) #error "CONFIG_TSI108_ETH_NUM_PORTS must be defined as 1 or 2" #endif @@ -1032,5 +1029,3 @@ static void tsi108_eth_halt (struct eth_device *dev) /* Put MAC into reset state. */ reg_MAC_CONFIG_1(base) = MAC_CONFIG_1_SOFT_RESET; } - -#endif diff --git a/drivers/net/uli526x.c b/drivers/net/uli526x.c index 79d29ae..7145b72 100644 --- a/drivers/net/uli526x.c +++ b/drivers/net/uli526x.c @@ -22,9 +22,6 @@ /* some kernel function compatible define */ -#if defined(CONFIG_CMD_NET) && defined(CONFIG_NET_MULTI) && \ - defined(CONFIG_ULI526X) - #undef DEBUG /* Board/System/Debug information/definition */ @@ -993,4 +990,3 @@ static void set_mac_addr(struct eth_device *dev) udelay(10); return; } -#endif diff --git a/drivers/net/vsc7385.c b/drivers/net/vsc7385.c index 4095bce..4e7259f 100644 --- a/drivers/net/vsc7385.c +++ b/drivers/net/vsc7385.c @@ -13,9 +13,6 @@ */ #include - -#ifdef CONFIG_VSC7385_ENET - #include #include #include @@ -97,5 +94,3 @@ int vsc7385_upload_firmware(void *firmware, unsigned int size) return 0; } - -#endif -- cgit v1.1 From dd7e5fa5f847188f78f62f2c52de6cb3def3ecdb Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 17 Jun 2008 13:07:15 +0900 Subject: net: ne2000: Fix compile error of NE2000 If enable DEBUG, can not compile ne2000 driver. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Ben Warren --- drivers/net/ne2000.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ne2000.c b/drivers/net/ne2000.c index 2da57b6..eab3dd5 100644 --- a/drivers/net/ne2000.c +++ b/drivers/net/ne2000.c @@ -769,14 +769,14 @@ static void pcnet_reset_8390(void) { int i, r; - PRINTK("nic base is %lx\n", nic_base); + PRINTK("nic base is %lx\n", nic.base); n2k_outb(E8390_NODMA + E8390_PAGE0+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", nic_base + E8390_CMD, n2k_inb(E8390_CMD)); + PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD)); n2k_outb(E8390_NODMA+E8390_PAGE1+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", nic_base + E8390_CMD, n2k_inb(E8390_CMD)); + PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD)); n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); - PRINTK("cmd (at %lx) is %x\n", nic_base + E8390_CMD, n2k_inb(E8390_CMD)); + PRINTK("cmd (at %lx) is %x\n", nic.base + E8390_CMD, n2k_inb(E8390_CMD)); n2k_outb(E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD); n2k_outb(n2k_inb(PCNET_RESET), PCNET_RESET); @@ -852,8 +852,6 @@ int __get_prom(u8* mac_addr) return 0; } -u32 nic_base; - /* U-boot specific routines */ static u8 *pbuf = NULL; @@ -901,7 +899,6 @@ int eth_init(bd_t *bd) { } #endif - nic_base = CONFIG_DRIVER_NE2000_BASE; nic.base = (u8 *) CONFIG_DRIVER_NE2000_BASE; r = get_prom(dev_addr); -- cgit v1.1 From cbb6289569ae4fc6e2d676528e46ffcc72d743d0 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Tue, 17 Jun 2008 13:07:11 +0900 Subject: net: ne2000: Move dev_addr variable from grobal to local. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Ben Warren --- drivers/net/ne2000.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ne2000.c b/drivers/net/ne2000.c index eab3dd5..ec92485 100644 --- a/drivers/net/ne2000.c +++ b/drivers/net/ne2000.c @@ -758,8 +758,6 @@ static hw_info_t hw_info[] = { #define NR_INFO (sizeof(hw_info)/sizeof(hw_info_t)) -u8 dev_addr[6]; - #define PCNET_CMD 0x00 #define PCNET_DATAPORT 0x10 /* NatSemi-defined port window offset. */ #define PCNET_RESET 0x1f /* Issue a read to reset, a write to clear. */ @@ -877,6 +875,7 @@ void uboot_push_tx_done(int key, int val) { int eth_init(bd_t *bd) { int r; + u8 dev_addr[6]; char ethaddr[20]; PRINTK("### eth_init\n"); -- cgit v1.1 From 5cacc5d0ec52678a5eb83ecda5c3bcb22eb47f30 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Mon, 30 Jun 2008 17:45:01 +0900 Subject: net: fix compile problem in smc911x driver. Signed-off-by: Nobuhiro Iwamatsu Acked-by: Ben Warren --- drivers/net/smc911x.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index 7555cb9..a2d3cb2 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -33,7 +33,7 @@ CONFIG_DRIVER_SMC911X_16_BIT shall be set" #endif -#ifdef CONFIG_DRIVER_SMC911X_32_BIT +#if defined (CONFIG_DRIVER_SMC911X_32_BIT) static inline u32 reg_read(u32 addr) { return *(volatile u32*)addr; @@ -42,7 +42,7 @@ static inline void reg_write(u32 addr, u32 val) { *(volatile u32*)addr = val; } -#elif CONFIG_DRIVER_SMC911X_16_BIT +#elif defined (CONFIG_DRIVER_SMC911X_16_BIT) static inline u32 reg_read(u32 addr) { volatile u16 *addr_16 = (u16 *)addr; -- cgit v1.1 From 9047bfa1e737d787be460387dd6f45737eeceb10 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 3 Jul 2008 23:16:06 +0900 Subject: net: smc911x: Fix typo Signed-off-by: Nobuhiro Iwamatsu --- drivers/net/smc911x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c index a2d3cb2..1484b0b 100644 --- a/drivers/net/smc911x.c +++ b/drivers/net/smc911x.c @@ -597,7 +597,7 @@ int eth_init(bd_t *bd) val = reg_read(BYTE_TEST); if (val != 0x87654321) { - printf(DRIVERNAME ": Invalid chip endian 0x08%x\n", val); + printf(DRIVERNAME ": Invalid chip endian 0x%08x\n", val); goto err_out; } -- cgit v1.1 From 9751ee0990f467941da0b095a4e995f863672d7a Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Wed, 11 Jun 2008 21:05:00 +0900 Subject: net: sh: Renesas SH7763 Ethernet device support Renesas SH7763 has 2 channel Ethernet device. This is 10/100/1000 Base support. But this patch check 10/100 Base only. Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Ben Warren --- drivers/net/Makefile | 1 + drivers/net/sh_eth.c | 603 +++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/sh_eth.h | 446 +++++++++++++++++++++++++++++++++++++ 3 files changed, 1050 insertions(+) create mode 100644 drivers/net/sh_eth.c create mode 100644 drivers/net/sh_eth.h (limited to 'drivers/net') diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 84be288..bcf31cb 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -66,6 +66,7 @@ COBJS-$(CONFIG_ULI526X) += uli526x.o COBJS-$(CONFIG_VSC7385_ENET) += vsc7385.o COBJS-$(CONFIG_XILINX_EMAC) += xilinx_emac.o COBJS-$(CONFIG_XILINX_EMACLITE) += xilinx_emaclite.o +COBJS-$(CONFIG_SH_ETHER) += sh_eth.o COBJS := $(COBJS-y) SRCS := $(COBJS:.o=.c) diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c new file mode 100644 index 0000000..9e3cf98 --- /dev/null +++ b/drivers/net/sh_eth.c @@ -0,0 +1,603 @@ +/* + * sh_eth.c - Driver for Renesas SH7763's ethernet controler. + * + * Copyright (C) 2008 Renesas Solutions Corp. + * Copyright (c) 2008 Nobuhiro Iwamatsu + * Copyright (c) 2007 Carlos Munoz + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "sh_eth.h" + +#ifndef CONFIG_SH_ETHER_USE_PORT +# error "Please define CONFIG_SH_ETHER_USE_PORT" +#endif +#ifndef CONFIG_SH_ETHER_PHY_ADDR +# error "Please define CONFIG_SH_ETHER_PHY_ADDR" +#endif + +extern int eth_init(bd_t *bd); +extern void eth_halt(void); +extern int eth_rx(void); +extern int eth_send(volatile void *packet, int length); + +static struct dev_info_s *dev; + +/* + * Bits are written to the PHY serially using the + * PIR register, just like a bit banger. + */ +static void sh_eth_mii_write_phy_bits(int port, u32 val, int len) +{ + int i; + u32 pir; + + /* Bit positions is 1 less than the number of bits */ + for (i = len - 1; i >= 0; i--) { + /* Write direction, bit to write, clock is low */ + pir = 2 | ((val & 1 << i) ? 1 << 2 : 0); + outl(pir, PIR(port)); + udelay(1); + /* Write direction, bit to write, clock is high */ + pir = 3 | ((val & 1 << i) ? 1 << 2 : 0); + outl(pir, PIR(port)); + udelay(1); + /* Write direction, bit to write, clock is low */ + pir = 2 | ((val & 1 << i) ? 1 << 2 : 0); + outl(pir, PIR(port)); + udelay(1); + } +} + +static void sh_eth_mii_bus_release(int port) +{ + /* Read direction, clock is low */ + outl(0, PIR(port)); + udelay(1); + /* Read direction, clock is high */ + outl(1, PIR(port)); + udelay(1); + /* Read direction, clock is low */ + outl(0, PIR(port)); + udelay(1); +} + +static void sh_eth_mii_ind_bus_release(int port) +{ + /* Read direction, clock is low */ + outl(0, PIR(port)); + udelay(1); +} + +static int sh_eth_mii_read_phy_bits(int port, u32 * val, int len) +{ + int i; + u32 pir; + + *val = 0; + for (i = len - 1; i >= 0; i--) { + /* Read direction, clock is high */ + outl(1, PIR(port)); + udelay(1); + /* Read bit */ + pir = inl(PIR(port)); + *val |= (pir & 8) ? 1 << i : 0; + /* Read direction, clock is low */ + outl(0, PIR(port)); + udelay(1); + } + + return 0; +} + +#define PHY_INIT 0xFFFFFFFF +#define PHY_READ 0x02 +#define PHY_WRITE 0x01 +/* + * To read a phy register, mii managements frames are sent to the phy. + * The frames look like this: + * pre (32 bits): 0xffff ffff + * st (2 bits): 01 + * op (2bits): 10: read 01: write + * phyad (5 bits): xxxxx + * regad (5 bits): xxxxx + * ta (Bus release): + * data (16 bits): read data + */ +static u32 sh_eth_mii_read_phy_reg(int port, u8 phy_addr, int reg) +{ + u32 val; + + /* Sent mii management frame */ + /* pre */ + sh_eth_mii_write_phy_bits(port, PHY_INIT, 32); + /* st (start of frame) */ + sh_eth_mii_write_phy_bits(port, 0x1, 2); + /* op (code) */ + sh_eth_mii_write_phy_bits(port, PHY_READ, 2); + /* phy address */ + sh_eth_mii_write_phy_bits(port, phy_addr, 5); + /* Register to read */ + sh_eth_mii_write_phy_bits(port, reg, 5); + + /* Bus release */ + sh_eth_mii_bus_release(port); + + /* Read register */ + sh_eth_mii_read_phy_bits(port, &val, 16); + + return val; +} + +/* + * To write a phy register, mii managements frames are sent to the phy. + * The frames look like this: + * pre (32 bits): 0xffff ffff + * st (2 bits): 01 + * op (2bits): 10: read 01: write + * phyad (5 bits): xxxxx + * regad (5 bits): xxxxx + * ta (2 bits): 10 + * data (16 bits): write data + * idle (Independent bus release) + */ +static void sh_eth_mii_write_phy_reg(int port, u8 phy_addr, int reg, u16 val) +{ + /* Sent mii management frame */ + /* pre */ + sh_eth_mii_write_phy_bits(port, PHY_INIT, 32); + /* st (start of frame) */ + sh_eth_mii_write_phy_bits(port, 0x1, 2); + /* op (code) */ + sh_eth_mii_write_phy_bits(port, PHY_WRITE, 2); + /* phy address */ + sh_eth_mii_write_phy_bits(port, phy_addr, 5); + /* Register to read */ + sh_eth_mii_write_phy_bits(port, reg, 5); + /* ta */ + sh_eth_mii_write_phy_bits(port, PHY_READ, 2); + /* Write register data */ + sh_eth_mii_write_phy_bits(port, val, 16); + + /* Independent bus release */ + sh_eth_mii_ind_bus_release(port); +} + +void eth_halt(void) +{ +} + +int eth_send(volatile void *packet, int len) +{ + int port = dev->port; + struct port_info_s *port_info = &dev->port_info[port]; + int timeout; + int rc = 0; + + if (!packet || len > 0xffff) { + printf("eth_send: Invalid argument\n"); + return -EINVAL; + } + + /* packet must be a 4 byte boundary */ + if ((int)packet & (4 - 1)) { + printf("eth_send: packet not 4 byte alligned\n"); + return -EFAULT; + } + + /* Update tx descriptor */ + port_info->tx_desc_cur->td2 = ADDR_TO_PHY(packet); + port_info->tx_desc_cur->td1 = len << 16; + /* Must preserve the end of descriptor list indication */ + if (port_info->tx_desc_cur->td0 & TD_TDLE) + port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP | TD_TDLE; + else + port_info->tx_desc_cur->td0 = TD_TACT | TD_TFP; + + /* Restart the transmitter if disabled */ + if (!(inl(EDTRR(port)) & EDTRR_TRNS)) + outl(EDTRR_TRNS, EDTRR(port)); + + /* Wait until packet is transmitted */ + timeout = 1000; + while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--) + udelay(100); + + if (timeout < 0) { + printf("eth_send: transmit timeout\n"); + rc = -1; + goto err; + } + +err: + port_info->tx_desc_cur++; + if (port_info->tx_desc_cur >= port_info->tx_desc_base + NUM_TX_DESC) + port_info->tx_desc_cur = port_info->tx_desc_base; + + return rc; +} + +int eth_rx(void) +{ + int port = dev->port; + struct port_info_s *port_info = &dev->port_info[port]; + int len = 0; + volatile u8 *packet; + + /* Check if the rx descriptor is ready */ + if (!(port_info->rx_desc_cur->rd0 & RD_RACT)) { + /* Check for errors */ + if (!(port_info->rx_desc_cur->rd0 & RD_RFE)) { + len = port_info->rx_desc_cur->rd1 & 0xffff; + packet = (volatile u8 *) + ADDR_TO_P2(port_info->rx_desc_cur->rd2); + NetReceive(packet, len); + } + + /* Make current descriptor available again */ + if (port_info->rx_desc_cur->rd0 & RD_RDLE) + port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE; + else + port_info->rx_desc_cur->rd0 = RD_RACT; + + /* Point to the next descriptor */ + port_info->rx_desc_cur++; + if (port_info->rx_desc_cur >= + port_info->rx_desc_base + NUM_RX_DESC) + port_info->rx_desc_cur = port_info->rx_desc_base; + } + + /* Restart the receiver if disabled */ + if (!(inl(EDRRR(port)) & EDRRR_R)) + outl(EDRRR_R, EDRRR(port)); + + return len; +} + +#define EDMR_INIT_CNT 1000 +static int sh_eth_reset(struct dev_info_s *dev) +{ + int port = dev->port; + int i; + + /* Start e-dmac transmitter and receiver */ + outl(EDSR_ENALL, EDSR(port)); + + /* Perform a software reset and wait for it to complete */ + outl(EDMR_SRST, EDMR(port)); + for (i = 0; i < EDMR_INIT_CNT; i++) { + if (!(inl(EDMR(port)) & EDMR_SRST)) + break; + udelay(1000); + } + + if (i == EDMR_INIT_CNT) { + printf("Error: Software reset timeout\n"); + return -1; + } + return 0; +} + +static int sh_eth_tx_desc_init(struct dev_info_s *dev) +{ + int port = dev->port; + struct port_info_s *port_info = &dev->port_info[port]; + u32 tmp_addr; + struct tx_desc_s *cur_tx_desc; + int i; + + /* Allocate tx descriptors. They must be TX_DESC_SIZE bytes + aligned */ + if (!(port_info->tx_desc_malloc = malloc(NUM_TX_DESC * + sizeof(struct tx_desc_s) + + TX_DESC_SIZE - 1))) { + printf("Error: malloc failed\n"); + return -ENOMEM; + } + tmp_addr = (u32) (((int)port_info->tx_desc_malloc + TX_DESC_SIZE - 1) & + ~(TX_DESC_SIZE - 1)); + /* Make sure we use a P2 address (non-cacheable) */ + port_info->tx_desc_base = (struct tx_desc_s *)ADDR_TO_P2(tmp_addr); + + port_info->tx_desc_cur = port_info->tx_desc_base; + + /* Initialize all descriptors */ + for (cur_tx_desc = port_info->tx_desc_base, i = 0; i < NUM_TX_DESC; + cur_tx_desc++, i++) { + cur_tx_desc->td0 = 0x00; + cur_tx_desc->td1 = 0x00; + cur_tx_desc->td2 = 0x00; + } + + /* Mark the end of the descriptors */ + cur_tx_desc--; + cur_tx_desc->td0 |= TD_TDLE; + + /* Point the controller to the tx descriptor list. Must use physical + addresses */ + outl(ADDR_TO_PHY(port_info->tx_desc_base), TDLAR(port)); + outl(ADDR_TO_PHY(port_info->tx_desc_base), TDFAR(port)); + outl(ADDR_TO_PHY(cur_tx_desc), TDFXR(port)); + outl(0x01, TDFFR(port));/* Last discriptor bit */ + + return 0; +} + +static int sh_eth_rx_desc_init(struct dev_info_s *dev) +{ + int port = dev->port; + struct port_info_s *port_info = &dev->port_info[port]; + u32 tmp_addr; + struct rx_desc_s *cur_rx_desc; + u8 *rx_buf; + int i; + + /* Allocate rx descriptors. They must be RX_DESC_SIZE bytes + aligned */ + if (!(port_info->rx_desc_malloc = malloc(NUM_RX_DESC * + sizeof(struct rx_desc_s) + + RX_DESC_SIZE - 1))) { + printf("Error: malloc failed\n"); + return -ENOMEM; + } + tmp_addr = (u32) (((int)port_info->rx_desc_malloc + RX_DESC_SIZE - 1) & + ~(RX_DESC_SIZE - 1)); + /* Make sure we use a P2 address (non-cacheable) */ + port_info->rx_desc_base = (struct rx_desc_s *)ADDR_TO_P2(tmp_addr); + + port_info->rx_desc_cur = port_info->rx_desc_base; + + /* Allocate rx data buffers. They must be 32 bytes aligned and in + P2 area */ + if (!(port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE + + 31))) { + printf("Error: malloc failed\n"); + free(port_info->rx_desc_malloc); + port_info->rx_desc_malloc = NULL; + return -ENOMEM; + } + tmp_addr = (u32)(((int)port_info->rx_buf_malloc + (32 - 1)) & + ~(32 - 1)); + port_info->rx_buf_base = (u8 *)ADDR_TO_P2(tmp_addr); + + /* Initialize all descriptors */ + for (cur_rx_desc = port_info->rx_desc_base, + rx_buf = port_info->rx_buf_base, i = 0; + i < NUM_RX_DESC; cur_rx_desc++, rx_buf += MAX_BUF_SIZE, i++) { + cur_rx_desc->rd0 = RD_RACT; + cur_rx_desc->rd1 = MAX_BUF_SIZE << 16; + cur_rx_desc->rd2 = (u32) ADDR_TO_PHY(rx_buf); + } + + /* Mark the end of the descriptors */ + cur_rx_desc--; + cur_rx_desc->rd0 |= RD_RDLE; + + /* Point the controller to the rx descriptor list */ + outl(ADDR_TO_PHY(port_info->rx_desc_base), RDLAR(port)); + outl(ADDR_TO_PHY(port_info->rx_desc_base), RDFAR(port)); + outl(ADDR_TO_PHY(cur_rx_desc), RDFXR(port)); + outl(RDFFR_RDLF, RDFFR(port)); + + return 0; +} + +static void sh_eth_desc_free(struct dev_info_s *dev) +{ + int port = dev->port; + struct port_info_s *port_info = &dev->port_info[port]; + + if (port_info->tx_desc_malloc) { + free(port_info->tx_desc_malloc); + port_info->tx_desc_malloc = NULL; + } + + if (port_info->rx_desc_malloc) { + free(port_info->rx_desc_malloc); + port_info->rx_desc_malloc = NULL; + } + + if (port_info->rx_buf_malloc) { + free(port_info->rx_buf_malloc); + port_info->rx_buf_malloc = NULL; + } +} + +static int sh_eth_desc_init(struct dev_info_s *dev) +{ + int rc; + + if ((rc = sh_eth_tx_desc_init(dev)) || (rc = sh_eth_rx_desc_init(dev))) { + sh_eth_desc_free(dev); + return rc; + } + + return 0; +} + +static int sh_eth_phy_config(struct dev_info_s *dev) +{ + int port = dev->port; + struct port_info_s *port_info = &dev->port_info[port]; + int timeout; + u32 val; + /* Reset phy */ + sh_eth_mii_write_phy_reg(port, port_info->phy_addr, PHY_CTRL, PHY_C_RESET); + timeout = 10; + while (timeout--) { + val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, PHY_CTRL); + if (!(val & PHY_C_RESET)) + break; + udelay(50000); + } + if (timeout < 0) { + printf("%s phy reset timeout\n", __func__); + return -1; + } + + /* Advertise 100/10 baseT full/half duplex */ + sh_eth_mii_write_phy_reg(port, port_info->phy_addr, PHY_ANA, + (PHY_A_FDX|PHY_A_HDX|PHY_A_10FDX|PHY_A_10HDX|PHY_A_EXT)); + /* Autonegotiation, normal operation, full duplex, enable tx */ + sh_eth_mii_write_phy_reg(port, port_info->phy_addr, PHY_CTRL, + (PHY_C_ANEGEN|PHY_C_RANEG)); + /* Wait for autonegotiation to complete */ + timeout = 100; + while (timeout--) { + val = sh_eth_mii_read_phy_reg(port, port_info->phy_addr, 1); + if (val & PHY_S_ANEGC) + break; + udelay(50000); + } + if (timeout < 0) { + printf("sh_eth_phy_config() phy auto-negotiation failed\n"); + return -1; + } + + return 0; +} + +static int sh_eth_config(struct dev_info_s *dev, bd_t * bd) +{ + int port = dev->port; + struct port_info_s *port_info = &dev->port_info[port]; + u32 val; + u32 phy_status; + int rc; + + /* Configure e-dmac registers */ + outl((inl(EDMR(port)) & ~EMDR_DESC_R) | EDMR_EL, EDMR(port)); + outl(0, EESIPR(port)); + outl(0, TRSCER(port)); + outl(0, TFTR(port)); + outl((FIFO_SIZE_T | FIFO_SIZE_R), FDR(port)); + outl(RMCR_RST, RMCR(port)); + outl(0, RPADIR(port)); + outl((FIFO_F_D_RFF | FIFO_F_D_RFD), FCFTR(port)); + + /* Configure e-mac registers */ + outl(0, ECSIPR(port)); + + /* Set Mac address */ + val = bd->bi_enetaddr[0] << 24 | bd->bi_enetaddr[1] << 16 | + bd->bi_enetaddr[2] << 8 | bd->bi_enetaddr[3]; + outl(val, MAHR(port)); + + val = bd->bi_enetaddr[4] << 8 | bd->bi_enetaddr[5]; + outl(val, MALR(port)); + + outl(RFLR_RFL_MIN, RFLR(port)); + outl(0, PIPR(port)); + outl(APR_AP, APR(port)); + outl(MPR_MP, MPR(port)); + outl(TPAUSER_TPAUSE, TPAUSER(port)); + + /* Configure phy */ + if ((rc = sh_eth_phy_config(dev))) + return rc; + + /* Read phy status to finish configuring the e-mac */ + phy_status = sh_eth_mii_read_phy_reg(dev->port, + dev->port_info[dev->port].phy_addr, + 1); + + /* Set the transfer speed */ + if (phy_status & (PHY_S_100X_F|PHY_S_100X_H)) { + printf("100Base/"); + outl(GECMR_100B, GECMR(port)); + } else { + printf("10Base/"); + outl(GECMR_10B, GECMR(port)); + } + + /* Check if full duplex mode is supported by the phy */ + if (phy_status & (PHY_S_100X_F|PHY_S_10T_F)) { + printf("Full\n"); + outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE|ECMR_DM), ECMR(port)); + } else { + printf("Half\n"); + outl((ECMR_CHG_DM|ECMR_RE|ECMR_TE), ECMR(port)); + } + return 0; +} + +static int sh_eth_start(struct dev_info_s *dev) +{ + /* + * Enable the e-dmac receiver only. The transmitter will be enabled when + * we have something to transmit + */ + outl(EDRRR_R, EDRRR(dev->port)); + + return 0; +} + +static int sh_eth_get_mac(bd_t *bd) +{ + char *s, *e; + int i; + + s = getenv("ethaddr"); + if (s != NULL) { + for (i = 0; i < 6; ++i) { + bd->bi_enetaddr[i] = s ? simple_strtoul(s, &e, 16) : 0; + if (s) + s = (*e) ? e + 1 : e; + } + } else { + puts("Please set MAC address\n"); + } + return 0; +} + +int eth_init(bd_t *bd) +{ + int rc; + /* Allocate main device information structure */ + if (!(dev = malloc(sizeof(*dev)))) { + printf("eth_init: malloc failed\n"); + return -ENOMEM; + } + + memset(dev, 0, sizeof(*dev)); + + dev->port = CONFIG_SH_ETHER_USE_PORT; + dev->port_info[dev->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR; + + sh_eth_get_mac(bd); + + if ((rc = sh_eth_reset(dev)) || (rc = sh_eth_desc_init(dev))) + goto err; + + if ((rc = sh_eth_config(dev, bd)) || (rc = sh_eth_start(dev))) + goto err_desc; + + return 0; + +err_desc: + sh_eth_desc_free(dev); +err: + free(dev); + printf("eth_init: Failed\n"); + return rc; +} diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h new file mode 100644 index 0000000..9cf0ea0 --- /dev/null +++ b/drivers/net/sh_eth.h @@ -0,0 +1,446 @@ +/* + * sh_eth.h - Driver for Renesas SH7763's gigabit ethernet controler. + * + * Copyright (C) 2008 Renesas Solutions Corp. + * Copyright (c) 2008 Nobuhiro Iwamatsu + * Copyright (c) 2007 Carlos Munoz + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include + +#define SHETHER_NAME "sh_eth" + +/* Malloc returns addresses in the P1 area (cacheable). However we need to + use area P2 (non-cacheable) */ +#define ADDR_TO_P2(addr) ((((int)(addr) & ~0xe0000000) | 0xa0000000)) + +/* The ethernet controller needs to use physical addresses */ +#define ADDR_TO_PHY(addr) ((int)(addr) & ~0xe0000000) + +/* Number of supported ports */ +#define MAX_PORT_NUM 2 + +/* Buffers must be big enough to hold the largest ethernet frame. Also, rx + buffers must be a multiple of 32 bytes */ +#define MAX_BUF_SIZE (48 * 32) + +/* The number of tx descriptors must be large enough to point to 5 or more + frames. If each frame uses 2 descriptors, at least 10 descriptors are needed. + We use one descriptor per frame */ +#define NUM_TX_DESC 8 + +/* The size of the tx descriptor is determined by how much padding is used. + 4, 20, or 52 bytes of padding can be used */ +#define TX_DESC_PADDING 4 +#define TX_DESC_SIZE (12 + TX_DESC_PADDING) + +/* Tx descriptor. We always use 4 bytes of padding */ +struct tx_desc_s { + volatile u32 td0; + u32 td1; + u32 td2; /* Buffer start */ + u32 padding; +}; + +/* There is no limitation in the number of rx descriptors */ +#define NUM_RX_DESC 8 + +/* The size of the rx descriptor is determined by how much padding is used. + 4, 20, or 52 bytes of padding can be used */ +#define RX_DESC_PADDING 4 +#define RX_DESC_SIZE (12 + RX_DESC_PADDING) + +/* Rx descriptor. We always use 4 bytes of padding */ +struct rx_desc_s { + volatile u32 rd0; + volatile u32 rd1; + u32 rd2; /* Buffer start */ + u32 padding; +}; + +struct port_info_s { + struct tx_desc_s *tx_desc_malloc; + struct tx_desc_s *tx_desc_base; + struct tx_desc_s *tx_desc_cur; + struct rx_desc_s *rx_desc_malloc; + struct rx_desc_s *rx_desc_base; + struct rx_desc_s *rx_desc_cur; + u8 *rx_buf_malloc; + u8 *rx_buf_base; + u8 mac_addr[6]; + u8 phy_addr; +}; + +struct dev_info_s { + int port; + struct port_info_s port_info[MAX_PORT_NUM]; +}; + +/* Register Address */ +#define BASE_IO_ADDR 0xfee00000 + +#define EDSR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0000) + +#define TDLAR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0010) +#define TDFAR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0014) +#define TDFXR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0018) +#define TDFFR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x001c) + +#define RDLAR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0030) +#define RDFAR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0034) +#define RDFXR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0038) +#define RDFFR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x003c) + +#define EDMR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0400) +#define EDTRR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0408) +#define EDRRR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0410) +#define EESR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0428) +#define EESIPR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0430) +#define TRSCER(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0438) +#define TFTR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0448) +#define FDR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0450) +#define RMCR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0458) +#define RPADIR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0460) +#define FCFTR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0468) +#define ECMR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0500) +#define RFLR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0508) +#define ECSIPR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0518) +#define PIR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0520) +#define PIPR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x052c) +#define APR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0554) +#define MPR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0558) +#define TPAUSER(port) (BASE_IO_ADDR + 0x800 * (port) + 0x0564) +#define GECMR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x05b0) +#define MALR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x05c8) +#define MAHR(port) (BASE_IO_ADDR + 0x800 * (port) + 0x05c0) + +/* + * Register's bits + * Copy from Linux driver source code + */ +#ifdef CONFIG_CPU_SH7763 +/* EDSR */ +enum EDSR_BIT { + EDSR_ENT = 0x01, EDSR_ENR = 0x02, +}; +#define EDSR_ENALL (EDSR_ENT|EDSR_ENR) +#endif + +/* EDMR */ +enum DMAC_M_BIT { + EDMR_DL1 = 0x20, EDMR_DL0 = 0x10, +#ifdef CONFIG_CPU_SH7763 + EDMR_SRST = 0x03, + EMDR_DESC_R = 0x30, /* Descriptor reserve size */ + EDMR_EL = 0x40, /* Litte endian */ +#else /* CONFIG_CPU_SH7763 */ + EDMR_SRST = 0x01, +#endif +}; + +/* RFLR */ +#define RFLR_RFL_MIN 0x05EE /* Recv Frame length 1518 byte */ + +/* EDTRR */ +enum DMAC_T_BIT { +#ifdef CONFIG_CPU_SH7763 + EDTRR_TRNS = 0x03, +#else + EDTRR_TRNS = 0x01, +#endif +}; + +/* GECMR */ +enum GECMR_BIT { + GECMR_1000B = 0x01, GECMR_100B = 0x40, GECMR_10B = 0x00, +}; + +/* EDRRR*/ +enum EDRRR_R_BIT { + EDRRR_R = 0x01, +}; + +/* TPAUSER */ +enum TPAUSER_BIT { + TPAUSER_TPAUSE = 0x0000ffff, + TPAUSER_UNLIMITED = 0, +}; + +/* BCFR */ +enum BCFR_BIT { + BCFR_RPAUSE = 0x0000ffff, + BCFR_UNLIMITED = 0, +}; + +/* PIR */ +enum PIR_BIT { + PIR_MDI = 0x08, PIR_MDO = 0x04, PIR_MMD = 0x02, PIR_MDC = 0x01, +}; + +/* PSR */ +enum PHY_STATUS_BIT { PHY_ST_LINK = 0x01, }; + +/* EESR */ +enum EESR_BIT { +#ifndef CONFIG_CPU_SH7763 + EESR_TWB = 0x40000000, +#else + EESR_TWB = 0xC0000000, + EESR_TC1 = 0x20000000, + EESR_TUC = 0x10000000, + EESR_ROC = 0x80000000, +#endif + EESR_TABT = 0x04000000, + EESR_RABT = 0x02000000, EESR_RFRMER = 0x01000000, +#ifndef CONFIG_CPU_SH7763 + EESR_ADE = 0x00800000, +#endif + EESR_ECI = 0x00400000, + EESR_FTC = 0x00200000, EESR_TDE = 0x00100000, + EESR_TFE = 0x00080000, EESR_FRC = 0x00040000, + EESR_RDE = 0x00020000, EESR_RFE = 0x00010000, +#ifndef CONFIG_CPU_SH7763 + EESR_CND = 0x00000800, +#endif + EESR_DLC = 0x00000400, + EESR_CD = 0x00000200, EESR_RTO = 0x00000100, + EESR_RMAF = 0x00000080, EESR_CEEF = 0x00000040, + EESR_CELF = 0x00000020, EESR_RRF = 0x00000010, + rESR_RTLF = 0x00000008, EESR_RTSF = 0x00000004, + EESR_PRE = 0x00000002, EESR_CERF = 0x00000001, +}; + + +#ifdef CONFIG_CPU_SH7763 +# define TX_CHECK (EESR_TC1 | EESR_FTC) +# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \ + | EESR_RFRMER | EESR_TFE | EESR_TDE | EESR_ECI) +# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_TDE | EESR_TFE) + +#else +# define TX_CHECK (EESR_FTC | EESR_CND | EESR_DLC | EESR_CD | EESR_RTO) +# define EESR_ERR_CHECK (EESR_TWB | EESR_TABT | EESR_RABT | EESR_RDE \ + | EESR_RFRMER | EESR_ADE | EESR_TFE | EESR_TDE | EESR_ECI) +# define TX_ERROR_CEHCK (EESR_TWB | EESR_TABT | EESR_ADE | EESR_TDE | EESR_TFE) +#endif + +/* EESIPR */ +enum DMAC_IM_BIT { + DMAC_M_TWB = 0x40000000, DMAC_M_TABT = 0x04000000, + DMAC_M_RABT = 0x02000000, + DMAC_M_RFRMER = 0x01000000, DMAC_M_ADF = 0x00800000, + DMAC_M_ECI = 0x00400000, DMAC_M_FTC = 0x00200000, + DMAC_M_TDE = 0x00100000, DMAC_M_TFE = 0x00080000, + DMAC_M_FRC = 0x00040000, DMAC_M_RDE = 0x00020000, + DMAC_M_RFE = 0x00010000, DMAC_M_TINT4 = 0x00000800, + DMAC_M_TINT3 = 0x00000400, DMAC_M_TINT2 = 0x00000200, + DMAC_M_TINT1 = 0x00000100, DMAC_M_RINT8 = 0x00000080, + DMAC_M_RINT5 = 0x00000010, DMAC_M_RINT4 = 0x00000008, + DMAC_M_RINT3 = 0x00000004, DMAC_M_RINT2 = 0x00000002, + DMAC_M_RINT1 = 0x00000001, +}; + +/* Receive descriptor bit */ +enum RD_STS_BIT { + RD_RACT = 0x80000000, RD_RDLE = 0x40000000, + RD_RFP1 = 0x20000000, RD_RFP0 = 0x10000000, + RD_RFE = 0x08000000, RD_RFS10 = 0x00000200, + RD_RFS9 = 0x00000100, RD_RFS8 = 0x00000080, + RD_RFS7 = 0x00000040, RD_RFS6 = 0x00000020, + RD_RFS5 = 0x00000010, RD_RFS4 = 0x00000008, + RD_RFS3 = 0x00000004, RD_RFS2 = 0x00000002, + RD_RFS1 = 0x00000001, +}; +#define RDF1ST RD_RFP1 +#define RDFEND RD_RFP0 +#define RD_RFP (RD_RFP1|RD_RFP0) + +/* RDFFR*/ +enum RDFFR_BIT { + RDFFR_RDLF = 0x01, +}; + +/* FCFTR */ +enum FCFTR_BIT { + FCFTR_RFF2 = 0x00040000, FCFTR_RFF1 = 0x00020000, + FCFTR_RFF0 = 0x00010000, FCFTR_RFD2 = 0x00000004, + FCFTR_RFD1 = 0x00000002, FCFTR_RFD0 = 0x00000001, +}; +#define FIFO_F_D_RFF (FCFTR_RFF2|FCFTR_RFF1|FCFTR_RFF0) +#define FIFO_F_D_RFD (FCFTR_RFD2|FCFTR_RFD1|FCFTR_RFD0) + +/* Transfer descriptor bit */ +enum TD_STS_BIT { +#ifdef CONFIG_CPU_SH7763 + TD_TACT = 0x80000000, +#else + TD_TACT = 0x7fffffff, +#endif + TD_TDLE = 0x40000000, TD_TFP1 = 0x20000000, + TD_TFP0 = 0x10000000, +}; +#define TDF1ST TD_TFP1 +#define TDFEND TD_TFP0 +#define TD_TFP (TD_TFP1|TD_TFP0) + +/* RMCR */ +enum RECV_RST_BIT { RMCR_RST = 0x01, }; +/* ECMR */ +enum FELIC_MODE_BIT { +#ifdef CONFIG_CPU_SH7763 + ECMR_TRCCM=0x04000000, ECMR_RCSC= 0x00800000, ECMR_DPAD= 0x00200000, + ECMR_RZPF = 0x00100000, +#endif + ECMR_ZPF = 0x00080000, ECMR_PFR = 0x00040000, ECMR_RXF = 0x00020000, + ECMR_TXF = 0x00010000, ECMR_MCT = 0x00002000, ECMR_PRCEF = 0x00001000, + ECMR_PMDE = 0x00000200, ECMR_RE = 0x00000040, ECMR_TE = 0x00000020, + ECMR_ILB = 0x00000008, ECMR_ELB = 0x00000004, ECMR_DM = 0x00000002, + ECMR_PRM = 0x00000001, +}; + +#ifdef CONFIG_CPU_SH7763 +#define ECMR_CHG_DM (ECMR_TRCCM | ECMR_RZPF | ECMR_ZPF | ECMR_PFR | ECMR_RXF | \ + ECMR_TXF | ECMR_MCT) +#else +#define ECMR_CHG_DM (ECMR_ZPF | ECMR_PFR ECMR_RXF | ECMR_TXF | ECMR_MCT) +#endif + +/* ECSR */ +enum ECSR_STATUS_BIT { +#ifndef CONFIG_CPU_SH7763 + ECSR_BRCRX = 0x20, ECSR_PSRTO = 0x10, +#endif + ECSR_LCHNG = 0x04, + ECSR_MPD = 0x02, ECSR_ICD = 0x01, +}; + +#ifdef CONFIG_CPU_SH7763 +# define ECSR_INIT (ECSR_ICD | ECSIPR_MPDIP) +#else +# define ECSR_INIT (ECSR_BRCRX | ECSR_PSRTO | \ + ECSR_LCHNG | ECSR_ICD | ECSIPR_MPDIP) +#endif + +/* ECSIPR */ +enum ECSIPR_STATUS_MASK_BIT { +#ifndef CONFIG_CPU_SH7763 + ECSIPR_BRCRXIP = 0x20, ECSIPR_PSRTOIP = 0x10, +#endif + ECSIPR_LCHNGIP = 0x04, + ECSIPR_MPDIP = 0x02, ECSIPR_ICDIP = 0x01, +}; + +#ifdef CONFIG_CPU_SH7763 +# define ECSIPR_INIT (ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP) +#else +# define ECSIPR_INIT (ECSIPR_BRCRXIP | ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | \ + ECSIPR_ICDIP | ECSIPR_MPDIP) +#endif + +/* APR */ +enum APR_BIT { + APR_AP = 0x00000004, +}; + +/* MPR */ +enum MPR_BIT { + MPR_MP = 0x00000006, +}; + +/* TRSCER */ +enum DESC_I_BIT { + DESC_I_TINT4 = 0x0800, DESC_I_TINT3 = 0x0400, DESC_I_TINT2 = 0x0200, + DESC_I_TINT1 = 0x0100, DESC_I_RINT8 = 0x0080, DESC_I_RINT5 = 0x0010, + DESC_I_RINT4 = 0x0008, DESC_I_RINT3 = 0x0004, DESC_I_RINT2 = 0x0002, + DESC_I_RINT1 = 0x0001, +}; + +/* RPADIR */ +enum RPADIR_BIT { + RPADIR_PADS1 = 0x20000, RPADIR_PADS0 = 0x10000, + RPADIR_PADR = 0x0003f, +}; + +#ifdef CONFIG_CPU_SH7763 +# define RPADIR_INIT (0x00) +#else +# define RPADIR_INIT (RPADIR_PADS1) +#endif + +/* FDR */ +enum FIFO_SIZE_BIT { + FIFO_SIZE_T = 0x00000700, FIFO_SIZE_R = 0x00000007, +}; + +enum PHY_OFFSETS { + PHY_CTRL = 0, PHY_STAT = 1, PHY_IDT1 = 2, PHY_IDT2 = 3, + PHY_ANA = 4, PHY_ANL = 5, PHY_ANE = 6, + PHY_16 = 16, +}; + +/* PHY_CTRL */ +enum PHY_CTRL_BIT { + PHY_C_RESET = 0x8000, PHY_C_LOOPBK = 0x4000, PHY_C_SPEEDSL = 0x2000, + PHY_C_ANEGEN = 0x1000, PHY_C_PWRDN = 0x0800, PHY_C_ISO = 0x0400, + PHY_C_RANEG = 0x0200, PHY_C_DUPLEX = 0x0100, PHY_C_COLT = 0x0080, +}; +#define DM9161_PHY_C_ANEGEN 0 /* auto nego special */ + +/* PHY_STAT */ +enum PHY_STAT_BIT { + PHY_S_100T4 = 0x8000, PHY_S_100X_F = 0x4000, PHY_S_100X_H = 0x2000, + PHY_S_10T_F = 0x1000, PHY_S_10T_H = 0x0800, PHY_S_ANEGC = 0x0020, + PHY_S_RFAULT = 0x0010, PHY_S_ANEGA = 0x0008, PHY_S_LINK = 0x0004, + PHY_S_JAB = 0x0002, PHY_S_EXTD = 0x0001, +}; + +/* PHY_ANA */ +enum PHY_ANA_BIT { + PHY_A_NP = 0x8000, PHY_A_ACK = 0x4000, PHY_A_RF = 0x2000, + PHY_A_FCS = 0x0400, PHY_A_T4 = 0x0200, PHY_A_FDX = 0x0100, + PHY_A_HDX = 0x0080, PHY_A_10FDX = 0x0040, PHY_A_10HDX = 0x0020, + PHY_A_SEL = 0x001e, + PHY_A_EXT = 0x0001, +}; + +/* PHY_ANL */ +enum PHY_ANL_BIT { + PHY_L_NP = 0x8000, PHY_L_ACK = 0x4000, PHY_L_RF = 0x2000, + PHY_L_FCS = 0x0400, PHY_L_T4 = 0x0200, PHY_L_FDX = 0x0100, + PHY_L_HDX = 0x0080, PHY_L_10FDX = 0x0040, PHY_L_10HDX = 0x0020, + PHY_L_SEL = 0x001f, +}; + +/* PHY_ANE */ +enum PHY_ANE_BIT { + PHY_E_PDF = 0x0010, PHY_E_LPNPA = 0x0008, PHY_E_NPA = 0x0004, + PHY_E_PRX = 0x0002, PHY_E_LPANEGA = 0x0001, +}; + +/* DM9161 */ +enum PHY_16_BIT { + PHY_16_BP4B45 = 0x8000, PHY_16_BPSCR = 0x4000, PHY_16_BPALIGN = 0x2000, + PHY_16_BP_ADPOK = 0x1000, PHY_16_Repeatmode = 0x0800, + PHY_16_TXselect = 0x0400, + PHY_16_Rsvd = 0x0200, PHY_16_RMIIEnable = 0x0100, + PHY_16_Force100LNK = 0x0080, + PHY_16_APDLED_CTL = 0x0040, PHY_16_COLLED_CTL = 0x0020, + PHY_16_RPDCTR_EN = 0x0010, + PHY_16_ResetStMch = 0x0008, PHY_16_PreamSupr = 0x0004, + PHY_16_Sleepmode = 0x0002, + PHY_16_RemoteLoopOut = 0x0001, +}; -- cgit v1.1 From fec61431a003f5778bafa2624073a571af8bec9f Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Wed, 18 Jun 2008 12:10:31 -0400 Subject: Remove duplicate definitions in include/lxt971a.h. Remove duplicate definitions in include/lxt971a.h. Remove duplicate registers and bits definitions in include/lxt971a.h for standard MII registers, and use values in include/miiphy.h instead. Signed-off-by: Hugo Villeneuve Signed-off-by: Ben Warren --- drivers/net/ns7520_eth.c | 42 ++++++++++++++++------------------ drivers/net/ns9750_eth.c | 59 +++++++++++++++++++++++------------------------- 2 files changed, 47 insertions(+), 54 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ns7520_eth.c b/drivers/net/ns7520_eth.c index 37411df..e19c223 100644 --- a/drivers/net/ns7520_eth.c +++ b/drivers/net/ns7520_eth.c @@ -387,8 +387,8 @@ static int ns7520_eth_reset(void) ns7520_mii_get_clock_divisor(nPhyMaxMdioClock); /* reset PHY */ - ns7520_mii_write(PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET); - ns7520_mii_write(PHY_COMMON_CTRL, 0); + ns7520_mii_write(PHY_BMCR, PHY_BMCR_RESET); + ns7520_mii_write(PHY_BMCR, 0); udelay(3000); /* [2] p.70 says at least 300us reset recovery time. */ @@ -438,26 +438,23 @@ static void ns7520_link_auto_negotiate(void) /* run auto-negotation */ /* define what we are capable of */ - ns7520_mii_write(PHY_COMMON_AUTO_ADV, - PHY_COMMON_AUTO_ADV_100BTXFD | - PHY_COMMON_AUTO_ADV_100BTX | - PHY_COMMON_AUTO_ADV_10BTFD | - PHY_COMMON_AUTO_ADV_10BT | - PHY_COMMON_AUTO_ADV_802_3); + ns7520_mii_write(PHY_ANAR, + PHY_ANLPAR_TXFD | + PHY_ANLPAR_TX | + PHY_ANLPAR_10FD | + PHY_ANLPAR_10 | + PHY_ANLPAR_PSB_802_3); /* start auto-negotiation */ - ns7520_mii_write(PHY_COMMON_CTRL, - PHY_COMMON_CTRL_AUTO_NEG | - PHY_COMMON_CTRL_RES_AUTO); + ns7520_mii_write(PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); /* wait for completion */ ulStartJiffies = get_timer(0); while (get_timer(0) < ulStartJiffies + NS7520_MII_NEG_DELAY) { - uiStatus = ns7520_mii_read(PHY_COMMON_STAT); + uiStatus = ns7520_mii_read(PHY_BMSR); if ((uiStatus & - (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) - == - (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) { + (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)) == + (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)) { /* lucky we are, auto-negotiation succeeded */ ns7520_link_print_changed(); ns7520_link_update_egcr(); @@ -518,14 +515,13 @@ static void ns7520_link_print_changed(void) DEBUG_FN(DEBUG_LINK); - uiControl = ns7520_mii_read(PHY_COMMON_CTRL); + uiControl = ns7520_mii_read(PHY_BMCR); - if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) == - PHY_COMMON_CTRL_AUTO_NEG) { - /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */ - uiStatus = ns7520_mii_read(PHY_COMMON_STAT); + if ((uiControl & PHY_BMCR_AUTON) == PHY_BMCR_AUTON) { + /* PHY_BMSR_LS is only set on autonegotiation */ + uiStatus = ns7520_mii_read(PHY_BMSR); - if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) { + if (!(uiStatus & PHY_BMSR_LS)) { printk(KERN_WARNING NS7520_DRIVER_NAME ": link down\n"); /* @TODO Linux: carrier_off */ @@ -586,12 +582,12 @@ static char ns7520_mii_identify_phy(void) DEBUG_FN(DEBUG_MII); - phyDetected = (PhyType) uiID1 = ns7520_mii_read(PHY_COMMON_ID1); + phyDetected = (PhyType) uiID1 = ns7520_mii_read(PHY_PHYIDR1); switch (phyDetected) { case PHY_LXT971A: szName = "LXT971A"; - uiID2 = ns7520_mii_read(PHY_COMMON_ID2); + uiID2 = ns7520_mii_read(PHY_PHYIDR2); nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK; cRes = 1; break; diff --git a/drivers/net/ns9750_eth.c b/drivers/net/ns9750_eth.c index 0559710..cade831 100644 --- a/drivers/net/ns9750_eth.c +++ b/drivers/net/ns9750_eth.c @@ -37,7 +37,7 @@ #include "ns9750_eth.h" /* for Ethernet and PHY */ -/* some definition to make transistion to linux easier */ +/* some definition to make transition to linux easier */ #define NS9750_DRIVER_NAME "eth" #define KERN_WARNING "Warning:" @@ -399,8 +399,8 @@ static int ns9750_eth_reset (void) ns9750_mii_get_clock_divisor (nPhyMaxMdioClock); /* reset PHY */ - ns9750_mii_write (PHY_COMMON_CTRL, PHY_COMMON_CTRL_RESET); - ns9750_mii_write (PHY_COMMON_CTRL, 0); + ns9750_mii_write(PHY_BMCR, PHY_BMCR_RESET); + ns9750_mii_write(PHY_BMCR, 0); /* @TODO check time */ udelay (3000); /* [2] p.70 says at least 300us reset recovery time. But @@ -455,26 +455,26 @@ static void ns9750_link_force (void) DEBUG_FN (DEBUG_LINK); - uiControl = ns9750_mii_read (PHY_COMMON_CTRL); - uiControl &= ~(PHY_COMMON_CTRL_SPD_MA | - PHY_COMMON_CTRL_AUTO_NEG | PHY_COMMON_CTRL_DUPLEX); + uiControl = ns9750_mii_read(PHY_BMCR); + uiControl &= ~(PHY_BMCR_SPEED_MASK | + PHY_BMCR_AUTON | PHY_BMCR_DPLX); uiLastLinkStatus = 0; if ((ucLinkMode & FS_EEPROM_AUTONEG_SPEED_MASK) == FS_EEPROM_AUTONEG_SPEED_100) { - uiControl |= PHY_COMMON_CTRL_SPD_100; + uiControl |= PHY_BMCR_100MB; uiLastLinkStatus |= PHY_LXT971_STAT2_100BTX; } else - uiControl |= PHY_COMMON_CTRL_SPD_10; + uiControl |= PHY_BMCR_10_MBPS; if ((ucLinkMode & FS_EEPROM_AUTONEG_DUPLEX_MASK) == FS_EEPROM_AUTONEG_DUPLEX_FULL) { - uiControl |= PHY_COMMON_CTRL_DUPLEX; + uiControl |= PHY_BMCR_DPLX; uiLastLinkStatus |= PHY_LXT971_STAT2_DUPLEX_MODE; } - ns9750_mii_write (PHY_COMMON_CTRL, uiControl); + ns9750_mii_write(PHY_BMCR, uiControl); ns9750_link_print_changed (); ns9750_link_update_egcr (); @@ -495,25 +495,23 @@ static void ns9750_link_auto_negotiate (void) /* run auto-negotation */ /* define what we are capable of */ - ns9750_mii_write (PHY_COMMON_AUTO_ADV, - PHY_COMMON_AUTO_ADV_100BTXFD | - PHY_COMMON_AUTO_ADV_100BTX | - PHY_COMMON_AUTO_ADV_10BTFD | - PHY_COMMON_AUTO_ADV_10BT | - PHY_COMMON_AUTO_ADV_802_3); + ns9750_mii_write(PHY_ANAR, + PHY_ANLPAR_TXFD | + PHY_ANLPAR_TX | + PHY_ANLPAR_10FD | + PHY_ANLPAR_10 | + PHY_ANLPAR_PSB_802_3); /* start auto-negotiation */ - ns9750_mii_write (PHY_COMMON_CTRL, - PHY_COMMON_CTRL_AUTO_NEG | - PHY_COMMON_CTRL_RES_AUTO); + ns9750_mii_write(PHY_BMCR, PHY_BMCR_AUTON | PHY_BMCR_RST_NEG); /* wait for completion */ ulStartJiffies = get_ticks (); while (get_ticks () < ulStartJiffies + NS9750_MII_NEG_DELAY) { - uiStatus = ns9750_mii_read (PHY_COMMON_STAT); + uiStatus = ns9750_mii_read(PHY_BMSR); if ((uiStatus & - (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) == - (PHY_COMMON_STAT_AN_COMP | PHY_COMMON_STAT_LNK_STAT)) { + (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)) == + (PHY_BMSR_AUTN_COMP | PHY_BMSR_LS)) { /* lucky we are, auto-negotiation succeeded */ ns9750_link_print_changed (); ns9750_link_update_egcr (); @@ -571,14 +569,13 @@ static void ns9750_link_print_changed (void) DEBUG_FN (DEBUG_LINK); - uiControl = ns9750_mii_read (PHY_COMMON_CTRL); + uiControl = ns9750_mii_read(PHY_BMCR); - if ((uiControl & PHY_COMMON_CTRL_AUTO_NEG) == - PHY_COMMON_CTRL_AUTO_NEG) { - /* PHY_COMMON_STAT_LNK_STAT is only set on autonegotiation */ - uiStatus = ns9750_mii_read (PHY_COMMON_STAT); + if ((uiControl & PHY_BMCR_AUTON) == PHY_BMCR_AUTON) { + /* PHY_BMSR_LS is only set on autonegotiation */ + uiStatus = ns9750_mii_read(PHY_BMSR); - if (!(uiStatus & PHY_COMMON_STAT_LNK_STAT)) { + if (!(uiStatus & PHY_BMSR_LS)) { printk (KERN_WARNING NS9750_DRIVER_NAME ": link down\n"); /* @TODO Linux: carrier_off */ @@ -592,7 +589,7 @@ static void ns9750_link_print_changed (void) /* mask out all uninteresting parts */ } - /* other PHYs must store there link information in + /* other PHYs must store their link information in uiStatus as PHY_LXT971 */ } } else { @@ -637,12 +634,12 @@ static char ns9750_mii_identify_phy (void) DEBUG_FN (DEBUG_MII); - phyDetected = (PhyType) uiID1 = ns9750_mii_read (PHY_COMMON_ID1); + phyDetected = (PhyType) uiID1 = ns9750_mii_read(PHY_PHYIDR1); switch (phyDetected) { case PHY_LXT971A: szName = "LXT971A"; - uiID2 = ns9750_mii_read (PHY_COMMON_ID2); + uiID2 = ns9750_mii_read(PHY_PHYIDR2); nPhyMaxMdioClock = PHY_LXT971_MDIO_MAX_CLK; cRes = 1; break; -- cgit v1.1 From 8915f1189c1d29d8be7f4de325702d90a8988219 Mon Sep 17 00:00:00 2001 From: Paul Gortmaker Date: Wed, 9 Jul 2008 17:50:45 -0400 Subject: e1000: add support for 82545GM 64bit PCI-X copper variant This PCI-X e1000 variant works by just adding in the correct PCI IDs in the appropriate places. Signed-off-by: Paul Gortmaker --- drivers/net/e1000.c | 2 ++ drivers/net/e1000.h | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index c31029a..060b518 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -75,6 +75,7 @@ static struct pci_device_id supported[] = { {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82544GC_LOM}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82540EM}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_COPPER}, + {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545GM_COPPER}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_COPPER}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82545EM_FIBER}, {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82546EB_FIBER}, @@ -636,6 +637,7 @@ e1000_set_mac_type(struct e1000_hw *hw) hw->mac_type = e1000_82540; break; case E1000_DEV_ID_82545EM_COPPER: + case E1000_DEV_ID_82545GM_COPPER: case E1000_DEV_ID_82545EM_FIBER: hw->mac_type = e1000_82545; break; diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 23b2eb9..c258bc2 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -217,13 +217,14 @@ struct e1000_phy_stats { #define E1000_DEV_ID_82544GC_LOM 0x100D #define E1000_DEV_ID_82540EM 0x100E #define E1000_DEV_ID_82540EM_LOM 0x1015 +#define E1000_DEV_ID_82545GM_COPPER 0x1026 #define E1000_DEV_ID_82545EM_COPPER 0x100F #define E1000_DEV_ID_82545EM_FIBER 0x1011 #define E1000_DEV_ID_82546EB_COPPER 0x1010 #define E1000_DEV_ID_82546EB_FIBER 0x1012 #define E1000_DEV_ID_82541ER 0x1078 #define E1000_DEV_ID_82541GI_LF 0x107C -#define NUM_DEV_IDS 15 +#define NUM_DEV_IDS 16 #define NODE_ADDRESS_SIZE 6 #define ETH_LENGTH_OF_ADDRESS 6 -- cgit v1.1