Commit e8a2b6a4207332a2d59628a12cece9e8c1d769e4

Authored by Andy Fleming
Committed by Jeff Garzik
1 parent cabdfb373a

[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 <afleming@freescale.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

Showing 7 changed files with 93 additions and 23 deletions Side-by-side Diff

Documentation/networking/phy.txt
1 1  
2 2 -------
3 3 PHY Abstraction Layer
4   -(Updated 2005-07-21)
  4 +(Updated 2006-11-30)
5 5  
6 6 Purpose
7 7  
8 8  
... ... @@ -97,11 +97,12 @@
97 97  
98 98 Next, you need to know the device name of the PHY connected to this device.
99 99 The name will look something like, "phy0:0", where the first number is the
100   - bus id, and the second is the PHY's address on that bus.
  100 + bus id, and the second is the PHY's address on that bus. Typically,
  101 + the bus is responsible for making its ID unique.
101 102  
102 103 Now, to connect, just call this function:
103 104  
104   - phydev = phy_connect(dev, phy_name, &adjust_link, flags);
  105 + phydev = phy_connect(dev, phy_name, &adjust_link, flags, interface);
105 106  
106 107 phydev is a pointer to the phy_device structure which represents the PHY. If
107 108 phy_connect is successful, it will return the pointer. dev, here, is the
... ... @@ -115,6 +116,10 @@
115 116 This is useful if the system has put hardware restrictions on
116 117 the PHY/controller, of which the PHY needs to be aware.
117 118  
  119 + interface is a u32 which specifies the connection type used
  120 + between the controller and the PHY. Examples are GMII, MII,
  121 + RGMII, and SGMII. For a full list, see include/linux/phy.h
  122 +
118 123 Now just make sure that phydev->supported and phydev->advertising have any
119 124 values pruned from them which don't make sense for your controller (a 10/100
120 125 controller may be connected to a gigabit capable PHY, so you would need to
... ... @@ -191,7 +196,7 @@
191 196 start, or disables then frees them for stop.
192 197  
193 198 struct phy_device * phy_attach(struct net_device *dev, const char *phy_id,
194   - u32 flags);
  199 + u32 flags, phy_interface_t interface);
195 200  
196 201 Attaches a network device to a particular PHY, binding the PHY to a generic
197 202 driver if none was found during bus initialization. Passes in
drivers/net/au1000_eth.c
... ... @@ -360,7 +360,8 @@
360 360 BUG_ON(!phydev);
361 361 BUG_ON(phydev->attached_dev);
362 362  
363   - phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0);
  363 + phydev = phy_connect(dev, phydev->dev.bus_id, &au1000_adjust_link, 0,
  364 + PHY_INTERFACE_MODE_MII);
364 365  
365 366 if (IS_ERR(phydev)) {
366 367 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
drivers/net/fs_enet/fs_enet-main.c
... ... @@ -779,7 +779,8 @@
779 779 fep->oldspeed = 0;
780 780 fep->oldduplex = -1;
781 781 if(fep->fpi->bus_id)
782   - phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0);
  782 + phydev = phy_connect(dev, fep->fpi->bus_id, &fs_adjust_link, 0,
  783 + PHY_INTERFACE_MODE_MII);
783 784 else {
784 785 printk("No phy bus ID specified in BSP code\n");
785 786 return -EINVAL;
drivers/net/gianfar.c
... ... @@ -9,7 +9,7 @@
9 9 * Author: Andy Fleming
10 10 * Maintainer: Kumar Gala
11 11 *
12   - * Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
  12 + * Copyright (c) 2002-2006 Freescale Semiconductor, Inc.
13 13 *
14 14 * This program is free software; you can redistribute it and/or modify it
15 15 * under the terms of the GNU General Public License as published by the
... ... @@ -398,6 +398,38 @@
398 398 }
399 399  
400 400  
  401 +/* Reads the controller's registers to determine what interface
  402 + * connects it to the PHY.
  403 + */
  404 +static phy_interface_t gfar_get_interface(struct net_device *dev)
  405 +{
  406 + struct gfar_private *priv = netdev_priv(dev);
  407 + u32 ecntrl = gfar_read(&priv->regs->ecntrl);
  408 +
  409 + if (ecntrl & ECNTRL_SGMII_MODE)
  410 + return PHY_INTERFACE_MODE_SGMII;
  411 +
  412 + if (ecntrl & ECNTRL_TBI_MODE) {
  413 + if (ecntrl & ECNTRL_REDUCED_MODE)
  414 + return PHY_INTERFACE_MODE_RTBI;
  415 + else
  416 + return PHY_INTERFACE_MODE_TBI;
  417 + }
  418 +
  419 + if (ecntrl & ECNTRL_REDUCED_MODE) {
  420 + if (ecntrl & ECNTRL_REDUCED_MII_MODE)
  421 + return PHY_INTERFACE_MODE_RMII;
  422 + else
  423 + return PHY_INTERFACE_MODE_RGMII;
  424 + }
  425 +
  426 + if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT)
  427 + return PHY_INTERFACE_MODE_GMII;
  428 +
  429 + return PHY_INTERFACE_MODE_MII;
  430 +}
  431 +
  432 +
401 433 /* Initializes driver's PHY state, and attaches to the PHY.
402 434 * Returns 0 on success.
403 435 */
... ... @@ -409,6 +441,7 @@
409 441 SUPPORTED_1000baseT_Full : 0;
410 442 struct phy_device *phydev;
411 443 char phy_id[BUS_ID_SIZE];
  444 + phy_interface_t interface;
412 445  
413 446 priv->oldlink = 0;
414 447 priv->oldspeed = 0;
... ... @@ -416,7 +449,9 @@
416 449  
417 450 snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT, priv->einfo->bus_id, priv->einfo->phy_id);
418 451  
419   - phydev = phy_connect(dev, phy_id, &adjust_link, 0);
  452 + interface = gfar_get_interface(dev);
  453 +
  454 + phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface);
420 455  
421 456 if (IS_ERR(phydev)) {
422 457 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
drivers/net/gianfar.h
... ... @@ -160,7 +160,10 @@
160 160  
161 161 #define ECNTRL_INIT_SETTINGS 0x00001000
162 162 #define ECNTRL_TBI_MODE 0x00000020
  163 +#define ECNTRL_REDUCED_MODE 0x00000010
163 164 #define ECNTRL_R100 0x00000008
  165 +#define ECNTRL_REDUCED_MII_MODE 0x00000004
  166 +#define ECNTRL_SGMII_MODE 0x00000002
164 167  
165 168 #define MRBLR_INIT_SETTINGS DEFAULT_RX_BUFFER_SIZE
166 169  
drivers/net/phy/phy_device.c
... ... @@ -59,6 +59,7 @@
59 59 dev->duplex = -1;
60 60 dev->pause = dev->asym_pause = 0;
61 61 dev->link = 1;
  62 + dev->interface = PHY_INTERFACE_MODE_GMII;
62 63  
63 64 dev->autoneg = AUTONEG_ENABLE;
64 65  
65 66  
... ... @@ -137,11 +138,12 @@
137 138 * the desired functionality.
138 139 */
139 140 struct phy_device * phy_connect(struct net_device *dev, const char *phy_id,
140   - void (*handler)(struct net_device *), u32 flags)
  141 + void (*handler)(struct net_device *), u32 flags,
  142 + u32 interface)
141 143 {
142 144 struct phy_device *phydev;
143 145  
144   - phydev = phy_attach(dev, phy_id, flags);
  146 + phydev = phy_attach(dev, phy_id, flags, interface);
145 147  
146 148 if (IS_ERR(phydev))
147 149 return phydev;
... ... @@ -186,7 +188,7 @@
186 188 }
187 189  
188 190 struct phy_device *phy_attach(struct net_device *dev,
189   - const char *phy_id, u32 flags)
  191 + const char *phy_id, u32 flags, u32 interface)
190 192 {
191 193 struct bus_type *bus = &mdio_bus_type;
192 194 struct phy_device *phydev;
... ... @@ -231,6 +233,20 @@
231 233  
232 234 phydev->dev_flags = flags;
233 235  
  236 + phydev->interface = interface;
  237 +
  238 + /* Do initial configuration here, now that
  239 + * we have certain key parameters
  240 + * (dev_flags and interface) */
  241 + if (phydev->drv->config_init) {
  242 + int err;
  243 +
  244 + err = phydev->drv->config_init(phydev);
  245 +
  246 + if (err < 0)
  247 + return ERR_PTR(err);
  248 + }
  249 +
234 250 return phydev;
235 251 }
236 252 EXPORT_SYMBOL(phy_attach);
237 253  
... ... @@ -612,13 +628,8 @@
612 628  
613 629 spin_unlock(&phydev->lock);
614 630  
615   - if (err < 0)
616   - return err;
617   -
618   - if (phydev->drv->config_init)
619   - err = phydev->drv->config_init(phydev);
620   -
621 631 return err;
  632 +
622 633 }
623 634  
624 635 static int phy_remove(struct device *dev)
... ... @@ -47,15 +47,26 @@
47 47 #define PHY_HAS_INTERRUPT 0x00000001
48 48 #define PHY_HAS_MAGICANEG 0x00000002
49 49  
  50 +/* Interface Mode definitions */
  51 +typedef enum {
  52 + PHY_INTERFACE_MODE_MII,
  53 + PHY_INTERFACE_MODE_GMII,
  54 + PHY_INTERFACE_MODE_SGMII,
  55 + PHY_INTERFACE_MODE_TBI,
  56 + PHY_INTERFACE_MODE_RMII,
  57 + PHY_INTERFACE_MODE_RGMII,
  58 + PHY_INTERFACE_MODE_RTBI
  59 +} phy_interface_t;
  60 +
50 61 #define MII_BUS_MAX 4
51 62  
52 63  
53   -#define PHY_INIT_TIMEOUT 100000
  64 +#define PHY_INIT_TIMEOUT 100000
54 65 #define PHY_STATE_TIME 1
55 66 #define PHY_FORCE_TIMEOUT 10
56 67 #define PHY_AN_TIMEOUT 10
57 68  
58   -#define PHY_MAX_ADDR 32
  69 +#define PHY_MAX_ADDR 32
59 70  
60 71 /* Used when trying to connect to a specific phy (mii bus id:phy device id) */
61 72 #define PHY_ID_FMT "%x:%02x"
... ... @@ -87,8 +98,8 @@
87 98 int *irq;
88 99 };
89 100  
90   -#define PHY_INTERRUPT_DISABLED 0x0
91   -#define PHY_INTERRUPT_ENABLED 0x80000000
  101 +#define PHY_INTERRUPT_DISABLED 0x0
  102 +#define PHY_INTERRUPT_ENABLED 0x80000000
92 103  
93 104 /* PHY state machine states:
94 105 *
... ... @@ -230,6 +241,8 @@
230 241  
231 242 u32 dev_flags;
232 243  
  244 + phy_interface_t interface;
  245 +
233 246 /* Bus address of the PHY (0-32) */
234 247 int addr;
235 248  
236 249  
... ... @@ -345,9 +358,10 @@
345 358 int phy_clear_interrupt(struct phy_device *phydev);
346 359 int phy_config_interrupt(struct phy_device *phydev, u32 interrupts);
347 360 struct phy_device * phy_attach(struct net_device *dev,
348   - const char *phy_id, u32 flags);
  361 + const char *phy_id, u32 flags, phy_interface_t interface);
349 362 struct phy_device * phy_connect(struct net_device *dev, const char *phy_id,
350   - void (*handler)(struct net_device *), u32 flags);
  363 + void (*handler)(struct net_device *), u32 flags,
  364 + phy_interface_t interface);
351 365 void phy_disconnect(struct phy_device *phydev);
352 366 void phy_detach(struct phy_device *phydev);
353 367 void phy_start(struct phy_device *phydev);