*/
#include <config.h>
-#include <common.h>
#include <cpu_func.h>
#include <env.h>
#include <log.h>
#include <asm/cache.h>
#include <linux/delay.h>
#include <linux/errno.h>
+#include <asm/global_data.h>
#include <asm/io.h>
-#ifdef CONFIG_DM_ETH
#include <clk.h>
#include <dm.h>
#include <linux/mii.h>
#include <asm/gpio.h>
-#endif
#include "sh_eth.h"
-#ifndef CONFIG_SH_ETHER_USE_PORT
-# error "Please define CONFIG_SH_ETHER_USE_PORT"
+#ifndef CFG_SH_ETHER_USE_PORT
+# error "Please define CFG_SH_ETHER_USE_PORT"
#endif
-#ifndef CONFIG_SH_ETHER_PHY_ADDR
-# error "Please define CONFIG_SH_ETHER_PHY_ADDR"
+#ifndef CFG_SH_ETHER_PHY_ADDR
+# error "Please define CFG_SH_ETHER_PHY_ADDR"
#endif
-#if defined(CONFIG_SH_ETHER_CACHE_WRITEBACK) && \
+#if defined(CFG_SH_ETHER_CACHE_WRITEBACK) && \
!CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
#define flush_cache_wback(addr, len) \
flush_dcache_range((unsigned long)addr, \
- (unsigned long)(addr + ALIGN(len, CONFIG_SH_ETHER_ALIGNE_SIZE)))
+ (unsigned long)(addr + ALIGN(len, CFG_SH_ETHER_ALIGNE_SIZE)))
#else
#define flush_cache_wback(...)
#endif
-#if defined(CONFIG_SH_ETHER_CACHE_INVALIDATE) && defined(CONFIG_ARM)
+#if defined(CFG_SH_ETHER_CACHE_INVALIDATE) && defined(CONFIG_ARM)
#define invalidate_cache(addr, len) \
{ \
- unsigned long line_size = CONFIG_SH_ETHER_ALIGNE_SIZE; \
+ unsigned long line_size = CFG_SH_ETHER_ALIGNE_SIZE; \
unsigned long start, end; \
\
start = (unsigned long)addr; \
/* Check if the rx descriptor is ready */
invalidate_cache(port_info->rx_desc_cur, sizeof(struct rx_desc_s));
if (port_info->rx_desc_cur->rd0 & RD_RACT)
- return -EINVAL;
+ return -EAGAIN;
/* Check for errors */
if (port_info->rx_desc_cur->rd0 & RD_RFE)
- return -EINVAL;
+ return 0;
return port_info->rx_desc_cur->rd1 & 0xffff;
}
{
struct sh_eth_info *port_info = ð->port_info[eth->port];
+ invalidate_cache(ADDR_TO_P2(port_info->rx_desc_cur->rd2), MAX_BUF_SIZE);
+
/* Make current descriptor available again */
if (port_info->rx_desc_cur->rd0 & RD_RDLE)
port_info->rx_desc_cur->rd0 = RD_RACT | RD_RDLE;
goto err;
}
- flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size);
-
/* Make sure we use a P2 address (non-cacheable) */
port_info->tx_desc_base =
(struct tx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->tx_desc_alloc);
cur_tx_desc--;
cur_tx_desc->td0 |= TD_TDLE;
+ flush_cache_wback(port_info->tx_desc_alloc, alloc_desc_size);
/*
* Point the controller to the tx descriptor list. Must use physical
* addresses
goto err;
}
- flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size);
-
/* Make sure we use a P2 address (non-cacheable) */
port_info->rx_desc_base =
(struct rx_desc_s *)ADDR_TO_P2((uintptr_t)port_info->rx_desc_alloc);
cur_rx_desc--;
cur_rx_desc->rd0 |= RD_RDLE;
+ invalidate_cache(port_info->rx_buf_alloc, NUM_RX_DESC * MAX_BUF_SIZE);
+ flush_cache_wback(port_info->rx_desc_alloc, alloc_desc_size);
+
/* Point the controller to the rx descriptor list */
sh_eth_write(port_info, ADDR_TO_PHY(port_info->rx_desc_base), RDLAR);
#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
return 0;
}
-#ifndef CONFIG_DM_ETH
-static int sh_eth_phy_config_legacy(struct sh_eth_dev *eth)
-{
- int ret = 0;
- struct sh_eth_info *port_info = ð->port_info[eth->port];
- struct eth_device *dev = port_info->dev;
- struct phy_device *phydev;
-
- phydev = phy_connect(
- miiphy_get_dev_by_name(dev->name),
- port_info->phy_addr, dev, CONFIG_SH_ETHER_PHY_MODE);
- port_info->phydev = phydev;
- phy_config(phydev);
-
- return ret;
-}
-
-static int sh_eth_send_legacy(struct eth_device *dev, void *packet, int len)
-{
- struct sh_eth_dev *eth = dev->priv;
-
- return sh_eth_send_common(eth, packet, len);
-}
-
-static int sh_eth_recv_common(struct sh_eth_dev *eth)
-{
- int len = 0;
- struct sh_eth_info *port_info = ð->port_info[eth->port];
- uchar *packet = (uchar *)ADDR_TO_P2(port_info->rx_desc_cur->rd2);
-
- len = sh_eth_recv_start(eth);
- if (len > 0) {
- invalidate_cache(packet, len);
- net_process_received_packet(packet, len);
- sh_eth_recv_finish(eth);
- } else
- len = 0;
-
- /* Restart the receiver if disabled */
- if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
- sh_eth_write(port_info, EDRRR_R, EDRRR);
-
- return len;
-}
-
-static int sh_eth_recv_legacy(struct eth_device *dev)
-{
- struct sh_eth_dev *eth = dev->priv;
-
- return sh_eth_recv_common(eth);
-}
-
-static int sh_eth_init_legacy(struct eth_device *dev, struct bd_info *bd)
-{
- struct sh_eth_dev *eth = dev->priv;
- int ret;
-
- ret = sh_eth_init_common(eth, dev->enetaddr);
- if (ret)
- return ret;
-
- ret = sh_eth_phy_config_legacy(eth);
- if (ret) {
- printf(SHETHER_NAME ": phy config timeout\n");
- goto err_start;
- }
-
- ret = sh_eth_start_common(eth);
- if (ret)
- goto err_start;
-
- return 0;
-
-err_start:
- sh_eth_tx_desc_free(eth);
- sh_eth_rx_desc_free(eth);
- return ret;
-}
-
-void sh_eth_halt_legacy(struct eth_device *dev)
-{
- struct sh_eth_dev *eth = dev->priv;
-
- sh_eth_stop(eth);
-}
-
-int sh_eth_initialize(struct bd_info *bd)
-{
- int ret = 0;
- struct sh_eth_dev *eth = NULL;
- struct eth_device *dev = NULL;
- struct mii_dev *mdiodev;
-
- eth = (struct sh_eth_dev *)malloc(sizeof(struct sh_eth_dev));
- if (!eth) {
- printf(SHETHER_NAME ": %s: malloc failed\n", __func__);
- ret = -ENOMEM;
- goto err;
- }
-
- dev = (struct eth_device *)malloc(sizeof(struct eth_device));
- if (!dev) {
- printf(SHETHER_NAME ": %s: malloc failed\n", __func__);
- ret = -ENOMEM;
- goto err;
- }
- memset(dev, 0, sizeof(struct eth_device));
- memset(eth, 0, sizeof(struct sh_eth_dev));
-
- eth->port = CONFIG_SH_ETHER_USE_PORT;
- eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR;
- eth->port_info[eth->port].iobase =
- (void __iomem *)(BASE_IO_ADDR + 0x800 * eth->port);
-
- dev->priv = (void *)eth;
- dev->iobase = 0;
- dev->init = sh_eth_init_legacy;
- dev->halt = sh_eth_halt_legacy;
- dev->send = sh_eth_send_legacy;
- dev->recv = sh_eth_recv_legacy;
- eth->port_info[eth->port].dev = dev;
-
- strcpy(dev->name, SHETHER_NAME);
-
- /* Register Device to EtherNet subsystem */
- eth_register(dev);
-
- bb_miiphy_buses[0].priv = eth;
- mdiodev = mdio_alloc();
- if (!mdiodev)
- return -ENOMEM;
- strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
- mdiodev->read = bb_miiphy_read;
- mdiodev->write = bb_miiphy_write;
-
- ret = mdio_register(mdiodev);
- if (ret < 0)
- return ret;
-
- if (!eth_env_get_enetaddr("ethaddr", dev->enetaddr))
- puts("Please set MAC address\n");
-
- return ret;
-
-err:
- if (dev)
- free(dev);
-
- if (eth)
- free(eth);
-
- printf(SHETHER_NAME ": Failed\n");
- return ret;
-}
-
-#else /* CONFIG_DM_ETH */
-
struct sh_ether_priv {
struct sh_eth_dev shdev;
struct mii_dev *bus;
phys_addr_t iobase;
struct clk clk;
- struct gpio_desc reset_gpio;
};
static int sh_ether_send(struct udevice *dev, void *packet, int len)
*packetp = packet;
return len;
- } else {
- len = 0;
+ }
- /* Restart the receiver if disabled */
- if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
- sh_eth_write(port_info, EDRRR_R, EDRRR);
+ /* Restart the receiver if disabled */
+ if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
+ sh_eth_write(port_info, EDRRR_R, EDRRR);
- return -EAGAIN;
- }
+ return len;
}
static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
int ret = 0;
struct sh_eth_info *port_info = ð->port_info[eth->port];
struct phy_device *phydev;
- int mask = 0xffffffff;
- phydev = phy_find_by_mask(priv->bus, mask, pdata->phy_interface);
+ phydev = phy_connect(priv->bus, -1, dev, pdata->phy_interface);
if (!phydev)
return -ENODEV;
- phy_connect_dev(phydev, dev);
-
port_info->phydev = phydev;
phy_config(phydev);
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 ofnode_phandle_args phandle_args;
struct mii_dev *mdiodev;
int ret;
if (ret < 0)
return ret;
#endif
-
- ret = dev_read_phandle_with_args(udev, "phy-handle", NULL, 0, 0, &phandle_args);
- if (!ret) {
- gpio_request_by_name_nodev(phandle_args.node, "reset-gpios", 0,
- &priv->reset_gpio, GPIOD_IS_OUT);
- }
-
- if (!dm_gpio_is_valid(&priv->reset_gpio)) {
- gpio_request_by_name(udev, "reset-gpios", 0, &priv->reset_gpio,
- GPIOD_IS_OUT);
- }
-
mdiodev = mdio_alloc();
if (!mdiodev) {
ret = -ENOMEM;
priv->bus = miiphy_get_dev_by_name(udev->name);
- eth->port = CONFIG_SH_ETHER_USE_PORT;
- eth->port_info[eth->port].phy_addr = CONFIG_SH_ETHER_PHY_ADDR;
+ eth->port = CFG_SH_ETHER_USE_PORT;
+ eth->port_info[eth->port].phy_addr = CFG_SH_ETHER_PHY_ADDR;
eth->port_info[eth->port].iobase =
(void __iomem *)(uintptr_t)(BASE_IO_ADDR + 0x800 * eth->port);
mdio_unregister(priv->bus);
mdio_free(priv->bus);
- if (dm_gpio_is_valid(&priv->reset_gpio))
- dm_gpio_free(udev, &priv->reset_gpio);
-
return 0;
}
int sh_ether_of_to_plat(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_plat(dev);
- const char *phy_mode;
const fdt32_t *cell;
- int ret = 0;
pdata->iobase = dev_read_addr(dev);
- pdata->phy_interface = -1;
- phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "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);
+
+ pdata->phy_interface = dev_read_phy_mode(dev);
+ if (pdata->phy_interface == PHY_INTERFACE_MODE_NA)
return -EINVAL;
- }
pdata->max_speed = 1000;
cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "max-speed", NULL);
sprintf(bb_miiphy_buses[0].name, dev->name);
- return ret;
+ return 0;
}
static const struct udevice_id sh_ether_ids[] = {
.plat_auto = sizeof(struct eth_pdata),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
-#endif
/******* for bb_miiphy *******/
static int sh_eth_bb_init(struct bb_miiphy_bus *bus)