summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig16
-rw-r--r--drivers/net/altera_tse.c2
-rw-r--r--drivers/net/at91_emac.c2
-rw-r--r--drivers/net/ax88180.c2
-rw-r--r--drivers/net/cpsw.c2
-rw-r--r--drivers/net/davinci_emac.c2
-rw-r--r--drivers/net/designware.c2
-rw-r--r--drivers/net/dm9000x.c2
-rw-r--r--drivers/net/e1000.c77
-rw-r--r--drivers/net/e1000.h31
-rw-r--r--drivers/net/e1000_spi.c9
-rw-r--r--drivers/net/eepro100.c8
-rw-r--r--drivers/net/fm/fm.c3
-rw-r--r--drivers/net/fm/memac_phy.c2
-rw-r--r--drivers/net/fm/tgec_phy.c2
-rw-r--r--drivers/net/fsl-mc/dpio/qbman_portal.c4
-rw-r--r--drivers/net/fsl-mc/dpni.c81
-rw-r--r--drivers/net/fsl-mc/mc.c68
-rw-r--r--drivers/net/fsl_mdio.c2
-rw-r--r--drivers/net/ftgmac100.c2
-rw-r--r--drivers/net/ftmac100.c2
-rw-r--r--drivers/net/greth.c4
-rw-r--r--drivers/net/keystone_net.c2
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.c126
-rw-r--r--drivers/net/ldpaa_eth/ldpaa_eth.h2
-rw-r--r--drivers/net/lpc32xx_eth.c16
-rw-r--r--drivers/net/mpc512x_fec.c2
-rw-r--r--drivers/net/mpc5xxx_fec.c2
-rw-r--r--drivers/net/mvgbe.c2
-rw-r--r--drivers/net/mvneta.c230
-rw-r--r--drivers/net/ne2000_base.c2
-rw-r--r--drivers/net/pch_gbe.c2
-rw-r--r--drivers/net/pcnet.c28
-rw-r--r--drivers/net/phy/cortina.c3
-rw-r--r--drivers/net/phy/ti.c3
-rw-r--r--drivers/net/sh_eth.c2
-rw-r--r--drivers/net/tsec.c2
-rw-r--r--drivers/net/xilinx_axi_emac.c280
-rw-r--r--drivers/net/xilinx_emaclite.c610
-rw-r--r--drivers/net/xilinx_ll_temac.c3
-rw-r--r--drivers/net/zynq_gem.c39
41 files changed, 1094 insertions, 587 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index de54ca8014..218e1fee22 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -102,6 +102,22 @@ config PCH_GBE
This MAC is present in Intel Platform Controller Hub EG20T. It
supports 10/100/1000 Mbps operation.
+config XILINX_AXIEMAC
+ depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
+ select PHYLIB
+ select MII
+ bool "Xilinx AXI Ethernet"
+ help
+ This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
+
+config XILINX_EMACLITE
+ depends on DM_ETH && (MICROBLAZE || ARCH_ZYNQ || ARCH_ZYNQMP)
+ select PHYLIB
+ select MII
+ bool "Xilinx Ethernetlite"
+ help
+ This MAC is present in Xilinx Microblaze, Zynq and ZynqMP SoCs.
+
config ZYNQ_GEM
depends on DM_ETH && (ARCH_ZYNQ || ARCH_ZYNQMP)
select PHYLIB
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index 3eaa270677..92a1b64495 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -417,7 +417,7 @@ static int tse_mdio_init(const char *name, struct altera_tse_priv *priv)
bus->read = tse_mdio_read;
bus->write = tse_mdio_write;
- snprintf(bus->name, sizeof(bus->name), name);
+ snprintf(bus->name, sizeof(bus->name), "%s", name);
bus->priv = (void *)priv;
diff --git a/drivers/net/at91_emac.c b/drivers/net/at91_emac.c
index d51e098c56..26595929c5 100644
--- a/drivers/net/at91_emac.c
+++ b/drivers/net/at91_emac.c
@@ -490,7 +490,7 @@ int at91emac_register(bd_t *bis, unsigned long iobase)
memset(emacfix, 0, sizeof(emac_device));
memset(dev, 0, sizeof(*dev));
- sprintf(dev->name, "emac");
+ strcpy(dev->name, "emac");
dev->iobase = iobase;
dev->priv = emacfix;
dev->init = at91emac_init;
diff --git a/drivers/net/ax88180.c b/drivers/net/ax88180.c
index ded9e064e5..43a67a514b 100644
--- a/drivers/net/ax88180.c
+++ b/drivers/net/ax88180.c
@@ -722,7 +722,7 @@ int ax88180_initialize (bd_t * bis)
memset (priv, 0, sizeof *priv);
- sprintf (dev->name, "ax88180");
+ strcpy(dev->name, "ax88180");
dev->iobase = AX88180_BASE;
dev->priv = priv;
dev->init = ax88180_init;
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 3dff9df377..7104754463 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -567,7 +567,7 @@ static void cpsw_mdio_init(const char *name, u32 mdio_base, u32 div)
bus->read = cpsw_mdio_read;
bus->write = cpsw_mdio_write;
- sprintf(bus->name, name);
+ strcpy(bus->name, name);
mdio_register(bus);
}
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 04447953c9..92c3dcae3c 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -777,7 +777,7 @@ int davinci_emac_initialize(void)
return -1;
memset(dev, 0, sizeof *dev);
- sprintf(dev->name, "DaVinci-EMAC");
+ strcpy(dev->name, "DaVinci-EMAC");
dev->iobase = 0;
dev->init = davinci_eth_open;
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index f1bcc92a81..77b98c94c0 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -81,7 +81,7 @@ static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p)
bus->read = dw_mdio_read;
bus->write = dw_mdio_write;
- snprintf(bus->name, sizeof(bus->name), name);
+ snprintf(bus->name, sizeof(bus->name), "%s", name);
bus->priv = (void *)mac_regs_p;
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
index 3c41cec3e4..93c6667bca 100644
--- a/drivers/net/dm9000x.c
+++ b/drivers/net/dm9000x.c
@@ -630,7 +630,7 @@ int dm9000_initialize(bd_t *bis)
dev->halt = dm9000_halt;
dev->send = dm9000_send;
dev->recv = dm9000_rx;
- sprintf(dev->name, "dm9000");
+ strcpy(dev->name, "dm9000");
eth_register(dev);
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index 027f2bfd11..70fc02ee5c 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -551,43 +551,6 @@ static int32_t e1000_init_eeprom_params(struct e1000_hw *hw)
eeprom->use_eerd = true;
eeprom->use_eewr = false;
break;
-
- /* ich8lan does not support currently. if needed, please
- * add corresponding code and functions.
- */
-#if 0
- case e1000_ich8lan:
- {
- int32_t i = 0;
-
- eeprom->type = e1000_eeprom_ich8;
- eeprom->use_eerd = false;
- eeprom->use_eewr = false;
- eeprom->word_size = E1000_SHADOW_RAM_WORDS;
- uint32_t flash_size = E1000_READ_ICH_FLASH_REG(hw,
- ICH_FLASH_GFPREG);
- /* Zero the shadow RAM structure. But don't load it from NVM
- * so as to save time for driver init */
- if (hw->eeprom_shadow_ram != NULL) {
- for (i = 0; i < E1000_SHADOW_RAM_WORDS; i++) {
- hw->eeprom_shadow_ram[i].modified = false;
- hw->eeprom_shadow_ram[i].eeprom_word = 0xFFFF;
- }
- }
-
- hw->flash_base_addr = (flash_size & ICH_GFPREG_BASE_MASK) *
- ICH_FLASH_SECTOR_SIZE;
-
- hw->flash_bank_size = ((flash_size >> 16)
- & ICH_GFPREG_BASE_MASK) + 1;
- hw->flash_bank_size -= (flash_size & ICH_GFPREG_BASE_MASK);
-
- hw->flash_bank_size *= ICH_FLASH_SECTOR_SIZE;
-
- hw->flash_bank_size /= 2 * sizeof(uint16_t);
- break;
- }
-#endif
default:
break;
}
@@ -838,14 +801,6 @@ e1000_read_eeprom(struct e1000_hw *hw, uint16_t offset,
if (eeprom->use_eerd == true)
return e1000_read_eeprom_eerd(hw, offset, words, data);
- /* ich8lan does not support currently. if needed, please
- * add corresponding code and functions.
- */
-#if 0
- /* ICH EEPROM access is done via the ICH flash controller */
- if (eeprom->type == e1000_eeprom_ich8)
- return e1000_read_eeprom_ich8(hw, offset, words, data);
-#endif
/* Set up the SPI or Microwire EEPROM for bit-bang reading. We have
* acquired the EEPROM at this point, so any returns should relase it */
if (eeprom->type == e1000_eeprom_spi) {
@@ -1732,17 +1687,7 @@ e1000_init_hw(struct e1000_hw *hw, unsigned char enetaddr[6])
* occuring when accessing our register space */
E1000_WRITE_FLUSH(hw);
}
-#if 0
- /* Set the PCI priority bit correctly in the CTRL register. This
- * determines if the adapter gives priority to receives, or if it
- * gives equal priority to transmits and receives. Valid only on
- * 82542 and 82543 silicon.
- */
- if (hw->dma_fairness && hw->mac_type <= e1000_82543) {
- ctrl = E1000_READ_REG(hw, CTRL);
- E1000_WRITE_REG(hw, CTRL, ctrl | E1000_CTRL_PRIOR);
- }
-#endif
+
switch (hw->mac_type) {
case e1000_82545_rev_3:
case e1000_82546_rev_3:
@@ -1842,20 +1787,6 @@ e1000_init_hw(struct e1000_hw *hw, unsigned char enetaddr[6])
break;
}
-#if 0
- /* Clear all of the statistics registers (clear on read). It is
- * important that we do this after we have tried to establish link
- * because the symbol error count will increment wildly if there
- * is no link.
- */
- e1000_clear_hw_cntrs(hw);
-
- /* ICH8 No-snoop bits are opposite polarity.
- * Set to snoop by default after reset. */
- if (hw->mac_type == e1000_ich8lan)
- e1000_set_pci_ex_no_snoop(hw, PCI_EX_82566_SNOOP_ALL);
-#endif
-
if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER ||
hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) {
ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
@@ -5230,10 +5161,6 @@ _e1000_disable(struct e1000_hw *hw)
E1000_WRITE_REG(hw, RDH, 0);
E1000_WRITE_REG(hw, RDT, 0);
- /* put the card in its initial state */
-#if 0
- E1000_WRITE_REG(hw, CTRL, E1000_CTRL_RST);
-#endif
mdelay(10);
}
@@ -5359,7 +5286,6 @@ static int e1000_init_one(struct e1000_hw *hw, int cardnum, pci_dev_t devno,
#ifndef CONFIG_E1000_NO_NVM
/* Validate the EEPROM and get chipset information */
-#if !defined(CONFIG_MVBC_1G)
if (e1000_init_eeprom_params(hw)) {
E1000_ERR(hw, "EEPROM is invalid!\n");
return -EINVAL;
@@ -5367,7 +5293,6 @@ static int e1000_init_one(struct e1000_hw *hw, int cardnum, pci_dev_t devno,
if ((E1000_READ_REG(hw, I210_EECD) & E1000_EECD_FLUPD) &&
e1000_validate_eeprom_checksum(hw))
return -ENXIO;
-#endif
e1000_read_mac_addr(hw, enetaddr);
#endif
e1000_get_bus_type(hw);
diff --git a/drivers/net/e1000.h b/drivers/net/e1000.h
index c851922ae5..e46edcd4e1 100644
--- a/drivers/net/e1000.h
+++ b/drivers/net/e1000.h
@@ -1093,11 +1093,6 @@ struct e1000_hw {
e1000_media_type media_type;
e1000_fc_type fc;
e1000_bus_type bus_type;
-#if 0
- e1000_bus_speed bus_speed;
- e1000_bus_width bus_width;
- uint32_t io_base;
-#endif
uint32_t asf_firmware_present;
#ifndef CONFIG_E1000_NO_NVM
uint32_t eeprom_semaphore_present;
@@ -1116,29 +1111,11 @@ struct e1000_hw {
uint32_t original_fc;
uint32_t txcw;
uint32_t autoneg_failed;
-#if 0
- uint32_t max_frame_size;
- uint32_t min_frame_size;
- uint32_t mc_filter_type;
- uint32_t num_mc_addrs;
- uint32_t collision_delta;
- uint32_t tx_packet_delta;
- uint32_t ledctl_default;
- uint32_t ledctl_mode1;
- uint32_t ledctl_mode2;
-#endif
uint16_t autoneg_advertised;
uint16_t pci_cmd_word;
uint16_t fc_high_water;
uint16_t fc_low_water;
uint16_t fc_pause_time;
-#if 0
- uint16_t current_ifs_val;
- uint16_t ifs_min_val;
- uint16_t ifs_max_val;
- uint16_t ifs_step_size;
- uint16_t ifs_ratio;
-#endif
uint16_t device_id;
uint16_t vendor_id;
uint16_t subsystem_id;
@@ -1149,9 +1126,6 @@ struct e1000_hw {
uint8_t forced_speed_duplex;
uint8_t wait_autoneg_complete;
uint8_t dma_fairness;
-#if 0
- uint8_t perm_mac_addr[NODE_ADDRESS_SIZE];
-#endif
bool disable_polarity_correction;
bool speed_downgraded;
bool get_link_status;
@@ -1162,11 +1136,6 @@ struct e1000_hw {
bool report_tx_early;
bool phy_reset_disable;
bool initialize_hw_bits_disable;
-#if 0
- bool adaptive_ifs;
- bool ifs_params_forced;
- bool in_ifs_mode;
-#endif
e1000_smart_speed smart_speed;
e1000_dsp_config dsp_config_state;
};
diff --git a/drivers/net/e1000_spi.c b/drivers/net/e1000_spi.c
index df72375238..576ddb8b24 100644
--- a/drivers/net/e1000_spi.c
+++ b/drivers/net/e1000_spi.c
@@ -182,22 +182,21 @@ static int e1000_spi_eeprom_enable_wr(struct e1000_hw *hw, bool intr)
* These have been tested to perform correctly, but they are not used by any
* of the EEPROM commands at this time.
*/
-#if 0
-static int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw, bool intr)
+static __maybe_unused int e1000_spi_eeprom_disable_wr(struct e1000_hw *hw,
+ bool intr)
{
u8 op[] = { SPI_EEPROM_DISABLE_WR };
e1000_standby_eeprom(hw);
return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
}
-static int e1000_spi_eeprom_write_status(struct e1000_hw *hw,
- u8 status, bool intr)
+static __maybe_unused int e1000_spi_eeprom_write_status(struct e1000_hw *hw,
+ u8 status, bool intr)
{
u8 op[] = { SPI_EEPROM_WRITE_STATUS, status };
e1000_standby_eeprom(hw);
return e1000_spi_xfer(hw, 8*sizeof(op), op, NULL, intr);
}
-#endif
static int e1000_spi_eeprom_read_status(struct e1000_hw *hw, bool intr)
{
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index f2cd32c548..d4a6386810 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -240,23 +240,23 @@ static void eepro100_halt (struct eth_device *dev);
static inline int INW (struct eth_device *dev, u_long addr)
{
- return le16_to_cpu (*(volatile u16 *) (addr + dev->iobase));
+ return le16_to_cpu(*(volatile u16 *)(addr + (u_long)dev->iobase));
}
static inline void OUTW (struct eth_device *dev, int command, u_long addr)
{
- *(volatile u16 *) ((addr + dev->iobase)) = cpu_to_le16 (command);
+ *(volatile u16 *)((addr + (u_long)dev->iobase)) = cpu_to_le16(command);
}
static inline void OUTL (struct eth_device *dev, int command, u_long addr)
{
- *(volatile u32 *) ((addr + dev->iobase)) = cpu_to_le32 (command);
+ *(volatile u32 *)((addr + (u_long)dev->iobase)) = cpu_to_le32(command);
}
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
static inline int INL (struct eth_device *dev, u_long addr)
{
- return le32_to_cpu (*(volatile u32 *) (addr + dev->iobase));
+ return le32_to_cpu(*(volatile u32 *)(addr + (u_long)dev->iobase));
}
static int get_phyreg (struct eth_device *dev, unsigned char addr,
diff --git a/drivers/net/fm/fm.c b/drivers/net/fm/fm.c
index df5db723ba..40fbf19c75 100644
--- a/drivers/net/fm/fm.c
+++ b/drivers/net/fm/fm.c
@@ -395,7 +395,8 @@ int fm_init_common(int index, struct ccsr_fman *reg)
printf("\nMMC read: dev # %u, block # %u, count %u ...\n",
dev, blk, cnt);
mmc_init(mmc);
- (void)mmc->block_dev.block_read(dev, blk, cnt, addr);
+ (void)mmc->block_dev.block_read(&mmc->block_dev, blk, cnt,
+ addr);
/* flush cache after read */
flush_cache((ulong)addr, cnt * 512);
}
diff --git a/drivers/net/fm/memac_phy.c b/drivers/net/fm/memac_phy.c
index 4ab78e6c25..5079342682 100644
--- a/drivers/net/fm/memac_phy.c
+++ b/drivers/net/fm/memac_phy.c
@@ -146,7 +146,7 @@ int fm_memac_mdio_init(bd_t *bis, struct memac_mdio_info *info)
bus->read = memac_mdio_read;
bus->write = memac_mdio_write;
bus->reset = memac_mdio_reset;
- sprintf(bus->name, info->name);
+ strcpy(bus->name, info->name);
bus->priv = info->regs;
diff --git a/drivers/net/fm/tgec_phy.c b/drivers/net/fm/tgec_phy.c
index 24cb17b6ed..f038541c8d 100644
--- a/drivers/net/fm/tgec_phy.c
+++ b/drivers/net/fm/tgec_phy.c
@@ -118,7 +118,7 @@ int fm_tgec_mdio_init(bd_t *bis, struct tgec_mdio_info *info)
bus->read = tgec_mdio_read;
bus->write = tgec_mdio_write;
bus->reset = tgec_mdio_reset;
- sprintf(bus->name, info->name);
+ strcpy(bus->name, info->name);
bus->priv = info->regs;
diff --git a/drivers/net/fsl-mc/dpio/qbman_portal.c b/drivers/net/fsl-mc/dpio/qbman_portal.c
index 449ff8a8ba..4b64c8ae73 100644
--- a/drivers/net/fsl-mc/dpio/qbman_portal.c
+++ b/drivers/net/fsl-mc/dpio/qbman_portal.c
@@ -102,12 +102,14 @@ struct qbman_swp *qbman_swp_init(const struct qbman_swp_desc *d)
void *qbman_swp_mc_start(struct qbman_swp *p)
{
void *ret;
+ int *return_val;
#ifdef QBMAN_CHECKING
BUG_ON(p->mc.check != swp_mc_can_start);
#endif
ret = qbman_cena_write_start(&p->sys, QBMAN_CENA_SWP_CR);
#ifdef QBMAN_CHECKING
- if (!ret)
+ return_val = (int *)ret;
+ if (!(*return_val))
p->mc.check = swp_mc_can_submit;
#endif
return ret;
diff --git a/drivers/net/fsl-mc/dpni.c b/drivers/net/fsl-mc/dpni.c
index eacb3c8bb2..41bf56abf5 100644
--- a/drivers/net/fsl-mc/dpni.c
+++ b/drivers/net/fsl-mc/dpni.c
@@ -8,6 +8,26 @@
#include <fsl-mc/fsl_mc_cmd.h>
#include <fsl-mc/fsl_dpni.h>
+int dpni_prepare_extended_cfg(const struct dpni_extended_cfg *cfg,
+ uint8_t *ext_cfg_buf)
+{
+ uint64_t *ext_params = (uint64_t *)ext_cfg_buf;
+
+ DPNI_PREP_EXTENDED_CFG(ext_params, cfg);
+
+ return 0;
+}
+
+int dpni_extract_extended_cfg(struct dpni_extended_cfg *cfg,
+ const uint8_t *ext_cfg_buf)
+{
+ uint64_t *ext_params = (uint64_t *)ext_cfg_buf;
+
+ DPNI_EXT_EXTENDED_CFG(ext_params, cfg);
+
+ return 0;
+}
+
int dpni_open(struct fsl_mc_io *mc_io,
uint32_t cmd_flags,
int dpni_id,
@@ -162,6 +182,7 @@ int dpni_get_attributes(struct fsl_mc_io *mc_io,
cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_ATTR,
cmd_flags,
token);
+ DPNI_CMD_GET_ATTR(cmd, attr);
/* send command to mc*/
err = mc_send_command(mc_io, &cmd);
@@ -174,6 +195,23 @@ int dpni_get_attributes(struct fsl_mc_io *mc_io,
return 0;
}
+int dpni_set_errors_behavior(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ struct dpni_error_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_ERRORS_BEHAVIOR,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_ERRORS_BEHAVIOR(cmd, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
int dpni_get_rx_buffer_layout(struct fsl_mc_io *mc_io,
uint32_t cmd_flags,
uint16_t token,
@@ -602,3 +640,46 @@ int dpni_get_rx_flow(struct fsl_mc_io *mc_io,
return 0;
}
+
+int dpni_set_tx_conf(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t flow_id,
+ const struct dpni_tx_conf_cfg *cfg)
+{
+ struct mc_command cmd = { 0 };
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_TX_CONF,
+ cmd_flags,
+ token);
+ DPNI_CMD_SET_TX_CONF(cmd, flow_id, cfg);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+}
+
+int dpni_get_tx_conf(struct fsl_mc_io *mc_io,
+ uint32_t cmd_flags,
+ uint16_t token,
+ uint16_t flow_id,
+ struct dpni_tx_conf_attr *attr)
+{
+ struct mc_command cmd = { 0 };
+ int err;
+
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_TX_CONF,
+ cmd_flags,
+ token);
+ DPNI_CMD_GET_TX_CONF(cmd, flow_id);
+
+ /* send command to mc*/
+ err = mc_send_command(mc_io, &cmd);
+ if (err)
+ return err;
+
+ DPNI_RSP_GET_TX_CONF(cmd, attr);
+
+ return 0;
+}
diff --git a/drivers/net/fsl-mc/mc.c b/drivers/net/fsl-mc/mc.c
index bac4610fd9..d38e98a2fb 100644
--- a/drivers/net/fsl-mc/mc.c
+++ b/drivers/net/fsl-mc/mc.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
#include <errno.h>
+#include <linux/bug.h>
#include <asm/io.h>
#include <libfdt.h>
#include <fdt_support.h>
@@ -655,6 +656,26 @@ int fsl_mc_ldpaa_init(bd_t *bis)
return 0;
}
+static int dprc_version_check(struct fsl_mc_io *mc_io, uint16_t handle)
+{
+ struct dprc_attributes attr;
+ int error;
+
+ memset(&attr, 0, sizeof(struct dprc_attributes));
+ error = dprc_get_attributes(mc_io, MC_CMD_NO_FLAGS, handle, &attr);
+ if (error == 0) {
+ if ((attr.version.major != DPRC_VER_MAJOR) ||
+ (attr.version.minor != DPRC_VER_MINOR)) {
+ printf("DPRC version mismatch found %u.%u,",
+ attr.version.major,
+ attr.version.minor);
+ printf("supported version is %u.%u\n",
+ DPRC_VER_MAJOR, DPRC_VER_MINOR);
+ }
+ }
+ return error;
+}
+
static int dpio_init(void)
{
struct qbman_swp_desc p_des;
@@ -688,11 +709,18 @@ static int dpio_init(void)
goto err_get_attr;
}
+ if ((attr.version.major != DPIO_VER_MAJOR) ||
+ (attr.version.minor != DPIO_VER_MINOR)) {
+ printf("DPIO version mismatch found %u.%u,",
+ attr.version.major, attr.version.minor);
+ printf("supported version is %u.%u\n",
+ DPIO_VER_MAJOR, DPIO_VER_MINOR);
+ }
+
dflt_dpio->dpio_id = attr.id;
#ifdef DEBUG
printf("Init: DPIO id=0x%d\n", dflt_dpio->dpio_id);
#endif
-
err = dpio_enable(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpio->dpio_handle);
if (err < 0) {
printf("dpio_enable() failed %d\n", err);
@@ -784,11 +812,17 @@ static int dprc_init(void)
goto err_root_open;
}
+ err = dprc_version_check(root_mc_io, root_dprc_handle);
+ if (err < 0) {
+ printf("dprc_version_check() failed: %d\n", err);
+ goto err_root_open;
+ }
+
cfg.options = DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED |
DPRC_CFG_OPT_OBJ_CREATE_ALLOWED |
DPRC_CFG_OPT_ALLOC_ALLOWED;
cfg.icid = DPRC_GET_ICID_FROM_POOL;
- cfg.portal_id = 250;
+ cfg.portal_id = DPRC_GET_PORTAL_ID_FROM_POOL;
err = dprc_create_container(root_mc_io, MC_CMD_NO_FLAGS,
root_dprc_handle,
&cfg,
@@ -906,6 +940,14 @@ static int dpbp_init(void)
goto err_get_attr;
}
+ if ((dpbp_attr.version.major != DPBP_VER_MAJOR) ||
+ (dpbp_attr.version.minor != DPBP_VER_MINOR)) {
+ printf("DPBP version mismatch found %u.%u,",
+ dpbp_attr.version.major, dpbp_attr.version.minor);
+ printf("supported version is %u.%u\n",
+ DPBP_VER_MAJOR, DPBP_VER_MINOR);
+ }
+
dflt_dpbp->dpbp_attr.id = dpbp_attr.id;
#ifdef DEBUG
printf("Init: DPBP id=0x%d\n", dflt_dpbp->dpbp_attr.id);
@@ -963,6 +1005,8 @@ static int dpni_init(void)
{
int err;
struct dpni_attr dpni_attr;
+ uint8_t ext_cfg_buf[256] = {0};
+ struct dpni_extended_cfg dpni_extended_cfg;
struct dpni_cfg dpni_cfg;
dflt_dpni = (struct fsl_dpni_obj *)malloc(sizeof(struct fsl_dpni_obj));
@@ -972,10 +1016,19 @@ static int dpni_init(void)
goto err_malloc;
}
+ memset(&dpni_extended_cfg, 0, sizeof(dpni_extended_cfg));
+ err = dpni_prepare_extended_cfg(&dpni_extended_cfg, &ext_cfg_buf[0]);
+ if (err < 0) {
+ err = -ENODEV;
+ printf("dpni_prepare_extended_cfg() failed: %d\n", err);
+ goto err_prepare_extended_cfg;
+ }
+
memset(&dpni_cfg, 0, sizeof(dpni_cfg));
dpni_cfg.adv.options = DPNI_OPT_UNICAST_FILTER |
DPNI_OPT_MULTICAST_FILTER;
+ dpni_cfg.adv.ext_cfg_iova = (uint64_t)&ext_cfg_buf[0];
err = dpni_create(dflt_mc_io, MC_CMD_NO_FLAGS, &dpni_cfg,
&dflt_dpni->dpni_handle);
@@ -994,6 +1047,14 @@ static int dpni_init(void)
goto err_get_attr;
}
+ if ((dpni_attr.version.major != DPNI_VER_MAJOR) ||
+ (dpni_attr.version.minor != DPNI_VER_MINOR)) {
+ printf("DPNI version mismatch found %u.%u,",
+ dpni_attr.version.major, dpni_attr.version.minor);
+ printf("supported version is %u.%u\n",
+ DPNI_VER_MAJOR, DPNI_VER_MINOR);
+ }
+
dflt_dpni->dpni_id = dpni_attr.id;
#ifdef DEBUG
printf("Init: DPNI id=0x%d\n", dflt_dpni->dpni_id);
@@ -1008,11 +1069,12 @@ static int dpni_init(void)
return 0;
err_close:
- free(dflt_dpni);
err_get_attr:
dpni_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
dpni_destroy(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpni->dpni_handle);
err_create:
+err_prepare_extended_cfg:
+ free(dflt_dpni);
err_malloc:
return err;
}
diff --git a/drivers/net/fsl_mdio.c b/drivers/net/fsl_mdio.c
index ae3d035848..77b9739a24 100644
--- a/drivers/net/fsl_mdio.c
+++ b/drivers/net/fsl_mdio.c
@@ -104,7 +104,7 @@ int fsl_pq_mdio_init(bd_t *bis, struct fsl_pq_mdio_info *info)
bus->read = tsec_phy_read;
bus->write = tsec_phy_write;
bus->reset = fsl_pq_mdio_reset;
- sprintf(bus->name, info->name);
+ strcpy(bus->name, info->name);
bus->priv = (void *)info->regs;
diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c
index 515f0b2746..5ccc4beda8 100644
--- a/drivers/net/ftgmac100.c
+++ b/drivers/net/ftgmac100.c
@@ -562,7 +562,7 @@ int ftgmac100_initialize(bd_t *bd)
memset(dev, 0, sizeof(*dev));
memset(priv, 0, sizeof(*priv));
- sprintf(dev->name, "FTGMAC100");
+ strcpy(dev->name, "FTGMAC100");
dev->iobase = CONFIG_FTGMAC100_BASE;
dev->init = ftgmac100_init;
dev->halt = ftgmac100_halt;
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index bd94f83f04..1fc7da9a3e 100644
--- a/drivers/net/ftmac100.c
+++ b/drivers/net/ftmac100.c
@@ -246,7 +246,7 @@ int ftmac100_initialize (bd_t *bd)
memset (dev, 0, sizeof (*dev));
memset (priv, 0, sizeof (*priv));
- sprintf (dev->name, "FTMAC100");
+ strcpy(dev->name, "FTMAC100");
dev->iobase = CONFIG_FTMAC100_BASE;
dev->init = ftmac100_init;
dev->halt = ftmac100_halt;
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index 088cb229da..aa5d7114a5 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -640,9 +640,9 @@ int greth_initialize(bd_t * bis)
/* Make descriptor string */
if (greth->gbit_mac) {
- sprintf(dev->name, "GRETH_10/100/GB");
+ strcpy(dev->name, "GRETH_10/100/GB");
} else {
- sprintf(dev->name, "GRETH_10/100");
+ strcpy(dev->name, "GRETH_10/100");
}
/* initiate PHY, select speed/duplex depending on connected PHY */
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
index 24ca52e2df..209fae94a7 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/keystone_net.c
@@ -586,7 +586,7 @@ int keystone2_emac_initialize(struct eth_priv_t *eth_priv)
mdio_bus->write = keystone2_mdio_write;
mdio_bus->reset = keystone2_mdio_reset;
mdio_bus->priv = (void *)EMAC_MDIO_BASE_ADDR;
- sprintf(mdio_bus->name, "ethernet-mdio");
+ strcpy(mdio_bus->name, "ethernet-mdio");
res = mdio_register(mdio_bus);
if (res)
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.c b/drivers/net/ldpaa_eth/ldpaa_eth.c
index 69530b11cf..7f96883d34 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.c
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.c
@@ -100,6 +100,83 @@ static void ldpaa_eth_get_dpni_counter(void)
}
printf("DPNI_CNT_EGR_FRAME_DISCARD =%lld\n", value);
}
+
+static void ldpaa_eth_get_dpmac_counter(struct eth_device *net_dev)
+{
+ struct ldpaa_eth_priv *priv = (struct ldpaa_eth_priv *)net_dev->priv;
+ int err = 0;
+ u64 value;
+
+ err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
+ priv->dpmac_handle,
+ DPMAC_CNT_ING_BYTE,
+ &value);
+ if (err < 0) {
+ printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
+ return;
+ }
+ printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
+
+ err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
+ priv->dpmac_handle,
+ DPMAC_CNT_ING_FRAME_DISCARD,
+ &value);
+ if (err < 0) {
+ printf("dpmac_get_counter: DPMAC_CNT_ING_FRAME_DISCARD failed\n");
+ return;
+ }
+ printf("DPMAC_CNT_ING_FRAME_DISCARD=%lld\n", value);
+
+ err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
+ priv->dpmac_handle,
+ DPMAC_CNT_ING_ALIGN_ERR,
+ &value);
+ if (err < 0) {
+ printf("dpmac_get_counter: DPMAC_CNT_ING_ALIGN_ERR failed\n");
+ return;
+ }
+ printf("DPMAC_CNT_ING_ALIGN_ERR =%lld\n", value);
+
+ err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
+ priv->dpmac_handle,
+ DPMAC_CNT_ING_BYTE,
+ &value);
+ if (err < 0) {
+ printf("dpmac_get_counter: DPMAC_CNT_ING_BYTE failed\n");
+ return;
+ }
+ printf("DPMAC_CNT_ING_BYTE=%lld\n", value);
+
+ err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
+ priv->dpmac_handle,
+ DPMAC_CNT_ING_ERR_FRAME,
+ &value);
+ if (err < 0) {
+ printf("dpmac_get_counter: DPMAC_CNT_ING_ERR_FRAME failed\n");
+ return;
+ }
+ printf("DPMAC_CNT_ING_ERR_FRAME=%lld\n", value);
+
+ err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
+ priv->dpmac_handle,
+ DPMAC_CNT_EGR_BYTE ,
+ &value);
+ if (err < 0) {
+ printf("dpmac_get_counter: DPMAC_CNT_EGR_BYTE failed\n");
+ return;
+ }
+ printf("DPMAC_CNT_EGR_BYTE =%lld\n", value);
+
+ err = dpmac_get_counter(dflt_mc_io, MC_CMD_NO_FLAGS,
+ priv->dpmac_handle,
+ DPMAC_CNT_EGR_ERR_FRAME ,
+ &value);
+ if (err < 0) {
+ printf("dpmac_get_counter: DPMAC_CNT_EGR_ERR_FRAME failed\n");
+ return;
+ }
+ printf("DPMAC_CNT_EGR_ERR_FRAME =%lld\n", value);
+}
#endif
static void ldpaa_eth_rx(struct ldpaa_eth_priv *priv,
@@ -436,6 +513,7 @@ static void ldpaa_eth_stop(struct eth_device *net_dev)
#ifdef DEBUG
ldpaa_eth_get_dpni_counter();
+ ldpaa_eth_get_dpmac_counter(net_dev);
#endif
err = dprc_disconnect(dflt_mc_io, MC_CMD_NO_FLAGS,
@@ -599,6 +677,29 @@ static void ldpaa_dpbp_free(void)
dpbp_close(dflt_mc_io, MC_CMD_NO_FLAGS, dflt_dpbp->dpbp_handle);
}
+static int ldpaa_dpmac_version_check(struct fsl_mc_io *mc_io,
+ struct ldpaa_eth_priv *priv)
+{
+ struct dpmac_attr attr;
+ int error;
+
+ memset(&attr, 0, sizeof(struct dpmac_attr));
+ error = dpmac_get_attributes(mc_io, MC_CMD_NO_FLAGS,
+ priv->dpmac_handle,
+ &attr);
+ if (error == 0) {
+ if ((attr.version.major != DPMAC_VER_MAJOR) ||
+ (attr.version.minor != DPMAC_VER_MINOR)) {
+ printf("DPMAC version mismatch found %u.%u,",
+ attr.version.major, attr.version.minor);
+ printf("supported version is %u.%u\n",
+ DPMAC_VER_MAJOR, DPMAC_VER_MINOR);
+ }
+ }
+
+ return error;
+}
+
static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
{
int err = 0;
@@ -609,6 +710,11 @@ static int ldpaa_dpmac_setup(struct ldpaa_eth_priv *priv)
&priv->dpmac_handle);
if (err)
printf("dpmac_create() failed\n");
+
+ err = ldpaa_dpmac_version_check(dflt_mc_io, priv);
+ if (err < 0)
+ printf("ldpaa_dpmac_version_check() failed: %d\n", err);
+
return err;
}
@@ -628,11 +734,11 @@ static int ldpaa_dpmac_bind(struct ldpaa_eth_priv *priv)
#endif
memset(&dpmac_endpoint, 0, sizeof(struct dprc_endpoint));
- sprintf(dpmac_endpoint.type, "dpmac");
+ strcpy(dpmac_endpoint.type, "dpmac");
dpmac_endpoint.id = priv->dpmac_id;
memset(&dpni_endpoint, 0, sizeof(struct dprc_endpoint));
- sprintf(dpni_endpoint.type, "dpni");
+ strcpy(dpni_endpoint.type, "dpni");
dpni_endpoint.id = dflt_dpni->dpni_id;
err = dprc_connect(dflt_mc_io, MC_CMD_NO_FLAGS,
@@ -755,6 +861,7 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
{
struct dpni_pools_cfg pools_params;
struct dpni_tx_flow_cfg dflt_tx_flow;
+ struct dpni_tx_conf_cfg tx_conf_cfg;
int err = 0;
pools_params.num_dpbp = 1;
@@ -770,9 +877,7 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
priv->tx_flow_id = DPNI_NEW_FLOW_ID;
memset(&dflt_tx_flow, 0, sizeof(dflt_tx_flow));
- dflt_tx_flow.options = DPNI_TX_FLOW_OPT_ONLY_TX_ERROR;
- dflt_tx_flow.conf_err_cfg.use_default_queue = 0;
- dflt_tx_flow.conf_err_cfg.errors_only = 1;
+ dflt_tx_flow.use_common_tx_conf_queue = 0;
err = dpni_set_tx_flow(dflt_mc_io, MC_CMD_NO_FLAGS,
dflt_dpni->dpni_handle, &priv->tx_flow_id,
&dflt_tx_flow);
@@ -781,6 +886,17 @@ static int ldpaa_dpni_bind(struct ldpaa_eth_priv *priv)
return err;
}
+ memset(&tx_conf_cfg, 0, sizeof(struct dpni_tx_conf_cfg));
+ tx_conf_cfg.errors_only = true;
+ /*Set tx-conf and error configuration*/
+ err = dpni_set_tx_conf(dflt_mc_io, MC_CMD_NO_FLAGS,
+ dflt_dpni->dpni_handle,
+ priv->tx_flow_id, &tx_conf_cfg);
+ if (err) {
+ printf("dpni_set_tx_conf() failed\n");
+ return err;
+ }
+
return 0;
}
diff --git a/drivers/net/ldpaa_eth/ldpaa_eth.h b/drivers/net/ldpaa_eth/ldpaa_eth.h
index af41b27844..3b16150735 100644
--- a/drivers/net/ldpaa_eth/ldpaa_eth.h
+++ b/drivers/net/ldpaa_eth/ldpaa_eth.h
@@ -24,7 +24,7 @@ enum ldpaa_eth_type {
};
/* Arbitrary values for now, but we'll need to tune */
-#define LDPAA_ETH_NUM_BUFS (2 * 7)
+#define LDPAA_ETH_NUM_BUFS (7 * 7)
#define LDPAA_ETH_REFILL_THRESH (LDPAA_ETH_NUM_BUFS/2)
#define LDPAA_ETH_RX_BUFFER_SIZE 2048
diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c
index e76e9bc2b5..6cc273c33c 100644
--- a/drivers/net/lpc32xx_eth.c
+++ b/drivers/net/lpc32xx_eth.c
@@ -304,6 +304,13 @@ static int mii_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
return -EFAULT;
}
+ /* write the phy and reg addressse into the MII address reg */
+ writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET),
+ &regs->madr);
+
+ /* write data to the MII write register */
+ writel(data, &regs->mwtd);
+
/* wait till the MII is not busy */
timeout = MII_TIMEOUT;
do {
@@ -319,13 +326,6 @@ static int mii_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
return -EFAULT;
}
- /* write the phy and reg addressse into the MII address reg */
- writel((phy_adr << MADR_PHY_OFFSET) | (reg_ofs << MADR_REG_OFFSET),
- &regs->madr);
-
- /* write data to the MII write register */
- writel(data, &regs->mwtd);
-
/*debug("%s:(adr %d, off %d) <= %04x\n", __func__, phy_adr,
reg_ofs, data);*/
@@ -582,7 +582,7 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid)
}
bus->read = lpc32xx_eth_phy_read;
bus->write = lpc32xx_eth_phy_write;
- sprintf(bus->name, dev->name);
+ strcpy(bus->name, dev->name);
ret = mdio_register(bus);
if (ret) {
diff --git a/drivers/net/mpc512x_fec.c b/drivers/net/mpc512x_fec.c
index 22ea114f01..e850672a4f 100644
--- a/drivers/net/mpc512x_fec.c
+++ b/drivers/net/mpc512x_fec.c
@@ -635,7 +635,7 @@ int mpc512x_fec_initialize (bd_t * bis)
dev->send = mpc512x_fec_send;
dev->recv = mpc512x_fec_recv;
- sprintf (dev->name, "FEC");
+ strcpy(dev->name, "FEC");
eth_register (dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
diff --git a/drivers/net/mpc5xxx_fec.c b/drivers/net/mpc5xxx_fec.c
index 2ebd1761c3..e13b4cf32b 100644
--- a/drivers/net/mpc5xxx_fec.c
+++ b/drivers/net/mpc5xxx_fec.c
@@ -913,7 +913,7 @@ int mpc5xxx_fec_initialize(bd_t * bis)
dev->send = mpc5xxx_fec_send;
dev->recv = mpc5xxx_fec_recv;
- sprintf(dev->name, "FEC");
+ strcpy(dev->name, "FEC");
eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
index ab5aa68fc8..b16be92142 100644
--- a/drivers/net/mvgbe.c
+++ b/drivers/net/mvgbe.c
@@ -675,7 +675,7 @@ int mvgbe_phylib_init(struct eth_device *dev, int phyid)
}
bus->read = mvgbe_phy_read;
bus->write = mvgbe_phy_write;
- sprintf(bus->name, dev->name);
+ strcpy(bus->name, dev->name);
ret = mdio_register(bus);
if (ret) {
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index 38ad14eff9..fa20f548e5 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -2,7 +2,7 @@
* Driver for Marvell NETA network card for Armada XP and Armada 370 SoCs.
*
* U-Boot version:
- * Copyright (C) 2014 Stefan Roese <sr@denx.de>
+ * Copyright (C) 2014-2015 Stefan Roese <sr@denx.de>
*
* Based on the Linux version which is:
* Copyright (C) 2012 Marvell
@@ -14,6 +14,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <net.h>
#include <netdev.h>
#include <config.h>
@@ -28,6 +29,8 @@
#include <linux/compat.h>
#include <linux/mbus.h>
+DECLARE_GLOBAL_DATA_PTR;
+
#if !defined(CONFIG_PHYLIB)
# error Marvell mvneta requires PHYLIB
#endif
@@ -1115,9 +1118,9 @@ static void mvneta_start_dev(struct mvneta_port *pp)
mvneta_port_enable(pp);
}
-static void mvneta_adjust_link(struct eth_device *dev)
+static void mvneta_adjust_link(struct udevice *dev)
{
- struct mvneta_port *pp = dev->priv;
+ struct mvneta_port *pp = dev_get_priv(dev);
struct phy_device *phydev = pp->phydev;
int status_change = 0;
@@ -1171,9 +1174,9 @@ static void mvneta_adjust_link(struct eth_device *dev)
}
}
-static int mvneta_open(struct eth_device *dev)
+static int mvneta_open(struct udevice *dev)
{
- struct mvneta_port *pp = dev->priv;
+ struct mvneta_port *pp = dev_get_priv(dev);
int ret;
ret = mvneta_setup_rxqs(pp);
@@ -1192,7 +1195,7 @@ static int mvneta_open(struct eth_device *dev)
}
/* Initialize hw */
-static int mvneta_init(struct mvneta_port *pp)
+static int mvneta_init2(struct mvneta_port *pp)
{
int queue;
@@ -1314,23 +1317,22 @@ static int mvneta_port_power_up(struct mvneta_port *pp, int phy_mode)
}
/* Device initialization routine */
-static int mvneta_probe(struct eth_device *dev)
+static int mvneta_init(struct udevice *dev)
{
- struct mvneta_port *pp = dev->priv;
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct mvneta_port *pp = dev_get_priv(dev);
int err;
pp->tx_ring_size = MVNETA_MAX_TXD;
pp->rx_ring_size = MVNETA_MAX_RXD;
- err = mvneta_init(pp);
+ err = mvneta_init2(pp);
if (err < 0) {
dev_err(&pdev->dev, "can't init eth hal\n");
return err;
}
- mvneta_conf_mbus_windows(pp);
-
- mvneta_mac_addr_set(pp, dev->enetaddr, rxq_def);
+ mvneta_mac_addr_set(pp, pdata->enetaddr, rxq_def);
err = mvneta_port_power_up(pp, pp->phy_interface);
if (err < 0) {
@@ -1367,25 +1369,24 @@ static int smi_wait_ready(struct mvneta_port *pp)
}
/*
- * smi_reg_read - miiphy_read callback function.
+ * mvneta_mdio_read - miiphy_read callback function.
*
* Returns 16bit phy register value, or 0xffff on error
*/
-static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data)
+static int mvneta_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
{
- struct eth_device *dev = eth_get_dev_by_name(devname);
- struct mvneta_port *pp = dev->priv;
+ struct mvneta_port *pp = bus->priv;
u32 smi_reg;
u32 timeout;
/* check parameters */
- if (phy_adr > MVNETA_PHY_ADDR_MASK) {
- printf("Error: Invalid PHY address %d\n", phy_adr);
+ if (addr > MVNETA_PHY_ADDR_MASK) {
+ printf("Error: Invalid PHY address %d\n", addr);
return -EFAULT;
}
- if (reg_ofs > MVNETA_PHY_REG_MASK) {
- printf("Err: Invalid register offset %d\n", reg_ofs);
+ if (reg > MVNETA_PHY_REG_MASK) {
+ printf("Err: Invalid register offset %d\n", reg);
return -EFAULT;
}
@@ -1394,14 +1395,14 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data)
return -EFAULT;
/* fill the phy address and regiser offset and read opcode */
- smi_reg = (phy_adr << MVNETA_SMI_DEV_ADDR_OFFS)
- | (reg_ofs << MVNETA_SMI_REG_ADDR_OFFS)
+ smi_reg = (addr << MVNETA_SMI_DEV_ADDR_OFFS)
+ | (reg << MVNETA_SMI_REG_ADDR_OFFS)
| MVNETA_SMI_OPCODE_READ;
/* write the smi register */
mvreg_write(pp, MVNETA_SMI, smi_reg);
- /*wait till read value is ready */
+ /* wait till read value is ready */
timeout = MVNETA_SMI_TIMEOUT;
do {
@@ -1417,31 +1418,29 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data)
for (timeout = 0; timeout < MVNETA_SMI_TIMEOUT; timeout++)
;
- *data = (u16)(mvreg_read(pp, MVNETA_SMI) & MVNETA_SMI_DATA_MASK);
-
- return 0;
+ return mvreg_read(pp, MVNETA_SMI) & MVNETA_SMI_DATA_MASK;
}
/*
- * smi_reg_write - imiiphy_write callback function.
+ * mvneta_mdio_write - miiphy_write callback function.
*
* Returns 0 if write succeed, -EINVAL on bad parameters
* -ETIME on timeout
*/
-static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
+static int mvneta_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+ u16 value)
{
- struct eth_device *dev = eth_get_dev_by_name(devname);
- struct mvneta_port *pp = dev->priv;
+ struct mvneta_port *pp = bus->priv;
u32 smi_reg;
/* check parameters */
- if (phy_adr > MVNETA_PHY_ADDR_MASK) {
- printf("Error: Invalid PHY address %d\n", phy_adr);
+ if (addr > MVNETA_PHY_ADDR_MASK) {
+ printf("Error: Invalid PHY address %d\n", addr);
return -EFAULT;
}
- if (reg_ofs > MVNETA_PHY_REG_MASK) {
- printf("Err: Invalid register offset %d\n", reg_ofs);
+ if (reg > MVNETA_PHY_REG_MASK) {
+ printf("Err: Invalid register offset %d\n", reg);
return -EFAULT;
}
@@ -1450,9 +1449,9 @@ static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
return -EFAULT;
/* fill the phy addr and reg offset and write opcode and data */
- smi_reg = (data << MVNETA_SMI_DATA_OFFS);
- smi_reg |= (phy_adr << MVNETA_SMI_DEV_ADDR_OFFS)
- | (reg_ofs << MVNETA_SMI_REG_ADDR_OFFS);
+ smi_reg = value << MVNETA_SMI_DATA_OFFS;
+ smi_reg |= (addr << MVNETA_SMI_DEV_ADDR_OFFS)
+ | (reg << MVNETA_SMI_REG_ADDR_OFFS);
smi_reg &= ~MVNETA_SMI_OPCODE_READ;
/* write the smi register */
@@ -1461,9 +1460,9 @@ static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
return 0;
}
-static int mvneta_init_u_boot(struct eth_device *dev, bd_t *bis)
+static int mvneta_start(struct udevice *dev)
{
- struct mvneta_port *pp = dev->priv;
+ struct mvneta_port *pp = dev_get_priv(dev);
struct phy_device *phydev;
mvneta_port_power_up(pp, pp->phy_interface);
@@ -1483,7 +1482,7 @@ static int mvneta_init_u_boot(struct eth_device *dev, bd_t *bis)
}
/* Full init on first call */
- mvneta_probe(dev);
+ mvneta_init(dev);
pp->init = 1;
} else {
/* Upon all following calls, this is enough */
@@ -1494,9 +1493,9 @@ static int mvneta_init_u_boot(struct eth_device *dev, bd_t *bis)
return 0;
}
-static int mvneta_send(struct eth_device *dev, void *ptr, int len)
+static int mvneta_send(struct udevice *dev, void *packet, int length)
{
- struct mvneta_port *pp = dev->priv;
+ struct mvneta_port *pp = dev_get_priv(dev);
struct mvneta_tx_queue *txq = &pp->txqs[0];
struct mvneta_tx_desc *tx_desc;
int sent_desc;
@@ -1505,9 +1504,9 @@ static int mvneta_send(struct eth_device *dev, void *ptr, int len)
/* Get a descriptor for the first part of the packet */
tx_desc = mvneta_txq_next_desc_get(txq);
- tx_desc->buf_phys_addr = (u32)ptr;
- tx_desc->data_size = len;
- flush_dcache_range((u32)ptr, (u32)ptr + len);
+ tx_desc->buf_phys_addr = (u32)packet;
+ tx_desc->data_size = length;
+ flush_dcache_range((u32)packet, (u32)packet + length);
/* First and Last descriptor */
tx_desc->command = MVNETA_TX_L4_CSUM_NOT | MVNETA_TXD_FLZ_DESC;
@@ -1525,28 +1524,25 @@ static int mvneta_send(struct eth_device *dev, void *ptr, int len)
/* txDone has increased - hw sent packet */
mvneta_txq_sent_desc_dec(pp, txq, sent_desc);
- return 0;
return 0;
}
-static int mvneta_recv(struct eth_device *dev)
+static int mvneta_recv(struct udevice *dev, int flags, uchar **packetp)
{
- struct mvneta_port *pp = dev->priv;
+ struct mvneta_port *pp = dev_get_priv(dev);
int rx_done;
- int packets_done;
struct mvneta_rx_queue *rxq;
+ int rx_bytes = 0;
/* get rx queue */
rxq = mvneta_rxq_handle_get(pp, rxq_def);
rx_done = mvneta_rxq_busy_desc_num_get(pp, rxq);
- packets_done = rx_done;
- while (packets_done--) {
+ if (rx_done) {
struct mvneta_rx_desc *rx_desc;
unsigned char *data;
u32 rx_status;
- int rx_bytes;
/*
* No cache invalidation needed here, since the desc's are
@@ -1559,7 +1555,7 @@ static int mvneta_recv(struct eth_device *dev)
(rx_status & MVNETA_RXD_ERR_SUMMARY)) {
mvneta_rx_error(pp, rx_desc);
/* leave the descriptor untouched */
- continue;
+ return -EIO;
}
/* 2 bytes for marvell header. 4 bytes for crc */
@@ -1571,40 +1567,24 @@ static int mvneta_recv(struct eth_device *dev)
* No cache invalidation needed here, since the rx_buffer's are
* located in a uncached memory region
*/
- net_process_received_packet(data, rx_bytes);
- }
+ *packetp = data;
- /* Update rxq management counters */
- if (rx_done)
mvneta_rxq_desc_num_update(pp, rxq, rx_done, rx_done);
+ }
- return 0;
-}
-
-static void mvneta_halt(struct eth_device *dev)
-{
- struct mvneta_port *pp = dev->priv;
-
- mvneta_port_down(pp);
- mvneta_port_disable(pp);
+ return rx_bytes;
}
-int mvneta_initialize(bd_t *bis, int base_addr, int devnum, int phy_addr)
+static int mvneta_probe(struct udevice *dev)
{
- struct eth_device *dev;
- struct mvneta_port *pp;
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct mvneta_port *pp = dev_get_priv(dev);
+ void *blob = (void *)gd->fdt_blob;
+ int node = dev->of_offset;
+ struct mii_dev *bus;
+ unsigned long addr;
void *bd_space;
- dev = calloc(1, sizeof(*dev));
- if (dev == NULL)
- return -ENOMEM;
-
- pp = calloc(1, sizeof(*pp));
- if (pp == NULL)
- return -ENOMEM;
-
- dev->priv = pp;
-
/*
* Allocate buffer area for descs and rx_buffers. This is only
* done once for all interfaces. As only one interface can
@@ -1625,28 +1605,82 @@ int mvneta_initialize(bd_t *bis, int base_addr, int devnum, int phy_addr)
MVNETA_MAX_RXD * sizeof(struct mvneta_rx_desc));
}
- sprintf(dev->name, "neta%d", devnum);
+ pp->base = (void __iomem *)pdata->iobase;
- pp->base = (void __iomem *)base_addr;
- dev->iobase = base_addr;
- dev->init = mvneta_init_u_boot;
- dev->halt = mvneta_halt;
- dev->send = mvneta_send;
- dev->recv = mvneta_recv;
- dev->write_hwaddr = NULL;
+ /* Configure MBUS address windows */
+ mvneta_conf_mbus_windows(pp);
- /*
- * The PHY interface type is configured via the
- * board specific CONFIG_SYS_NETA_INTERFACE_TYPE
- * define.
- */
- pp->phy_interface = CONFIG_SYS_NETA_INTERFACE_TYPE;
+ /* PHY interface is already decoded in mvneta_ofdata_to_platdata() */
+ pp->phy_interface = pdata->phy_interface;
+
+ /* Now read phyaddr from DT */
+ addr = fdtdec_get_int(blob, node, "phy", 0);
+ addr = fdt_node_offset_by_phandle(blob, addr);
+ pp->phyaddr = fdtdec_get_int(blob, addr, "reg", 0);
+
+ bus = mdio_alloc();
+ if (!bus) {
+ printf("Failed to allocate MDIO bus\n");
+ return -ENOMEM;
+ }
+
+ bus->read = mvneta_mdio_read;
+ bus->write = mvneta_mdio_write;
+ snprintf(bus->name, sizeof(bus->name), dev->name);
+ bus->priv = (void *)pp;
+ pp->bus = bus;
- eth_register(dev);
+ return mdio_register(bus);
+}
- pp->phyaddr = phy_addr;
- miiphy_register(dev->name, smi_reg_read, smi_reg_write);
- pp->bus = miiphy_get_dev_by_name(dev->name);
+static void mvneta_stop(struct udevice *dev)
+{
+ struct mvneta_port *pp = dev_get_priv(dev);
- return 1;
+ mvneta_port_down(pp);
+ mvneta_port_disable(pp);
}
+
+static const struct eth_ops mvneta_ops = {
+ .start = mvneta_start,
+ .send = mvneta_send,
+ .recv = mvneta_recv,
+ .stop = mvneta_stop,
+};
+
+static int mvneta_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ const char *phy_mode;
+
+ pdata->iobase = dev_get_addr(dev);
+
+ /* Get phy-mode / phy_interface from DT */
+ pdata->phy_interface = -1;
+ phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+ if (phy_mode)
+ pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+ if (pdata->phy_interface == -1) {
+ debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id mvneta_ids[] = {
+ { .compatible = "marvell,armada-370-neta" },
+ { .compatible = "marvell,armada-xp-neta" },
+ { }
+};
+
+U_BOOT_DRIVER(mvneta) = {
+ .name = "mvneta",
+ .id = UCLASS_ETH,
+ .of_match = mvneta_ids,
+ .ofdata_to_platdata = mvneta_ofdata_to_platdata,
+ .probe = mvneta_probe,
+ .ops = &mvneta_ops,
+ .priv_auto_alloc_size = sizeof(struct mvneta_port),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c
index 07a7cec2a8..887cfd957b 100644
--- a/drivers/net/ne2000_base.c
+++ b/drivers/net/ne2000_base.c
@@ -794,7 +794,7 @@ int ne2k_register(void)
dev->send = ne2k_send;
dev->recv = ne2k_recv;
- sprintf(dev->name, "NE2000");
+ strcpy(dev->name, "NE2000");
return eth_register(dev);
}
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index 1b4dd56d52..56d29d47af 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -386,7 +386,7 @@ static int pch_gbe_mdio_init(const char *name, struct pch_gbe_regs *mac_regs)
bus->read = pch_gbe_mdio_read;
bus->write = pch_gbe_mdio_write;
- sprintf(bus->name, name);
+ strcpy(bus->name, name);
bus->priv = (void *)mac_regs;
diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c
index cfcb1b4e23..16a7512b0c 100644
--- a/drivers/net/pcnet.c
+++ b/drivers/net/pcnet.c
@@ -134,8 +134,17 @@ static int pcnet_recv (struct eth_device *dev);
static void pcnet_halt (struct eth_device *dev);
static int pcnet_probe (struct eth_device *dev, bd_t * bis, int dev_num);
-#define PCI_TO_MEM(d, a) pci_virt_to_mem((pci_dev_t)d->priv, (a))
-#define PCI_TO_MEM_LE(d,a) (u32)(cpu_to_le32(PCI_TO_MEM(d,a)))
+static inline pci_addr_t pcnet_virt_to_mem(const struct eth_device *dev,
+ void *addr, bool uncached)
+{
+ pci_dev_t devbusfn = (pci_dev_t)dev->priv;
+ void *virt_addr = addr;
+
+ if (uncached)
+ virt_addr = (void *)CKSEG0ADDR(addr);
+
+ return pci_virt_to_mem(devbusfn, virt_addr);
+}
static struct pci_device_id supported[] = {
{PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_LANCE},
@@ -352,7 +361,8 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis)
*/
lp->cur_rx = 0;
for (i = 0; i < RX_RING_SIZE; i++) {
- uc->rx_ring[i].base = PCI_TO_MEM_LE(dev, (*lp->rx_buf)[i]);
+ addr = pcnet_virt_to_mem(dev, (*lp->rx_buf)[i], false);
+ uc->rx_ring[i].base = cpu_to_le32(addr);
uc->rx_ring[i].buf_length = cpu_to_le16(-PKT_BUF_SZ);
uc->rx_ring[i].status = cpu_to_le16(0x8000);
PCNET_DEBUG1
@@ -383,8 +393,10 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis)
uc->init_block.tlen_rlen = cpu_to_le16(TX_RING_LEN_BITS |
RX_RING_LEN_BITS);
- uc->init_block.rx_ring = PCI_TO_MEM_LE(dev, uc->rx_ring);
- uc->init_block.tx_ring = PCI_TO_MEM_LE(dev, uc->tx_ring);
+ addr = pcnet_virt_to_mem(dev, uc->rx_ring, true);
+ uc->init_block.rx_ring = cpu_to_le32(addr);
+ addr = pcnet_virt_to_mem(dev, uc->tx_ring, true);
+ uc->init_block.tx_ring = cpu_to_le32(addr);
PCNET_DEBUG1("\ntlen_rlen=0x%x rx_ring=0x%x tx_ring=0x%x\n",
uc->init_block.tlen_rlen,
@@ -394,7 +406,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis)
* Tell the controller where the Init Block is located.
*/
barrier();
- addr = PCI_TO_MEM(dev, &lp->uc->init_block);
+ addr = pcnet_virt_to_mem(dev, &lp->uc->init_block, true);
pcnet_write_csr(dev, 1, addr & 0xffff);
pcnet_write_csr(dev, 2, (addr >> 16) & 0xffff);
@@ -424,6 +436,7 @@ static int pcnet_init(struct eth_device *dev, bd_t *bis)
static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len)
{
int i, status;
+ u32 addr;
struct pcnet_tx_head *entry = &lp->uc->tx_ring[lp->cur_tx];
PCNET_DEBUG2("Tx%d: %d bytes from 0x%p ", lp->cur_tx, pkt_len,
@@ -451,9 +464,10 @@ static int pcnet_send(struct eth_device *dev, void *packet, int pkt_len)
* Setup Tx ring. Caution: the write order is important here,
* set the status with the "ownership" bits last.
*/
+ addr = pcnet_virt_to_mem(dev, packet, false);
writew(-pkt_len, &entry->length);
writel(0, &entry->misc);
- writel(PCI_TO_MEM(dev, packet), &entry->base);
+ writel(addr, &entry->base);
writew(0x8300, &entry->status);
/* Trigger an immediate send poll. */
diff --git a/drivers/net/phy/cortina.c b/drivers/net/phy/cortina.c
index ba1157fd10..f975fd8209 100644
--- a/drivers/net/phy/cortina.c
+++ b/drivers/net/phy/cortina.c
@@ -174,7 +174,8 @@ void cs4340_upload_firmware(struct phy_device *phydev)
printf("MMC read: dev # %u, block # %u, count %u ...\n",
dev, blk, cnt);
mmc_init(mmc);
- (void)mmc->block_dev.block_read(dev, blk, cnt, addr);
+ (void)mmc->block_dev.block_read(&mmc->block_dev, blk, cnt,
+ addr);
/* flush cache after read */
flush_cache((ulong)addr, cnt * 512);
}
diff --git a/drivers/net/phy/ti.c b/drivers/net/phy/ti.c
index 541a57f980..c3912d52f3 100644
--- a/drivers/net/phy/ti.c
+++ b/drivers/net/phy/ti.c
@@ -41,6 +41,8 @@
/* PHY CTRL bits */
#define DP83867_PHYCR_FIFO_DEPTH_SHIFT 14
+#define DP83867_MDI_CROSSOVER 5
+#define DP83867_MDI_CROSSOVER_AUTO 2
/* RGMIIDCTL bits */
#define DP83867_RGMII_TX_CLK_DELAY_SHIFT 4
@@ -149,6 +151,7 @@ static int dp83867_config(struct phy_device *phydev)
if (phy_interface_is_rgmii(phydev)) {
ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_PHYCTRL,
+ (DP83867_MDI_CROSSOVER_AUTO << DP83867_MDI_CROSSOVER) |
(FIFO_DEPTH << DP83867_PHYCR_FIFO_DEPTH_SHIFT));
if (ret)
return ret;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index a320b4d75b..443a4da527 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -560,7 +560,7 @@ int sh_eth_initialize(bd_t *bd)
dev->recv = sh_eth_recv;
eth->port_info[eth->port].dev = dev;
- sprintf(dev->name, SHETHER_NAME);
+ strcpy(dev->name, SHETHER_NAME);
/* Register Device to EtherNet subsystem */
eth_register(dev);
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 025e7a76f1..be0f38288f 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -710,7 +710,7 @@ static int tsec_initialize(bd_t *bis, struct tsec_info_struct *tsec_info)
priv->tbiaddr = CONFIG_SYS_TBIPA_VALUE;
priv->flags = tsec_info->flags;
- sprintf(dev->name, tsec_info->devname);
+ strcpy(dev->name, tsec_info->devname);
priv->interface = tsec_info->interface;
priv->bus = miiphy_get_dev_by_name(tsec_info->mii_devname);
priv->dev = dev;
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index df053feee8..81274ee13b 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -8,15 +8,14 @@
#include <config.h>
#include <common.h>
+#include <dm.h>
#include <net.h>
#include <malloc.h>
#include <asm/io.h>
#include <phy.h>
#include <miiphy.h>
-#if !defined(CONFIG_PHYLIB)
-# error AXI_ETHERNET requires PHYLIB
-#endif
+DECLARE_GLOBAL_DATA_PTR;
/* Link setup */
#define XAE_EMMC_LINKSPEED_MASK 0xC0000000 /* Link speed */
@@ -86,7 +85,8 @@ struct axidma_priv {
struct axidma_reg *dmatx;
struct axidma_reg *dmarx;
int phyaddr;
-
+ struct axi_regs *iobase;
+ phy_interface_t interface;
struct phy_device *phydev;
struct mii_dev *bus;
};
@@ -147,9 +147,8 @@ struct axi_regs {
*/
#define PHY_DETECT_MASK 0x1808
-static inline int mdio_wait(struct eth_device *dev)
+static inline int mdio_wait(struct axi_regs *regs)
{
- struct axi_regs *regs = (struct axi_regs *)dev->iobase;
u32 timeout = 200;
/* Wait till MDIO interface is ready to accept a new transaction. */
@@ -165,13 +164,13 @@ static inline int mdio_wait(struct eth_device *dev)
return 0;
}
-static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum,
- u16 *val)
+static u32 phyread(struct axidma_priv *priv, u32 phyaddress, u32 registernum,
+ u16 *val)
{
- struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+ struct axi_regs *regs = priv->iobase;
u32 mdioctrlreg = 0;
- if (mdio_wait(dev))
+ if (mdio_wait(regs))
return 1;
mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) &
@@ -183,7 +182,7 @@ static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum,
out_be32(&regs->mdio_mcr, mdioctrlreg);
- if (mdio_wait(dev))
+ if (mdio_wait(regs))
return 1;
/* Read data */
@@ -191,13 +190,13 @@ static u32 phyread(struct eth_device *dev, u32 phyaddress, u32 registernum,
return 0;
}
-static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum,
- u32 data)
+static u32 phywrite(struct axidma_priv *priv, u32 phyaddress, u32 registernum,
+ u32 data)
{
- struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+ struct axi_regs *regs = priv->iobase;
u32 mdioctrlreg = 0;
- if (mdio_wait(dev))
+ if (mdio_wait(regs))
return 1;
mdioctrlreg = ((phyaddress << XAE_MDIO_MCR_PHYAD_SHIFT) &
@@ -212,19 +211,18 @@ static u32 phywrite(struct eth_device *dev, u32 phyaddress, u32 registernum,
out_be32(&regs->mdio_mcr, mdioctrlreg);
- if (mdio_wait(dev))
+ if (mdio_wait(regs))
return 1;
return 0;
}
-/* Setting axi emac and phy to proper setting */
-static int setup_phy(struct eth_device *dev)
+static int axiemac_phy_init(struct udevice *dev)
{
u16 phyreg;
- u32 i, speed, emmc_reg, ret;
- struct axidma_priv *priv = dev->priv;
- struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+ u32 i, ret;
+ struct axidma_priv *priv = dev_get_priv(dev);
+ struct axi_regs *regs = priv->iobase;
struct phy_device *phydev;
u32 supported = SUPPORTED_10baseT_Half |
@@ -234,16 +232,19 @@ static int setup_phy(struct eth_device *dev)
SUPPORTED_1000baseT_Half |
SUPPORTED_1000baseT_Full;
+ /* Set default MDIO divisor */
+ out_be32(&regs->mdio_mc, XAE_MDIO_DIV_DFT | XAE_MDIO_MC_MDIOEN_MASK);
+
if (priv->phyaddr == -1) {
/* Detect the PHY address */
for (i = 31; i >= 0; i--) {
- ret = phyread(dev, i, PHY_DETECT_REG, &phyreg);
+ ret = phyread(priv, i, PHY_DETECT_REG, &phyreg);
if (!ret && (phyreg != 0xFFFF) &&
((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
/* Found a valid PHY address */
priv->phyaddr = i;
debug("axiemac: Found valid phy address, %x\n",
- phyreg);
+ i);
break;
}
}
@@ -256,6 +257,18 @@ static int setup_phy(struct eth_device *dev)
phydev->advertising = phydev->supported;
priv->phydev = phydev;
phy_config(phydev);
+
+ return 0;
+}
+
+/* Setting axi emac and phy to proper setting */
+static int setup_phy(struct udevice *dev)
+{
+ u32 speed, emmc_reg;
+ struct axidma_priv *priv = dev_get_priv(dev);
+ struct axi_regs *regs = priv->iobase;
+ struct phy_device *phydev = priv->phydev;
+
if (phy_startup(phydev)) {
printf("axiemac: could not initialize PHY %s\n",
phydev->dev->name);
@@ -299,9 +312,9 @@ static int setup_phy(struct eth_device *dev)
}
/* STOP DMA transfers */
-static void axiemac_halt(struct eth_device *dev)
+static void axiemac_stop(struct udevice *dev)
{
- struct axidma_priv *priv = dev->priv;
+ struct axidma_priv *priv = dev_get_priv(dev);
u32 temp;
/* Stop the hardware */
@@ -316,9 +329,9 @@ static void axiemac_halt(struct eth_device *dev)
debug("axiemac: Halted\n");
}
-static int axi_ethernet_init(struct eth_device *dev)
+static int axi_ethernet_init(struct axidma_priv *priv)
{
- struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+ struct axi_regs *regs = priv->iobase;
u32 timeout = 200;
/*
@@ -359,25 +372,26 @@ static int axi_ethernet_init(struct eth_device *dev)
return 0;
}
-static int axiemac_setup_mac(struct eth_device *dev)
+static int axiemac_write_hwaddr(struct udevice *dev)
{
- struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct axidma_priv *priv = dev_get_priv(dev);
+ struct axi_regs *regs = priv->iobase;
/* Set the MAC address */
- int val = ((dev->enetaddr[3] << 24) | (dev->enetaddr[2] << 16) |
- (dev->enetaddr[1] << 8) | (dev->enetaddr[0]));
+ int val = ((pdata->enetaddr[3] << 24) | (pdata->enetaddr[2] << 16) |
+ (pdata->enetaddr[1] << 8) | (pdata->enetaddr[0]));
out_be32(&regs->uaw0, val);
- val = (dev->enetaddr[5] << 8) | dev->enetaddr[4] ;
+ val = (pdata->enetaddr[5] << 8) | pdata->enetaddr[4];
val |= in_be32(&regs->uaw1) & ~XAE_UAW1_UNICASTADDR_MASK;
out_be32(&regs->uaw1, val);
return 0;
}
/* Reset DMA engine */
-static void axi_dma_init(struct eth_device *dev)
+static void axi_dma_init(struct axidma_priv *priv)
{
- struct axidma_priv *priv = dev->priv;
u32 timeout = 500;
/* Reset the engine so the hardware starts from a known state */
@@ -388,9 +402,9 @@ static void axi_dma_init(struct eth_device *dev)
while (timeout--) {
/* Check transmit/receive channel */
/* Reset is done when the reset bit is low */
- if (!(in_be32(&priv->dmatx->control) |
+ if (!((in_be32(&priv->dmatx->control) |
in_be32(&priv->dmarx->control))
- & XAXIDMA_CR_RESET_MASK) {
+ & XAXIDMA_CR_RESET_MASK)) {
break;
}
}
@@ -398,10 +412,10 @@ static void axi_dma_init(struct eth_device *dev)
printf("%s: Timeout\n", __func__);
}
-static int axiemac_init(struct eth_device *dev, bd_t * bis)
+static int axiemac_start(struct udevice *dev)
{
- struct axidma_priv *priv = dev->priv;
- struct axi_regs *regs = (struct axi_regs *)dev->iobase;
+ struct axidma_priv *priv = dev_get_priv(dev);
+ struct axi_regs *regs = priv->iobase;
u32 temp;
debug("axiemac: Init started\n");
@@ -411,10 +425,10 @@ static int axiemac_init(struct eth_device *dev, bd_t * bis)
* reset, and since AXIDMA reset line is connected to AxiEthernet, this
* would ensure a reset of AxiEthernet.
*/
- axi_dma_init(dev);
+ axi_dma_init(priv);
/* Initialize AxiEthernet hardware. */
- if (axi_ethernet_init(dev))
+ if (axi_ethernet_init(priv))
return -1;
/* Disable all RX interrupts before RxBD space setup */
@@ -452,7 +466,7 @@ static int axiemac_init(struct eth_device *dev, bd_t * bis)
/* PHY setup */
if (!setup_phy(dev)) {
- axiemac_halt(dev);
+ axiemac_stop(dev);
return -1;
}
@@ -460,9 +474,9 @@ static int axiemac_init(struct eth_device *dev, bd_t * bis)
return 0;
}
-static int axiemac_send(struct eth_device *dev, void *ptr, int len)
+static int axiemac_send(struct udevice *dev, void *ptr, int len)
{
- struct axidma_priv *priv = dev->priv;
+ struct axidma_priv *priv = dev_get_priv(dev);
u32 timeout;
if (len > PKTSIZE_ALIGN)
@@ -498,8 +512,8 @@ static int axiemac_send(struct eth_device *dev, void *ptr, int len)
/* Wait for transmission to complete */
debug("axiemac: Waiting for tx to be done\n");
timeout = 200;
- while (timeout && (!in_be32(&priv->dmatx->status) &
- (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) {
+ while (timeout && (!(in_be32(&priv->dmatx->status) &
+ (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK)))) {
timeout--;
udelay(1);
}
@@ -512,10 +526,9 @@ static int axiemac_send(struct eth_device *dev, void *ptr, int len)
return 0;
}
-static int isrxready(struct eth_device *dev)
+static int isrxready(struct axidma_priv *priv)
{
u32 status;
- struct axidma_priv *priv = dev->priv;
/* Read pending interrupts */
status = in_be32(&priv->dmarx->status);
@@ -533,15 +546,15 @@ static int isrxready(struct eth_device *dev)
return 0;
}
-static int axiemac_recv(struct eth_device *dev)
+static int axiemac_recv(struct udevice *dev, int flags, uchar **packetp)
{
u32 length;
- struct axidma_priv *priv = dev->priv;
+ struct axidma_priv *priv = dev_get_priv(dev);
u32 temp;
/* Wait for an incoming packet */
- if (!isrxready(dev))
- return 0;
+ if (!isrxready(priv))
+ return -1;
debug("axiemac: RX data ready\n");
@@ -554,9 +567,14 @@ static int axiemac_recv(struct eth_device *dev)
#ifdef DEBUG
print_buffer(&rxframe, &rxframe[0], 1, length, 16);
#endif
- /* Pass the received frame up for processing */
- if (length)
- net_process_received_packet(rxframe, length);
+
+ *packetp = rxframe;
+ return length;
+}
+
+static int axiemac_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+ struct axidma_priv *priv = dev_get_priv(dev);
#ifdef DEBUG
/* It is useful to clear buffer to be sure that it is consistent */
@@ -581,76 +599,128 @@ static int axiemac_recv(struct eth_device *dev)
debug("axiemac: RX completed, framelength = %d\n", length);
- return length;
+ return 0;
}
-static int axiemac_miiphy_read(const char *devname, uchar addr,
- uchar reg, ushort *val)
+static int axiemac_miiphy_read(struct mii_dev *bus, int addr,
+ int devad, int reg)
{
- struct eth_device *dev = eth_get_dev();
- u32 ret;
+ int ret;
+ u16 value;
- ret = phyread(dev, addr, reg, val);
- debug("axiemac: Read MII 0x%x, 0x%x, 0x%x\n", addr, reg, *val);
- return ret;
+ ret = phyread(bus->priv, addr, reg, &value);
+ debug("axiemac: Read MII 0x%x, 0x%x, 0x%x, %d\n", addr, reg,
+ value, ret);
+ return value;
}
-static int axiemac_miiphy_write(const char *devname, uchar addr,
- uchar reg, ushort val)
+static int axiemac_miiphy_write(struct mii_dev *bus, int addr, int devad,
+ int reg, u16 value)
{
- struct eth_device *dev = eth_get_dev();
-
- debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, val);
- return phywrite(dev, addr, reg, val);
+ debug("axiemac: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, value);
+ return phywrite(bus->priv, addr, reg, value);
}
-static int axiemac_bus_reset(struct mii_dev *bus)
+static int axi_emac_probe(struct udevice *dev)
{
- debug("axiemac: Bus reset\n");
+ struct axidma_priv *priv = dev_get_priv(dev);
+ int ret;
+
+ priv->bus = mdio_alloc();
+ priv->bus->read = axiemac_miiphy_read;
+ priv->bus->write = axiemac_miiphy_write;
+ priv->bus->priv = priv;
+ strcpy(priv->bus->name, "axi_emac");
+
+ ret = mdio_register(priv->bus);
+ if (ret)
+ return ret;
+
+ axiemac_phy_init(dev);
+
return 0;
}
-int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr,
- unsigned long dma_addr)
+static int axi_emac_remove(struct udevice *dev)
{
- struct eth_device *dev;
- struct axidma_priv *priv;
+ struct axidma_priv *priv = dev_get_priv(dev);
- dev = calloc(1, sizeof(struct eth_device));
- if (dev == NULL)
- return -1;
+ free(priv->phydev);
+ mdio_unregister(priv->bus);
+ mdio_free(priv->bus);
- dev->priv = calloc(1, sizeof(struct axidma_priv));
- if (dev->priv == NULL) {
- free(dev);
- return -1;
- }
- priv = dev->priv;
+ return 0;
+}
- sprintf(dev->name, "aximac.%lx", base_addr);
+static const struct eth_ops axi_emac_ops = {
+ .start = axiemac_start,
+ .send = axiemac_send,
+ .recv = axiemac_recv,
+ .free_pkt = axiemac_free_pkt,
+ .stop = axiemac_stop,
+ .write_hwaddr = axiemac_write_hwaddr,
+};
- dev->iobase = base_addr;
- priv->dmatx = (struct axidma_reg *)dma_addr;
+static int axi_emac_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct axidma_priv *priv = dev_get_priv(dev);
+ int offset = 0;
+ const char *phy_mode;
+
+ pdata->iobase = (phys_addr_t)dev_get_addr(dev);
+ priv->iobase = (struct axi_regs *)pdata->iobase;
+
+ offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+ "axistream-connected");
+ if (offset <= 0) {
+ printf("%s: axistream is not found\n", __func__);
+ return -EINVAL;
+ }
+ priv->dmatx = (struct axidma_reg *)fdtdec_get_int(gd->fdt_blob,
+ offset, "reg", 0);
+ if (!priv->dmatx) {
+ printf("%s: axi_dma register space not found\n", __func__);
+ return -EINVAL;
+ }
/* RX channel offset is 0x30 */
- priv->dmarx = (struct axidma_reg *)(dma_addr + 0x30);
- dev->init = axiemac_init;
- dev->halt = axiemac_halt;
- dev->send = axiemac_send;
- dev->recv = axiemac_recv;
- dev->write_hwaddr = axiemac_setup_mac;
-
-#ifdef CONFIG_PHY_ADDR
- priv->phyaddr = CONFIG_PHY_ADDR;
-#else
+ priv->dmarx = (struct axidma_reg *)((u32)priv->dmatx + 0x30);
+
priv->phyaddr = -1;
-#endif
- eth_register(dev);
+ offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+ "phy-handle");
+ if (offset > 0)
+ priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
+
+ phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+ if (phy_mode)
+ pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+ if (pdata->phy_interface == -1) {
+ debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+ return -EINVAL;
+ }
+ priv->interface = pdata->phy_interface;
+
+ printf("AXI EMAC: %lx, phyaddr %d, interface %s\n", (ulong)priv->iobase,
+ priv->phyaddr, phy_string_for_interface(priv->interface));
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
- miiphy_register(dev->name, axiemac_miiphy_read, axiemac_miiphy_write);
- priv->bus = miiphy_get_dev_by_name(dev->name);
- priv->bus->reset = axiemac_bus_reset;
-#endif
- return 1;
+ return 0;
}
+
+static const struct udevice_id axi_emac_ids[] = {
+ { .compatible = "xlnx,axi-ethernet-1.00.a" },
+ { }
+};
+
+U_BOOT_DRIVER(axi_emac) = {
+ .name = "axi_emac",
+ .id = UCLASS_ETH,
+ .of_match = axi_emac_ids,
+ .ofdata_to_platdata = axi_emac_ofdata_to_platdata,
+ .probe = axi_emac_probe,
+ .remove = axi_emac_remove,
+ .ops = &axi_emac_ops,
+ .priv_auto_alloc_size = sizeof(struct axidma_priv),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 564205df83..5862bf0a7e 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -10,27 +10,25 @@
#include <common.h>
#include <net.h>
#include <config.h>
+#include <dm.h>
+#include <console.h>
#include <malloc.h>
#include <asm/io.h>
+#include <phy.h>
+#include <miiphy.h>
#include <fdtdec.h>
+#include <asm-generic/errno.h>
+#include <linux/kernel.h>
-#undef DEBUG
+DECLARE_GLOBAL_DATA_PTR;
#define ENET_ADDR_LENGTH 6
-
-/* EmacLite constants */
-#define XEL_BUFFER_OFFSET 0x0800 /* Next buffer's offset */
-#define XEL_TPLR_OFFSET 0x07F4 /* Tx packet length */
-#define XEL_TSR_OFFSET 0x07FC /* Tx status */
-#define XEL_RSR_OFFSET 0x17FC /* Rx status */
-#define XEL_RXBUFF_OFFSET 0x1000 /* Receive Buffer */
+#define ETH_FCS_LEN 4 /* Octets in the FCS */
/* Xmit complete */
#define XEL_TSR_XMIT_BUSY_MASK 0x00000001UL
/* Xmit interrupt enable bit */
#define XEL_TSR_XMIT_IE_MASK 0x00000008UL
-/* Buffer is active, SW bit only */
-#define XEL_TSR_XMIT_ACTIVE_MASK 0x80000000UL
/* Program the MAC address */
#define XEL_TSR_PROGRAM_MASK 0x00000002UL
/* define for programming the MAC address into the EMAC Lite */
@@ -46,14 +44,56 @@
/* Recv interrupt enable bit */
#define XEL_RSR_RECV_IE_MASK 0x00000008UL
+/* MDIO Address Register Bit Masks */
+#define XEL_MDIOADDR_REGADR_MASK 0x0000001F /* Register Address */
+#define XEL_MDIOADDR_PHYADR_MASK 0x000003E0 /* PHY Address */
+#define XEL_MDIOADDR_PHYADR_SHIFT 5
+#define XEL_MDIOADDR_OP_MASK 0x00000400 /* RD/WR Operation */
+
+/* MDIO Write Data Register Bit Masks */
+#define XEL_MDIOWR_WRDATA_MASK 0x0000FFFF /* Data to be Written */
+
+/* MDIO Read Data Register Bit Masks */
+#define XEL_MDIORD_RDDATA_MASK 0x0000FFFF /* Data to be Read */
+
+/* MDIO Control Register Bit Masks */
+#define XEL_MDIOCTRL_MDIOSTS_MASK 0x00000001 /* MDIO Status Mask */
+#define XEL_MDIOCTRL_MDIOEN_MASK 0x00000008 /* MDIO Enable */
+
+struct emaclite_regs {
+ u32 tx_ping; /* 0x0 - TX Ping buffer */
+ u32 reserved1[504];
+ u32 mdioaddr; /* 0x7e4 - MDIO Address Register */
+ u32 mdiowr; /* 0x7e8 - MDIO Write Data Register */
+ u32 mdiord;/* 0x7ec - MDIO Read Data Register */
+ u32 mdioctrl; /* 0x7f0 - MDIO Control Register */
+ u32 tx_ping_tplr; /* 0x7f4 - Tx packet length */
+ u32 global_interrupt; /* 0x7f8 - Global interrupt enable */
+ u32 tx_ping_tsr; /* 0x7fc - Tx status */
+ u32 tx_pong; /* 0x800 - TX Pong buffer */
+ u32 reserved2[508];
+ u32 tx_pong_tplr; /* 0xff4 - Tx packet length */
+ u32 reserved3; /* 0xff8 */
+ u32 tx_pong_tsr; /* 0xffc - Tx status */
+ u32 rx_ping; /* 0x1000 - Receive Buffer */
+ u32 reserved4[510];
+ u32 rx_ping_rsr; /* 0x17fc - Rx status */
+ u32 rx_pong; /* 0x1800 - Receive Buffer */
+ u32 reserved5[510];
+ u32 rx_pong_rsr; /* 0x1ffc - Rx status */
+};
+
struct xemaclite {
- u32 nexttxbuffertouse; /* Next TX buffer to write to */
- u32 nextrxbuffertouse; /* Next RX buffer to read from */
+ bool use_rx_pong_buffer_next; /* Next RX buffer to read from */
u32 txpp; /* TX ping pong buffer */
u32 rxpp; /* RX ping pong buffer */
+ int phyaddr;
+ struct emaclite_regs *regs;
+ struct phy_device *phydev;
+ struct mii_dev *bus;
};
-static u32 etherrxbuff[PKTSIZE_ALIGN/4]; /* Receive buffer */
+static uchar etherrxbuff[PKTSIZE_ALIGN]; /* Receive buffer */
static void xemaclite_alignedread(u32 *srcptr, void *destptr, u32 bytecount)
{
@@ -81,7 +121,7 @@ static void xemaclite_alignedread(u32 *srcptr, void *destptr, u32 bytecount)
*to8ptr++ = *from8ptr++;
}
-static void xemaclite_alignedwrite(void *srcptr, u32 destptr, u32 bytecount)
+static void xemaclite_alignedwrite(void *srcptr, u32 *destptr, u32 bytecount)
{
u32 i;
u32 alignbuffer;
@@ -107,42 +147,206 @@ static void xemaclite_alignedwrite(void *srcptr, u32 destptr, u32 bytecount)
*to32ptr++ = alignbuffer;
}
-static void emaclite_halt(struct eth_device *dev)
+static int wait_for_bit(const char *func, u32 *reg, const u32 mask,
+ bool set, unsigned int timeout)
+{
+ u32 val;
+ unsigned long start = get_timer(0);
+
+ while (1) {
+ val = readl(reg);
+
+ if (!set)
+ val = ~val;
+
+ if ((val & mask) == mask)
+ return 0;
+
+ if (get_timer(start) > timeout)
+ break;
+
+ if (ctrlc()) {
+ puts("Abort\n");
+ return -EINTR;
+ }
+
+ udelay(1);
+ }
+
+ debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
+ func, reg, mask, set);
+
+ return -ETIMEDOUT;
+}
+
+static int mdio_wait(struct emaclite_regs *regs)
{
- debug("eth_halt\n");
+ return wait_for_bit(__func__, &regs->mdioctrl,
+ XEL_MDIOCTRL_MDIOSTS_MASK, false, 2000);
}
-static int emaclite_init(struct eth_device *dev, bd_t *bis)
+static u32 phyread(struct xemaclite *emaclite, u32 phyaddress, u32 registernum,
+ u16 *data)
{
- struct xemaclite *emaclite = dev->priv;
+ struct emaclite_regs *regs = emaclite->regs;
+
+ if (mdio_wait(regs))
+ return 1;
+
+ u32 ctrl_reg = in_be32(&regs->mdioctrl);
+ out_be32(&regs->mdioaddr, XEL_MDIOADDR_OP_MASK |
+ ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum));
+ out_be32(&regs->mdioctrl, ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
+
+ if (mdio_wait(regs))
+ return 1;
+
+ /* Read data */
+ *data = in_be32(&regs->mdiord);
+ return 0;
+}
+
+static u32 phywrite(struct xemaclite *emaclite, u32 phyaddress, u32 registernum,
+ u16 data)
+{
+ struct emaclite_regs *regs = emaclite->regs;
+
+ if (mdio_wait(regs))
+ return 1;
+
+ /*
+ * Write the PHY address, register number and clear the OP bit in the
+ * MDIO Address register and then write the value into the MDIO Write
+ * Data register. Finally, set the Status bit in the MDIO Control
+ * register to start a MDIO write transaction.
+ */
+ u32 ctrl_reg = in_be32(&regs->mdioctrl);
+ out_be32(&regs->mdioaddr, ~XEL_MDIOADDR_OP_MASK &
+ ((phyaddress << XEL_MDIOADDR_PHYADR_SHIFT) | registernum));
+ out_be32(&regs->mdiowr, data);
+ out_be32(&regs->mdioctrl, ctrl_reg | XEL_MDIOCTRL_MDIOSTS_MASK);
+
+ if (mdio_wait(regs))
+ return 1;
+
+ return 0;
+}
+
+static void emaclite_stop(struct udevice *dev)
+{
+ debug("eth_stop\n");
+}
+
+/* Use MII register 1 (MII status register) to detect PHY */
+#define PHY_DETECT_REG 1
+
+/* Mask used to verify certain PHY features (or register contents)
+ * in the register above:
+ * 0x1000: 10Mbps full duplex support
+ * 0x0800: 10Mbps half duplex support
+ * 0x0008: Auto-negotiation support
+ */
+#define PHY_DETECT_MASK 0x1808
+
+static int setup_phy(struct udevice *dev)
+{
+ int i;
+ u16 phyreg;
+ struct xemaclite *emaclite = dev_get_priv(dev);
+ struct phy_device *phydev;
+
+ u32 supported = SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full;
+
+ if (emaclite->phyaddr != -1) {
+ phyread(emaclite, emaclite->phyaddr, PHY_DETECT_REG, &phyreg);
+ if ((phyreg != 0xFFFF) &&
+ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+ /* Found a valid PHY address */
+ debug("Default phy address %d is valid\n",
+ emaclite->phyaddr);
+ } else {
+ debug("PHY address is not setup correctly %d\n",
+ emaclite->phyaddr);
+ emaclite->phyaddr = -1;
+ }
+ }
+
+ if (emaclite->phyaddr == -1) {
+ /* detect the PHY address */
+ for (i = 31; i >= 0; i--) {
+ phyread(emaclite, i, PHY_DETECT_REG, &phyreg);
+ if ((phyreg != 0xFFFF) &&
+ ((phyreg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+ /* Found a valid PHY address */
+ emaclite->phyaddr = i;
+ debug("emaclite: Found valid phy address, %d\n",
+ i);
+ break;
+ }
+ }
+ }
+
+ /* interface - look at tsec */
+ phydev = phy_connect(emaclite->bus, emaclite->phyaddr, dev,
+ PHY_INTERFACE_MODE_MII);
+ /*
+ * Phy can support 1000baseT but device NOT that's why phydev->supported
+ * must be setup for 1000baseT. phydev->advertising setups what speeds
+ * will be used for autonegotiation where 1000baseT must be disabled.
+ */
+ phydev->supported = supported | SUPPORTED_1000baseT_Half |
+ SUPPORTED_1000baseT_Full;
+ phydev->advertising = supported;
+ emaclite->phydev = phydev;
+ phy_config(phydev);
+ phy_startup(phydev);
+
+ if (!phydev->link) {
+ printf("%s: No link.\n", phydev->dev->name);
+ return 0;
+ }
+
+ /* Do not setup anything */
+ return 1;
+}
+
+static int emaclite_start(struct udevice *dev)
+{
+ struct xemaclite *emaclite = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct emaclite_regs *regs = emaclite->regs;
+
debug("EmacLite Initialization Started\n");
/*
* TX - TX_PING & TX_PONG initialization
*/
/* Restart PING TX */
- out_be32 (dev->iobase + XEL_TSR_OFFSET, 0);
+ out_be32(&regs->tx_ping_tsr, 0);
/* Copy MAC address */
- xemaclite_alignedwrite(dev->enetaddr, dev->iobase, ENET_ADDR_LENGTH);
+ xemaclite_alignedwrite(pdata->enetaddr, &regs->tx_ping,
+ ENET_ADDR_LENGTH);
/* Set the length */
- out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH);
+ out_be32(&regs->tx_ping_tplr, ENET_ADDR_LENGTH);
/* Update the MAC address in the EMAC Lite */
- out_be32 (dev->iobase + XEL_TSR_OFFSET, XEL_TSR_PROG_MAC_ADDR);
+ out_be32(&regs->tx_ping_tsr, XEL_TSR_PROG_MAC_ADDR);
/* Wait for EMAC Lite to finish with the MAC address update */
- while ((in_be32 (dev->iobase + XEL_TSR_OFFSET) &
+ while ((in_be32 (&regs->tx_ping_tsr) &
XEL_TSR_PROG_MAC_ADDR) != 0)
;
if (emaclite->txpp) {
/* The same operation with PONG TX */
- out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET, 0);
- xemaclite_alignedwrite(dev->enetaddr, dev->iobase +
- XEL_BUFFER_OFFSET, ENET_ADDR_LENGTH);
- out_be32 (dev->iobase + XEL_TPLR_OFFSET, ENET_ADDR_LENGTH);
- out_be32 (dev->iobase + XEL_TSR_OFFSET + XEL_BUFFER_OFFSET,
- XEL_TSR_PROG_MAC_ADDR);
- while ((in_be32 (dev->iobase + XEL_TSR_OFFSET +
- XEL_BUFFER_OFFSET) & XEL_TSR_PROG_MAC_ADDR) != 0)
+ out_be32(&regs->tx_pong_tsr, 0);
+ xemaclite_alignedwrite(pdata->enetaddr, &regs->tx_pong,
+ ENET_ADDR_LENGTH);
+ out_be32(&regs->tx_pong_tplr, ENET_ADDR_LENGTH);
+ out_be32(&regs->tx_pong_tsr, XEL_TSR_PROG_MAC_ADDR);
+ while ((in_be32(&regs->tx_pong_tsr) &
+ XEL_TSR_PROG_MAC_ADDR) != 0)
;
}
@@ -150,52 +354,48 @@ static int emaclite_init(struct eth_device *dev, bd_t *bis)
* RX - RX_PING & RX_PONG initialization
*/
/* Write out the value to flush the RX buffer */
- out_be32 (dev->iobase + XEL_RSR_OFFSET, XEL_RSR_RECV_IE_MASK);
+ out_be32(&regs->rx_ping_rsr, XEL_RSR_RECV_IE_MASK);
if (emaclite->rxpp)
- out_be32 (dev->iobase + XEL_RSR_OFFSET + XEL_BUFFER_OFFSET,
- XEL_RSR_RECV_IE_MASK);
+ out_be32(&regs->rx_pong_rsr, XEL_RSR_RECV_IE_MASK);
+
+ out_be32(&regs->mdioctrl, XEL_MDIOCTRL_MDIOEN_MASK);
+ if (in_be32(&regs->mdioctrl) & XEL_MDIOCTRL_MDIOEN_MASK)
+ if (!setup_phy(dev))
+ return -1;
debug("EmacLite Initialization complete\n");
return 0;
}
-static int xemaclite_txbufferavailable(struct eth_device *dev)
+static int xemaclite_txbufferavailable(struct xemaclite *emaclite)
{
- u32 reg;
- u32 txpingbusy;
- u32 txpongbusy;
- struct xemaclite *emaclite = dev->priv;
+ u32 tmp;
+ struct emaclite_regs *regs = emaclite->regs;
/*
* Read the other buffer register
* and determine if the other buffer is available
*/
- reg = in_be32 (dev->iobase +
- emaclite->nexttxbuffertouse + 0);
- txpingbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
- XEL_TSR_XMIT_BUSY_MASK);
-
- reg = in_be32 (dev->iobase +
- (emaclite->nexttxbuffertouse ^ XEL_TSR_OFFSET) + 0);
- txpongbusy = ((reg & XEL_TSR_XMIT_BUSY_MASK) ==
- XEL_TSR_XMIT_BUSY_MASK);
+ tmp = ~in_be32(&regs->tx_ping_tsr);
+ if (emaclite->txpp)
+ tmp |= ~in_be32(&regs->tx_pong_tsr);
- return !(txpingbusy && txpongbusy);
+ return !(tmp & XEL_TSR_XMIT_BUSY_MASK);
}
-static int emaclite_send(struct eth_device *dev, void *ptr, int len)
+static int emaclite_send(struct udevice *dev, void *ptr, int len)
{
u32 reg;
- u32 baseaddress;
- struct xemaclite *emaclite = dev->priv;
+ struct xemaclite *emaclite = dev_get_priv(dev);
+ struct emaclite_regs *regs = emaclite->regs;
u32 maxtry = 1000;
if (len > PKTSIZE)
len = PKTSIZE;
- while (!xemaclite_txbufferavailable(dev) && maxtry) {
+ while (xemaclite_txbufferavailable(emaclite) && maxtry) {
udelay(10);
maxtry--;
}
@@ -203,58 +403,40 @@ static int emaclite_send(struct eth_device *dev, void *ptr, int len)
if (!maxtry) {
printf("Error: Timeout waiting for ethernet TX buffer\n");
/* Restart PING TX */
- out_be32 (dev->iobase + XEL_TSR_OFFSET, 0);
+ out_be32(&regs->tx_ping_tsr, 0);
if (emaclite->txpp) {
- out_be32 (dev->iobase + XEL_TSR_OFFSET +
- XEL_BUFFER_OFFSET, 0);
+ out_be32(&regs->tx_pong_tsr, 0);
}
return -1;
}
- /* Determine the expected TX buffer address */
- baseaddress = (dev->iobase + emaclite->nexttxbuffertouse);
-
/* Determine if the expected buffer address is empty */
- reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
- if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
- && ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
- & XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
-
- if (emaclite->txpp)
- emaclite->nexttxbuffertouse ^= XEL_BUFFER_OFFSET;
-
- debug("Send packet from 0x%x\n", baseaddress);
+ reg = in_be32(&regs->tx_ping_tsr);
+ if ((reg & XEL_TSR_XMIT_BUSY_MASK) == 0) {
+ debug("Send packet from tx_ping buffer\n");
/* Write the frame to the buffer */
- xemaclite_alignedwrite(ptr, baseaddress, len);
- out_be32 (baseaddress + XEL_TPLR_OFFSET,(len &
- (XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO)));
- reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+ xemaclite_alignedwrite(ptr, &regs->tx_ping, len);
+ out_be32(&regs->tx_ping_tplr, len &
+ (XEL_TPLR_LENGTH_MASK_HI | XEL_TPLR_LENGTH_MASK_LO));
+ reg = in_be32(&regs->tx_ping_tsr);
reg |= XEL_TSR_XMIT_BUSY_MASK;
- if ((reg & XEL_TSR_XMIT_IE_MASK) != 0)
- reg |= XEL_TSR_XMIT_ACTIVE_MASK;
- out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
+ out_be32(&regs->tx_ping_tsr, reg);
return 0;
}
if (emaclite->txpp) {
- /* Switch to second buffer */
- baseaddress ^= XEL_BUFFER_OFFSET;
/* Determine if the expected buffer address is empty */
- reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
- if (((reg & XEL_TSR_XMIT_BUSY_MASK) == 0)
- && ((in_be32 ((baseaddress) + XEL_TSR_OFFSET)
- & XEL_TSR_XMIT_ACTIVE_MASK) == 0)) {
- debug("Send packet from 0x%x\n", baseaddress);
+ reg = in_be32(&regs->tx_pong_tsr);
+ if ((reg & XEL_TSR_XMIT_BUSY_MASK) == 0) {
+ debug("Send packet from tx_pong buffer\n");
/* Write the frame to the buffer */
- xemaclite_alignedwrite(ptr, baseaddress, len);
- out_be32 (baseaddress + XEL_TPLR_OFFSET, (len &
- (XEL_TPLR_LENGTH_MASK_HI |
- XEL_TPLR_LENGTH_MASK_LO)));
- reg = in_be32 (baseaddress + XEL_TSR_OFFSET);
+ xemaclite_alignedwrite(ptr, &regs->tx_pong, len);
+ out_be32(&regs->tx_pong_tplr, len &
+ (XEL_TPLR_LENGTH_MASK_HI |
+ XEL_TPLR_LENGTH_MASK_LO));
+ reg = in_be32(&regs->tx_pong_tsr);
reg |= XEL_TSR_XMIT_BUSY_MASK;
- if ((reg & XEL_TSR_XMIT_IE_MASK) != 0)
- reg |= XEL_TSR_XMIT_ACTIVE_MASK;
- out_be32 (baseaddress + XEL_TSR_OFFSET, reg);
+ out_be32(&regs->tx_pong_tsr, reg);
return 0;
}
}
@@ -263,130 +445,188 @@ static int emaclite_send(struct eth_device *dev, void *ptr, int len)
return -1;
}
-static int emaclite_recv(struct eth_device *dev)
+static int emaclite_recv(struct udevice *dev, int flags, uchar **packetp)
{
- u32 length;
- u32 reg;
- u32 baseaddress;
+ u32 length, first_read, reg, attempt = 0;
+ void *addr, *ack;
struct xemaclite *emaclite = dev->priv;
+ struct emaclite_regs *regs = emaclite->regs;
+ struct ethernet_hdr *eth;
+ struct ip_udp_hdr *ip;
+
+try_again:
+ if (!emaclite->use_rx_pong_buffer_next) {
+ reg = in_be32(&regs->rx_ping_rsr);
+ debug("Testing data at rx_ping\n");
+ if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
+ debug("Data found in rx_ping buffer\n");
+ addr = &regs->rx_ping;
+ ack = &regs->rx_ping_rsr;
+ } else {
+ debug("Data not found in rx_ping buffer\n");
+ /* Pong buffer is not available - return immediately */
+ if (!emaclite->rxpp)
+ return -1;
- baseaddress = dev->iobase + emaclite->nextrxbuffertouse;
- reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
- debug("Testing data at address 0x%x\n", baseaddress);
- if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
- if (emaclite->rxpp)
- emaclite->nextrxbuffertouse ^= XEL_BUFFER_OFFSET;
+ /* Try pong buffer if this is first attempt */
+ if (attempt++)
+ return -1;
+ emaclite->use_rx_pong_buffer_next =
+ !emaclite->use_rx_pong_buffer_next;
+ goto try_again;
+ }
} else {
-
- if (!emaclite->rxpp) {
- debug("No data was available - address 0x%x\n",
- baseaddress);
- return 0;
+ reg = in_be32(&regs->rx_pong_rsr);
+ debug("Testing data at rx_pong\n");
+ if ((reg & XEL_RSR_RECV_DONE_MASK) == XEL_RSR_RECV_DONE_MASK) {
+ debug("Data found in rx_pong buffer\n");
+ addr = &regs->rx_pong;
+ ack = &regs->rx_pong_rsr;
} else {
- baseaddress ^= XEL_BUFFER_OFFSET;
- reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
- if ((reg & XEL_RSR_RECV_DONE_MASK) !=
- XEL_RSR_RECV_DONE_MASK) {
- debug("No data was available - address 0x%x\n",
- baseaddress);
- return 0;
- }
+ debug("Data not found in rx_pong buffer\n");
+ /* Try ping buffer if this is first attempt */
+ if (attempt++)
+ return -1;
+ emaclite->use_rx_pong_buffer_next =
+ !emaclite->use_rx_pong_buffer_next;
+ goto try_again;
}
}
- /* Get the length of the frame that arrived */
- switch(((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET + 0xC))) &
- 0xFFFF0000 ) >> 16) {
- case 0x806:
- length = 42 + 20; /* FIXME size of ARP */
- debug("ARP Packet\n");
- break;
- case 0x800:
- length = 14 + 14 +
- (((ntohl(in_be32 (baseaddress + XEL_RXBUFF_OFFSET +
- 0x10))) & 0xFFFF0000) >> 16);
- /* FIXME size of IP packet */
- debug ("IP Packet\n");
- break;
- default:
- debug("Other Packet\n");
- length = PKTSIZE;
- break;
+
+ /* Read all bytes for ARP packet with 32bit alignment - 48bytes */
+ first_read = ALIGN(ETHER_HDR_SIZE + ARP_HDR_SIZE + ETH_FCS_LEN, 4);
+ xemaclite_alignedread(addr, etherrxbuff, first_read);
+
+ /* Detect real packet size */
+ eth = (struct ethernet_hdr *)etherrxbuff;
+ switch (ntohs(eth->et_protlen)) {
+ case PROT_ARP:
+ length = first_read;
+ debug("ARP Packet %x\n", length);
+ break;
+ case PROT_IP:
+ ip = (struct ip_udp_hdr *)(etherrxbuff + ETHER_HDR_SIZE);
+ length = ntohs(ip->ip_len);
+ length += ETHER_HDR_SIZE + ETH_FCS_LEN;
+ debug("IP Packet %x\n", length);
+ break;
+ default:
+ debug("Other Packet\n");
+ length = PKTSIZE;
+ break;
}
- xemaclite_alignedread((u32 *) (baseaddress + XEL_RXBUFF_OFFSET),
- etherrxbuff, length);
+ /* Read the rest of the packet which is longer then first read */
+ if (length != first_read)
+ xemaclite_alignedread(addr + first_read,
+ etherrxbuff + first_read,
+ length - first_read);
/* Acknowledge the frame */
- reg = in_be32 (baseaddress + XEL_RSR_OFFSET);
+ reg = in_be32(ack);
reg &= ~XEL_RSR_RECV_DONE_MASK;
- out_be32 (baseaddress + XEL_RSR_OFFSET, reg);
+ out_be32(ack, reg);
- debug("Packet receive from 0x%x, length %dB\n", baseaddress, length);
- net_process_received_packet((uchar *)etherrxbuff, length);
+ debug("Packet receive from 0x%p, length %dB\n", addr, length);
+ *packetp = etherrxbuff;
return length;
-
}
-int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
- int txpp, int rxpp)
+static int emaclite_miiphy_read(struct mii_dev *bus, int addr,
+ int devad, int reg)
{
- struct eth_device *dev;
- struct xemaclite *emaclite;
+ u32 ret;
+ u16 val = 0;
- dev = calloc(1, sizeof(*dev));
- if (dev == NULL)
- return -1;
+ ret = phyread(bus->priv, addr, reg, &val);
+ debug("emaclite: Read MII 0x%x, 0x%x, 0x%x, %d\n", addr, reg, val, ret);
+ return val;
+}
- emaclite = calloc(1, sizeof(struct xemaclite));
- if (emaclite == NULL) {
- free(dev);
- return -1;
- }
+static int emaclite_miiphy_write(struct mii_dev *bus, int addr, int devad,
+ int reg, u16 value)
+{
+ debug("emaclite: Write MII 0x%x, 0x%x, 0x%x\n", addr, reg, value);
+ return phywrite(bus->priv, addr, reg, value);
+}
+
+static int emaclite_probe(struct udevice *dev)
+{
+ struct xemaclite *emaclite = dev_get_priv(dev);
+ int ret;
- dev->priv = emaclite;
+ emaclite->bus = mdio_alloc();
+ emaclite->bus->read = emaclite_miiphy_read;
+ emaclite->bus->write = emaclite_miiphy_write;
+ emaclite->bus->priv = emaclite;
+ strcpy(emaclite->bus->name, "emaclite");
- emaclite->txpp = txpp;
- emaclite->rxpp = rxpp;
+ ret = mdio_register(emaclite->bus);
+ if (ret)
+ return ret;
- sprintf(dev->name, "Xelite.%lx", base_addr);
+ return 0;
+}
- dev->iobase = base_addr;
- dev->init = emaclite_init;
- dev->halt = emaclite_halt;
- dev->send = emaclite_send;
- dev->recv = emaclite_recv;
+static int emaclite_remove(struct udevice *dev)
+{
+ struct xemaclite *emaclite = dev_get_priv(dev);
- eth_register(dev);
+ free(emaclite->phydev);
+ mdio_unregister(emaclite->bus);
+ mdio_free(emaclite->bus);
- return 1;
+ return 0;
}
-#if CONFIG_IS_ENABLED(OF_CONTROL)
-int xilinx_emaclite_of_init(const void *blob)
+static const struct eth_ops emaclite_ops = {
+ .start = emaclite_start,
+ .send = emaclite_send,
+ .recv = emaclite_recv,
+ .stop = emaclite_stop,
+};
+
+static int emaclite_ofdata_to_platdata(struct udevice *dev)
{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct xemaclite *emaclite = dev_get_priv(dev);
int offset = 0;
- u32 ret = 0;
- u32 reg;
- do {
- offset = fdt_node_offset_by_compatible(blob, offset,
- "xlnx,xps-ethernetlite-1.00.a");
- if (offset != -1) {
- reg = fdtdec_get_addr(blob, offset, "reg");
- if (reg != FDT_ADDR_T_NONE) {
- u32 rxpp = fdtdec_get_int(blob, offset,
- "xlnx,rx-ping-pong", 0);
- u32 txpp = fdtdec_get_int(blob, offset,
- "xlnx,tx-ping-pong", 0);
- ret |= xilinx_emaclite_initialize(NULL, reg,
- txpp, rxpp);
- } else {
- debug("EMACLITE: Can't get base address\n");
- return -1;
- }
- }
- } while (offset != -1);
+ pdata->iobase = (phys_addr_t)dev_get_addr(dev);
+ emaclite->regs = (struct emaclite_regs *)pdata->iobase;
+
+ emaclite->phyaddr = -1;
+
+ offset = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset,
+ "phy-handle");
+ if (offset > 0)
+ emaclite->phyaddr = fdtdec_get_int(gd->fdt_blob, offset,
+ "reg", -1);
+
+ emaclite->txpp = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "xlnx,tx-ping-pong", 0);
+ emaclite->rxpp = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "xlnx,rx-ping-pong", 0);
- return ret;
+ printf("EMACLITE: %lx, phyaddr %d, %d/%d\n", (ulong)emaclite->regs,
+ emaclite->phyaddr, emaclite->txpp, emaclite->rxpp);
+
+ return 0;
}
-#endif
+
+static const struct udevice_id emaclite_ids[] = {
+ { .compatible = "xlnx,xps-ethernetlite-1.00.a" },
+ { }
+};
+
+U_BOOT_DRIVER(emaclite) = {
+ .name = "emaclite",
+ .id = UCLASS_ETH,
+ .of_match = emaclite_ids,
+ .ofdata_to_platdata = emaclite_ofdata_to_platdata,
+ .probe = emaclite_probe,
+ .remove = emaclite_remove,
+ .ops = &emaclite_ops,
+ .priv_auto_alloc_size = sizeof(struct xemaclite),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/xilinx_ll_temac.c b/drivers/net/xilinx_ll_temac.c
index 7cc86571e4..ca09546ab5 100644
--- a/drivers/net/xilinx_ll_temac.c
+++ b/drivers/net/xilinx_ll_temac.c
@@ -303,7 +303,8 @@ int xilinx_ll_temac_initialize(bd_t *bis, struct ll_temac_info *devinf)
if (devinf->devname) {
strncpy(dev->name, devinf->devname, sizeof(dev->name));
} else {
- snprintf(dev->name, sizeof(dev->name), "lltemac.%lx", devinf->base_addr);
+ snprintf(dev->name, sizeof(dev->name), "ll_tem.%lx",
+ devinf->base_addr);
devinf->devname = dev->name;
}
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 7059c8432a..b3821c31a9 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -19,6 +19,7 @@
#include <asm/io.h>
#include <phy.h>
#include <miiphy.h>
+#include <wait_bit.h>
#include <watchdog.h>
#include <asm/system.h>
#include <asm/arch/hardware.h>
@@ -56,7 +57,11 @@ DECLARE_GLOBAL_DATA_PTR;
#define ZYNQ_GEM_NWCFG_SPEED1000 0x000000400 /* 1Gbps operation */
#define ZYNQ_GEM_NWCFG_FDEN 0x000000002 /* Full Duplex mode */
#define ZYNQ_GEM_NWCFG_FSREM 0x000020000 /* FCS removal */
+#ifdef CONFIG_ARM64
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x000100000 /* Div pclk by 64, max 160MHz */
+#else
#define ZYNQ_GEM_NWCFG_MDCCLKDIV 0x0000c0000 /* Div pclk by 48, max 120MHz */
+#endif
#ifdef CONFIG_ARM64
# define ZYNQ_GEM_DBUS_WIDTH (1 << 21) /* 64 bit bus */
@@ -448,38 +453,6 @@ static int zynq_gem_init(struct udevice *dev)
return 0;
}
-static int wait_for_bit(const char *func, u32 *reg, const u32 mask,
- bool set, unsigned int timeout)
-{
- u32 val;
- unsigned long start = get_timer(0);
-
- while (1) {
- val = readl(reg);
-
- if (!set)
- val = ~val;
-
- if ((val & mask) == mask)
- return 0;
-
- if (get_timer(start) > timeout)
- break;
-
- if (ctrlc()) {
- puts("Abort\n");
- return -EINTR;
- }
-
- udelay(1);
- }
-
- debug("%s: Timeout (reg=%p mask=%08x wait_set=%i)\n",
- func, reg, mask, set);
-
- return -ETIMEDOUT;
-}
-
static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
{
u32 addr, size;
@@ -521,7 +494,7 @@ static int zynq_gem_send(struct udevice *dev, void *ptr, int len)
printf("TX buffers exhausted in mid frame\n");
return wait_for_bit(__func__, &regs->txsr, ZYNQ_GEM_TSR_DONE,
- true, 20000);
+ true, 20000, true);
}
/* Do not check frame_recd flag in rx_status register 0x20 - just poll BD */
OpenPOWER on IntegriCloud