*
* swconfig interface based on ar8216.c
*
- * Copyright (c) 2008 Felix Fietkau <nbd@openwrt.org>
+ * Copyright (c) 2008 Felix Fietkau <nbd@nbd.name>
* VLAN support Copyright (c) 2010, 2011 Peter Lebbing <peter@digitalbrains.com>
* Copyright (c) 2013 Hauke Mehrtens <hauke@hauke-m.de>
* Copyright (c) 2014 Matti Laakso <malaakso@elisanet.fi>
u8 eecs;
u8 eesk;
u8 eedi;
- u8 eerc;
enum adm6996_model model;
MIB_DESC(ADM_CL30, "Error"),
};
+#define ADM6996_MIB_RXB_ID 1
+#define ADM6996_MIB_TXB_ID 3
+
static inline u16
r16(struct adm6996_priv *priv, enum admreg reg)
{
adm6996_read_mii_reg(struct adm6996_priv *priv, enum admreg reg)
{
struct phy_device *phydev = priv->priv;
- struct mii_bus *bus = phydev->bus;
+ struct mii_bus *bus = phydev->mdio.bus;
return bus->read(bus, PHYADDR(reg));
}
adm6996_write_mii_reg(struct adm6996_priv *priv, enum admreg reg, u16 val)
{
struct phy_device *phydev = priv->priv;
- struct mii_bus *bus = phydev->bus;
+ struct mii_bus *bus = phydev->mdio.bus;
bus->write(bus, PHYADDR(reg), val);
}
reg = r16(priv, adm6996_mibs[i].offset + ADM_OFFSET_PORT(port));
reg += r16(priv, adm6996_mibs[i].offset + ADM_OFFSET_PORT(port) + 1) << 16;
len += snprintf(buf + len, sizeof(priv->buf) - len,
- "%-12s: %lu\n",
+ "%-12s: %u\n",
adm6996_mibs[i].name,
reg);
}
return 0;
}
+static int
+adm6996_get_port_stats(struct switch_dev *dev, int port,
+ struct switch_port_stats *stats)
+{
+ struct adm6996_priv *priv = to_adm(dev);
+ int id;
+ u32 reg = 0;
+
+ if (port >= ADM_NUM_PORTS)
+ return -EINVAL;
+
+ mutex_lock(&priv->mib_lock);
+
+ id = ADM6996_MIB_TXB_ID;
+ reg = r16(priv, adm6996_mibs[id].offset + ADM_OFFSET_PORT(port));
+ reg += r16(priv, adm6996_mibs[id].offset + ADM_OFFSET_PORT(port) + 1) << 16;
+ stats->tx_bytes = reg;
+
+ id = ADM6996_MIB_RXB_ID;
+ reg = r16(priv, adm6996_mibs[id].offset + ADM_OFFSET_PORT(port));
+ reg += r16(priv, adm6996_mibs[id].offset + ADM_OFFSET_PORT(port) + 1) << 16;
+ stats->rx_bytes = reg;
+
+ mutex_unlock(&priv->mib_lock);
+
+ return 0;
+}
+
static struct switch_attr adm6996_globals[] = {
{
.type = SWITCH_TYPE_INT,
.apply_config = adm6996_hw_apply,
.reset_switch = adm6996_reset_switch,
.get_port_link = adm6996_get_port_link,
+ .get_port_stats = adm6996_get_port_stats,
};
static int adm6996_switch_init(struct adm6996_priv *priv, const char *alias, struct net_device *netdev)
pdev->supported = ADVERTISED_100baseT_Full;
pdev->advertising = ADVERTISED_100baseT_Full;
- if (pdev->addr != 0) {
+ if (pdev->mdio.addr != 0) {
pr_info ("%s: PHY overlaps ADM6996, providing fixed PHY 0x%x.\n"
- , pdev->attached_dev->name, pdev->addr);
+ , pdev->attached_dev->name, pdev->mdio.addr);
return 0;
}
- priv = devm_kzalloc(&pdev->dev, sizeof(struct adm6996_priv), GFP_KERNEL);
+ priv = devm_kzalloc(&pdev->mdio.dev, sizeof(struct adm6996_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
}
/*
- * Warning: phydev->priv is NULL if phydev->addr != 0
+ * Warning: phydev->priv is NULL if phydev->mdio.addr != 0
*/
static int adm6996_read_status(struct phy_device *phydev)
{
phydev->speed = SPEED_100;
phydev->duplex = DUPLEX_FULL;
phydev->link = 1;
+
+ phydev->state = PHY_RUNNING;
+ netif_carrier_on(phydev->attached_dev);
+ phydev->adjust_link(phydev->attached_dev);
+
return 0;
}
/*
- * Warning: phydev->priv is NULL if phydev->addr != 0
+ * Warning: phydev->priv is NULL if phydev->mdio.addr != 0
*/
static int adm6996_config_aneg(struct phy_device *phydev)
{
static int adm6996_fixup(struct phy_device *dev)
{
- struct mii_bus *bus = dev->bus;
+ struct mii_bus *bus = dev->mdio.bus;
u16 reg;
/* Our custom registers are at PHY addresses 0-10. Claim those. */
- if (dev->addr > 10)
+ if (dev->mdio.addr > 10)
return 0;
/* look for the switch on the bus */
unregister_switch(&priv->dev);
}
+static int adm6996_soft_reset(struct phy_device *phydev)
+{
+ /* we don't need an extra reset */
+ return 0;
+}
static struct phy_driver adm6996_phy_driver = {
.name = "Infineon ADM6996",
.config_init = &adm6996_config_init,
.config_aneg = &adm6996_config_aneg,
.read_status = &adm6996_read_status,
- .driver = { .owner = THIS_MODULE,},
+ .soft_reset = adm6996_soft_reset,
};
static int adm6996_gpio_probe(struct platform_device *pdev)
if (!pdata)
return -EINVAL;
-
+
priv = devm_kzalloc(&pdev->dev, sizeof(struct adm6996_priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->eecs = pdata->eecs;
priv->eedi = pdata->eedi;
- priv->eerc = pdata->eerc;
priv->eesk = pdata->eesk;
priv->model = pdata->model;
if (ret)
return ret;
ret = devm_gpio_request(&pdev->dev, priv->eedi, "adm_eedi");
- if (ret)
- return ret;
- ret = devm_gpio_request(&pdev->dev, priv->eerc, "adm_eerc");
if (ret)
return ret;
ret = devm_gpio_request(&pdev->dev, priv->eesk, "adm_eesk");
int err;
phy_register_fixup_for_id(PHY_ANY_ID, adm6996_fixup);
- err = phy_driver_register(&adm6996_phy_driver);
+ err = phy_driver_register(&adm6996_phy_driver, THIS_MODULE);
if (err)
return err;