diff options
Diffstat (limited to 'drivers/net/phy')
| -rw-r--r-- | drivers/net/phy/mdio-mux-gpio.c | 1 | ||||
| -rw-r--r-- | drivers/net/phy/mdio-mux.c | 2 | ||||
| -rw-r--r-- | drivers/net/phy/mdio-octeon.c | 92 | ||||
| -rw-r--r-- | drivers/net/phy/phy.c | 74 |
4 files changed, 66 insertions, 103 deletions
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c index e0cc4ef33dee..eefe49e8713c 100644 --- a/drivers/net/phy/mdio-mux-gpio.c +++ b/drivers/net/phy/mdio-mux-gpio.c @@ -101,7 +101,6 @@ err: n--; gpio_free(s->gpio[n]); } - devm_kfree(&pdev->dev, s); return r; } diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c index 5c120189ec86..4d4d25efc1e1 100644 --- a/drivers/net/phy/mdio-mux.c +++ b/drivers/net/phy/mdio-mux.c @@ -132,7 +132,7 @@ int mdio_mux_init(struct device *dev, pb->mii_bus = parent_bus; ret_val = -ENODEV; - for_each_child_of_node(dev->of_node, child_bus_node) { + for_each_available_child_of_node(dev->of_node, child_bus_node) { u32 v; r = of_property_read_u32(child_bus_node, "reg", &v); diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c index 826d961f39f7..d4015aa663e6 100644 --- a/drivers/net/phy/mdio-octeon.c +++ b/drivers/net/phy/mdio-octeon.c @@ -3,14 +3,17 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2009 Cavium Networks + * Copyright (C) 2009,2011 Cavium, Inc. */ -#include <linux/gfp.h> -#include <linux/init.h> -#include <linux/module.h> #include <linux/platform_device.h> +#include <linux/of_mdio.h> +#include <linux/delay.h> +#include <linux/module.h> +#include <linux/init.h> +#include <linux/gfp.h> #include <linux/phy.h> +#include <linux/io.h> #include <asm/octeon/octeon.h> #include <asm/octeon/cvmx-smix-defs.h> @@ -18,9 +21,17 @@ #define DRV_VERSION "1.0" #define DRV_DESCRIPTION "Cavium Networks Octeon SMI/MDIO driver" +#define SMI_CMD 0x0 +#define SMI_WR_DAT 0x8 +#define SMI_RD_DAT 0x10 +#define SMI_CLK 0x18 +#define SMI_EN 0x20 + struct octeon_mdiobus { struct mii_bus *mii_bus; - int unit; + u64 register_base; + resource_size_t mdio_phys; + resource_size_t regsize; int phy_irq[PHY_MAX_ADDR]; }; @@ -35,15 +46,15 @@ static int octeon_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) smi_cmd.s.phy_op = 1; /* MDIO_CLAUSE_22_READ */ smi_cmd.s.phy_adr = phy_id; smi_cmd.s.reg_adr = regnum; - cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64); + cvmx_write_csr(p->register_base + SMI_CMD, smi_cmd.u64); do { /* * Wait 1000 clocks so we don't saturate the RSL bus * doing reads. */ - cvmx_wait(1000); - smi_rd.u64 = cvmx_read_csr(CVMX_SMIX_RD_DAT(p->unit)); + __delay(1000); + smi_rd.u64 = cvmx_read_csr(p->register_base + SMI_RD_DAT); } while (smi_rd.s.pending && --timeout); if (smi_rd.s.val) @@ -62,21 +73,21 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id, smi_wr.u64 = 0; smi_wr.s.dat = val; - cvmx_write_csr(CVMX_SMIX_WR_DAT(p->unit), smi_wr.u64); + cvmx_write_csr(p->register_base + SMI_WR_DAT, smi_wr.u64); smi_cmd.u64 = 0; smi_cmd.s.phy_op = 0; /* MDIO_CLAUSE_22_WRITE */ smi_cmd.s.phy_adr = phy_id; smi_cmd.s.reg_adr = regnum; - cvmx_write_csr(CVMX_SMIX_CMD(p->unit), smi_cmd.u64); + cvmx_write_csr(p->register_base + SMI_CMD, smi_cmd.u64); do { /* * Wait 1000 clocks so we don't saturate the RSL bus * doing reads. */ - cvmx_wait(1000); - smi_wr.u64 = cvmx_read_csr(CVMX_SMIX_WR_DAT(p->unit)); + __delay(1000); + smi_wr.u64 = cvmx_read_csr(p->register_base + SMI_WR_DAT); } while (smi_wr.s.pending && --timeout); if (timeout <= 0) @@ -88,38 +99,44 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id, static int __devinit octeon_mdiobus_probe(struct platform_device *pdev) { struct octeon_mdiobus *bus; + struct resource *res_mem; union cvmx_smix_en smi_en; - int i; int err = -ENOENT; bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); if (!bus) return -ENOMEM; - /* The platform_device id is our unit number. */ - bus->unit = pdev->id; + res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + if (res_mem == NULL) { + dev_err(&pdev->dev, "found no memory resource\n"); + err = -ENXIO; + goto fail; + } + bus->mdio_phys = res_mem->start; + bus->regsize = resource_size(res_mem); + if (!devm_request_mem_region(&pdev->dev, bus->mdio_phys, bus->regsize, + res_mem->name)) { + dev_err(&pdev->dev, "request_mem_region failed\n"); + goto fail; + } + bus->register_base = + (u64)devm_ioremap(&pdev->dev, bus->mdio_phys, bus->regsize); bus->mii_bus = mdiobus_alloc(); if (!bus->mii_bus) - goto err; + goto fail; smi_en.u64 = 0; smi_en.s.en = 1; - cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64); - - /* - * Standard Octeon evaluation boards don't support phy - * interrupts, we need to poll. - */ - for (i = 0; i < PHY_MAX_ADDR; i++) - bus->phy_irq[i] = PHY_POLL; + cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64); bus->mii_bus->priv = bus; bus->mii_bus->irq = bus->phy_irq; bus->mii_bus->name = "mdio-octeon"; - snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%s-%x", - bus->mii_bus->name, bus->unit); + snprintf(bus->mii_bus->id, MII_BUS_ID_SIZE, "%llx", bus->register_base); bus->mii_bus->parent = &pdev->dev; bus->mii_bus->read = octeon_mdiobus_read; @@ -127,20 +144,18 @@ static int __devinit octeon_mdiobus_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, bus); - err = mdiobus_register(bus->mii_bus); + err = of_mdiobus_register(bus->mii_bus, pdev->dev.of_node); if (err) - goto err_register; + goto fail_register; dev_info(&pdev->dev, "Version " DRV_VERSION "\n"); return 0; -err_register: +fail_register: mdiobus_free(bus->mii_bus); - -err: - devm_kfree(&pdev->dev, bus); +fail: smi_en.u64 = 0; - cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64); + cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64); return err; } @@ -154,14 +169,23 @@ static int __devexit octeon_mdiobus_remove(struct platform_device *pdev) mdiobus_unregister(bus->mii_bus); mdiobus_free(bus->mii_bus); smi_en.u64 = 0; - cvmx_write_csr(CVMX_SMIX_EN(bus->unit), smi_en.u64); + cvmx_write_csr(bus->register_base + SMI_EN, smi_en.u64); return 0; } +static struct of_device_id octeon_mdiobus_match[] = { + { + .compatible = "cavium,octeon-3860-mdio", + }, + {}, +}; +MODULE_DEVICE_TABLE(of, octeon_mdiobus_match); + static struct platform_driver octeon_mdiobus_driver = { .driver = { .name = "mdio-octeon", .owner = THIS_MODULE, + .of_match_table = octeon_mdiobus_match, }, .probe = octeon_mdiobus_probe, .remove = __devexit_p(octeon_mdiobus_remove), diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 7ca2ff97c368..ef9ea9248223 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -1035,66 +1035,6 @@ static void phy_write_mmd_indirect(struct mii_bus *bus, int prtad, int devad, bus->write(bus, addr, MII_MMD_DATA, data); } -static u32 phy_eee_to_adv(u16 eee_adv) -{ - u32 adv = 0; - - if (eee_adv & MDIO_EEE_100TX) - adv |= ADVERTISED_100baseT_Full; - if (eee_adv & MDIO_EEE_1000T) - adv |= ADVERTISED_1000baseT_Full; - if (eee_adv & MDIO_EEE_10GT) - adv |= ADVERTISED_10000baseT_Full; - if (eee_adv & MDIO_EEE_1000KX) - adv |= ADVERTISED_1000baseKX_Full; - if (eee_adv & MDIO_EEE_10GKX4) - adv |= ADVERTISED_10000baseKX4_Full; - if (eee_adv & MDIO_EEE_10GKR) - adv |= ADVERTISED_10000baseKR_Full; - - return adv; -} - -static u32 phy_eee_to_supported(u16 eee_caported) -{ - u32 supported = 0; - - if (eee_caported & MDIO_EEE_100TX) - supported |= SUPPORTED_100baseT_Full; - if (eee_caported & MDIO_EEE_1000T) - supported |= SUPPORTED_1000baseT_Full; - if (eee_caported & MDIO_EEE_10GT) - supported |= SUPPORTED_10000baseT_Full; - if (eee_caported & MDIO_EEE_1000KX) - supported |= SUPPORTED_1000baseKX_Full; - if (eee_caported & MDIO_EEE_10GKX4) - supported |= SUPPORTED_10000baseKX4_Full; - if (eee_caported & MDIO_EEE_10GKR) - supported |= SUPPORTED_10000baseKR_Full; - - return supported; -} - -static u16 phy_adv_to_eee(u32 adv) -{ - u16 reg = 0; - - if (adv & ADVERTISED_100baseT_Full) - reg |= MDIO_EEE_100TX; - if (adv & ADVERTISED_1000baseT_Full) - reg |= MDIO_EEE_1000T; - if (adv & ADVERTISED_10000baseT_Full) - reg |= MDIO_EEE_10GT; - if (adv & ADVERTISED_1000baseKX_Full) - reg |= MDIO_EEE_1000KX; - if (adv & ADVERTISED_10000baseKX4_Full) - reg |= MDIO_EEE_10GKX4; - if (adv & ADVERTISED_10000baseKR_Full) - reg |= MDIO_EEE_10GKR; - - return reg; -} - /** * phy_init_eee - init and check the EEE feature * @phydev: target phy_device struct @@ -1132,7 +1072,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) if (eee_cap < 0) return eee_cap; - cap = phy_eee_to_supported(eee_cap); + cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap); if (!cap) goto eee_exit; @@ -1149,8 +1089,8 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable) if (eee_adv < 0) return eee_adv; - adv = phy_eee_to_adv(eee_adv); - lp = phy_eee_to_adv(eee_lp); + adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv); + lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp); idx = phy_find_setting(phydev->speed, phydev->duplex); if ((lp & adv & settings[idx].setting)) goto eee_exit; @@ -1210,21 +1150,21 @@ int phy_ethtool_get_eee(struct phy_device *phydev, struct ethtool_eee *data) MDIO_MMD_PCS, phydev->addr); if (val < 0) return val; - data->supported = phy_eee_to_supported(val); + data->supported = mmd_eee_cap_to_ethtool_sup_t(val); /* Get advertisement EEE */ val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN, phydev->addr); if (val < 0) return val; - data->advertised = phy_eee_to_adv(val); + data->advertised = mmd_eee_adv_to_ethtool_adv_t(val); /* Get LP advertisement EEE */ val = phy_read_mmd_indirect(phydev->bus, MDIO_AN_EEE_LPABLE, MDIO_MMD_AN, phydev->addr); if (val < 0) return val; - data->lp_advertised = phy_eee_to_adv(val); + data->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(val); return 0; } @@ -1241,7 +1181,7 @@ int phy_ethtool_set_eee(struct phy_device *phydev, struct ethtool_eee *data) { int val; - val = phy_adv_to_eee(data->advertised); + val = ethtool_adv_to_mmd_eee_adv_t(data->advertised); phy_write_mmd_indirect(phydev->bus, MDIO_AN_EEE_ADV, MDIO_MMD_AN, phydev->addr, val); |
