Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e8a2b6a4 authored by Andy Fleming's avatar Andy Fleming Committed by Jeff Garzik
Browse files

[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: default avatarAndrew Fleming <afleming@freescale.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent cabdfb37
Loading
Loading
Loading
Loading
+9 −4
Original line number Diff line number Diff line

-------
PHY Abstraction Layer
(Updated 2005-07-21)
(Updated 2006-11-30)

Purpose

@@ -97,11 +97,12 @@ Letting the PHY Abstraction Layer do Everything
 
 Next, you need to know the device name of the PHY connected to this device. 
 The name will look something like, "phy0:0", where the first number is the
 bus id, and the second is the PHY's address on that bus.
 bus id, and the second is the PHY's address on that bus.  Typically,
 the bus is responsible for making its ID unique.
 
 Now, to connect, just call this function:
 
   phydev = phy_connect(dev, phy_name, &adjust_link, flags);
   phydev = phy_connect(dev, phy_name, &adjust_link, flags, interface);

 phydev is a pointer to the phy_device structure which represents the PHY.  If
 phy_connect is successful, it will return the pointer.  dev, here, is the
@@ -115,6 +116,10 @@ Letting the PHY Abstraction Layer do Everything
 This is useful if the system has put hardware restrictions on
 the PHY/controller, of which the PHY needs to be aware.

 interface is a u32 which specifies the connection type used
 between the controller and the PHY.  Examples are GMII, MII,
 RGMII, and SGMII.  For a full list, see include/linux/phy.h

 Now just make sure that phydev->supported and phydev->advertising have any
 values pruned from them which don't make sense for your controller (a 10/100
 controller may be connected to a gigabit capable PHY, so you would need to
@@ -191,7 +196,7 @@ Doing it all yourself
   start, or disables then frees them for stop.

 struct phy_device * phy_attach(struct net_device *dev, const char *phy_id,
		 u32 flags);
		 u32 flags, phy_interface_t interface);

   Attaches a network device to a particular PHY, binding the PHY to a generic
   driver if none was found during bus initialization.  Passes in
+2 −1
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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;
+37 −2
Original line number Diff line number Diff line
@@ -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);
+3 −0
Original line number Diff line number Diff line
@@ -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

Loading