mirror of
https://source.denx.de/u-boot/u-boot.git
synced 2026-06-13 15:03:58 +03:00
net: sh_eth: Pass struct port_info around
The struct sh_eth_dev .port member is always set to 0, therefore only single-ported SH Ethernet is ever used. Support for multiple SH Ethernet ports implemented on driver level is a remnant from before U-Boot DM existed. Pass struct sh_eth_info port_info around directly and remove the struct sh_eth_dev entirely. Handling of multiple ports should be done by U-Boot DM and multiple per-driver-instance private data. No functional change intended. Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
This commit is contained in:
@@ -64,10 +64,9 @@
|
||||
|
||||
#define TIMEOUT_CNT 1000
|
||||
|
||||
static int sh_eth_send_common(struct sh_eth_dev *eth, void *packet, int len)
|
||||
static int sh_eth_send_common(struct sh_eth_info *port_info, void *packet, int len)
|
||||
{
|
||||
int ret = 0, timeout;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
|
||||
if (!packet || len > 0xffff) {
|
||||
printf(SHETHER_NAME ": %s: Invalid argument\n", __func__);
|
||||
@@ -121,10 +120,8 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sh_eth_recv_start(struct sh_eth_dev *eth)
|
||||
static int sh_eth_recv_start(struct sh_eth_info *port_info)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
|
||||
/* 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)
|
||||
@@ -137,10 +134,8 @@ static int sh_eth_recv_start(struct sh_eth_dev *eth)
|
||||
return port_info->rx_desc_cur->rd1 & 0xffff;
|
||||
}
|
||||
|
||||
static void sh_eth_recv_finish(struct sh_eth_dev *eth)
|
||||
static void sh_eth_recv_finish(struct sh_eth_info *port_info)
|
||||
{
|
||||
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 */
|
||||
@@ -159,9 +154,8 @@ static void sh_eth_recv_finish(struct sh_eth_dev *eth)
|
||||
port_info->rx_desc_cur = port_info->rx_desc_base;
|
||||
}
|
||||
|
||||
static int sh_eth_reset(struct sh_eth_dev *eth)
|
||||
static int sh_eth_reset(struct sh_eth_info *port_info)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
#if defined(SH_ETH_TYPE_GETHER) || defined(SH_ETH_TYPE_RZ)
|
||||
int ret = 0, i;
|
||||
|
||||
@@ -192,12 +186,11 @@ static int sh_eth_reset(struct sh_eth_dev *eth)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int sh_eth_tx_desc_init(struct sh_eth_dev *eth)
|
||||
static int sh_eth_tx_desc_init(struct sh_eth_info *port_info)
|
||||
{
|
||||
int i, ret = 0;
|
||||
u32 alloc_desc_size = NUM_TX_DESC * sizeof(struct tx_desc_s);
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct tx_desc_s *cur_tx_desc;
|
||||
int i, ret = 0;
|
||||
|
||||
/*
|
||||
* Allocate rx descriptors. They must be aligned to size of struct
|
||||
@@ -244,11 +237,10 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sh_eth_rx_desc_init(struct sh_eth_dev *eth)
|
||||
static int sh_eth_rx_desc_init(struct sh_eth_info *port_info)
|
||||
{
|
||||
int i, ret = 0;
|
||||
u32 alloc_desc_size = NUM_RX_DESC * sizeof(struct rx_desc_s);
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct rx_desc_s *cur_rx_desc;
|
||||
u8 *rx_buf;
|
||||
|
||||
@@ -318,20 +310,16 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sh_eth_tx_desc_free(struct sh_eth_dev *eth)
|
||||
static void sh_eth_tx_desc_free(struct sh_eth_info *port_info)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
|
||||
if (port_info->tx_desc_alloc) {
|
||||
free(port_info->tx_desc_alloc);
|
||||
port_info->tx_desc_alloc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void sh_eth_rx_desc_free(struct sh_eth_dev *eth)
|
||||
static void sh_eth_rx_desc_free(struct sh_eth_info *port_info)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
|
||||
if (port_info->rx_desc_alloc) {
|
||||
free(port_info->rx_desc_alloc);
|
||||
port_info->rx_desc_alloc = NULL;
|
||||
@@ -343,21 +331,21 @@ static void sh_eth_rx_desc_free(struct sh_eth_dev *eth)
|
||||
}
|
||||
}
|
||||
|
||||
static int sh_eth_desc_init(struct sh_eth_dev *eth)
|
||||
static int sh_eth_desc_init(struct sh_eth_info *port_info)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = sh_eth_tx_desc_init(eth);
|
||||
ret = sh_eth_tx_desc_init(port_info);
|
||||
if (ret)
|
||||
goto err_tx_init;
|
||||
|
||||
ret = sh_eth_rx_desc_init(eth);
|
||||
ret = sh_eth_rx_desc_init(port_info);
|
||||
if (ret)
|
||||
goto err_rx_init;
|
||||
|
||||
return ret;
|
||||
err_rx_init:
|
||||
sh_eth_tx_desc_free(eth);
|
||||
sh_eth_tx_desc_free(port_info);
|
||||
|
||||
err_tx_init:
|
||||
return ret;
|
||||
@@ -375,9 +363,8 @@ static void sh_eth_write_hwaddr(struct sh_eth_info *port_info,
|
||||
sh_eth_write(port_info, val, MALR);
|
||||
}
|
||||
|
||||
static void sh_eth_mac_regs_config(struct sh_eth_dev *eth, unsigned char *mac)
|
||||
static void sh_eth_mac_regs_config(struct sh_eth_info *port_info, unsigned char *mac)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
unsigned long edmr;
|
||||
|
||||
/* Configure e-dmac registers */
|
||||
@@ -422,9 +409,8 @@ static void sh_eth_mac_regs_config(struct sh_eth_dev *eth, unsigned char *mac)
|
||||
#endif
|
||||
}
|
||||
|
||||
static int sh_eth_phy_regs_config(struct sh_eth_dev *eth)
|
||||
static int sh_eth_phy_regs_config(struct sh_eth_info *port_info)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct phy_device *phy = port_info->phydev;
|
||||
int ret = 0;
|
||||
u32 val = 0;
|
||||
@@ -470,10 +456,8 @@ static int sh_eth_phy_regs_config(struct sh_eth_dev *eth)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sh_eth_start(struct sh_eth_dev *eth)
|
||||
static void sh_eth_start(struct sh_eth_info *port_info)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
|
||||
/*
|
||||
* Enable the e-dmac receiver only. The transmitter will be enabled when
|
||||
* we have something to transmit
|
||||
@@ -481,33 +465,30 @@ static void sh_eth_start(struct sh_eth_dev *eth)
|
||||
sh_eth_write(port_info, EDRRR_R, EDRRR);
|
||||
}
|
||||
|
||||
static void sh_eth_stop(struct sh_eth_dev *eth)
|
||||
static void sh_eth_stop(struct sh_eth_info *port_info)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
|
||||
sh_eth_write(port_info, ~EDRRR_R, EDRRR);
|
||||
}
|
||||
|
||||
static int sh_eth_init_common(struct sh_eth_dev *eth, unsigned char *mac)
|
||||
static int sh_eth_init_common(struct sh_eth_info *port_info, unsigned char *mac)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ret = sh_eth_reset(eth);
|
||||
ret = sh_eth_reset(port_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = sh_eth_desc_init(eth);
|
||||
ret = sh_eth_desc_init(port_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sh_eth_mac_regs_config(eth, mac);
|
||||
sh_eth_mac_regs_config(port_info, mac);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sh_eth_start_common(struct sh_eth_dev *eth)
|
||||
static int sh_eth_start_common(struct sh_eth_info *port_info)
|
||||
{
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
int ret;
|
||||
|
||||
ret = phy_startup(port_info->phydev);
|
||||
@@ -516,17 +497,17 @@ static int sh_eth_start_common(struct sh_eth_dev *eth)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = sh_eth_phy_regs_config(eth);
|
||||
ret = sh_eth_phy_regs_config(port_info);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
sh_eth_start(eth);
|
||||
sh_eth_start(port_info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct sh_ether_priv {
|
||||
struct sh_eth_dev shdev;
|
||||
struct sh_eth_info port_info;
|
||||
|
||||
struct mii_dev *bus;
|
||||
phys_addr_t iobase;
|
||||
@@ -536,20 +517,19 @@ struct sh_ether_priv {
|
||||
static int sh_ether_send(struct udevice *dev, void *packet, int len)
|
||||
{
|
||||
struct sh_ether_priv *priv = dev_get_priv(dev);
|
||||
struct sh_eth_dev *eth = &priv->shdev;
|
||||
struct sh_eth_info *port_info = &priv->port_info;
|
||||
|
||||
return sh_eth_send_common(eth, packet, len);
|
||||
return sh_eth_send_common(port_info, packet, len);
|
||||
}
|
||||
|
||||
static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp)
|
||||
{
|
||||
struct sh_ether_priv *priv = dev_get_priv(dev);
|
||||
struct sh_eth_dev *eth = &priv->shdev;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = &priv->port_info;
|
||||
uchar *packet = (uchar *)ADDR_TO_P2((uintptr_t)port_info->rx_desc_cur->rd2);
|
||||
int len;
|
||||
|
||||
len = sh_eth_recv_start(eth);
|
||||
len = sh_eth_recv_start(port_info);
|
||||
if (len > 0) {
|
||||
invalidate_cache(packet, len);
|
||||
*packetp = packet;
|
||||
@@ -567,10 +547,9 @@ static int sh_ether_recv(struct udevice *dev, int flags, uchar **packetp)
|
||||
static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
|
||||
{
|
||||
struct sh_ether_priv *priv = dev_get_priv(dev);
|
||||
struct sh_eth_dev *eth = &priv->shdev;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = &priv->port_info;
|
||||
|
||||
sh_eth_recv_finish(eth);
|
||||
sh_eth_recv_finish(port_info);
|
||||
|
||||
/* Restart the receiver if disabled */
|
||||
if (!(sh_eth_read(port_info, EDRRR) & EDRRR_R))
|
||||
@@ -582,8 +561,7 @@ static int sh_ether_free_pkt(struct udevice *dev, uchar *packet, int length)
|
||||
static int sh_ether_write_hwaddr(struct udevice *dev)
|
||||
{
|
||||
struct sh_ether_priv *priv = dev_get_priv(dev);
|
||||
struct sh_eth_dev *eth = &priv->shdev;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = &priv->port_info;
|
||||
struct eth_pdata *pdata = dev_get_plat(dev);
|
||||
|
||||
sh_eth_write_hwaddr(port_info, pdata->enetaddr);
|
||||
@@ -595,10 +573,9 @@ static int sh_eth_phy_config(struct udevice *dev)
|
||||
{
|
||||
struct sh_ether_priv *priv = dev_get_priv(dev);
|
||||
struct eth_pdata *pdata = dev_get_plat(dev);
|
||||
struct sh_eth_dev *eth = &priv->shdev;
|
||||
int ret = 0;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = &priv->port_info;
|
||||
struct phy_device *phydev;
|
||||
int ret = 0;
|
||||
|
||||
phydev = phy_connect(priv->bus, -1, dev, pdata->phy_interface);
|
||||
if (!phydev)
|
||||
@@ -614,40 +591,38 @@ static int sh_ether_start(struct udevice *dev)
|
||||
{
|
||||
struct sh_ether_priv *priv = dev_get_priv(dev);
|
||||
struct eth_pdata *pdata = dev_get_plat(dev);
|
||||
struct sh_eth_dev *eth = &priv->shdev;
|
||||
struct sh_eth_info *port_info = &priv->port_info;
|
||||
int ret;
|
||||
|
||||
ret = sh_eth_init_common(eth, pdata->enetaddr);
|
||||
ret = sh_eth_init_common(port_info, pdata->enetaddr);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = sh_eth_start_common(eth);
|
||||
ret = sh_eth_start_common(port_info);
|
||||
if (ret)
|
||||
goto err_start;
|
||||
|
||||
return 0;
|
||||
|
||||
err_start:
|
||||
sh_eth_tx_desc_free(eth);
|
||||
sh_eth_rx_desc_free(eth);
|
||||
sh_eth_tx_desc_free(port_info);
|
||||
sh_eth_rx_desc_free(port_info);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sh_ether_stop(struct udevice *dev)
|
||||
{
|
||||
struct sh_ether_priv *priv = dev_get_priv(dev);
|
||||
struct sh_eth_dev *eth = &priv->shdev;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = &priv->port_info;
|
||||
|
||||
phy_shutdown(port_info->phydev);
|
||||
sh_eth_stop(&priv->shdev);
|
||||
sh_eth_stop(port_info);
|
||||
}
|
||||
|
||||
/******* for bb_miiphy *******/
|
||||
static int sh_eth_bb_mdio_active(struct mii_dev *miidev)
|
||||
{
|
||||
struct sh_eth_dev *eth = miidev->priv;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = miidev->priv;
|
||||
|
||||
sh_eth_write(port_info, sh_eth_read(port_info, PIR) | PIR_MMD, PIR);
|
||||
|
||||
@@ -656,8 +631,7 @@ static int sh_eth_bb_mdio_active(struct mii_dev *miidev)
|
||||
|
||||
static int sh_eth_bb_mdio_tristate(struct mii_dev *miidev)
|
||||
{
|
||||
struct sh_eth_dev *eth = miidev->priv;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = miidev->priv;
|
||||
|
||||
sh_eth_write(port_info, sh_eth_read(port_info, PIR) & ~PIR_MMD, PIR);
|
||||
|
||||
@@ -666,8 +640,7 @@ static int sh_eth_bb_mdio_tristate(struct mii_dev *miidev)
|
||||
|
||||
static int sh_eth_bb_set_mdio(struct mii_dev *miidev, int v)
|
||||
{
|
||||
struct sh_eth_dev *eth = miidev->priv;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = miidev->priv;
|
||||
|
||||
if (v)
|
||||
sh_eth_write(port_info,
|
||||
@@ -681,8 +654,7 @@ static int sh_eth_bb_set_mdio(struct mii_dev *miidev, int v)
|
||||
|
||||
static int sh_eth_bb_get_mdio(struct mii_dev *miidev, int *v)
|
||||
{
|
||||
struct sh_eth_dev *eth = miidev->priv;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = miidev->priv;
|
||||
|
||||
*v = (sh_eth_read(port_info, PIR) & PIR_MDI) >> 3;
|
||||
|
||||
@@ -691,8 +663,7 @@ static int sh_eth_bb_get_mdio(struct mii_dev *miidev, int *v)
|
||||
|
||||
static int sh_eth_bb_set_mdc(struct mii_dev *miidev, int v)
|
||||
{
|
||||
struct sh_eth_dev *eth = miidev->priv;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = miidev->priv;
|
||||
|
||||
if (v)
|
||||
sh_eth_write(port_info,
|
||||
@@ -738,7 +709,7 @@ 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 sh_eth_info *port_info = &priv->port_info;
|
||||
struct mii_dev *mdiodev;
|
||||
int ret;
|
||||
|
||||
@@ -757,7 +728,7 @@ static int sh_ether_probe(struct udevice *udev)
|
||||
|
||||
mdiodev->read = sh_eth_bb_miiphy_read;
|
||||
mdiodev->write = sh_eth_bb_miiphy_write;
|
||||
mdiodev->priv = eth;
|
||||
mdiodev->priv = port_info;
|
||||
snprintf(mdiodev->name, sizeof(mdiodev->name), udev->name);
|
||||
|
||||
ret = mdio_register(mdiodev);
|
||||
@@ -766,10 +737,8 @@ static int sh_ether_probe(struct udevice *udev)
|
||||
|
||||
priv->bus = mdiodev;
|
||||
|
||||
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);
|
||||
port_info->phy_addr = CFG_SH_ETHER_PHY_ADDR;
|
||||
port_info->iobase = (void __iomem *)(uintptr_t)BASE_IO_ADDR;
|
||||
|
||||
#if CONFIG_IS_ENABLED(CLK)
|
||||
ret = clk_enable(&priv->clk);
|
||||
@@ -777,7 +746,7 @@ static int sh_ether_probe(struct udevice *udev)
|
||||
goto err_mdio_register;
|
||||
#endif
|
||||
|
||||
ret = sh_eth_init_common(eth, pdata->enetaddr);
|
||||
ret = sh_eth_init_common(port_info, pdata->enetaddr);
|
||||
if (ret)
|
||||
goto err_phy_config;
|
||||
|
||||
@@ -801,8 +770,7 @@ err_mdio_register:
|
||||
static int sh_ether_remove(struct udevice *udev)
|
||||
{
|
||||
struct sh_ether_priv *priv = dev_get_priv(udev);
|
||||
struct sh_eth_dev *eth = &priv->shdev;
|
||||
struct sh_eth_info *port_info = ð->port_info[eth->port];
|
||||
struct sh_eth_info *port_info = &priv->port_info;
|
||||
|
||||
#if CONFIG_IS_ENABLED(CLK)
|
||||
clk_disable(&priv->clk);
|
||||
|
||||
@@ -33,9 +33,6 @@
|
||||
#define CFG_SH_ETHER_ALIGNE_SIZE 16
|
||||
#endif
|
||||
|
||||
/* Number of supported ports */
|
||||
#define MAX_PORT_NUM 2
|
||||
|
||||
/* Buffers must be big enough to hold the largest ethernet frame. Also, rx
|
||||
buffers must be a multiple of 32 bytes */
|
||||
#define MAX_BUF_SIZE (48 * 32)
|
||||
@@ -90,11 +87,6 @@ struct sh_eth_info {
|
||||
void __iomem *iobase;
|
||||
};
|
||||
|
||||
struct sh_eth_dev {
|
||||
int port;
|
||||
struct sh_eth_info port_info[MAX_PORT_NUM];
|
||||
};
|
||||
|
||||
/* from linux/drivers/net/ethernet/renesas/sh_eth.h */
|
||||
enum {
|
||||
/* E-DMAC registers */
|
||||
|
||||
Reference in New Issue
Block a user