Index: linux-2.6.27/drivers/net/gianfar_ethtool.c =================================================================== --- linux-2.6.27.orig/drivers/net/gianfar_ethtool.c +++ linux-2.6.27/drivers/net/gianfar_ethtool.c @@ -182,13 +182,7 @@ static void gfar_gdrvinfo(struct net_dev static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd) { - struct gfar_private *priv = netdev_priv(dev); - struct phy_device *phydev = priv->phydev; - - if (NULL == phydev) - return -ENODEV; - - return phy_ethtool_sset(phydev, cmd); + return 0; } @@ -196,15 +190,11 @@ static int gfar_ssettings(struct net_dev static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd) { struct gfar_private *priv = netdev_priv(dev); - struct phy_device *phydev = priv->phydev; - - if (NULL == phydev) - return -ENODEV; cmd->maxtxpkt = priv->txcount; cmd->maxrxpkt = priv->rxcount; - return phy_ethtool_gset(phydev, cmd); + return 0; } /* Return the length of the register structure */ @@ -232,18 +222,7 @@ static unsigned int gfar_usecs2ticks(str unsigned int count; /* The timer is different, depending on the interface speed */ - switch (priv->phydev->speed) { - case SPEED_1000: - count = GFAR_GBIT_TIME; - break; - case SPEED_100: - count = GFAR_100_TIME; - break; - case SPEED_10: - default: - count = GFAR_10_TIME; - break; - } + count = GFAR_100_TIME; /* Make sure we return a number greater than 0 * if usecs > 0 */ @@ -256,18 +235,7 @@ static unsigned int gfar_ticks2usecs(str unsigned int count; /* The timer is different, depending on the interface speed */ - switch (priv->phydev->speed) { - case SPEED_1000: - count = GFAR_GBIT_TIME; - break; - case SPEED_100: - count = GFAR_100_TIME; - break; - case SPEED_10: - default: - count = GFAR_10_TIME; - break; - } + count = GFAR_100_TIME; /* Make sure we return a number greater than 0 */ /* if ticks is > 0 */ @@ -283,9 +251,6 @@ static int gfar_gcoalesce(struct net_dev if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE)) return -EOPNOTSUPP; - if (NULL == priv->phydev) - return -ENODEV; - cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime); cvals->rx_max_coalesced_frames = priv->rxcount; @@ -342,9 +307,6 @@ static int gfar_scoalesce(struct net_dev else priv->rxcoalescing = 1; - if (NULL == priv->phydev) - return -ENODEV; - /* Check the bounds of the values */ if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) { pr_info("Coalescing is limited to %d microseconds\n", Index: linux-2.6.27/drivers/net/gianfar.c =================================================================== --- linux-2.6.27.orig/drivers/net/gianfar.c +++ linux-2.6.27/drivers/net/gianfar.c @@ -116,7 +116,6 @@ static int gfar_change_mtu(struct net_de static irqreturn_t gfar_error(int irq, void *dev_id); static irqreturn_t gfar_transmit(int irq, void *dev_id); static irqreturn_t gfar_interrupt(int irq, void *dev_id); -static void adjust_link(struct net_device *dev); static void init_registers(struct net_device *dev); static int init_phy(struct net_device *dev); static int gfar_probe(struct platform_device *pdev); @@ -124,7 +123,6 @@ static int gfar_remove(struct platform_d static void free_skb_resources(struct gfar_private *priv); static void gfar_set_multi(struct net_device *dev); static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); -static void gfar_configure_serdes(struct net_device *dev); static int gfar_poll(struct napi_struct *napi, int budget); #ifdef CONFIG_NET_POLL_CONTROLLER static void gfar_netpoll(struct net_device *dev); @@ -424,8 +422,6 @@ static int gfar_suspend(struct platform_ tempval = gfar_read(&priv->regs->maccfg2); tempval |= MACCFG2_MPEN; gfar_write(&priv->regs->maccfg2, tempval); - } else { - phy_stop(priv->phydev); } } @@ -438,17 +434,12 @@ static int gfar_resume(struct platform_d struct gfar_private *priv = netdev_priv(dev); unsigned long flags; u32 tempval; - int magic_packet = priv->wol_en && - (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET); if (!netif_running(dev)) { netif_device_attach(dev); return 0; } - if (!magic_packet && priv->phydev) - phy_start(priv->phydev); - /* Disable Magic Packet mode, in case something * else woke us up. */ @@ -476,47 +467,6 @@ static int gfar_resume(struct platform_d #define gfar_resume NULL #endif -/* 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 { - phy_interface_t interface = priv->einfo->interface; - - /* - * This isn't autodetected right now, so it must - * be set by the device tree or platform code. - */ - if (interface == PHY_INTERFACE_MODE_RGMII_ID) - return PHY_INTERFACE_MODE_RGMII_ID; - - 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. @@ -524,10 +474,6 @@ static phy_interface_t gfar_get_interfac static int init_phy(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); - uint gigabit_support = - priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ? - SUPPORTED_1000baseT_Full : 0; - struct phy_device *phydev; char phy_id[BUS_ID_SIZE]; phy_interface_t interface; @@ -537,54 +483,11 @@ static int init_phy(struct net_device *d snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id); - interface = gfar_get_interface(dev); - - phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface); - - if (interface == PHY_INTERFACE_MODE_SGMII) - gfar_configure_serdes(dev); - - if (IS_ERR(phydev)) { - printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); - return PTR_ERR(phydev); - } - - /* Remove any features not supported by the controller */ - phydev->supported &= (GFAR_SUPPORTED | gigabit_support); - phydev->advertising = phydev->supported; - - priv->phydev = phydev; + interface = PHY_INTERFACE_MODE_MII; return 0; } -/* - * Initialize TBI PHY interface for communicating with the - * SERDES lynx PHY on the chip. We communicate with this PHY - * through the MDIO bus on each controller, treating it as a - * "normal" PHY at the address found in the TBIPA register. We assume - * that the TBIPA register is valid. Either the MDIO bus code will set - * it to a value that doesn't conflict with other PHYs on the bus, or the - * value doesn't matter, as there are no other PHYs on the bus. - */ -static void gfar_configure_serdes(struct net_device *dev) -{ - struct gfar_private *priv = netdev_priv(dev); - struct gfar_mii __iomem *regs = - (void __iomem *)&priv->regs->gfar_mii_regs; - int tbipa = gfar_read(&priv->regs->tbipa); - - /* Single clk mode, mii mode off(for serdes communication) */ - gfar_local_mdio_write(regs, tbipa, MII_TBICON, TBICON_CLK_SELECT); - - gfar_local_mdio_write(regs, tbipa, MII_ADVERTISE, - ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | - ADVERTISE_1000XPSE_ASYM); - - gfar_local_mdio_write(regs, tbipa, MII_BMCR, BMCR_ANENABLE | - BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000); -} - static void init_registers(struct net_device *dev) { struct gfar_private *priv = netdev_priv(dev); @@ -678,8 +581,6 @@ void stop_gfar(struct net_device *dev) struct gfar __iomem *regs = priv->regs; unsigned long flags; - phy_stop(priv->phydev); - /* Lock it down */ spin_lock_irqsave(&priv->txlock, flags); spin_lock(&priv->rxlock); @@ -949,7 +850,6 @@ int startup_gfar(struct net_device *dev) } } - phy_start(priv->phydev); /* Configure the coalescing support */ if (priv->txcoalescing) @@ -1217,9 +1117,6 @@ static int gfar_close(struct net_device cancel_work_sync(&priv->reset_task); stop_gfar(dev); - /* Disconnect from the PHY */ - phy_disconnect(priv->phydev); - priv->phydev = NULL; netif_stop_queue(dev); @@ -1777,86 +1674,6 @@ static irqreturn_t gfar_interrupt(int ir return IRQ_HANDLED; } -/* Called every time the controller might need to be made - * aware of new link state. The PHY code conveys this - * information through variables in the phydev structure, and this - * function converts those variables into the appropriate - * register values, and can bring down the device if needed. - */ -static void adjust_link(struct net_device *dev) -{ - struct gfar_private *priv = netdev_priv(dev); - struct gfar __iomem *regs = priv->regs; - unsigned long flags; - struct phy_device *phydev = priv->phydev; - int new_state = 0; - - spin_lock_irqsave(&priv->txlock, flags); - if (phydev->link) { - u32 tempval = gfar_read(®s->maccfg2); - u32 ecntrl = gfar_read(®s->ecntrl); - - /* Now we make sure that we can be in full duplex mode. - * If not, we operate in half-duplex mode. */ - if (phydev->duplex != priv->oldduplex) { - new_state = 1; - if (!(phydev->duplex)) - tempval &= ~(MACCFG2_FULL_DUPLEX); - else - tempval |= MACCFG2_FULL_DUPLEX; - - priv->oldduplex = phydev->duplex; - } - - if (phydev->speed != priv->oldspeed) { - new_state = 1; - switch (phydev->speed) { - case 1000: - tempval = - ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII); - break; - case 100: - case 10: - tempval = - ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII); - - /* Reduced mode distinguishes - * between 10 and 100 */ - if (phydev->speed == SPEED_100) - ecntrl |= ECNTRL_R100; - else - ecntrl &= ~(ECNTRL_R100); - break; - default: - if (netif_msg_link(priv)) - printk(KERN_WARNING - "%s: Ack! Speed (%d) is not 10/100/1000!\n", - dev->name, phydev->speed); - break; - } - - priv->oldspeed = phydev->speed; - } - - gfar_write(®s->maccfg2, tempval); - gfar_write(®s->ecntrl, ecntrl); - - if (!priv->oldlink) { - new_state = 1; - priv->oldlink = 1; - } - } else if (priv->oldlink) { - new_state = 1; - priv->oldlink = 0; - priv->oldspeed = 0; - priv->oldduplex = -1; - } - - if (new_state && netif_msg_link(priv)) - phy_print_status(phydev); - - spin_unlock_irqrestore(&priv->txlock, flags); -} /* Update the hash table based on the current list of multicast * addresses we subscribe to. Also, change the promiscuity of Index: linux-2.6.27/drivers/net/gianfar.h =================================================================== --- linux-2.6.27.orig/drivers/net/gianfar.h +++ linux-2.6.27/drivers/net/gianfar.h @@ -150,7 +150,7 @@ extern const char gfar_driver_version[]; #define MACCFG1_SYNCD_TX_EN 0x00000002 #define MACCFG1_TX_EN 0x00000001 -#define MACCFG2_INIT_SETTINGS 0x00007205 +#define MACCFG2_INIT_SETTINGS 0x00007105 #define MACCFG2_FULL_DUPLEX 0x00000001 #define MACCFG2_IF 0x00000300 #define MACCFG2_MII 0x00000100 @@ -748,7 +748,6 @@ struct gfar_private { struct gianfar_platform_data *einfo; /* PHY stuff */ - struct phy_device *phydev; struct mii_bus *mii_bus; int oldspeed; int oldduplex; Index: linux-2.6.27/drivers/net/gianfar_mii.c =================================================================== --- linux-2.6.27.orig/drivers/net/gianfar_mii.c +++ linux-2.6.27/drivers/net/gianfar_mii.c @@ -217,28 +217,10 @@ static int gfar_mdio_probe(struct device if (r) return r; - if (phy_id == 0xffffffff) - break; - } - - /* The bus is full. We don't support using 31 PHYs, sorry */ - if (i == 0) - return -EBUSY; - - gfar_write(&enet_regs->tbipa, i); - - err = mdiobus_register(new_bus); - - if (0 != err) { - printk (KERN_ERR "%s: Cannot register as MDIO bus\n", - new_bus->name); - goto bus_register_fail; } return 0; -bus_register_fail: - iounmap(regs); reg_map_fail: kfree(new_bus); Index: linux-2.6.27/drivers/net/gianfar_mii.h =================================================================== --- linux-2.6.27.orig/drivers/net/gianfar_mii.h +++ linux-2.6.27/drivers/net/gianfar_mii.h @@ -27,7 +27,6 @@ | SUPPORTED_10baseT_Full \ | SUPPORTED_100baseT_Half \ | SUPPORTED_100baseT_Full \ - | SUPPORTED_Autoneg \ | SUPPORTED_MII) struct gfar_mii { Index: linux-2.6.27/drivers/net/phy/phy_device.c =================================================================== --- linux-2.6.27.orig/drivers/net/phy/phy_device.c +++ linux-2.6.27/drivers/net/phy/phy_device.c @@ -281,7 +281,7 @@ struct phy_device * phy_connect(struct n if (IS_ERR(phydev)) return phydev; - phy_prepare_link(phydev, handler); + phydev->link = 1; phy_start_machine(phydev, NULL); @@ -302,7 +302,7 @@ void phy_disconnect(struct phy_device *p phy_stop_interrupts(phydev); phy_stop_machine(phydev); - + phydev->adjust_link = NULL; phy_detach(phydev); @@ -438,7 +438,7 @@ int genphy_config_advert(struct phy_devi if (adv < 0) return adv; - adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | + adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM); if (advertise & ADVERTISED_10baseT_Half) adv |= ADVERTISE_10HALF; @@ -503,7 +503,7 @@ int genphy_setup_forced(struct phy_devic if (DUPLEX_FULL == phydev->duplex) ctl |= BMCR_FULLDPLX; - + err = phy_write(phydev, MII_BMCR, ctl); if (err < 0) @@ -671,7 +671,7 @@ int genphy_read_status(struct phy_device phydev->duplex = DUPLEX_FULL; } else if (lpa & (LPA_100FULL | LPA_100HALF)) { phydev->speed = SPEED_100; - + if (lpa & LPA_100FULL) phydev->duplex = DUPLEX_FULL; } else Index: linux-2.6.27/include/linux/phy.h =================================================================== --- linux-2.6.27.orig/include/linux/phy.h +++ linux-2.6.27/include/linux/phy.h @@ -339,6 +339,11 @@ struct phy_driver { u32 features; u32 flags; + /* Called during discovery to test if the + * device can attach to the bus, even if + phy id and mask do not match */ + bool (*detect)(struct mii_bus *bus, int addr); + /* * Called to initialize the PHY, * including after a reset