diff options
author | Kapil Juneja <Kapil.Juneja@freescale.com> | 2007-05-12 01:25:11 +0200 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2007-07-09 04:16:38 +0200 |
commit | d3c12873c36005263286cf5660663c8c10f9d2b5 (patch) | |
tree | 8b51ae1aec834ece23271e6b569d7c4189422ad5 /drivers/net/gianfar.c | |
parent | phylib: add the ICPlus IP175C PHY driver (diff) | |
download | linux-d3c12873c36005263286cf5660663c8c10f9d2b5.tar.xz linux-d3c12873c36005263286cf5660663c8c10f9d2b5.zip |
gianfar: add support for SGMII
Add code for initialising and configuring TBI interface and
programming it for connecting to on-chip SERDES (Lynx PHY)
in case of SGMII mode selected through HRCW at reset.
also add defines for TBI register configuration. TBI
interface is programmed towards the SERDES.
refactored mdio read/write functions to differentiate
programming local interface MII regs (e.g., for TBI) from
always programming the mdio master (TSEC1, for programming
the PHYs).
Signed-off-by: Kapil Juneja <Kapil.Juneja@freescale.com>
Signed-off-by: Andy Fleming <afleming@freescale.com>
Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net/gianfar.c')
-rw-r--r-- | drivers/net/gianfar.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 1b854bf07b09..d7a1a58de766 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -130,6 +130,9 @@ static int gfar_remove(struct platform_device *pdev); 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); +extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value); +extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum); #ifdef CONFIG_GFAR_NAPI static int gfar_poll(struct net_device *dev, int *budget); #endif @@ -451,6 +454,9 @@ static int init_phy(struct net_device *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); @@ -465,6 +471,27 @@ static int init_phy(struct net_device *dev) return 0; } +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; + + /* Initialise TBI i/f to communicate with serdes (lynx phy) */ + + /* Single clk mode, mii mode off(for aerdes communication) */ + gfar_local_mdio_write(regs, TBIPA_VALUE, MII_TBICON, TBICON_CLK_SELECT); + + /* Supported pause and full-duplex, no half-duplex */ + gfar_local_mdio_write(regs, TBIPA_VALUE, MII_ADVERTISE, + ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE | + ADVERTISE_1000XPSE_ASYM); + + /* ANEG enable, restart ANEG, full duplex mode, speed[1] set */ + gfar_local_mdio_write(regs, TBIPA_VALUE, 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); |