From e8a2b6a4207332a2d59628a12cece9e8c1d769e4 Mon Sep 17 00:00:00 2001 From: Andy Fleming Date: Fri, 1 Dec 2006 12:01:06 -0600 Subject: [PATCH] PHY: Add support for configuring the PHY connection interface Most PHYs connect to an ethernet controller over a GMII or MII interface. However, a growing number are connected over different interfaces, such as RGMII or SGMII. The ethernet driver will tell the PHY what type of connection it is by setting it manually, or passing it in through phy_connect (or phy_attach). Changes include: * Updates to documentation * Updates to PHY Lib consumers * Changes to PHY Lib to add interface support * Some minor changes to whitespace in phy.h * gianfar driver now detects interface and passes appropriate value to PHY Lib Signed-off-by: Andrew Fleming Signed-off-by: Jeff Garzik --- drivers/net/gianfar.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) (limited to 'drivers/net/gianfar.c') 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); -- cgit v1.2.3