diff options
author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-12-10 14:31:56 +0100 |
---|---|---|
committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-12-10 22:23:59 +0100 |
commit | f15ea6e1d67782a1626d4a4922b6c20e380085e5 (patch) | |
tree | 57d78f1ee94a2060eaa591533278d2934d4f1da3 /drivers/net | |
parent | cb7ee1b98cac6baf244daefb1192adf5a47bc983 (diff) | |
parent | f44483b57c49282299da0e5c10073b909cdad979 (diff) | |
download | u-boot-imx-f15ea6e1d67782a1626d4a4922b6c20e380085e5.zip u-boot-imx-f15ea6e1d67782a1626d4a4922b6c20e380085e5.tar.gz u-boot-imx-f15ea6e1d67782a1626d4a4922b6c20e380085e5.tar.bz2 |
Merge branch 'u-boot/master' into 'u-boot-arm/master'
Conflicts:
arch/arm/cpu/armv7/rmobile/Makefile
doc/README.scrapyard
Needed manual fix:
arch/arm/cpu/armv7/omap-common/Makefile
board/compulab/cm_t335/u-boot.lds
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/designware.c | 2 | ||||
-rw-r--r-- | drivers/net/designware.h | 7 | ||||
-rw-r--r-- | drivers/net/dm9000x.c | 9 | ||||
-rw-r--r-- | drivers/net/e1000.c | 34 | ||||
-rw-r--r-- | drivers/net/e1000.h | 9 | ||||
-rw-r--r-- | drivers/net/fm/Makefile | 7 | ||||
-rw-r--r-- | drivers/net/fm/eth.c | 12 | ||||
-rw-r--r-- | drivers/net/fm/fm.h | 2 | ||||
-rw-r--r-- | drivers/net/fm/init.c | 18 | ||||
-rw-r--r-- | drivers/net/fm/t2080.c | 91 | ||||
-rw-r--r-- | drivers/net/fsl_mdio.c | 17 | ||||
-rw-r--r-- | drivers/net/mvgbe.c | 5 | ||||
-rw-r--r-- | drivers/net/npe/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/pcnet.c | 277 | ||||
-rw-r--r-- | drivers/net/phy/atheros.c | 8 | ||||
-rw-r--r-- | drivers/net/phy/micrel.c | 34 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 5 | ||||
-rw-r--r-- | drivers/net/phy/realtek.c | 6 | ||||
-rw-r--r-- | drivers/net/phy/smsc.c | 3 | ||||
-rw-r--r-- | drivers/net/phy/vitesse.c | 69 | ||||
-rw-r--r-- | drivers/net/rtl8139.c | 2 | ||||
-rw-r--r-- | drivers/net/rtl8169.c | 90 | ||||
-rw-r--r-- | drivers/net/sh_eth.c | 51 | ||||
-rw-r--r-- | drivers/net/sh_eth.h | 34 | ||||
-rw-r--r-- | drivers/net/tsec.c | 199 | ||||
-rw-r--r-- | drivers/net/zynq_gem.c | 82 |
26 files changed, 744 insertions, 332 deletions
diff --git a/drivers/net/designware.c b/drivers/net/designware.c index 8413d57..22155b4 100644 --- a/drivers/net/designware.c +++ b/drivers/net/designware.c @@ -96,7 +96,7 @@ static int mac_reset(struct eth_device *dev) ulong start; int timeout = CONFIG_MACRESET_TIMEOUT; - writel(DMAMAC_SRST, &dma_p->busmode); + writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode); if (priv->interface != PHY_INTERFACE_MODE_RGMII) writel(MII_PORTSELECT, &mac_p->conf); diff --git a/drivers/net/designware.h b/drivers/net/designware.h index e80002a..5440c92 100644 --- a/drivers/net/designware.h +++ b/drivers/net/designware.h @@ -112,7 +112,7 @@ struct dmamacdescr { u32 dmamac_cntl; void *dmamac_addr; struct dmamacdescr *dmamac_next; -}; +} __aligned(16); /* * txrx_status definitions @@ -224,8 +224,7 @@ struct dw_eth_dev { u32 tx_currdescnum; u32 rx_currdescnum; u32 phy_configured; - int link_printed; - u32 padding; + u32 link_printed; struct dmamacdescr tx_mac_descrtable[CONFIG_TX_DESCR_NUM]; struct dmamacdescr rx_mac_descrtable[CONFIG_RX_DESCR_NUM]; @@ -237,7 +236,7 @@ struct dw_eth_dev { struct eth_dma_regs *dma_regs_p; struct eth_device *dev; -} __attribute__ ((aligned(8))); +}; /* Speed specific definitions */ #define SPEED_10M 1 diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c index f7170e0..b68d808 100644 --- a/drivers/net/dm9000x.c +++ b/drivers/net/dm9000x.c @@ -342,6 +342,15 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd) DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS); printf("MAC: %pM\n", dev->enetaddr); + if (!is_valid_ether_addr(dev->enetaddr)) { +#ifdef CONFIG_RANDOM_MACADDR + printf("Bad MAC address (uninitialized EEPROM?), randomizing\n"); + eth_random_enetaddr(dev->enetaddr); + printf("MAC: %pM\n", dev->enetaddr); +#else + printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n"); +#endif + } /* fill device MAC address registers */ for (i = 0, oft = DM9000_PAR; i < 6; i++, oft++) diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c index 57aa53d..9a66e68 100644 --- a/drivers/net/e1000.c +++ b/drivers/net/e1000.c @@ -114,12 +114,13 @@ static int e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, static int32_t e1000_phy_hw_reset(struct e1000_hw *hw); static int e1000_phy_reset(struct e1000_hw *hw); static int e1000_detect_gig_phy(struct e1000_hw *hw); -static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw); static void e1000_set_media_type(struct e1000_hw *hw); static int32_t e1000_swfw_sync_acquire(struct e1000_hw *hw, uint16_t mask); static int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); +#ifndef CONFIG_E1000_NO_NVM +static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw); static int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data); @@ -885,6 +886,7 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw *hw) return -E1000_ERR_EEPROM; } +#endif /* CONFIG_E1000_NO_NVM */ /***************************************************************************** * Set PHY to class A mode @@ -897,6 +899,7 @@ static int e1000_validate_eeprom_checksum(struct e1000_hw *hw) static int32_t e1000_set_phy_mode(struct e1000_hw *hw) { +#ifndef CONFIG_E1000_NO_NVM int32_t ret_val; uint16_t eeprom_data; @@ -923,10 +926,11 @@ e1000_set_phy_mode(struct e1000_hw *hw) hw->phy_reset_disable = false; } } - +#endif return E1000_SUCCESS; } +#ifndef CONFIG_E1000_NO_NVM /*************************************************************************** * * Obtaining software semaphore bit (SMBI) before resetting PHY. @@ -965,6 +969,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw) return E1000_SUCCESS; } +#endif /*************************************************************************** * This function clears HW semaphore bits. @@ -977,6 +982,7 @@ e1000_get_software_semaphore(struct e1000_hw *hw) static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) { +#ifndef CONFIG_E1000_NO_NVM uint32_t swsm; DEBUGFUNC(); @@ -991,6 +997,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) } else swsm &= ~(E1000_SWSM_SWESMBI); E1000_WRITE_REG(hw, SWSM, swsm); +#endif } /*************************************************************************** @@ -1007,6 +1014,7 @@ e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw) static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) { +#ifndef CONFIG_E1000_NO_NVM int32_t timeout; uint32_t swsm; @@ -1043,7 +1051,7 @@ e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw) "SWESMBI bit is set.\n"); return -E1000_ERR_EEPROM; } - +#endif return E1000_SUCCESS; } @@ -1097,6 +1105,7 @@ static bool e1000_is_second_port(struct e1000_hw *hw) } } +#ifndef CONFIG_E1000_NO_NVM /****************************************************************************** * Reads the adapter's MAC address from the EEPROM and inverts the LSB for the * second function of dual function devices @@ -1136,6 +1145,7 @@ e1000_read_mac_addr(struct eth_device *nic) #endif return 0; } +#endif /****************************************************************************** * Initializes receive address filters. @@ -1764,9 +1774,11 @@ static int e1000_setup_link(struct eth_device *nic) { struct e1000_hw *hw = nic->priv; - uint32_t ctrl_ext; int32_t ret_val; +#ifndef CONFIG_E1000_NO_NVM + uint32_t ctrl_ext; uint16_t eeprom_data; +#endif DEBUGFUNC(); @@ -1775,6 +1787,7 @@ e1000_setup_link(struct eth_device *nic) if (e1000_check_phy_reset_block(hw)) return E1000_SUCCESS; +#ifndef CONFIG_E1000_NO_NVM /* Read and store word 0x0F of the EEPROM. This word contains bits * that determine the hardware's default PAUSE (flow control) mode, * a bit that determines whether the HW defaults to enabling or @@ -1788,7 +1801,7 @@ e1000_setup_link(struct eth_device *nic) DEBUGOUT("EEPROM Read Error\n"); return -E1000_ERR_EEPROM; } - +#endif if (hw->fc == e1000_fc_default) { switch (hw->mac_type) { case e1000_ich8lan: @@ -1797,6 +1810,7 @@ e1000_setup_link(struct eth_device *nic) hw->fc = e1000_fc_full; break; default: +#ifndef CONFIG_E1000_NO_NVM ret_val = e1000_read_eeprom(hw, EEPROM_INIT_CONTROL2_REG, 1, &eeprom_data); if (ret_val) { @@ -1809,6 +1823,7 @@ e1000_setup_link(struct eth_device *nic) EEPROM_WORD0F_ASM_DIR) hw->fc = e1000_fc_tx_pause; else +#endif hw->fc = e1000_fc_full; break; } @@ -1828,6 +1843,7 @@ e1000_setup_link(struct eth_device *nic) DEBUGOUT("After fix-ups FlowControl is now = %x\n", hw->fc); +#ifndef CONFIG_E1000_NO_NVM /* Take the 4 bits from EEPROM word 0x0F that determine the initial * polarity value for the SW controlled pins, and setup the * Extended Device Control reg with that info. @@ -1840,6 +1856,7 @@ e1000_setup_link(struct eth_device *nic) SWDPIO__EXT_SHIFT); E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); } +#endif /* Call the necessary subroutine to configure the link. */ ret_val = (hw->media_type == e1000_media_type_fiber) ? @@ -5196,6 +5213,7 @@ e1000_initialize(bd_t * bis) e1000_reset_hw(hw); list_add_tail(&hw->list_node, &e1000_hw_list); +#ifndef CONFIG_E1000_NO_NVM /* Validate the EEPROM and get chipset information */ #if !defined(CONFIG_MVBC_1G) if (e1000_init_eeprom_params(hw)) { @@ -5206,11 +5224,17 @@ e1000_initialize(bd_t * bis) continue; #endif e1000_read_mac_addr(nic); +#endif e1000_get_bus_type(hw); +#ifndef CONFIG_E1000_NO_NVM printf("e1000: %02x:%02x:%02x:%02x:%02x:%02x\n ", nic->enetaddr[0], nic->enetaddr[1], nic->enetaddr[2], nic->enetaddr[3], nic->enetaddr[4], nic->enetaddr[5]); +#else + memset(nic->enetaddr, 0, 6); + printf("e1000: no NVM\n"); +#endif /* Set up the function pointers and register the device */ nic->init = e1000_init; diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h index 25884f5..ff87af2 100644 --- a/drivers/net/e1000.h +++ b/drivers/net/e1000.h @@ -63,11 +63,14 @@ struct e1000_hw_stats; /* Internal E1000 helper functions */ struct e1000_hw *e1000_find_card(unsigned int cardnum); + +#ifndef CONFIG_E1000_NO_NVM int32_t e1000_acquire_eeprom(struct e1000_hw *hw); void e1000_standby_eeprom(struct e1000_hw *hw); void e1000_release_eeprom(struct e1000_hw *hw); void e1000_raise_ee_clk(struct e1000_hw *hw, uint32_t *eecd); void e1000_lower_ee_clk(struct e1000_hw *hw, uint32_t *eecd); +#endif #ifdef CONFIG_E1000_SPI int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw, @@ -1019,6 +1022,7 @@ struct e1000_hw_stats { uint64_t tsctfc; }; +#ifndef CONFIG_E1000_NO_NVM struct e1000_eeprom_info { e1000_eeprom_type type; uint16_t word_size; @@ -1029,6 +1033,7 @@ e1000_eeprom_type type; bool use_eerd; bool use_eewr; }; +#endif typedef enum { e1000_smart_speed_default = 0, @@ -1081,10 +1086,14 @@ struct e1000_hw { uint32_t io_base; #endif uint32_t asf_firmware_present; +#ifndef CONFIG_E1000_NO_NVM uint32_t eeprom_semaphore_present; +#endif uint32_t swfw_sync_present; uint32_t swfwhw_semaphore_present; +#ifndef CONFIG_E1000_NO_NVM struct e1000_eeprom_info eeprom; +#endif e1000_ms_type master_slave; e1000_ms_type original_master_slave; e1000_ffe_config ffe_config_state; diff --git a/drivers/net/fm/Makefile b/drivers/net/fm/Makefile index bec86c1..ee5d768 100644 --- a/drivers/net/fm/Makefile +++ b/drivers/net/fm/Makefile @@ -4,7 +4,6 @@ # SPDX-License-Identifier: GPL-2.0+ # -ifdef CONFIG_FMAN_ENET obj-y += dtsec.o obj-y += eth.o obj-y += fm.o @@ -26,8 +25,12 @@ obj-$(CONFIG_PPC_P4080) += p4080.o obj-$(CONFIG_PPC_P5020) += p5020.o obj-$(CONFIG_PPC_P5040) += p5040.o obj-$(CONFIG_PPC_T1040) += t1040.o +obj-$(CONFIG_PPC_T1042) += t1040.o +obj-$(CONFIG_PPC_T1020) += t1040.o +obj-$(CONFIG_PPC_T1022) += t1040.o +obj-$(CONFIG_PPC_T2080) += t2080.o +obj-$(CONFIG_PPC_T2081) += t2080.o obj-$(CONFIG_PPC_T4240) += t4240.o obj-$(CONFIG_PPC_T4160) += t4240.o obj-$(CONFIG_PPC_B4420) += b4860.o obj-$(CONFIG_PPC_B4860) += b4860.o -endif diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c index cb099cd..218a5ed 100644 --- a/drivers/net/fm/eth.c +++ b/drivers/net/fm/eth.c @@ -557,8 +557,16 @@ static int fm_eth_init_mac(struct fm_eth *fm_eth, struct ccsr_fman *reg) num = fm_eth->num; #ifdef CONFIG_SYS_FMAN_V3 - if (fm_eth->type == FM_ETH_10G_E) - num += 8; + if (fm_eth->type == FM_ETH_10G_E) { + /* 10GEC1/10GEC2 use mEMAC9/mEMAC10 + * 10GEC3/10GEC4 use mEMAC1/mEMAC2 + * so it needs to change the num. + */ + if (fm_eth->num >= 2) + num -= 2; + else + num += 8; + } base = ®->memac[num].fm_memac; phyregs = ®->memac[num].fm_memac_mdio; #else diff --git a/drivers/net/fm/fm.h b/drivers/net/fm/fm.h index 3ec49a4..43de114 100644 --- a/drivers/net/fm/fm.h +++ b/drivers/net/fm/fm.h @@ -18,9 +18,11 @@ #define RX_PORT_1G_BASE 0x08 #define MAX_NUM_RX_PORT_1G CONFIG_SYS_NUM_FM1_DTSEC #define RX_PORT_10G_BASE 0x10 +#define RX_PORT_10G_BASE2 0x08 #define TX_PORT_1G_BASE 0x28 #define MAX_NUM_TX_PORT_1G CONFIG_SYS_NUM_FM1_DTSEC #define TX_PORT_10G_BASE 0x30 +#define TX_PORT_10G_BASE2 0x28 #define MIIM_TIMEOUT 0xFFFF struct fm_muram { diff --git a/drivers/net/fm/init.c b/drivers/net/fm/init.c index 35edd7a..cd787f4 100644 --- a/drivers/net/fm/init.c +++ b/drivers/net/fm/init.c @@ -64,6 +64,12 @@ struct fm_eth_info fm_info[] = { #if (CONFIG_SYS_NUM_FM1_10GEC >= 2) FM_TGEC_INFO_INITIALIZER(1, 2), #endif +#if (CONFIG_SYS_NUM_FM1_10GEC >= 3) + FM_TGEC_INFO_INITIALIZER2(1, 3), +#endif +#if (CONFIG_SYS_NUM_FM1_10GEC >= 4) + FM_TGEC_INFO_INITIALIZER2(1, 4), +#endif #if (CONFIG_SYS_NUM_FM2_10GEC >= 1) FM_TGEC_INFO_INITIALIZER(2, 1), #endif @@ -239,10 +245,14 @@ static void ft_fixup_port(void *blob, struct fm_eth_info *info, char *prop) * FM1_10GEC1 is enabled and FM1_DTSEC9 is disabled, ensure that the * dual-role MAC is not disabled, ditto for other dual-role MACs. */ - if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1))) || - ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2))) || - ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9))) || - ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) + if (((info->port == FM1_DTSEC9) && (PORT_IS_ENABLED(FM1_10GEC1))) || + ((info->port == FM1_DTSEC10) && (PORT_IS_ENABLED(FM1_10GEC2))) || + ((info->port == FM1_DTSEC1) && (PORT_IS_ENABLED(FM1_10GEC3))) || + ((info->port == FM1_DTSEC2) && (PORT_IS_ENABLED(FM1_10GEC4))) || + ((info->port == FM1_10GEC1) && (PORT_IS_ENABLED(FM1_DTSEC9))) || + ((info->port == FM1_10GEC2) && (PORT_IS_ENABLED(FM1_DTSEC10))) || + ((info->port == FM1_10GEC3) && (PORT_IS_ENABLED(FM1_DTSEC1))) || + ((info->port == FM1_10GEC4) && (PORT_IS_ENABLED(FM1_DTSEC2))) #if (CONFIG_SYS_NUM_FMAN == 2) || ((info->port == FM2_DTSEC9) && (PORT_IS_ENABLED(FM2_10GEC1))) || diff --git a/drivers/net/fm/t2080.c b/drivers/net/fm/t2080.c new file mode 100644 index 0000000..b5c1e9f --- /dev/null +++ b/drivers/net/fm/t2080.c @@ -0,0 +1,91 @@ +/* + * Copyright 2012 Freescale Semiconductor, Inc. + * + * Shengzhou Liu <Shengzhou.Liu@freescale.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <phy.h> +#include <fm_eth.h> +#include <asm/immap_85xx.h> +#include <asm/fsl_serdes.h> + +u32 port_to_devdisr[] = { + [FM1_DTSEC1] = FSL_CORENET_DEVDISR2_DTSEC1_1, + [FM1_DTSEC2] = FSL_CORENET_DEVDISR2_DTSEC1_2, + [FM1_DTSEC3] = FSL_CORENET_DEVDISR2_DTSEC1_3, + [FM1_DTSEC4] = FSL_CORENET_DEVDISR2_DTSEC1_4, + [FM1_DTSEC5] = FSL_CORENET_DEVDISR2_DTSEC1_5, + [FM1_DTSEC6] = FSL_CORENET_DEVDISR2_DTSEC1_6, + [FM1_DTSEC9] = FSL_CORENET_DEVDISR2_DTSEC1_9, + [FM1_DTSEC10] = FSL_CORENET_DEVDISR2_DTSEC1_10, + [FM1_10GEC1] = FSL_CORENET_DEVDISR2_10GEC1_1, + [FM1_10GEC2] = FSL_CORENET_DEVDISR2_10GEC1_2, + [FM1_10GEC3] = FSL_CORENET_DEVDISR2_10GEC1_3, + [FM1_10GEC4] = FSL_CORENET_DEVDISR2_10GEC1_4, +}; + +static int is_device_disabled(enum fm_port port) +{ + ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 devdisr2 = in_be32(&gur->devdisr2); + + return port_to_devdisr[port] & devdisr2; +} + +void fman_disable_port(enum fm_port port) +{ + ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + + setbits_be32(&gur->devdisr2, port_to_devdisr[port]); +} + +phy_interface_t fman_port_enet_if(enum fm_port port) +{ + ccsr_gur_t *gur = (void __iomem *)(CONFIG_SYS_MPC85xx_GUTS_ADDR); + u32 rcwsr13 = in_be32(&gur->rcwsr[13]); + + if (is_device_disabled(port)) + return PHY_INTERFACE_MODE_NONE; + + if ((port == FM1_10GEC1 || port == FM1_10GEC2 || + port == FM1_10GEC3 || port == FM1_10GEC4) && + ((is_serdes_configured(XAUI_FM1_MAC9)) || + (is_serdes_configured(XFI_FM1_MAC1)) || + (is_serdes_configured(XFI_FM1_MAC2)) || + (is_serdes_configured(XFI_FM1_MAC9)) || + (is_serdes_configured(XFI_FM1_MAC10)))) + return PHY_INTERFACE_MODE_XGMII; + + if ((port == FM1_DTSEC3) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC1) == + FSL_CORENET_RCWSR13_EC1_DTSEC3_RGMII)) + return PHY_INTERFACE_MODE_RGMII; + + if ((port == FM1_DTSEC4) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == + FSL_CORENET_RCWSR13_EC2_DTSEC4_RGMII)) + return PHY_INTERFACE_MODE_RGMII; + + if ((port == FM1_DTSEC10) && ((rcwsr13 & FSL_CORENET_RCWSR13_EC2) == + FSL_CORENET_RCWSR13_EC2_DTSEC10_RGMII)) + return PHY_INTERFACE_MODE_RGMII; + + switch (port) { + case FM1_DTSEC1: + case FM1_DTSEC2: + case FM1_DTSEC3: + case FM1_DTSEC4: + case FM1_DTSEC5: + case FM1_DTSEC6: + case FM1_DTSEC9: + case FM1_DTSEC10: + if (is_serdes_configured(SGMII_FM1_DTSEC1 + port - FM1_DTSEC1)) + return PHY_INTERFACE_MODE_SGMII; + break; + default: + return PHY_INTERFACE_MODE_NONE; + } + + return PHY_INTERFACE_MODE_NONE; +} diff --git a/drivers/net/fsl_mdio.c b/drivers/net/fsl_mdio.c index ce36bd7..1d88e65 100644 --- a/drivers/net/fsl_mdio.c +++ b/drivers/net/fsl_mdio.c @@ -1,5 +1,5 @@ /* - * Copyright 2009-2010 Freescale Semiconductor, Inc. + * Copyright 2009-2010, 2013 Freescale Semiconductor, Inc. * Jun-jie Zhang <b18070@freescale.com> * Mingkai Hu <Mingkai.hu@freescale.com> * @@ -13,7 +13,7 @@ #include <asm/errno.h> #include <asm/fsl_enet.h> -void tsec_local_mdio_write(struct tsec_mii_mng *phyregs, int port_addr, +void tsec_local_mdio_write(struct tsec_mii_mng __iomem *phyregs, int port_addr, int dev_addr, int regnum, int value) { int timeout = 1000000; @@ -26,7 +26,7 @@ void tsec_local_mdio_write(struct tsec_mii_mng *phyregs, int port_addr, ; } -int tsec_local_mdio_read(struct tsec_mii_mng *phyregs, int port_addr, +int tsec_local_mdio_read(struct tsec_mii_mng __iomem *phyregs, int port_addr, int dev_addr, int regnum) { int value; @@ -57,7 +57,8 @@ int tsec_local_mdio_read(struct tsec_mii_mng *phyregs, int port_addr, static int fsl_pq_mdio_reset(struct mii_dev *bus) { - struct tsec_mii_mng *regs = bus->priv; + struct tsec_mii_mng __iomem *regs = + (struct tsec_mii_mng __iomem *)bus->priv; /* Reset MII (due to new addresses) */ out_be32(®s->miimcfg, MIIMCFG_RESET_MGMT); @@ -72,7 +73,8 @@ static int fsl_pq_mdio_reset(struct mii_dev *bus) int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum) { - struct tsec_mii_mng *phyregs = bus->priv; + struct tsec_mii_mng __iomem *phyregs = + (struct tsec_mii_mng __iomem *)bus->priv; return tsec_local_mdio_read(phyregs, addr, dev_addr, regnum); } @@ -80,7 +82,8 @@ int tsec_phy_read(struct mii_dev *bus, int addr, int dev_addr, int regnum) int tsec_phy_write(struct mii_dev *bus, int addr, int dev_addr, int regnum, u16 value) { - struct tsec_mii_mng *phyregs = bus->priv; + struct tsec_mii_mng __iomem *phyregs = + (struct tsec_mii_mng __iomem *)bus->priv; tsec_local_mdio_write(phyregs, addr, dev_addr, regnum, value); @@ -101,7 +104,7 @@ int fsl_pq_mdio_init(bd_t *bis, struct fsl_pq_mdio_info *info) bus->reset = fsl_pq_mdio_reset; sprintf(bus->name, info->name); - bus->priv = info->regs; + bus->priv = (void *)info->regs; return mdio_register(bus); } diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c index 6c901d1..0cd06b6 100644 --- a/drivers/net/mvgbe.c +++ b/drivers/net/mvgbe.c @@ -420,8 +420,9 @@ static int mvgbe_init(struct eth_device *dev) { struct mvgbe_device *dmvgbe = to_mvgbe(dev); struct mvgbe_registers *regs = dmvgbe->regs; -#if (defined (CONFIG_MII) || defined (CONFIG_CMD_MII)) \ - && defined (CONFIG_SYS_FAULT_ECHO_LINK_DOWN) +#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) && \ + !defined(CONFIG_PHYLIB) && \ + defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN) int i; #endif /* setup RX rings */ diff --git a/drivers/net/npe/Makefile b/drivers/net/npe/Makefile index 7fa5ea6..0779255 100644 --- a/drivers/net/npe/Makefile +++ b/drivers/net/npe/Makefile @@ -8,9 +8,8 @@ LOCAL_CFLAGS += -I$(TOPDIR)/drivers/net/npe/include -DCONFIG_IXP425_COMPONENT_ETHDB -D__linux CFLAGS += $(LOCAL_CFLAGS) CPPFLAGS += $(LOCAL_CFLAGS) # needed for depend -HOSTCFLAGS += $(LOCAL_CFLAGS) -obj-$(CONFIG_IXP4XX_NPE) := npe.o \ +obj-y := npe.o \ miiphy.o \ IxOsalBufferMgt.o \ IxOsalIoMem.o \ diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c index 283cb48..71a3110 100644 --- a/drivers/net/pcnet.c +++ b/drivers/net/pcnet.c @@ -89,39 +89,39 @@ static pcnet_priv_t *lp; #define PCNET_RESET 0x14 #define PCNET_BDP 0x16 -static u16 pcnet_read_csr (struct eth_device *dev, int index) +static u16 pcnet_read_csr(struct eth_device *dev, int index) { - outw (index, dev->iobase + PCNET_RAP); - return inw (dev->iobase + PCNET_RDP); + outw(index, dev->iobase + PCNET_RAP); + return inw(dev->iobase + PCNET_RDP); } -static void pcnet_write_csr (struct eth_device *dev, int index, u16 val) +static void pcnet_write_csr(struct eth_device *dev, int index, u16 val) { - outw (index, dev->iobase + PCNET_RAP); - outw (val, dev->iobase + PCNET_RDP); + outw(index, dev->iobase + PCNET_RAP); + outw(val, dev->iobase + PCNET_RDP); } -static u16 pcnet_read_bcr (struct eth_device *dev, int index) +static u16 pcnet_read_bcr(struct eth_device *dev, int index) { - outw (index, dev->iobase + PCNET_RAP); - return inw (dev->iobase + PCNET_BDP); + outw(index, dev->iobase + PCNET_RAP); + return inw(dev->iobase + PCNET_BDP); } -static void pcnet_write_bcr (struct eth_device *dev, int index, u16 val) +static void pcnet_write_bcr(struct eth_device *dev, int index, u16 val) { - outw (index, dev->iobase + PCNET_RAP); - outw (val, dev->iobase + PCNET_BDP); + outw(index, dev->iobase + PCNET_RAP); + outw(val, dev->iobase + PCNET_BDP); } -static void pcnet_reset (struct eth_device *dev) +static void pcnet_reset(struct eth_device *dev) { - inw (dev->iobase + PCNET_RESET); + inw(dev->iobase + PCNET_RESET); } -static int pcnet_check (struct eth_device *dev) +static int pcnet_check(struct eth_device *dev) { - outw (88, dev->iobase + PCNET_RAP); - return (inw (dev->iobase + PCNET_RAP) == 88); + outw(88, dev->iobase + PCNET_RAP); + return inw(dev->iobase + PCNET_RAP) == 88; } static int pcnet_init (struct eth_device *dev, bd_t * bis); @@ -139,63 +139,64 @@ static struct pci_device_id supported[] = { }; -int pcnet_initialize (bd_t * bis) +int pcnet_initialize(bd_t *bis) { pci_dev_t devbusfn; struct eth_device *dev; u16 command, status; int dev_nr = 0; - PCNET_DEBUG1 ("\npcnet_initialize...\n"); + PCNET_DEBUG1("\npcnet_initialize...\n"); for (dev_nr = 0;; dev_nr++) { /* * Find the PCnet PCI device(s). */ - if ((devbusfn = pci_find_devices (supported, dev_nr)) < 0) { + devbusfn = pci_find_devices(supported, dev_nr); + if (devbusfn < 0) break; - } /* * Allocate and pre-fill the device structure. */ - dev = (struct eth_device *) malloc (sizeof *dev); + dev = (struct eth_device *)malloc(sizeof(*dev)); if (!dev) { printf("pcnet: Can not allocate memory\n"); break; } memset(dev, 0, sizeof(*dev)); - dev->priv = (void *) devbusfn; - sprintf (dev->name, "pcnet#%d", dev_nr); + dev->priv = (void *)devbusfn; + sprintf(dev->name, "pcnet#%d", dev_nr); /* * Setup the PCI device. */ - pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, - (unsigned int *) &dev->iobase); - dev->iobase=pci_io_to_phys (devbusfn, dev->iobase); + pci_read_config_dword(devbusfn, PCI_BASE_ADDRESS_0, + (unsigned int *)&dev->iobase); + dev->iobase = pci_io_to_phys(devbusfn, dev->iobase); dev->iobase &= ~0xf; - PCNET_DEBUG1 ("%s: devbusfn=0x%x iobase=0x%x: ", - dev->name, devbusfn, dev->iobase); + PCNET_DEBUG1("%s: devbusfn=0x%x iobase=0x%x: ", + dev->name, devbusfn, dev->iobase); command = PCI_COMMAND_IO | PCI_COMMAND_MASTER; - pci_write_config_word (devbusfn, PCI_COMMAND, command); - pci_read_config_word (devbusfn, PCI_COMMAND, &status); + pci_write_config_word(devbusfn, PCI_COMMAND, command); + pci_read_config_word(devbusfn, PCI_COMMAND, &status); if ((status & command) != command) { - printf ("%s: Couldn't enable IO access or Bus Mastering\n", dev->name); - free (dev); + printf("%s: Couldn't enable IO access or Bus Mastering\n", + dev->name); + free(dev); continue; } - pci_write_config_byte (devbusfn, PCI_LATENCY_TIMER, 0x40); + pci_write_config_byte(devbusfn, PCI_LATENCY_TIMER, 0x40); /* * Probe the PCnet chip. */ - if (pcnet_probe (dev, bis, dev_nr) < 0) { - free (dev); + if (pcnet_probe(dev, bis, dev_nr) < 0) { + free(dev); continue; } @@ -207,15 +208,15 @@ int pcnet_initialize (bd_t * bis) dev->send = pcnet_send; dev->recv = pcnet_recv; - eth_register (dev); + eth_register(dev); } - udelay (10 * 1000); + udelay(10 * 1000); return dev_nr; } -static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr) +static int pcnet_probe(struct eth_device *dev, bd_t *bis, int dev_nr) { int chip_version; char *chipname; @@ -225,17 +226,17 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr) #endif /* Reset the PCnet controller */ - pcnet_reset (dev); + pcnet_reset(dev); /* Check if register access is working */ - if (pcnet_read_csr (dev, 0) != 4 || !pcnet_check (dev)) { - printf ("%s: CSR register access check failed\n", dev->name); + if (pcnet_read_csr(dev, 0) != 4 || !pcnet_check(dev)) { + printf("%s: CSR register access check failed\n", dev->name); return -1; } /* Identify the chip */ chip_version = - pcnet_read_csr (dev, 88) | (pcnet_read_csr (dev, 89) << 16); + pcnet_read_csr(dev, 88) | (pcnet_read_csr(dev, 89) << 16); if ((chip_version & 0xfff) != 0x003) return -1; chip_version = (chip_version >> 12) & 0xffff; @@ -254,12 +255,12 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr) break; #endif default: - printf ("%s: PCnet version %#x not supported\n", - dev->name, chip_version); + printf("%s: PCnet version %#x not supported\n", + dev->name, chip_version); return -1; } - PCNET_DEBUG1 ("AMD %s\n", chipname); + PCNET_DEBUG1("AMD %s\n", chipname); #ifdef PCNET_HAS_PROM /* @@ -270,7 +271,7 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr) for (i = 0; i < 3; i++) { unsigned int val; - val = pcnet_read_csr (dev, i + 12) & 0x0ffff; + val = pcnet_read_csr(dev, i + 12) & 0x0ffff; /* There may be endianness issues here. */ dev->enetaddr[2 * i] = val & 0x0ff; dev->enetaddr[2 * i + 1] = (val >> 8) & 0x0ff; @@ -280,35 +281,40 @@ static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_nr) return 0; } -static int pcnet_init (struct eth_device *dev, bd_t * bis) +static int pcnet_init(struct eth_device *dev, bd_t *bis) { int i, val; u32 addr; - PCNET_DEBUG1 ("%s: pcnet_init...\n", dev->name); + PCNET_DEBUG1("%s: pcnet_init...\n", dev->name); /* Switch pcnet to 32bit mode */ - pcnet_write_bcr (dev, 20, 2); - -#ifdef CONFIG_PN62 - /* Setup LED registers */ - val = pcnet_read_bcr (dev, 2) | 0x1000; - pcnet_write_bcr (dev, 2, val); /* enable LEDPE */ - pcnet_write_bcr (dev, 4, 0x5080); /* 100MBit */ - pcnet_write_bcr (dev, 5, 0x40c0); /* LNKSE */ - pcnet_write_bcr (dev, 6, 0x4090); /* TX Activity */ - pcnet_write_bcr (dev, 7, 0x4084); /* RX Activity */ -#endif + pcnet_write_bcr(dev, 20, 2); /* Set/reset autoselect bit */ - val = pcnet_read_bcr (dev, 2) & ~2; + val = pcnet_read_bcr(dev, 2) & ~2; val |= 2; - pcnet_write_bcr (dev, 2, val); + pcnet_write_bcr(dev, 2, val); /* Enable auto negotiate, setup, disable fd */ - val = pcnet_read_bcr (dev, 32) & ~0x98; + val = pcnet_read_bcr(dev, 32) & ~0x98; val |= 0x20; - pcnet_write_bcr (dev, 32, val); + pcnet_write_bcr(dev, 32, val); + + /* + * Enable NOUFLO on supported controllers, with the transmit + * start point set to the full packet. This will cause entire + * packets to be buffered by the ethernet controller before + * transmission, eliminating underflows which are common on + * slower devices. Controllers which do not support NOUFLO will + * simply be left with a larger transmit FIFO threshold. + */ + val = pcnet_read_bcr(dev, 18); + val |= 1 << 11; + pcnet_write_bcr(dev, 18, val); + val = pcnet_read_csr(dev, 80); + val |= 0x3 << 10; + pcnet_write_csr(dev, 80, val); /* * We only maintain one structure because the drivers will never @@ -316,12 +322,12 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis) * must be aligned on 16-byte boundaries. */ if (lp == NULL) { - addr = (u32) malloc (sizeof (pcnet_priv_t) + 0x10); + addr = (u32)malloc(sizeof(pcnet_priv_t) + 0x10); addr = (addr + 0xf) & ~0xf; - lp = (pcnet_priv_t *) addr; + lp = (pcnet_priv_t *)addr; } - lp->init_block.mode = cpu_to_le16 (0x0000); + lp->init_block.mode = cpu_to_le16(0x0000); lp->init_block.filter[0] = 0x00000000; lp->init_block.filter[1] = 0x00000000; @@ -330,9 +336,9 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis) */ lp->cur_rx = 0; for (i = 0; i < RX_RING_SIZE; i++) { - lp->rx_ring[i].base = PCI_TO_MEM_LE (dev, lp->rx_buf[i]); - lp->rx_ring[i].buf_length = cpu_to_le16 (-PKT_BUF_SZ); - lp->rx_ring[i].status = cpu_to_le16 (0x8000); + lp->rx_ring[i].base = PCI_TO_MEM_LE(dev, lp->rx_buf[i]); + lp->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ); + lp->rx_ring[i].status = cpu_to_le16(0x8000); PCNET_DEBUG1 ("Rx%d: base=0x%x buf_length=0x%hx status=0x%hx\n", i, lp->rx_ring[i].base, lp->rx_ring[i].buf_length, @@ -352,48 +358,49 @@ static int pcnet_init (struct eth_device *dev, bd_t * bis) /* * Setup Init Block. */ - PCNET_DEBUG1 ("Init block at 0x%p: MAC", &lp->init_block); + PCNET_DEBUG1("Init block at 0x%p: MAC", &lp->init_block); for (i = 0; i < 6; i++) { lp->init_block.phys_addr[i] = dev->enetaddr[i]; - PCNET_DEBUG1 (" %02x", lp->init_block.phys_addr[i]); + PCNET_DEBUG1(" %02x", lp->init_block.phys_addr[i]); } - lp->init_block.tlen_rlen = cpu_to_le16 (TX_RING_LEN_BITS | - RX_RING_LEN_BITS); - lp->init_block.rx_ring = PCI_TO_MEM_LE (dev, lp->rx_ring); - lp->init_block.tx_ring = PCI_TO_MEM_LE (dev, lp->tx_ring); + lp->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS | + RX_RING_LEN_BITS); + lp->init_block.rx_ring = PCI_TO_MEM_LE(dev, lp->rx_ring); + lp->init_block.tx_ring = PCI_TO_MEM_LE(dev, lp->tx_ring); + flush_dcache_range((unsigned long)lp, (unsigned long)&lp->rx_buf); - PCNET_DEBUG1 ("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", - lp->init_block.tlen_rlen, - lp->init_block.rx_ring, lp->init_block.tx_ring); + PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n", + lp->init_block.tlen_rlen, + lp->init_block.rx_ring, lp->init_block.tx_ring); /* * Tell the controller where the Init Block is located. */ - addr = PCI_TO_MEM (dev, &lp->init_block); - pcnet_write_csr (dev, 1, addr & 0xffff); - pcnet_write_csr (dev, 2, (addr >> 16) & 0xffff); + addr = PCI_TO_MEM(dev, &lp->init_block); + pcnet_write_csr(dev, 1, addr & 0xffff); + pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff); - pcnet_write_csr (dev, 4, 0x0915); - pcnet_write_csr (dev, 0, 0x0001); /* start */ + pcnet_write_csr(dev, 4, 0x0915); + pcnet_write_csr(dev, 0, 0x0001); /* start */ /* Wait for Init Done bit */ for (i = 10000; i > 0; i--) { - if (pcnet_read_csr (dev, 0) & 0x0100) + if (pcnet_read_csr(dev, 0) & 0x0100) break; - udelay (10); + udelay(10); } if (i <= 0) { - printf ("%s: TIMEOUT: controller init failed\n", dev->name); - pcnet_reset (dev); + printf("%s: TIMEOUT: controller init failed\n", dev->name); + pcnet_reset(dev); return -1; } /* * Finally start network controller operation. */ - pcnet_write_csr (dev, 0, 0x0002); + pcnet_write_csr(dev, 0, 0x0002); return 0; } @@ -403,20 +410,25 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) int i, status; struct pcnet_tx_head *entry = &lp->tx_ring[lp->cur_tx]; - PCNET_DEBUG2 ("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, - packet); + PCNET_DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len, + packet); + + flush_dcache_range((unsigned long)packet, + (unsigned long)packet + pkt_len); /* Wait for completion by testing the OWN bit */ for (i = 1000; i > 0; i--) { - status = le16_to_cpu (entry->status); + invalidate_dcache_range((unsigned long)entry, + (unsigned long)entry + sizeof(*entry)); + status = le16_to_cpu(entry->status); if ((status & 0x8000) == 0) break; - udelay (100); - PCNET_DEBUG2 ("."); + udelay(100); + PCNET_DEBUG2("."); } if (i <= 0) { - printf ("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", - dev->name, lp->cur_tx, status); + printf("%s: TIMEOUT: Tx%d failed (status = 0x%x)\n", + dev->name, lp->cur_tx, status); pkt_len = 0; goto failure; } @@ -426,19 +438,21 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len) * set the status with the "ownership" bits last. */ status = 0x8300; - entry->length = le16_to_cpu (-pkt_len); + entry->length = cpu_to_le16(-pkt_len); entry->misc = 0x00000000; - entry->base = PCI_TO_MEM_LE (dev, packet); - entry->status = le16_to_cpu (status); + entry->base = PCI_TO_MEM_LE(dev, packet); + entry->status = cpu_to_le16(status); + flush_dcache_range((unsigned long)entry, + (unsigned long)entry + sizeof(*entry)); /* Trigger an immediate send poll. */ - pcnet_write_csr (dev, 0, 0x0008); + pcnet_write_csr(dev, 0, 0x0008); failure: if (++lp->cur_tx >= TX_RING_SIZE) lp->cur_tx = 0; - PCNET_DEBUG2 ("done\n"); + PCNET_DEBUG2("done\n"); return pkt_len; } @@ -450,43 +464,49 @@ static int pcnet_recv (struct eth_device *dev) while (1) { entry = &lp->rx_ring[lp->cur_rx]; + invalidate_dcache_range((unsigned long)entry, + (unsigned long)entry + sizeof(*entry)); /* * If we own the next entry, it's a new packet. Send it up. */ - if (((status = le16_to_cpu (entry->status)) & 0x8000) != 0) { + status = le16_to_cpu(entry->status); + if ((status & 0x8000) != 0) break; - } status >>= 8; if (status != 0x03) { /* There was an error. */ - - printf ("%s: Rx%d", dev->name, lp->cur_rx); - PCNET_DEBUG1 (" (status=0x%x)", status); + printf("%s: Rx%d", dev->name, lp->cur_rx); + PCNET_DEBUG1(" (status=0x%x)", status); if (status & 0x20) - printf (" Frame"); + printf(" Frame"); if (status & 0x10) - printf (" Overflow"); + printf(" Overflow"); if (status & 0x08) - printf (" CRC"); + printf(" CRC"); if (status & 0x04) - printf (" Fifo"); - printf (" Error\n"); - entry->status &= le16_to_cpu (0x03ff); + printf(" Fifo"); + printf(" Error\n"); + entry->status &= le16_to_cpu(0x03ff); } else { - - pkt_len = - (le32_to_cpu (entry->msg_length) & 0xfff) - 4; + pkt_len = (le32_to_cpu(entry->msg_length) & 0xfff) - 4; if (pkt_len < 60) { - printf ("%s: Rx%d: invalid packet length %d\n", dev->name, lp->cur_rx, pkt_len); + printf("%s: Rx%d: invalid packet length %d\n", + dev->name, lp->cur_rx, pkt_len); } else { - NetReceive (lp->rx_buf[lp->cur_rx], pkt_len); - PCNET_DEBUG2 ("Rx%d: %d bytes from 0x%p\n", - lp->cur_rx, pkt_len, - lp->rx_buf[lp->cur_rx]); + invalidate_dcache_range( + (unsigned long)lp->rx_buf[lp->cur_rx], + (unsigned long)lp->rx_buf[lp->cur_rx] + + pkt_len); + NetReceive(lp->rx_buf[lp->cur_rx], pkt_len); + PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n", + lp->cur_rx, pkt_len, + lp->rx_buf[lp->cur_rx]); } } - entry->status |= cpu_to_le16 (0x8000); + entry->status |= cpu_to_le16(0x8000); + flush_dcache_range((unsigned long)entry, + (unsigned long)entry + sizeof(*entry)); if (++lp->cur_rx >= RX_RING_SIZE) lp->cur_rx = 0; @@ -494,22 +514,21 @@ static int pcnet_recv (struct eth_device *dev) return pkt_len; } -static void pcnet_halt (struct eth_device *dev) +static void pcnet_halt(struct eth_device *dev) { int i; - PCNET_DEBUG1 ("%s: pcnet_halt...\n", dev->name); + PCNET_DEBUG1("%s: pcnet_halt...\n", dev->name); /* Reset the PCnet controller */ - pcnet_reset (dev); + pcnet_reset(dev); /* Wait for Stop bit */ for (i = 1000; i > 0; i--) { - if (pcnet_read_csr (dev, 0) & 0x4) + if (pcnet_read_csr(dev, 0) & 0x4) break; - udelay (10); - } - if (i <= 0) { - printf ("%s: TIMEOUT: controller reset failed\n", dev->name); + udelay(10); } + if (i <= 0) + printf("%s: TIMEOUT: controller reset failed\n", dev->name); } diff --git a/drivers/net/phy/atheros.c b/drivers/net/phy/atheros.c index 0f2dfd6..b20b4df 100644 --- a/drivers/net/phy/atheros.c +++ b/drivers/net/phy/atheros.c @@ -40,7 +40,7 @@ static int ar8035_config(struct phy_device *phydev) static struct phy_driver AR8021_driver = { .name = "AR8021", .uid = 0x4dd040, - .mask = 0xfffff0, + .mask = 0x4fffff, .features = PHY_GBIT_FEATURES, .config = ar8021_config, .startup = genphy_startup, @@ -48,11 +48,11 @@ static struct phy_driver AR8021_driver = { }; static struct phy_driver AR8031_driver = { - .name = "AR8031", + .name = "AR8031/AR8033", .uid = 0x4dd074, - .mask = 0xfffff0, + .mask = 0x4fffff, .features = PHY_GBIT_FEATURES, - .config = genphy_config, + .config = ar8021_config, .startup = genphy_startup, .shutdown = genphy_shutdown, }; diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index a7450f8..5d7e3be 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -100,6 +100,19 @@ int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum) return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR); } + +static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr, + int regnum) +{ + return ksz9021_phy_extended_read(phydev, regnum); +} + +static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr, + int devaddr, int regnum, u16 val) +{ + return ksz9021_phy_extended_write(phydev, regnum, val); +} + /* Micrel ksz9021 */ static int ksz9021_config(struct phy_device *phydev) { @@ -131,6 +144,8 @@ static struct phy_driver ksz9021_driver = { .config = &ksz9021_config, .startup = &ksz90xx_startup, .shutdown = &genphy_shutdown, + .writeext = &ksz9021_phy_extwrite, + .readext = &ksz9021_phy_extread, }; #endif @@ -171,14 +186,31 @@ int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr, return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9031_MMD_REG_DATA); } +static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr, + int regnum) +{ + return ksz9031_phy_extended_read(phydev, devaddr, regnum, + MII_KSZ9031_MOD_DATA_NO_POST_INC); +}; + +static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr, + int devaddr, int regnum, u16 val) +{ + return ksz9031_phy_extended_write(phydev, devaddr, regnum, + MII_KSZ9031_MOD_DATA_POST_INC_RW, val); +}; + + static struct phy_driver ksz9031_driver = { .name = "Micrel ksz9031", .uid = 0x221620, - .mask = 0xfffffe, + .mask = 0xfffff0, .features = PHY_GBIT_FEATURES, .config = &genphy_config, .startup = &ksz90xx_startup, .shutdown = &genphy_shutdown, + .writeext = &ksz9031_phy_extwrite, + .readext = &ksz9031_phy_extread, }; int phy_micrel_init(void) diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 62925bb..c691fbb 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -275,13 +275,14 @@ int genphy_parse_link(struct phy_device *phydev) int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR); /* We're using autonegotiation */ - if (mii_reg & BMSR_ANEGCAPABLE) { + if (phydev->supported & SUPPORTED_Autoneg) { u32 lpa = 0; int gblpa = 0; u32 estatus = 0; /* Check for gigabit capability */ - if (mii_reg & BMSR_ERCAP) { + if (phydev->supported & (SUPPORTED_1000baseT_Full | + SUPPORTED_1000baseT_Half)) { /* We want a list of states supported by * both PHYs in the link */ diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c index ddbbc35..a3ace68 100644 --- a/drivers/net/phy/realtek.c +++ b/drivers/net/phy/realtek.c @@ -102,7 +102,7 @@ static int rtl8211x_startup(struct phy_device *phydev) static struct phy_driver RTL8211B_driver = { .name = "RealTek RTL8211B", .uid = 0x1cc910, - .mask = 0xfffff0, + .mask = 0xffffff, .features = PHY_GBIT_FEATURES, .config = &rtl8211x_config, .startup = &rtl8211x_startup, @@ -113,7 +113,7 @@ static struct phy_driver RTL8211B_driver = { static struct phy_driver RTL8211E_driver = { .name = "RealTek RTL8211E", .uid = 0x1cc915, - .mask = 0xfffff0, + .mask = 0xffffff, .features = PHY_GBIT_FEATURES, .config = &rtl8211x_config, .startup = &rtl8211x_startup, @@ -124,7 +124,7 @@ static struct phy_driver RTL8211E_driver = { static struct phy_driver RTL8211DN_driver = { .name = "RealTek RTL8211DN", .uid = 0x1cc914, - .mask = 0xfffff0, + .mask = 0xffffff, .features = PHY_GBIT_FEATURES, .config = &rtl8211x_config, .startup = &rtl8211x_startup, diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c index 60ed92d..bfd9815 100644 --- a/drivers/net/phy/smsc.c +++ b/drivers/net/phy/smsc.c @@ -12,6 +12,7 @@ */ #include <miiphy.h> +/* This code does not check the partner abilities. */ static int smsc_parse_status(struct phy_device *phydev) { int mii_reg; @@ -64,7 +65,7 @@ static struct phy_driver lan8710_driver = { .mask = 0xffff0, .features = PHY_BASIC_FEATURES, .config = &genphy_config_aneg, - .startup = &smsc_startup, + .startup = &genphy_startup, .shutdown = &genphy_shutdown, }; diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c index 5cf103e..c555979 100644 --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -49,6 +49,15 @@ #define MIIM_VSC8574_18G_QSGMII 0x80e0 #define MIIM_VSC8574_18G_CMDSTAT 0x8000 +/* Vitesse VSC8514 control register */ +#define MIIM_VSC8514_GENERAL18 0x12 +#define MIIM_VSC8514_GENERAL19 0x13 +#define MIIM_VSC8514_GENERAL23 0x17 + +/* Vitesse VSC8514 gerenal purpose register 18 */ +#define MIIM_VSC8514_18G_QSGMII 0x80e0 +#define MIIM_VSC8514_18G_CMDSTAT 0x8000 + /* CIS8201 */ static int vitesse_config(struct phy_device *phydev) { @@ -148,7 +157,7 @@ static int vsc8601_config(struct phy_device *phydev) static int vsc8574_config(struct phy_device *phydev) { u32 val; - /* configure regiser 19G for MAC */ + /* configure register 19G for MAC */ phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, PHY_EXT_PAGE_ACCESS_GENERAL); @@ -188,6 +197,53 @@ static int vsc8574_config(struct phy_device *phydev) return 0; } +static int vsc8514_config(struct phy_device *phydev) +{ + u32 val; + int timeout = 1000000; + + /* configure register to access 19G */ + phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, + PHY_EXT_PAGE_ACCESS_GENERAL); + + val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL19); + if (phydev->interface == PHY_INTERFACE_MODE_QSGMII) { + /* set bit 15:14 to '01' for QSGMII mode */ + val = (val & 0x3fff) | (1 << 14); + phy_write(phydev, MDIO_DEVAD_NONE, + MIIM_VSC8514_GENERAL19, val); + /* Enable 4 ports MAC QSGMII */ + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18, + MIIM_VSC8514_18G_QSGMII); + } else { + /*TODO Add SGMII functionality once spec sheet + * for VSC8514 defines complete functionality + */ + } + + val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18); + /* When bit 15 is cleared the command has completed */ + while ((val & MIIM_VSC8514_18G_CMDSTAT) && timeout--) + val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL18); + + if (0 == timeout) { + printf("PHY 8514 config failed\n"); + return -1; + } + + phy_write(phydev, MDIO_DEVAD_NONE, PHY_EXT_PAGE_ACCESS, 0); + + /* configure register to access 23 */ + val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23); + /* set bits 10:8 to '000' */ + val = (val & 0xf8ff); + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_VSC8514_GENERAL23, val); + + genphy_config_aneg(phydev); + + return 0; +} + static struct phy_driver VSC8211_driver = { .name = "Vitesse VSC8211", .uid = 0xfc4b0, @@ -238,6 +294,16 @@ static struct phy_driver VSC8574_driver = { .shutdown = &genphy_shutdown, }; +static struct phy_driver VSC8514_driver = { + .name = "Vitesse VSC8514", + .uid = 0x70570, + .mask = 0xffff0, + .features = PHY_GBIT_FEATURES, + .config = &vsc8514_config, + .startup = &vitesse_startup, + .shutdown = &genphy_shutdown, +}; + static struct phy_driver VSC8601_driver = { .name = "Vitesse VSC8601", .uid = 0x70420, @@ -298,6 +364,7 @@ int phy_vitesse_init(void) phy_register(&VSC8211_driver); phy_register(&VSC8221_driver); phy_register(&VSC8574_driver); + phy_register(&VSC8514_driver); phy_register(&VSC8662_driver); phy_register(&cis8201_driver); phy_register(&cis8204_driver); diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c index 4186699..208ce5c 100644 --- a/drivers/net/rtl8139.c +++ b/drivers/net/rtl8139.c @@ -188,7 +188,7 @@ static int rtl_transmit(struct eth_device *dev, void *packet, int length); static int rtl_poll(struct eth_device *dev); static void rtl_disable(struct eth_device *dev); #ifdef CONFIG_MCAST_TFTP/* This driver already accepts all b/mcast */ -static int rtl_bcast_addr (struct eth_device *dev, u8 bcast_mac, u8 set) +static int rtl_bcast_addr(struct eth_device *dev, const u8 *bcast_mac, u8 set) { return (0); } diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c index 13fa9c0..d040ab1 100644 --- a/drivers/net/rtl8169.c +++ b/drivers/net/rtl8169.c @@ -246,6 +246,8 @@ static struct { {"RTL-8169sc/8110sc", 0x18, 0xff7e1880,}, {"RTL-8168b/8111sb", 0x30, 0xff7e1880,}, {"RTL-8168b/8111sb", 0x38, 0xff7e1880,}, + {"RTL-8168d/8111d", 0x28, 0xff7e1880,}, + {"RTL-8168evl/8111evl", 0x2e, 0xff7e1880,}, {"RTL-8101e", 0x34, 0xff7e1880,}, {"RTL-8100e", 0x32, 0xff7e1880,}, }; @@ -314,6 +316,7 @@ static const unsigned int rtl8169_rx_config = static struct pci_device_id supported[] = { {PCI_VENDOR_ID_REALTEK, 0x8167}, + {PCI_VENDOR_ID_REALTEK, 0x8168}, {PCI_VENDOR_ID_REALTEK, 0x8169}, {} }; @@ -394,6 +397,50 @@ match: return 0; } +/* + * Cache maintenance functions. These are simple wrappers around the more + * general purpose flush_cache() and invalidate_dcache_range() functions. + */ + +static void rtl_inval_rx_desc(struct RxDesc *desc) +{ + unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); + unsigned long end = ALIGN(start + sizeof(*desc), ARCH_DMA_MINALIGN); + + invalidate_dcache_range(start, end); +} + +static void rtl_flush_rx_desc(struct RxDesc *desc) +{ + flush_cache((unsigned long)desc, sizeof(*desc)); +} + +static void rtl_inval_tx_desc(struct TxDesc *desc) +{ + unsigned long start = (unsigned long)desc & ~(ARCH_DMA_MINALIGN - 1); + unsigned long end = ALIGN(start + sizeof(*desc), ARCH_DMA_MINALIGN); + + invalidate_dcache_range(start, end); +} + +static void rtl_flush_tx_desc(struct TxDesc *desc) +{ + flush_cache((unsigned long)desc, sizeof(*desc)); +} + +static void rtl_inval_buffer(void *buf, size_t size) +{ + unsigned long start = (unsigned long)buf & ~(ARCH_DMA_MINALIGN - 1); + unsigned long end = ALIGN(start + size, ARCH_DMA_MINALIGN); + + invalidate_dcache_range(start, end); +} + +static void rtl_flush_buffer(void *buf, size_t size) +{ + flush_cache((unsigned long)buf, size); +} + /************************************************************************** RECV - Receive a frame ***************************************************************************/ @@ -411,14 +458,16 @@ static int rtl_recv(struct eth_device *dev) ioaddr = dev->iobase; cur_rx = tpc->cur_rx; - flush_cache((unsigned long)&tpc->RxDescArray[cur_rx], - sizeof(struct RxDesc)); + + rtl_inval_rx_desc(&tpc->RxDescArray[cur_rx]); + if ((le32_to_cpu(tpc->RxDescArray[cur_rx].status) & OWNbit) == 0) { if (!(le32_to_cpu(tpc->RxDescArray[cur_rx].status) & RxRES)) { unsigned char rxdata[RX_BUF_LEN]; length = (int) (le32_to_cpu(tpc->RxDescArray[cur_rx]. status) & 0x00001FFF) - 4; + rtl_inval_buffer(tpc->RxBufferRing[cur_rx], length); memcpy(rxdata, tpc->RxBufferRing[cur_rx], length); NetReceive(rxdata, length); @@ -430,8 +479,7 @@ static int rtl_recv(struct eth_device *dev) cpu_to_le32(OWNbit + RX_BUF_SIZE); tpc->RxDescArray[cur_rx].buf_addr = cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx])); - flush_cache((unsigned long)tpc->RxBufferRing[cur_rx], - RX_BUF_SIZE); + rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]); } else { puts("Error Rx"); } @@ -473,7 +521,7 @@ static int rtl_send(struct eth_device *dev, void *packet, int length) /* point to the current txb incase multiple tx_rings are used */ ptxb = tpc->Tx_skbuff[entry * MAX_ETH_FRAME_SIZE]; memcpy(ptxb, (char *)packet, (int)length); - flush_cache((unsigned long)ptxb, length); + rtl_flush_buffer(ptxb, length); while (len < ETH_ZLEN) ptxb[len++] = '\0'; @@ -489,20 +537,20 @@ static int rtl_send(struct eth_device *dev, void *packet, int length) cpu_to_le32((OWNbit | EORbit | FSbit | LSbit) | ((len > ETH_ZLEN) ? len : ETH_ZLEN)); } + rtl_flush_tx_desc(&tpc->TxDescArray[entry]); RTL_W8(TxPoll, 0x40); /* set polling bit */ tpc->cur_tx++; to = currticks() + TX_TIMEOUT; do { - flush_cache((unsigned long)&tpc->TxDescArray[entry], - sizeof(struct TxDesc)); + rtl_inval_tx_desc(&tpc->TxDescArray[entry]); } while ((le32_to_cpu(tpc->TxDescArray[entry].status) & OWNbit) && (currticks() < to)); /* wait */ if (currticks() >= to) { #ifdef DEBUG_RTL8169_TX - puts ("tx timeout/error\n"); - printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); + puts("tx timeout/error\n"); + printf("%s elapsed time : %lu\n", __func__, currticks()-stime); #endif ret = 0; } else { @@ -604,7 +652,7 @@ static void rtl8169_hw_start(struct eth_device *dev) RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xF000); #ifdef DEBUG_RTL8169 - printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); + printf("%s elapsed time : %lu\n", __func__, currticks()-stime); #endif } @@ -638,11 +686,11 @@ static void rtl8169_init_ring(struct eth_device *dev) tpc->RxBufferRing[i] = &rxb[i * RX_BUF_SIZE]; tpc->RxDescArray[i].buf_addr = cpu_to_le32(bus_to_phys(tpc->RxBufferRing[i])); - flush_cache((unsigned long)tpc->RxBufferRing[i], RX_BUF_SIZE); + rtl_flush_rx_desc(&tpc->RxDescArray[i]); } #ifdef DEBUG_RTL8169 - printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); + printf("%s elapsed time : %lu\n", __func__, currticks()-stime); #endif } @@ -683,7 +731,7 @@ static int rtl_reset(struct eth_device *dev, bd_t *bis) txb[5] = dev->enetaddr[5]; #ifdef DEBUG_RTL8169 - printf ("%s elapsed time : %d\n", __FUNCTION__, currticks()-stime); + printf("%s elapsed time : %lu\n", __func__, currticks()-stime); #endif return 0; } @@ -869,11 +917,25 @@ int rtl8169_initialize(bd_t *bis) int idx=0; while(1){ + unsigned int region; + u16 device; + /* Find RTL8169 */ if ((devno = pci_find_devices(supported, idx++)) < 0) break; - pci_read_config_dword(devno, PCI_BASE_ADDRESS_1, &iobase); + pci_read_config_word(devno, PCI_DEVICE_ID, &device); + switch (device) { + case 0x8168: + region = 2; + break; + + default: + region = 1; + break; + } + + pci_read_config_dword(devno, PCI_BASE_ADDRESS_0 + (region * 4), &iobase); iobase &= ~0xf; debug ("rtl8169: REALTEK RTL8169 @0x%x\n", iobase); diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c index d5a83e0..5e132f2 100644 --- a/drivers/net/sh_eth.c +++ b/drivers/net/sh_eth.c @@ -4,6 +4,7 @@ * Copyright (C) 2008, 2011 Renesas Solutions Corp. * Copyright (c) 2008, 2011 Nobuhiro Iwamatsu * Copyright (c) 2007 Carlos Munoz <carlos@kenati.com> + * Copyright (C) 2013 Renesas Electronics Corporation * * SPDX-License-Identifier: GPL-2.0+ */ @@ -25,13 +26,31 @@ #ifndef CONFIG_SH_ETHER_PHY_ADDR # error "Please define CONFIG_SH_ETHER_PHY_ADDR" #endif -#ifdef CONFIG_SH_ETHER_CACHE_WRITEBACK -#define flush_cache_wback(addr, len) \ - dcache_wback_range((u32)addr, (u32)(addr + len - 1)) + +#if defined(CONFIG_SH_ETHER_CACHE_WRITEBACK) && !defined(CONFIG_SYS_DCACHE_OFF) +#define flush_cache_wback(addr, len) \ + flush_dcache_range((u32)addr, (u32)(addr + len - 1)) #else #define flush_cache_wback(...) #endif +#if defined(CONFIG_SH_ETHER_CACHE_INVALIDATE) && defined(CONFIG_ARM) +#define invalidate_cache(addr, len) \ + { \ + u32 line_size = CONFIG_SH_ETHER_ALIGNE_SIZE; \ + u32 start, end; \ + \ + start = (u32)addr; \ + end = start + len; \ + start &= ~(line_size - 1); \ + end = ((end + line_size - 1) & ~(line_size - 1)); \ + \ + invalidate_dcache_range(start, end); \ + } +#else +#define invalidate_cache(...) +#endif + #define TIMEOUT_CNT 1000 int sh_eth_send(struct eth_device *dev, void *packet, int len) @@ -69,8 +88,11 @@ int sh_eth_send(struct eth_device *dev, void *packet, int len) /* Wait until packet is transmitted */ timeout = TIMEOUT_CNT; - while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--) + do { + invalidate_cache(port_info->tx_desc_cur, + sizeof(struct tx_desc_s)); udelay(100); + } while (port_info->tx_desc_cur->td0 & TD_TACT && timeout--); if (timeout < 0) { printf(SHETHER_NAME ": transmit timeout\n"); @@ -94,12 +116,14 @@ int sh_eth_recv(struct eth_device *dev) uchar *packet; /* Check if the rx descriptor is ready */ + invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s)); 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 = (uchar *) ADDR_TO_P2(port_info->rx_desc_cur->rd2); + invalidate_cache(packet, len); NetReceive(packet, len); } @@ -108,7 +132,6 @@ int sh_eth_recv(struct eth_device *dev) 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 >= @@ -237,15 +260,17 @@ static int sh_eth_rx_desc_init(struct sh_eth_dev *eth) * Allocate rx data buffers. They must be 32 bytes aligned and in * P2 area */ - port_info->rx_buf_malloc = malloc(NUM_RX_DESC * MAX_BUF_SIZE + 31); + port_info->rx_buf_malloc = malloc( + NUM_RX_DESC * MAX_BUF_SIZE + RX_BUF_ALIGNE_SIZE - 1); if (!port_info->rx_buf_malloc) { printf(SHETHER_NAME ": malloc failed\n"); ret = -ENOMEM; goto err_buf_malloc; } - tmp_addr = (u32)(((int)port_info->rx_buf_malloc + (32 - 1)) & - ~(32 - 1)); + tmp_addr = (u32)(((int)port_info->rx_buf_malloc + + (RX_BUF_ALIGNE_SIZE - 1)) & + ~(RX_BUF_ALIGNE_SIZE - 1)); port_info->rx_buf_base = (u8 *)ADDR_TO_P2(tmp_addr); /* Initialize all descriptors */ @@ -351,8 +376,9 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) struct phy_device *phy; /* Configure e-dmac registers */ - sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | EDMR_EL, - EDMR); + sh_eth_write(eth, (sh_eth_read(eth, EDMR) & ~EMDR_DESC_R) | + (EMDR_DESC | EDMR_EL), EDMR); + sh_eth_write(eth, 0, EESIPR); sh_eth_write(eth, 0, TRSCER); sh_eth_write(eth, 0, TFTR); @@ -384,6 +410,8 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) #if defined(CONFIG_CPU_SH7734) || defined(CONFIG_R8A7740) sh_eth_write(eth, CONFIG_SH_ETHER_SH7734_MII, RMII_MII); +#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) + sh_eth_write(eth, sh_eth_read(eth, RMIIMR) | 0x1, RMIIMR); #endif /* Configure phy */ ret = sh_eth_phy_config(eth); @@ -407,7 +435,8 @@ static int sh_eth_config(struct sh_eth_dev *eth, bd_t *bd) sh_eth_write(eth, GECMR_100B, GECMR); #elif defined(CONFIG_CPU_SH7757) || defined(CONFIG_CPU_SH7752) sh_eth_write(eth, 1, RTRATE); -#elif defined(CONFIG_CPU_SH7724) +#elif defined(CONFIG_CPU_SH7724) || defined(CONFIG_R8A7790) || \ + defined(CONFIG_R8A7791) val = ECMR_RTM; #endif } else if (phy->speed == 10) { diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h index 9ad800e..8aa7109 100644 --- a/drivers/net/sh_eth.h +++ b/drivers/net/sh_eth.h @@ -31,6 +31,11 @@ #define ADDR_TO_P2(addr) (addr) #endif /* defined(CONFIG_SH) */ +/* base padding size is 16 */ +#ifndef CONFIG_SH_ETHER_ALIGNE_SIZE +#define CONFIG_SH_ETHER_ALIGNE_SIZE 16 +#endif + /* Number of supported ports */ #define MAX_PORT_NUM 2 @@ -45,15 +50,16 @@ /* 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) +#define TX_DESC_PADDING (CONFIG_SH_ETHER_ALIGNE_SIZE - 12) +/* same as CONFIG_SH_ETHER_ALIGNE_SIZE */ +#define TX_DESC_SIZE (12 + TX_DESC_PADDING) /* Tx descriptor. We always use 3 bytes of padding */ struct tx_desc_s { volatile u32 td0; u32 td1; u32 td2; /* Buffer start */ - u32 padding; + u8 padding[TX_DESC_PADDING]; /* aligned cache line size */ }; /* There is no limitation in the number of rx descriptors */ @@ -61,15 +67,18 @@ struct tx_desc_s { /* 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_PADDING (CONFIG_SH_ETHER_ALIGNE_SIZE - 12) +/* same as CONFIG_SH_ETHER_ALIGNE_SIZE */ #define RX_DESC_SIZE (12 + RX_DESC_PADDING) +/* aligned cache line size */ +#define RX_BUF_ALIGNE_SIZE (CONFIG_SH_ETHER_ALIGNE_SIZE > 32 ? 64 : 32) /* 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; + u8 padding[TX_DESC_PADDING]; /* aligned cache line size */ }; struct sh_eth_info { @@ -157,6 +166,7 @@ enum { TLFRCR, CERCR, CEECR, + RMIIMR, /* R8A7790 */ MAFCR, RTRATE, CSMR, @@ -263,6 +273,7 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { [RMCR] = 0x0058, [TFUCR] = 0x0064, [RFOCR] = 0x0068, + [RMIIMR] = 0x006C, [FCFTR] = 0x0070, [RPADIR] = 0x0078, [TRIMD] = 0x007c, @@ -290,6 +301,9 @@ static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = { #elif defined(CONFIG_R8A7740) #define SH_ETH_TYPE_GETHER #define BASE_IO_ADDR 0xE9A00000 +#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) +#define SH_ETH_TYPE_ETHER +#define BASE_IO_ADDR 0xEE700200 #endif /* @@ -320,6 +334,14 @@ enum DMAC_M_BIT { #endif }; +#if CONFIG_SH_ETHER_ALIGNE_SIZE == 64 +# define EMDR_DESC EDMR_DL1 +#elif CONFIG_SH_ETHER_ALIGNE_SIZE == 32 +# define EMDR_DESC EDMR_DL0 +#elif CONFIG_SH_ETHER_ALIGNE_SIZE == 16 /* Default */ +# define EMDR_DESC 0 +#endif + /* RFLR */ #define RFLR_RFL_MIN 0x05EE /* Recv Frame length 1518 byte */ @@ -485,6 +507,8 @@ enum FELIC_MODE_BIT { ECMR_PRM = 0x00000001, #ifdef CONFIG_CPU_SH7724 ECMR_RTM = 0x00000010, +#elif defined(CONFIG_R8A7790) || defined(CONFIG_R8A7791) + ECMR_RTM = 0x00000004, #endif }; diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c index f5e314b..e9138f0 100644 --- a/drivers/net/tsec.c +++ b/drivers/net/tsec.c @@ -5,7 +5,7 @@ * terms of the GNU Public License, Version 2, incorporated * herein by reference. * - * Copyright 2004-2011 Freescale Semiconductor, Inc. + * Copyright 2004-2011, 2013 Freescale Semiconductor, Inc. * (C) Copyright 2003, Motorola, Inc. * author Andy Fleming * @@ -25,21 +25,13 @@ DECLARE_GLOBAL_DATA_PTR; #define TX_BUF_CNT 2 -static uint rxIdx; /* index of the current RX buffer */ -static uint txIdx; /* index of the current TX buffer */ - -typedef volatile struct rtxbd { - txbd8_t txbd[TX_BUF_CNT]; - rxbd8_t rxbd[PKTBUFSRX]; -} RTXBD; - -#define MAXCONTROLLERS (8) - -static struct tsec_private *privlist[MAXCONTROLLERS]; -static int num_tsecs = 0; +static uint rx_idx; /* index of the current RX buffer */ +static uint tx_idx; /* index of the current TX buffer */ #ifdef __GNUC__ -static RTXBD rtx __attribute__ ((aligned(8))); +static struct txbd8 __iomem txbd[TX_BUF_CNT] __aligned(8); +static struct rxbd8 __iomem rxbd[PKTBUFSRX] __aligned(8); + #else #error "rtx must be 64-bit aligned" #endif @@ -57,7 +49,7 @@ static struct tsec_info_struct tsec_info[] = { #endif #ifdef CONFIG_MPC85XX_FEC { - .regs = (tsec_t *)(TSEC_BASE_ADDR + 0x2000), + .regs = TSEC_GET_REGS(2, 0x2000), .devname = CONFIG_MPC85XX_FEC_NAME, .phyaddr = FEC_PHY_ADDR, .flags = FEC_FLAGS, @@ -113,32 +105,31 @@ static void tsec_configure_serdes(struct tsec_private *priv) * result. * 2) Use the 8 most significant bits as a hash into a 256-entry * table. The table is controlled through 8 32-bit registers: - * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is - * gaddr7. This means that the 3 most significant bits in the + * gaddr0-7. gaddr0's MSB is entry 0, and gaddr7's LSB is entry + * 255. This means that the 3 most significant bits in the * hash index which gaddr register to use, and the 5 other bits * indicate which bit (assuming an IBM numbering scheme, which - * for PowerPC (tm) is usually the case) in the tregister holds + * for PowerPC (tm) is usually the case) in the register holds * the entry. */ static int -tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) +tsec_mcast_addr(struct eth_device *dev, const u8 *mcast_mac, u8 set) { - struct tsec_private *priv = privlist[1]; - volatile tsec_t *regs = priv->regs; - volatile u32 *reg_array, value; - u8 result, whichbit, whichreg; - - result = (u8)((ether_crc(MAC_ADDR_LEN,mcast_mac) >> 24) & 0xff); - whichbit = result & 0x1f; /* the 5 LSB = which bit to set */ - whichreg = result >> 5; /* the 3 MSB = which reg to set it in */ - value = (1 << (31-whichbit)); - - reg_array = &(regs->hash.gaddr0); - - if (set) { - reg_array[whichreg] |= value; - } else { - reg_array[whichreg] &= ~value; - } + struct tsec_private *priv = (struct tsec_private *)dev->priv; + struct tsec __iomem *regs = priv->regs; + u32 result, value; + u8 whichbit, whichreg; + + result = ether_crc(MAC_ADDR_LEN, mcast_mac); + whichbit = (result >> 24) & 0x1f; /* the 5 LSB = which bit to set */ + whichreg = result >> 29; /* the 3 MSB = which reg to set it in */ + + value = 1 << (31-whichbit); + + if (set) + setbits_be32(®s->hash.gaddr0 + whichreg, value); + else + clrbits_be32(®s->hash.gaddr0 + whichreg, value); + return 0; } #endif /* Multicast TFTP ? */ @@ -147,7 +138,7 @@ tsec_mcast_addr (struct eth_device *dev, u8 mcast_mac, u8 set) * those we don't care about (unless zero is bad, in which case, * choose a more appropriate value) */ -static void init_registers(tsec_t *regs) +static void init_registers(struct tsec __iomem *regs) { /* Clear IEVENT */ out_be32(®s->ievent, IEVENT_INIT_CLEAR); @@ -175,7 +166,7 @@ static void init_registers(tsec_t *regs) out_be32(®s->rctrl, 0x00000000); /* Init RMON mib registers */ - memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t)); + memset((void *)®s->rmon, 0, sizeof(regs->rmon)); out_be32(®s->rmon.cam1, 0xffffffff); out_be32(®s->rmon.cam2, 0xffffffff); @@ -194,7 +185,7 @@ static void init_registers(tsec_t *regs) */ static void adjust_link(struct tsec_private *priv, struct phy_device *phydev) { - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; u32 ecntrl, maccfg2; if (!phydev->link) { @@ -248,7 +239,7 @@ static void adjust_link(struct tsec_private *priv, struct phy_device *phydev) void redundant_init(struct eth_device *dev) { struct tsec_private *priv = dev->priv; - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; uint t, count = 0; int fail = 1; static const u8 pkt[] = { @@ -281,23 +272,26 @@ void redundant_init(struct eth_device *dev) clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); do { + uint16_t status; tsec_send(dev, (void *)pkt, sizeof(pkt)); /* Wait for buffer to be received */ - for (t = 0; rtx.rxbd[rxIdx].status & RXBD_EMPTY; t++) { + for (t = 0; in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY; t++) { if (t >= 10 * TOUT_LOOP) { printf("%s: tsec: rx error\n", dev->name); break; } } - if (!memcmp(pkt, (void *)NetRxPackets[rxIdx], sizeof(pkt))) + if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt))) fail = 0; - rtx.rxbd[rxIdx].length = 0; - rtx.rxbd[rxIdx].status = - RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); - rxIdx = (rxIdx + 1) % PKTBUFSRX; + out_be16(&rxbd[rx_idx].length, 0); + status = RXBD_EMPTY; + if ((rx_idx + 1) == PKTBUFSRX) + status |= RXBD_WRAP; + out_be16(&rxbd[rx_idx].status, status); + rx_idx = (rx_idx + 1) % PKTBUFSRX; if (in_be32(®s->ievent) & IEVENT_BSY) { out_be32(®s->ievent, IEVENT_BSY); @@ -325,36 +319,39 @@ void redundant_init(struct eth_device *dev) */ static void startup_tsec(struct eth_device *dev) { - int i; struct tsec_private *priv = (struct tsec_private *)dev->priv; - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; + uint16_t status; + int i; /* reset the indices to zero */ - rxIdx = 0; - txIdx = 0; + rx_idx = 0; + tx_idx = 0; #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 uint svr; #endif /* Point to the buffer descriptors */ - out_be32(®s->tbase, (unsigned int)(&rtx.txbd[txIdx])); - out_be32(®s->rbase, (unsigned int)(&rtx.rxbd[rxIdx])); + out_be32(®s->tbase, (u32)&txbd[0]); + out_be32(®s->rbase, (u32)&rxbd[0]); /* Initialize the Rx Buffer descriptors */ for (i = 0; i < PKTBUFSRX; i++) { - rtx.rxbd[i].status = RXBD_EMPTY; - rtx.rxbd[i].length = 0; - rtx.rxbd[i].bufPtr = (uint) NetRxPackets[i]; + out_be16(&rxbd[i].status, RXBD_EMPTY); + out_be16(&rxbd[i].length, 0); + out_be32(&rxbd[i].bufptr, (u32)NetRxPackets[i]); } - rtx.rxbd[PKTBUFSRX - 1].status |= RXBD_WRAP; + status = in_be16(&rxbd[PKTBUFSRX - 1].status); + out_be16(&rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP); /* Initialize the TX Buffer Descriptors */ for (i = 0; i < TX_BUF_CNT; i++) { - rtx.txbd[i].status = 0; - rtx.txbd[i].length = 0; - rtx.txbd[i].bufPtr = 0; + out_be16(&txbd[i].status, 0); + out_be16(&txbd[i].length, 0); + out_be32(&txbd[i].bufptr, 0); } - rtx.txbd[TX_BUF_CNT - 1].status |= TXBD_WRAP; + status = in_be16(&txbd[TX_BUF_CNT - 1].status); + out_be16(&txbd[TX_BUF_CNT - 1].status, status | TXBD_WRAP); #ifdef CONFIG_SYS_FSL_ERRATUM_NMG_ETSEC129 svr = get_svr(); @@ -378,66 +375,67 @@ static void startup_tsec(struct eth_device *dev) */ static int tsec_send(struct eth_device *dev, void *packet, int length) { - int i; - int result = 0; struct tsec_private *priv = (struct tsec_private *)dev->priv; - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; + uint16_t status; + int result = 0; + int i; /* Find an empty buffer descriptor */ - for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { + for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) { if (i >= TOUT_LOOP) { debug("%s: tsec: tx buffers full\n", dev->name); return result; } } - rtx.txbd[txIdx].bufPtr = (uint) packet; - rtx.txbd[txIdx].length = length; - rtx.txbd[txIdx].status |= - (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT); + out_be32(&txbd[tx_idx].bufptr, (u32)packet); + out_be16(&txbd[tx_idx].length, length); + status = in_be16(&txbd[tx_idx].status); + out_be16(&txbd[tx_idx].status, status | + (TXBD_READY | TXBD_LAST | TXBD_CRC | TXBD_INTERRUPT)); /* Tell the DMA to go */ out_be32(®s->tstat, TSTAT_CLEAR_THALT); /* Wait for buffer to be transmitted */ - for (i = 0; rtx.txbd[txIdx].status & TXBD_READY; i++) { + for (i = 0; in_be16(&txbd[tx_idx].status) & TXBD_READY; i++) { if (i >= TOUT_LOOP) { debug("%s: tsec: tx error\n", dev->name); return result; } } - txIdx = (txIdx + 1) % TX_BUF_CNT; - result = rtx.txbd[txIdx].status & TXBD_STATS; + tx_idx = (tx_idx + 1) % TX_BUF_CNT; + result = in_be16(&txbd[tx_idx].status) & TXBD_STATS; return result; } static int tsec_recv(struct eth_device *dev) { - int length; struct tsec_private *priv = (struct tsec_private *)dev->priv; - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; - while (!(rtx.rxbd[rxIdx].status & RXBD_EMPTY)) { - - length = rtx.rxbd[rxIdx].length; + while (!(in_be16(&rxbd[rx_idx].status) & RXBD_EMPTY)) { + int length = in_be16(&rxbd[rx_idx].length); + uint16_t status = in_be16(&rxbd[rx_idx].status); /* Send the packet up if there were no errors */ - if (!(rtx.rxbd[rxIdx].status & RXBD_STATS)) { - NetReceive(NetRxPackets[rxIdx], length - 4); - } else { - printf("Got error %x\n", - (rtx.rxbd[rxIdx].status & RXBD_STATS)); - } + if (!(status & RXBD_STATS)) + NetReceive(NetRxPackets[rx_idx], length - 4); + else + printf("Got error %x\n", (status & RXBD_STATS)); - rtx.rxbd[rxIdx].length = 0; + out_be16(&rxbd[rx_idx].length, 0); + status = RXBD_EMPTY; /* Set the wrap bit if this is the last element in the list */ - rtx.rxbd[rxIdx].status = - RXBD_EMPTY | (((rxIdx + 1) == PKTBUFSRX) ? RXBD_WRAP : 0); + if ((rx_idx + 1) == PKTBUFSRX) + status |= RXBD_WRAP; + out_be16(&rxbd[rx_idx].status, status); - rxIdx = (rxIdx + 1) % PKTBUFSRX; + rx_idx = (rx_idx + 1) % PKTBUFSRX; } if (in_be32(®s->ievent) & IEVENT_BSY) { @@ -453,7 +451,7 @@ static int tsec_recv(struct eth_device *dev) static void tsec_halt(struct eth_device *dev) { struct tsec_private *priv = (struct tsec_private *)dev->priv; - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; clrbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); setbits_be32(®s->dmactrl, DMACTRL_GRS | DMACTRL_GTS); @@ -475,11 +473,9 @@ static void tsec_halt(struct eth_device *dev) */ static int tsec_init(struct eth_device *dev, bd_t * bd) { - uint tempval; - char tmpbuf[MAC_ADDR_LEN]; - int i; struct tsec_private *priv = (struct tsec_private *)dev->priv; - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; + u32 tempval; int ret; /* Make sure the controller is stopped */ @@ -492,16 +488,16 @@ static int tsec_init(struct eth_device *dev, bd_t * bd) out_be32(®s->ecntrl, ECNTRL_INIT_SETTINGS); /* Copy the station address into the address registers. - * Backwards, because little endian MACS are dumb */ - for (i = 0; i < MAC_ADDR_LEN; i++) - tmpbuf[MAC_ADDR_LEN - 1 - i] = dev->enetaddr[i]; - - tempval = (tmpbuf[0] << 24) | (tmpbuf[1] << 16) | (tmpbuf[2] << 8) | - tmpbuf[3]; + * For a station address of 0x12345678ABCD in transmission + * order (BE), MACnADDR1 is set to 0xCDAB7856 and + * MACnADDR2 is set to 0x34120000. + */ + tempval = (dev->enetaddr[5] << 24) | (dev->enetaddr[4] << 16) | + (dev->enetaddr[3] << 8) | dev->enetaddr[2]; out_be32(®s->macstnaddr1, tempval); - tempval = *((uint *) (tmpbuf + 4)); + tempval = (dev->enetaddr[1] << 24) | (dev->enetaddr[0] << 16); out_be32(®s->macstnaddr2, tempval); @@ -527,7 +523,7 @@ static int tsec_init(struct eth_device *dev, bd_t * bd) static phy_interface_t tsec_get_interface(struct tsec_private *priv) { - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; u32 ecntrl; ecntrl = in_be32(®s->ecntrl); @@ -576,7 +572,7 @@ static int init_phy(struct eth_device *dev) { struct tsec_private *priv = (struct tsec_private *)dev->priv; struct phy_device *phydev; - tsec_t *regs = priv->regs; + struct tsec __iomem *regs = priv->regs; u32 supported = (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | @@ -626,7 +622,6 @@ static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info) if (NULL == priv) return 0; - privlist[num_tsecs++] = priv; priv->regs = tsec_info->regs; priv->phyregs_sgmii = tsec_info->miiregs_sgmii; @@ -684,7 +679,7 @@ int tsec_standard_init(bd_t *bis) { struct fsl_pq_mdio_info info; - info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR; + info.regs = TSEC_GET_MDIO_REGS_BASE(1); info.name = DEFAULT_MII_NAME; fsl_pq_mdio_init(bis, &info); diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c index 236a753..6a017a8 100644 --- a/drivers/net/zynq_gem.c +++ b/drivers/net/zynq_gem.c @@ -43,11 +43,6 @@ #define ZYNQ_GEM_TXBUF_WRAP_MASK 0x40000000 #define ZYNQ_GEM_TXBUF_LAST_MASK 0x00008000 /* Last buffer */ -#define ZYNQ_GEM_TXSR_HRESPNOK_MASK 0x00000100 /* Transmit hresp not OK */ -#define ZYNQ_GEM_TXSR_URUN_MASK 0x00000040 /* Transmit underrun */ -/* Transmit buffs exhausted mid frame */ -#define ZYNQ_GEM_TXSR_BUFEXH_MASK 0x00000010 - #define ZYNQ_GEM_NWCTRL_TXEN_MASK 0x00000008 /* Enable transmit */ #define ZYNQ_GEM_NWCTRL_RXEN_MASK 0x00000004 /* Enable receive */ #define ZYNQ_GEM_NWCTRL_MDEN_MASK 0x00000010 /* Enable MDIO port */ @@ -90,6 +85,11 @@ */ #define PHY_DETECT_MASK 0x1808 +/* TX BD status masks */ +#define ZYNQ_GEM_TXBUF_FRMLEN_MASK 0x000007ff +#define ZYNQ_GEM_TXBUF_EXHAUSTED 0x08000000 +#define ZYNQ_GEM_TXBUF_UNDERRUN 0x10000000 + /* Device registers */ struct zynq_gem_regs { u32 nwctrl; /* Network Control reg */ @@ -123,12 +123,18 @@ struct emac_bd { }; #define RX_BUF 3 +/* Page table entries are set to 1MB, or multiples of 1MB + * (not < 1MB). driver uses less bd's so use 1MB bdspace. + */ +#define BD_SPACE 0x100000 +/* BD separation space */ +#define BD_SEPRN_SPACE 64 /* Initialized, rxbd_current, rx_first_buf must be 0 after init */ struct zynq_gem_priv { - struct emac_bd tx_bd; - struct emac_bd rx_bd[RX_BUF]; - char rxbuffers[RX_BUF * PKTSIZE_ALIGN]; + struct emac_bd *tx_bd; + struct emac_bd *rx_bd; + char *rxbuffers; u32 rxbd_current; u32 rx_first_buf; int phyaddr; @@ -299,20 +305,18 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis) readl(®s->stat[i]); /* Setup RxBD space */ - memset(&(priv->rx_bd), 0, sizeof(priv->rx_bd)); - /* Create the RxBD ring */ - memset(&(priv->rxbuffers), 0, sizeof(priv->rxbuffers)); + memset(priv->rx_bd, 0, RX_BUF * sizeof(struct emac_bd)); for (i = 0; i < RX_BUF; i++) { priv->rx_bd[i].status = 0xF0000000; priv->rx_bd[i].addr = - (u32)((char *)&(priv->rxbuffers) + + ((u32)(priv->rxbuffers) + (i * PKTSIZE_ALIGN)); } /* WRAP bit to last BD */ priv->rx_bd[--i].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK; /* Write RxBDs to IP */ - writel((u32)&(priv->rx_bd), ®s->rxqbase); + writel((u32)priv->rx_bd, ®s->rxqbase); /* Setup for DMA Configuration register */ writel(ZYNQ_GEM_DMACR_INIT, ®s->dmacr); @@ -368,32 +372,35 @@ static int zynq_gem_init(struct eth_device *dev, bd_t * bis) static int zynq_gem_send(struct eth_device *dev, void *ptr, int len) { - u32 status; + u32 addr, size; struct zynq_gem_priv *priv = dev->priv; struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase; - const u32 mask = ZYNQ_GEM_TXSR_HRESPNOK_MASK | \ - ZYNQ_GEM_TXSR_URUN_MASK | ZYNQ_GEM_TXSR_BUFEXH_MASK; /* setup BD */ - writel((u32)&(priv->tx_bd), ®s->txqbase); + writel((u32)priv->tx_bd, ®s->txqbase); /* Setup Tx BD */ - memset((void *)&(priv->tx_bd), 0, sizeof(struct emac_bd)); + memset(priv->tx_bd, 0, sizeof(struct emac_bd)); + + priv->tx_bd->addr = (u32)ptr; + priv->tx_bd->status = (len & ZYNQ_GEM_TXBUF_FRMLEN_MASK) | + ZYNQ_GEM_TXBUF_LAST_MASK; - priv->tx_bd.addr = (u32)ptr; - priv->tx_bd.status = len | ZYNQ_GEM_TXBUF_LAST_MASK; + addr = (u32) ptr; + addr &= ~(ARCH_DMA_MINALIGN - 1); + size = roundup(len, ARCH_DMA_MINALIGN); + flush_dcache_range(addr, addr + size); + barrier(); /* Start transmit */ setbits_le32(®s->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK); - /* Read the stat register to know if the packet has been transmitted */ - status = readl(®s->txsr); - if (status & mask) - printf("Something has gone wrong here!? Status is 0x%x.\n", - status); + /* Read TX BD status */ + if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_UNDERRUN) + printf("TX underrun\n"); + if (priv->tx_bd->status & ZYNQ_GEM_TXBUF_EXHAUSTED) + printf("TX buffers exhausted in mid frame\n"); - /* Clear Tx status register before leaving . */ - writel(status, ®s->txsr); return 0; } @@ -416,8 +423,12 @@ static int zynq_gem_recv(struct eth_device *dev) frame_len = current_bd->status & ZYNQ_GEM_RXBUF_LEN_MASK; if (frame_len) { - NetReceive((u8 *) (current_bd->addr & - ZYNQ_GEM_RXBUF_ADD_MASK), frame_len); + u32 addr = current_bd->addr & ZYNQ_GEM_RXBUF_ADD_MASK; + addr &= ~(ARCH_DMA_MINALIGN - 1); + u32 size = roundup(frame_len, ARCH_DMA_MINALIGN); + invalidate_dcache_range(addr, addr + size); + + NetReceive((u8 *)addr, frame_len); if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK) priv->rx_first_buf = priv->rxbd_current; @@ -471,6 +482,7 @@ int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio) { struct eth_device *dev; struct zynq_gem_priv *priv; + void *bd_space; dev = calloc(1, sizeof(*dev)); if (dev == NULL) @@ -483,6 +495,18 @@ int zynq_gem_initialize(bd_t *bis, int base_addr, int phy_addr, u32 emio) } priv = dev->priv; + /* Align rxbuffers to ARCH_DMA_MINALIGN */ + priv->rxbuffers = memalign(ARCH_DMA_MINALIGN, RX_BUF * PKTSIZE_ALIGN); + memset(priv->rxbuffers, 0, RX_BUF * PKTSIZE_ALIGN); + + /* Align bd_space to 1MB */ + bd_space = memalign(1 << MMU_SECTION_SHIFT, BD_SPACE); + mmu_set_region_dcache_behaviour((u32)bd_space, BD_SPACE, DCACHE_OFF); + + /* Initialize the bd spaces for tx and rx bd's */ + priv->tx_bd = (struct emac_bd *)bd_space; + priv->rx_bd = (struct emac_bd *)((u32)bd_space + BD_SEPRN_SPACE); + priv->phyaddr = phy_addr; priv->emio = emio; |