summaryrefslogtreecommitdiff
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/Kconfig8
-rw-r--r--drivers/net/Makefile1
-rw-r--r--drivers/net/designware.c77
-rw-r--r--drivers/net/dwc_eth_qos.c6
-rw-r--r--drivers/net/dwc_eth_qos.h2
-rw-r--r--drivers/net/dwc_eth_qos_adi.c103
-rw-r--r--drivers/net/phy/miiphybb.c216
-rw-r--r--drivers/net/ravb.c81
-rw-r--r--drivers/net/sh_eth.c70
-rw-r--r--drivers/net/tsec.c39
10 files changed, 363 insertions, 240 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1563404ca17..3db784faedd 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -237,6 +237,13 @@ config DWC_ETH_QOS
Of Service) IP block. The IP supports many options for bus type,
clocking/reset structure, and feature list.
+config DWC_ETH_QOS_ADI
+ bool "Synopsys DWC Ethernet QOS device support for ADI SC59x-64 parts"
+ depends on DWC_ETH_QOS
+ help
+ The Synopsis Designware Ethernet QoS IP block with the specific
+ configuration used in the ADI ADSP-SC59X 64 bit SoCs
+
config DWC_ETH_QOS_IMX
bool "Synopsys DWC Ethernet QOS device support for IMX"
depends on DWC_ETH_QOS
@@ -852,6 +859,7 @@ config RENESAS_ETHER_SWITCH
config RENESAS_RAVB
bool "Renesas Ethernet AVB MAC"
depends on RCAR_64
+ select BITBANGMII
select PHYLIB
select PHY_ETHERNET_ID
help
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 80d70212971..d919d437c08 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -19,6 +19,7 @@ obj-$(CONFIG_DM_ETH_PHY) += eth-phy-uclass.o
obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
obj-$(CONFIG_DSA_SANDBOX) += dsa_sandbox.o
obj-$(CONFIG_DWC_ETH_QOS) += dwc_eth_qos.o
+obj-$(CONFIG_DWC_ETH_QOS_ADI) += dwc_eth_qos_adi.o
obj-$(CONFIG_DWC_ETH_QOS_IMX) += dwc_eth_qos_imx.o
obj-$(CONFIG_DWC_ETH_QOS_INTEL) += dwc_eth_qos_intel.o
obj-$(CONFIG_DWC_ETH_QOS_ROCKCHIP) += dwc_eth_qos_rockchip.o
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index 5a6e89c0575..0f93c25e3fe 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -227,9 +227,9 @@ static int dw_dm_mdio_init(const char *name, void *priv)
#endif
#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
-static int dw_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
+static int dw_eth_bb_mdio_active(struct mii_dev *miidev)
{
- struct dw_eth_dev *priv = bus->priv;
+ struct dw_eth_dev *priv = miidev->priv;
struct gpio_desc *desc = &priv->mdio_gpio;
desc->flags = 0;
@@ -238,9 +238,9 @@ static int dw_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
return 0;
}
-static int dw_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
+static int dw_eth_bb_mdio_tristate(struct mii_dev *miidev)
{
- struct dw_eth_dev *priv = bus->priv;
+ struct dw_eth_dev *priv = miidev->priv;
struct gpio_desc *desc = &priv->mdio_gpio;
desc->flags = 0;
@@ -249,9 +249,9 @@ static int dw_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
return 0;
}
-static int dw_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
+static int dw_eth_bb_set_mdio(struct mii_dev *miidev, int v)
{
- struct dw_eth_dev *priv = bus->priv;
+ struct dw_eth_dev *priv = miidev->priv;
if (v)
dm_gpio_set_value(&priv->mdio_gpio, 1);
@@ -261,18 +261,18 @@ static int dw_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
return 0;
}
-static int dw_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
+static int dw_eth_bb_get_mdio(struct mii_dev *miidev, int *v)
{
- struct dw_eth_dev *priv = bus->priv;
+ struct dw_eth_dev *priv = miidev->priv;
*v = dm_gpio_get_value(&priv->mdio_gpio);
return 0;
}
-static int dw_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
+static int dw_eth_bb_set_mdc(struct mii_dev *miidev, int v)
{
- struct dw_eth_dev *priv = bus->priv;
+ struct dw_eth_dev *priv = miidev->priv;
if (v)
dm_gpio_set_value(&priv->mdc_gpio, 1);
@@ -282,28 +282,48 @@ static int dw_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
return 0;
}
-static int dw_eth_bb_delay(struct bb_miiphy_bus *bus)
+static int dw_eth_bb_delay(struct mii_dev *miidev)
{
- struct dw_eth_dev *priv = bus->priv;
+ struct dw_eth_dev *priv = miidev->priv;
udelay(priv->bb_delay);
return 0;
}
+static const struct bb_miiphy_bus_ops dw_eth_bb_miiphy_bus_ops = {
+ .mdio_active = dw_eth_bb_mdio_active,
+ .mdio_tristate = dw_eth_bb_mdio_tristate,
+ .set_mdio = dw_eth_bb_set_mdio,
+ .get_mdio = dw_eth_bb_get_mdio,
+ .set_mdc = dw_eth_bb_set_mdc,
+ .delay = dw_eth_bb_delay,
+};
+
+static int dw_bb_miiphy_read(struct mii_dev *miidev, int addr,
+ int devad, int reg)
+{
+ return bb_miiphy_read(miidev, &dw_eth_bb_miiphy_bus_ops,
+ addr, devad, reg);
+}
+
+static int dw_bb_miiphy_write(struct mii_dev *miidev, int addr,
+ int devad, int reg, u16 value)
+{
+ return bb_miiphy_write(miidev, &dw_eth_bb_miiphy_bus_ops,
+ addr, devad, reg, value);
+}
+
static int dw_bb_mdio_init(const char *name, struct udevice *dev)
{
struct dw_eth_dev *dwpriv = dev_get_priv(dev);
- struct bb_miiphy_bus *bb_miiphy = bb_miiphy_alloc();
- struct mii_dev *bus;
+ struct mii_dev *bus = mdio_alloc();
int ret;
- if (!bb_miiphy) {
+ if (!bus) {
printf("Failed to allocate MDIO bus\n");
return -ENOMEM;
}
- bus = &bb_miiphy->mii;
-
debug("\n%s: use bitbang mii..\n", dev->name);
ret = gpio_request_by_name(dev, "snps,mdc-gpio", 0,
&dwpriv->mdc_gpio,
@@ -325,21 +345,13 @@ static int dw_bb_mdio_init(const char *name, struct udevice *dev)
dwpriv->dev = dev;
snprintf(bus->name, sizeof(bus->name), "%s", name);
- bus->read = bb_miiphy_read;
- bus->write = bb_miiphy_write;
+ bus->read = dw_bb_miiphy_read;
+ bus->write = dw_bb_miiphy_write;
#if CONFIG_IS_ENABLED(DM_GPIO)
bus->reset = dw_mdio_reset;
#endif
bus->priv = dwpriv;
- /* Copy the bus accessors and private data */
- bb_miiphy->mdio_active = dw_eth_bb_mdio_active;
- bb_miiphy->mdio_tristate = dw_eth_bb_mdio_tristate;
- bb_miiphy->set_mdio = dw_eth_bb_set_mdio;
- bb_miiphy->get_mdio = dw_eth_bb_get_mdio;
- bb_miiphy->set_mdc = dw_eth_bb_set_mdc;
- bb_miiphy->delay = dw_eth_bb_delay;
-
return mdio_register(bus);
}
#endif
@@ -840,7 +852,6 @@ int designware_eth_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct dw_eth_dev *priv = dev_get_priv(dev);
- bool __maybe_unused bbmiiphy = false;
phys_addr_t iobase = pdata->iobase;
void *ioaddr;
int ret, err;
@@ -932,8 +943,7 @@ int designware_eth_probe(struct udevice *dev)
priv->max_speed = pdata->max_speed;
#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
- bbmiiphy = dev_read_bool(dev, "snps,bitbang-mii");
- if (bbmiiphy) {
+ if (dev_read_bool(dev, "snps,bitbang-mii")) {
ret = dw_bb_mdio_init(dev->name, dev);
if (ret) {
err = ret;
@@ -963,12 +973,7 @@ int designware_eth_probe(struct udevice *dev)
/* continue here for cleanup if no PHY found */
err = ret;
mdio_unregister(priv->bus);
-#if IS_ENABLED(CONFIG_BITBANGMII) && IS_ENABLED(CONFIG_DM_GPIO)
- if (bbmiiphy)
- bb_miiphy_free(container_of(priv->bus, struct bb_miiphy_bus, mii));
- else
-#endif
- mdio_free(priv->bus);
+ mdio_free(priv->bus);
mdio_err:
#ifdef CONFIG_CLK
diff --git a/drivers/net/dwc_eth_qos.c b/drivers/net/dwc_eth_qos.c
index 2279481d935..b4ec3614696 100644
--- a/drivers/net/dwc_eth_qos.c
+++ b/drivers/net/dwc_eth_qos.c
@@ -1632,6 +1632,12 @@ static const struct udevice_id eqos_ids[] = {
.data = (ulong)&eqos_jh7110_config
},
#endif
+#if IS_ENABLED(CONFIG_DWC_ETH_QOS_ADI)
+ {
+ .compatible = "adi,sc59x-dwmac-eqos",
+ .data = (ulong)&eqos_adi_config
+ },
+#endif
{ }
};
diff --git a/drivers/net/dwc_eth_qos.h b/drivers/net/dwc_eth_qos.h
index 123f98d5d53..403e8203974 100644
--- a/drivers/net/dwc_eth_qos.h
+++ b/drivers/net/dwc_eth_qos.h
@@ -87,6 +87,7 @@ struct eqos_mac_regs {
#define EQOS_MAC_MDIO_ADDRESS_CR_MASK GENMASK(11, 8)
#define EQOS_MAC_MDIO_ADDRESS_CR_100_150 1
#define EQOS_MAC_MDIO_ADDRESS_CR_20_35 2
+#define EQOS_MAC_MDIO_ADDRESS_CR_150_250 4
#define EQOS_MAC_MDIO_ADDRESS_CR_250_300 5
#define EQOS_MAC_MDIO_ADDRESS_SKAP BIT(4)
#define EQOS_MAC_MDIO_ADDRESS_GOC_MASK GENMASK(3, 2)
@@ -301,3 +302,4 @@ extern struct eqos_config eqos_qcom_config;
extern struct eqos_config eqos_stm32mp13_config;
extern struct eqos_config eqos_stm32mp15_config;
extern struct eqos_config eqos_jh7110_config;
+extern struct eqos_config eqos_adi_config;
diff --git a/drivers/net/dwc_eth_qos_adi.c b/drivers/net/dwc_eth_qos_adi.c
new file mode 100644
index 00000000000..0e6a901e303
--- /dev/null
+++ b/drivers/net/dwc_eth_qos_adi.c
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0
+/**
+ * (C) Copyright 2024 - Analog Devices, Inc.
+ *
+ * Written and/or maintained by Timesys Corporation
+ *
+ * Author: Greg Malysa <greg.malysa@timesys.com>
+ * Additional Contact: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
+ */
+
+#include <clk.h>
+#include <dm.h>
+#include <net.h>
+#include <phy.h>
+#include <reset.h>
+#include <linux/io.h>
+
+#include <asm/arch-adi/sc5xx/sc5xx.h>
+
+#include "dwc_eth_qos.h"
+
+static int eqos_start_resets_adi(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+
+ /*
+ * Settings need to latch with the DMA reset below. Currently only
+ * rgmii is supported but other phy interfaces may be supported in
+ * the future
+ */
+ sc5xx_enable_rgmii();
+ setbits_32(&eqos->dma_regs->mode, EQOS_DMA_MODE_SWR);
+
+ return 0;
+}
+
+static int eqos_probe_resources_adi(struct udevice *dev)
+{
+ struct eqos_priv *eqos = dev_get_priv(dev);
+ phy_interface_t interface;
+ int ret;
+
+ ret = eqos_get_base_addr_dt(dev);
+ if (ret) {
+ pr_err("eqos_get_base_addr_dt failed: %d\n", ret);
+ return ret;
+ }
+
+ interface = eqos->config->interface(dev);
+ if (interface == PHY_INTERFACE_MODE_NA) {
+ pr_err("Invalid PHY interface\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * rgmii tx clock rate is set to 125 MHz regardless of phy mode, and
+ * by default the internal clock is always connected to 125 MHz. According
+ * to the HRM it is invalid for this clock to have any other speed, so
+ * the hardware won't work anyway if this is wrong.
+ */
+static ulong eqos_get_tick_clk_rate_adi(struct udevice *dev)
+{
+ return 125 * 1000000;
+}
+
+static int eqos_get_enetaddr_adi(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_plat(dev);
+
+ return eth_env_get_enetaddr("ethaddr", pdata->enetaddr);
+}
+
+static struct eqos_ops eqos_adi_ops = {
+ .eqos_inval_desc = eqos_inval_desc_generic,
+ .eqos_flush_desc = eqos_flush_desc_generic,
+ .eqos_inval_buffer = eqos_inval_buffer_generic,
+ .eqos_flush_buffer = eqos_flush_buffer_generic,
+ .eqos_probe_resources = eqos_probe_resources_adi,
+ .eqos_remove_resources = eqos_null_ops,
+ .eqos_start_resets = eqos_start_resets_adi,
+ .eqos_stop_resets = eqos_null_ops,
+ .eqos_start_clks = eqos_null_ops,
+ .eqos_stop_clks = eqos_null_ops,
+ .eqos_calibrate_pads = eqos_null_ops,
+ .eqos_disable_calibration = eqos_null_ops,
+ .eqos_set_tx_clk_speed = eqos_null_ops,
+ .eqos_get_enetaddr = eqos_get_enetaddr_adi,
+ .eqos_get_tick_clk_rate = eqos_get_tick_clk_rate_adi,
+};
+
+struct eqos_config __maybe_unused eqos_adi_config = {
+ .reg_access_always_ok = true,
+ .mdio_wait = 20,
+ .swr_wait = 50,
+ .config_mac = EQOS_MAC_RXQ_CTRL0_RXQ0EN_ENABLED_DCB,
+ .config_mac_mdio = EQOS_MAC_MDIO_ADDRESS_CR_150_250,
+ .axi_bus_width = EQOS_AXI_WIDTH_32,
+ .interface = dev_read_phy_mode,
+ .ops = &eqos_adi_ops,
+};
diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c
index 553af2c1032..76463da7299 100644
--- a/drivers/net/phy/miiphybb.c
+++ b/drivers/net/phy/miiphybb.c
@@ -14,40 +14,16 @@
#include <ioports.h>
#include <ppc_asm.tmpl>
-#include <malloc.h>
#include <miiphy.h>
#include <asm/global_data.h>
-static inline struct bb_miiphy_bus *bb_miiphy_getbus(struct mii_dev *miidev)
-{
- return container_of(miidev, struct bb_miiphy_bus, mii);
-}
-
-struct bb_miiphy_bus *bb_miiphy_alloc(void)
-{
- struct bb_miiphy_bus *bus;
-
- bus = malloc(sizeof(*bus));
- if (!bus)
- return bus;
-
- mdio_init(&bus->mii);
-
- return bus;
-}
-
-void bb_miiphy_free(struct bb_miiphy_bus *bus)
-{
- free(bus);
-}
-
/*****************************************************************************
*
* Utility to send the preamble, address, and register (common to read
* and write).
*/
-static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
- unsigned char addr, unsigned char reg)
+static void miiphy_pre(struct mii_dev *miidev, const struct bb_miiphy_bus_ops *ops,
+ char read, unsigned char addr, unsigned char reg)
{
int j;
@@ -59,62 +35,62 @@ static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
* but it is safer and will be much more robust.
*/
- bus->mdio_active(bus);
- bus->set_mdio(bus, 1);
+ ops->mdio_active(miidev);
+ ops->set_mdio(miidev, 1);
for (j = 0; j < 32; j++) {
- bus->set_mdc(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
}
/* send the start bit (01) and the read opcode (10) or write (10) */
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, read);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, !read);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, read);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, !read);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
/* send the PHY address */
for (j = 0; j < 5; j++) {
- bus->set_mdc(bus, 0);
+ ops->set_mdc(miidev, 0);
if ((addr & 0x10) == 0) {
- bus->set_mdio(bus, 0);
+ ops->set_mdio(miidev, 0);
} else {
- bus->set_mdio(bus, 1);
+ ops->set_mdio(miidev, 1);
}
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
addr <<= 1;
}
/* send the register address */
for (j = 0; j < 5; j++) {
- bus->set_mdc(bus, 0);
+ ops->set_mdc(miidev, 0);
if ((reg & 0x10) == 0) {
- bus->set_mdio(bus, 0);
+ ops->set_mdio(miidev, 0);
} else {
- bus->set_mdio(bus, 1);
+ ops->set_mdio(miidev, 1);
}
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
reg <<= 1;
}
}
@@ -126,62 +102,57 @@ static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
* Returns:
* 0 on success
*/
-int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg)
+int bb_miiphy_read(struct mii_dev *miidev, const struct bb_miiphy_bus_ops *ops,
+ int addr, int devad, int reg)
{
unsigned short rdreg; /* register working value */
int v;
int j; /* counter */
- struct bb_miiphy_bus *bus;
- bus = bb_miiphy_getbus(miidev);
- if (bus == NULL) {
- return -1;
- }
-
- miiphy_pre (bus, 1, addr, reg);
+ miiphy_pre(miidev, ops, 1, addr, reg);
/* tri-state our MDIO I/O pin so we can read */
- bus->set_mdc(bus, 0);
- bus->mdio_tristate(bus);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->mdio_tristate(miidev);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
/* check the turnaround bit: the PHY should be driving it to zero */
- bus->get_mdio(bus, &v);
+ ops->get_mdio(miidev, &v);
if (v != 0) {
/* puts ("PHY didn't drive TA low\n"); */
for (j = 0; j < 32; j++) {
- bus->set_mdc(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
}
/* There is no PHY, return */
return -1;
}
- bus->set_mdc(bus, 0);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
/* read 16 bits of register data, MSB first */
rdreg = 0;
for (j = 0; j < 16; j++) {
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
rdreg <<= 1;
- bus->get_mdio(bus, &v);
+ ops->get_mdio(miidev, &v);
rdreg |= (v & 0x1);
- bus->set_mdc(bus, 0);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
}
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
debug("%s[%s](0x%x) @ 0x%x = 0x%04x\n", __func__, miidev->name, reg, addr, rdreg);
@@ -195,54 +166,47 @@ int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg)
* Returns:
* 0 on success
*/
-int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,
- u16 value)
+int bb_miiphy_write(struct mii_dev *miidev, const struct bb_miiphy_bus_ops *ops,
+ int addr, int devad, int reg, u16 value)
{
- struct bb_miiphy_bus *bus;
int j; /* counter */
- bus = bb_miiphy_getbus(miidev);
- if (bus == NULL) {
- /* Bus not found! */
- return -1;
- }
-
- miiphy_pre (bus, 0, addr, reg);
+ miiphy_pre(miidev, ops, 0, addr, reg);
/* send the turnaround (10) */
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
/* write 16 bits of register data, MSB first */
for (j = 0; j < 16; j++) {
- bus->set_mdc(bus, 0);
+ ops->set_mdc(miidev, 0);
if ((value & 0x00008000) == 0) {
- bus->set_mdio(bus, 0);
+ ops->set_mdio(miidev, 0);
} else {
- bus->set_mdio(bus, 1);
+ ops->set_mdio(miidev, 1);
}
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
value <<= 1;
}
/*
* Tri-state the MDIO line.
*/
- bus->mdio_tristate(bus);
- bus->set_mdc(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->mdio_tristate(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
return 0;
}
diff --git a/drivers/net/ravb.c b/drivers/net/ravb.c
index cb727ae9bc1..c39bef17b79 100644
--- a/drivers/net/ravb.c
+++ b/drivers/net/ravb.c
@@ -354,8 +354,15 @@ static int ravb_mac_init(struct ravb_priv *eth)
/* Disable MAC Interrupt */
writel(0, eth->iobase + RAVB_REG_ECSIPR);
- /* Recv frame limit set register */
- writel(RFLR_RFL_MIN, eth->iobase + RAVB_REG_RFLR);
+ /*
+ * Set receive frame length
+ *
+ * The length set here describes the frame from the destination address
+ * up to and including the CRC data. However only the frame data,
+ * excluding the CRC, are transferred to memory. To allow for the
+ * largest frames add the CRC length to the maximum Rx descriptor size.
+ */
+ writel(RFLR_RFL_MIN + ETH_FCS_LEN, eth->iobase + RAVB_REG_RFLR);
return 0;
}
@@ -491,27 +498,27 @@ static void ravb_stop(struct udevice *dev)
}
/* Bitbang MDIO access */
-static int ravb_bb_mdio_active(struct bb_miiphy_bus *bus)
+static int ravb_bb_mdio_active(struct mii_dev *miidev)
{
- struct ravb_priv *eth = bus->priv;
+ struct ravb_priv *eth = miidev->priv;
setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MMD);
return 0;
}
-static int ravb_bb_mdio_tristate(struct bb_miiphy_bus *bus)
+static int ravb_bb_mdio_tristate(struct mii_dev *miidev)
{
- struct ravb_priv *eth = bus->priv;
+ struct ravb_priv *eth = miidev->priv;
clrbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MMD);
return 0;
}
-static int ravb_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
+static int ravb_bb_set_mdio(struct mii_dev *miidev, int v)
{
- struct ravb_priv *eth = bus->priv;
+ struct ravb_priv *eth = miidev->priv;
if (v)
setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDO);
@@ -521,18 +528,18 @@ static int ravb_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
return 0;
}
-static int ravb_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
+static int ravb_bb_get_mdio(struct mii_dev *miidev, int *v)
{
- struct ravb_priv *eth = bus->priv;
+ struct ravb_priv *eth = miidev->priv;
*v = (readl(eth->iobase + RAVB_REG_PIR) & PIR_MDI) >> 3;
return 0;
}
-static int ravb_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
+static int ravb_bb_set_mdc(struct mii_dev *miidev, int v)
{
- struct ravb_priv *eth = bus->priv;
+ struct ravb_priv *eth = miidev->priv;
if (v)
setbits_le32(eth->iobase + RAVB_REG_PIR, PIR_MDC);
@@ -542,18 +549,40 @@ static int ravb_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
return 0;
}
-static int ravb_bb_delay(struct bb_miiphy_bus *bus)
+static int ravb_bb_delay(struct mii_dev *miidev)
{
udelay(10);
return 0;
}
+static const struct bb_miiphy_bus_ops ravb_bb_miiphy_bus_ops = {
+ .mdio_active = ravb_bb_mdio_active,
+ .mdio_tristate = ravb_bb_mdio_tristate,
+ .set_mdio = ravb_bb_set_mdio,
+ .get_mdio = ravb_bb_get_mdio,
+ .set_mdc = ravb_bb_set_mdc,
+ .delay = ravb_bb_delay,
+};
+
+static int ravb_bb_miiphy_read(struct mii_dev *miidev, int addr,
+ int devad, int reg)
+{
+ return bb_miiphy_read(miidev, &ravb_bb_miiphy_bus_ops,
+ addr, devad, reg);
+}
+
+static int ravb_bb_miiphy_write(struct mii_dev *miidev, int addr,
+ int devad, int reg, u16 value)
+{
+ return bb_miiphy_write(miidev, &ravb_bb_miiphy_bus_ops,
+ addr, devad, reg, value);
+}
+
static int ravb_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
struct ravb_priv *eth = dev_get_priv(dev);
- struct bb_miiphy_bus *bb_miiphy;
struct mii_dev *mdiodev;
void __iomem *iobase;
int ret;
@@ -565,32 +594,22 @@ static int ravb_probe(struct udevice *dev)
if (ret < 0)
goto err_mdio_alloc;
- bb_miiphy = bb_miiphy_alloc();
- if (!bb_miiphy) {
+ mdiodev = mdio_alloc();
+ if (!mdiodev) {
ret = -ENOMEM;
goto err_mdio_alloc;
}
- mdiodev = &bb_miiphy->mii;
-
- mdiodev->read = bb_miiphy_read;
- mdiodev->write = bb_miiphy_write;
+ mdiodev->read = ravb_bb_miiphy_read;
+ mdiodev->write = ravb_bb_miiphy_write;
+ mdiodev->priv = eth;
snprintf(mdiodev->name, sizeof(mdiodev->name), dev->name);
- /* Copy the bus accessors and private data */
- bb_miiphy->mdio_active = ravb_bb_mdio_active;
- bb_miiphy->mdio_tristate = ravb_bb_mdio_tristate;
- bb_miiphy->set_mdio = ravb_bb_set_mdio;
- bb_miiphy->get_mdio = ravb_bb_get_mdio;
- bb_miiphy->set_mdc = ravb_bb_set_mdc;
- bb_miiphy->delay = ravb_bb_delay;
- bb_miiphy->priv = eth;
-
ret = mdio_register(mdiodev);
if (ret < 0)
goto err_mdio_register;
- eth->bus = &bb_miiphy->mii;
+ eth->bus = mdiodev;
/* Bring up PHY */
ret = clk_enable_bulk(&eth->clks);
@@ -610,7 +629,7 @@ static int ravb_probe(struct udevice *dev)
err_mdio_reset:
clk_release_bulk(&eth->clks);
err_mdio_register:
- bb_miiphy_free(bb_miiphy);
+ mdio_free(mdiodev);
err_mdio_alloc:
unmap_physmem(eth->iobase, MAP_NOCACHE);
return ret;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 83e48609224..f695a3a41d2 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -644,9 +644,9 @@ static void sh_ether_stop(struct udevice *dev)
}
/******* for bb_miiphy *******/
-static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
+static int sh_eth_bb_mdio_active(struct mii_dev *miidev)
{
- struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_dev *eth = miidev->priv;
struct sh_eth_info *port_info = &eth->port_info[eth->port];
sh_eth_write(port_info, sh_eth_read(port_info, PIR) | PIR_MMD, PIR);
@@ -654,9 +654,9 @@ static int sh_eth_bb_mdio_active(struct bb_miiphy_bus *bus)
return 0;
}
-static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
+static int sh_eth_bb_mdio_tristate(struct mii_dev *miidev)
{
- struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_dev *eth = miidev->priv;
struct sh_eth_info *port_info = &eth->port_info[eth->port];
sh_eth_write(port_info, sh_eth_read(port_info, PIR) & ~PIR_MMD, PIR);
@@ -664,9 +664,9 @@ static int sh_eth_bb_mdio_tristate(struct bb_miiphy_bus *bus)
return 0;
}
-static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
+static int sh_eth_bb_set_mdio(struct mii_dev *miidev, int v)
{
- struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_dev *eth = miidev->priv;
struct sh_eth_info *port_info = &eth->port_info[eth->port];
if (v)
@@ -679,9 +679,9 @@ static int sh_eth_bb_set_mdio(struct bb_miiphy_bus *bus, int v)
return 0;
}
-static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
+static int sh_eth_bb_get_mdio(struct mii_dev *miidev, int *v)
{
- struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_dev *eth = miidev->priv;
struct sh_eth_info *port_info = &eth->port_info[eth->port];
*v = (sh_eth_read(port_info, PIR) & PIR_MDI) >> 3;
@@ -689,9 +689,9 @@ static int sh_eth_bb_get_mdio(struct bb_miiphy_bus *bus, int *v)
return 0;
}
-static int sh_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
+static int sh_eth_bb_set_mdc(struct mii_dev *miidev, int v)
{
- struct sh_eth_dev *eth = bus->priv;
+ struct sh_eth_dev *eth = miidev->priv;
struct sh_eth_info *port_info = &eth->port_info[eth->port];
if (v)
@@ -704,19 +704,41 @@ static int sh_eth_bb_set_mdc(struct bb_miiphy_bus *bus, int v)
return 0;
}
-static int sh_eth_bb_delay(struct bb_miiphy_bus *bus)
+static int sh_eth_bb_delay(struct mii_dev *miidev)
{
udelay(10);
return 0;
}
+static const struct bb_miiphy_bus_ops sh_ether_bb_miiphy_bus_ops = {
+ .mdio_active = sh_eth_bb_mdio_active,
+ .mdio_tristate = sh_eth_bb_mdio_tristate,
+ .set_mdio = sh_eth_bb_set_mdio,
+ .get_mdio = sh_eth_bb_get_mdio,
+ .set_mdc = sh_eth_bb_set_mdc,
+ .delay = sh_eth_bb_delay,
+};
+
+static int sh_eth_bb_miiphy_read(struct mii_dev *miidev, int addr,
+ int devad, int reg)
+{
+ return bb_miiphy_read(miidev, &sh_ether_bb_miiphy_bus_ops,
+ addr, devad, reg);
+}
+
+static int sh_eth_bb_miiphy_write(struct mii_dev *miidev, int addr,
+ int devad, int reg, u16 value)
+{
+ return bb_miiphy_write(miidev, &sh_ether_bb_miiphy_bus_ops,
+ addr, devad, reg, value);
+}
+
static int sh_ether_probe(struct udevice *udev)
{
struct eth_pdata *pdata = dev_get_plat(udev);
struct sh_ether_priv *priv = dev_get_priv(udev);
struct sh_eth_dev *eth = &priv->shdev;
- struct bb_miiphy_bus *bb_miiphy;
struct mii_dev *mdiodev;
int ret;
@@ -727,32 +749,22 @@ static int sh_ether_probe(struct udevice *udev)
if (ret < 0)
return ret;
#endif
- bb_miiphy = bb_miiphy_alloc();
- if (!bb_miiphy) {
+ mdiodev = mdio_alloc();
+ if (!mdiodev) {
ret = -ENOMEM;
return ret;
}
- mdiodev = &bb_miiphy->mii;
-
- mdiodev->read = bb_miiphy_read;
- mdiodev->write = bb_miiphy_write;
+ mdiodev->read = sh_eth_bb_miiphy_read;
+ mdiodev->write = sh_eth_bb_miiphy_write;
+ mdiodev->priv = eth;
snprintf(mdiodev->name, sizeof(mdiodev->name), udev->name);
- /* Copy the bus accessors and private data */
- bb_miiphy->mdio_active = sh_eth_bb_mdio_active;
- bb_miiphy->mdio_tristate = sh_eth_bb_mdio_tristate;
- bb_miiphy->set_mdio = sh_eth_bb_set_mdio;
- bb_miiphy->get_mdio = sh_eth_bb_get_mdio;
- bb_miiphy->set_mdc = sh_eth_bb_set_mdc;
- bb_miiphy->delay = sh_eth_bb_delay;
- bb_miiphy->priv = eth;
-
ret = mdio_register(mdiodev);
if (ret < 0)
goto err_mdio_register;
- priv->bus = &bb_miiphy->mii;
+ priv->bus = mdiodev;
eth->port = CFG_SH_ETHER_USE_PORT;
eth->port_info[eth->port].phy_addr = CFG_SH_ETHER_PHY_ADDR;
@@ -782,7 +794,7 @@ err_phy_config:
clk_disable(&priv->clk);
#endif
err_mdio_register:
- bb_miiphy_free(bb_miiphy);
+ mdio_free(mdiodev);
return ret;
}
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index 6481ee24a60..bd4ebdd745a 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -278,6 +278,24 @@ static int tsec_send(struct udevice *dev, void *packet, int length)
return result;
}
+static int tsec_free_pkt(struct udevice *dev, uchar *packet, int length)
+{
+ struct tsec_private *priv = (struct tsec_private *)dev_get_priv(dev);
+ u16 status;
+
+ out_be16(&priv->rxbd[priv->rx_idx].length, 0);
+
+ status = RXBD_EMPTY;
+ /* Set the wrap bit if this is the last element in the list */
+ if ((priv->rx_idx + 1) == PKTBUFSRX)
+ status |= RXBD_WRAP;
+ out_be16(&priv->rxbd[priv->rx_idx].status, status);
+
+ priv->rx_idx = (priv->rx_idx + 1) % PKTBUFSRX;
+
+ return 0;
+}
+
static int tsec_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct tsec_private *priv = (struct tsec_private *)dev_get_priv(dev);
@@ -296,6 +314,9 @@ static int tsec_recv(struct udevice *dev, int flags, uchar **packetp)
ret = length - 4;
} else {
printf("Got error %x\n", (status & RXBD_STATS));
+
+ /* Rearm the packet buffer */
+ tsec_free_pkt(dev, NULL, 0);
}
}
@@ -307,24 +328,6 @@ static int tsec_recv(struct udevice *dev, int flags, uchar **packetp)
return ret;
}
-static int tsec_free_pkt(struct udevice *dev, uchar *packet, int length)
-{
- struct tsec_private *priv = (struct tsec_private *)dev_get_priv(dev);
- u16 status;
-
- out_be16(&priv->rxbd[priv->rx_idx].length, 0);
-
- status = RXBD_EMPTY;
- /* Set the wrap bit if this is the last element in the list */
- if ((priv->rx_idx + 1) == PKTBUFSRX)
- status |= RXBD_WRAP;
- out_be16(&priv->rxbd[priv->rx_idx].status, status);
-
- priv->rx_idx = (priv->rx_idx + 1) % PKTBUFSRX;
-
- return 0;
-}
-
static void tsec_halt(struct udevice *dev)
{
struct tsec_private *priv;