summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>2013-12-10 14:31:56 +0100
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2013-12-10 22:23:59 +0100
commitf15ea6e1d67782a1626d4a4922b6c20e380085e5 (patch)
tree57d78f1ee94a2060eaa591533278d2934d4f1da3 /drivers/net
parentcb7ee1b98cac6baf244daefb1192adf5a47bc983 (diff)
parentf44483b57c49282299da0e5c10073b909cdad979 (diff)
downloadu-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.c2
-rw-r--r--drivers/net/designware.h7
-rw-r--r--drivers/net/dm9000x.c9
-rw-r--r--drivers/net/e1000.c34
-rw-r--r--drivers/net/e1000.h9
-rw-r--r--drivers/net/fm/Makefile7
-rw-r--r--drivers/net/fm/eth.c12
-rw-r--r--drivers/net/fm/fm.h2
-rw-r--r--drivers/net/fm/init.c18
-rw-r--r--drivers/net/fm/t2080.c91
-rw-r--r--drivers/net/fsl_mdio.c17
-rw-r--r--drivers/net/mvgbe.c5
-rw-r--r--drivers/net/npe/Makefile3
-rw-r--r--drivers/net/pcnet.c277
-rw-r--r--drivers/net/phy/atheros.c8
-rw-r--r--drivers/net/phy/micrel.c34
-rw-r--r--drivers/net/phy/phy.c5
-rw-r--r--drivers/net/phy/realtek.c6
-rw-r--r--drivers/net/phy/smsc.c3
-rw-r--r--drivers/net/phy/vitesse.c69
-rw-r--r--drivers/net/rtl8139.c2
-rw-r--r--drivers/net/rtl8169.c90
-rw-r--r--drivers/net/sh_eth.c51
-rw-r--r--drivers/net/sh_eth.h34
-rw-r--r--drivers/net/tsec.c199
-rw-r--r--drivers/net/zynq_gem.c82
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 = &reg->memac[num].fm_memac;
phyregs = &reg->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(&regs->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(&regs->hash.gaddr0 + whichreg, value);
+ else
+ clrbits_be32(&regs->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(&regs->ievent, IEVENT_INIT_CLEAR);
@@ -175,7 +166,7 @@ static void init_registers(tsec_t *regs)
out_be32(&regs->rctrl, 0x00000000);
/* Init RMON mib registers */
- memset((void *)&(regs->rmon), 0, sizeof(rmon_mib_t));
+ memset((void *)&regs->rmon, 0, sizeof(regs->rmon));
out_be32(&regs->rmon.cam1, 0xffffffff);
out_be32(&regs->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(&regs->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(&regs->ievent) & IEVENT_BSY) {
out_be32(&regs->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(&regs->tbase, (unsigned int)(&rtx.txbd[txIdx]));
- out_be32(&regs->rbase, (unsigned int)(&rtx.rxbd[rxIdx]));
+ out_be32(&regs->tbase, (u32)&txbd[0]);
+ out_be32(&regs->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(&regs->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(&regs->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(&regs->dmactrl, DMACTRL_GRS | DMACTRL_GTS);
setbits_be32(&regs->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(&regs->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(&regs->macstnaddr1, tempval);
- tempval = *((uint *) (tmpbuf + 4));
+ tempval = (dev->enetaddr[1] << 24) | (dev->enetaddr[0] << 16);
out_be32(&regs->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(&regs->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(&regs->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), &regs->rxqbase);
+ writel((u32)priv->rx_bd, &regs->rxqbase);
/* Setup for DMA Configuration register */
writel(ZYNQ_GEM_DMACR_INIT, &regs->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), &regs->txqbase);
+ writel((u32)priv->tx_bd, &regs->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(&regs->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK);
- /* Read the stat register to know if the packet has been transmitted */
- status = readl(&regs->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, &regs->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;