diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/au1000_eth.c | 3 | ||||
-rw-r--r-- | drivers/net/fs_enet/fs_enet-main.c | 3 | ||||
-rw-r--r-- | drivers/net/gianfar.c | 39 | ||||
-rw-r--r-- | drivers/net/gianfar.h | 3 | ||||
-rw-r--r-- | drivers/net/phy/phy_device.c | 29 |
5 files changed, 64 insertions, 13 deletions
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 7db3c8af0894..f0b6879a1c7d 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -360,7 +360,8 @@ static int mii_probe (struct net_device *dev) BUG_ON(!phydev); BUG_ON(phydev->attached_dev); - phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0); + phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0, + PHY_INTERFACE_MODE_MII); if (IS_ERR(phydev)) { printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index cb3958704a87..889d3a13e95e 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -779,7 +779,8 @@ static int fs_init_phy(struct net_device *dev) fep->oldspeed = 0; fep->oldduplex = -1; if(fep->fpi->bus_id) - phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0); + phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0, + PHY_INTERFACE_MODE_MII); else { printk("No phy bus ID specified in BSP code\n"); return -EINVAL; diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 6bf18c82083d..baa35144134c 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -9,7 +9,7 @@ * Author: Andy Fleming * Maintainer: Kumar Gala * - * Copyright (c) 2002-2004 Freescale Semiconductor, Inc. + * Copyright (c) 2002-2006 Freescale Semiconductor, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -398,6 +398,38 @@ static int gfar_remove(struct platform_device *pdev) } +/* Reads the controller's registers to determine what interface + * connects it to the PHY. + */ +static phy_interface_t gfar_get_interface(struct net_device *dev) +{ + struct gfar_private *priv = netdev_priv(dev); + u32 ecntrl = gfar_read(&priv->regs->ecntrl); + + if (ecntrl & ECNTRL_SGMII_MODE) + return PHY_INTERFACE_MODE_SGMII; + + if (ecntrl & ECNTRL_TBI_MODE) { + if (ecntrl & ECNTRL_REDUCED_MODE) + return PHY_INTERFACE_MODE_RTBI; + else + return PHY_INTERFACE_MODE_TBI; + } + + if (ecntrl & ECNTRL_REDUCED_MODE) { + if (ecntrl & ECNTRL_REDUCED_MII_MODE) + return PHY_INTERFACE_MODE_RMII; + else + return PHY_INTERFACE_MODE_RGMII; + } + + if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT) + return PHY_INTERFACE_MODE_GMII; + + return PHY_INTERFACE_MODE_MII; +} + + /* Initializes driver's PHY state, and attaches to the PHY. * Returns 0 on success. */ @@ -409,6 +441,7 @@ static int init_phy(struct net_device *dev) SUPPORTED_1000baseT_Full : 0; struct phy_device *phydev; char phy_id[BUS_ID_SIZE]; + phy_interface_t interface; priv->oldlink = 0; priv->oldspeed = 0; @@ -416,7 +449,9 @@ static int init_phy(struct net_device *dev) snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id); - phydev = phy_connect(dev, phy_id, &adjust_link, 0); + interface = gfar_get_interface(dev); + + phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface); if (IS_ERR(phydev)) { printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 9e81a50cf2be..39e9e321fcbc 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h @@ -160,7 +160,10 @@ extern const char gfar_driver_version[]; #define ECNTRL_INIT_SETTINGS 0x00001000 #define ECNTRL_TBI_MODE 0x00000020 +#define ECNTRL_REDUCED_MODE 0x00000010 #define ECNTRL_R100 0x00000008 +#define ECNTRL_REDUCED_MII_MODE 0x00000004 +#define ECNTRL_SGMII_MODE 0x00000002 #define MRBLR_INIT_SETTINGS DEFAULT_RX_BUFFER_SIZE diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 2a08b2b62c4c..b01fc70a57db 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -59,6 +59,7 @@ struct phy_device* phy_device_create(struct mii_bus *bus, int addr, int phy_id) dev->duplex = -1; dev->pause = dev->asym_pause = 0; dev->link = 1; + dev->interface = PHY_INTERFACE_MODE_GMII; dev->autoneg = AUTONEG_ENABLE; @@ -137,11 +138,12 @@ void phy_prepare_link(struct phy_device *phydev, * the desired functionality. */ struct phy_device * phy_connect(struct net_device *dev, const char *phy_id, - void (*handler)(struct net_device *), u32 flags) + void (*handler)(struct net_device *), u32 flags, + u32 interface) { struct phy_device *phydev; - phydev = phy_attach(dev, phy_id, flags); + phydev = phy_attach(dev, phy_id, flags, interface); if (IS_ERR(phydev)) return phydev; @@ -186,7 +188,7 @@ static int phy_compare_id(struct device *dev, void *data) } struct phy_device *phy_attach(struct net_device *dev, - const char *phy_id, u32 flags) + const char *phy_id, u32 flags, u32 interface) { struct bus_type *bus = &mdio_bus_type; struct phy_device *phydev; @@ -231,6 +233,20 @@ struct phy_device *phy_attach(struct net_device *dev, phydev->dev_flags = flags; + phydev->interface = interface; + + /* Do initial configuration here, now that + * we have certain key parameters + * (dev_flags and interface) */ + if (phydev->drv->config_init) { + int err; + + err = phydev->drv->config_init(phydev); + + if (err < 0) + return ERR_PTR(err); + } + return phydev; } EXPORT_SYMBOL(phy_attach); @@ -612,13 +628,8 @@ static int phy_probe(struct device *dev) spin_unlock(&phydev->lock); - if (err < 0) - return err; - - if (phydev->drv->config_init) - err = phydev->drv->config_init(phydev); - return err; + } static int phy_remove(struct device *dev) |