aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/gianfar.c27
-rw-r--r--drivers/net/gianfar.h6
-rw-r--r--drivers/net/gianfar_mii.c55
3 files changed, 77 insertions, 11 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);
130static void free_skb_resources(struct gfar_private *priv); 130static void free_skb_resources(struct gfar_private *priv);
131static void gfar_set_multi(struct net_device *dev); 131static void gfar_set_multi(struct net_device *dev);
132static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr); 132static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr);
133static void gfar_configure_serdes(struct net_device *dev);
134extern int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id, int regnum, u16 value);
135extern int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum);
133#ifdef CONFIG_GFAR_NAPI 136#ifdef CONFIG_GFAR_NAPI
134static int gfar_poll(struct net_device *dev, int *budget); 137static int gfar_poll(struct net_device *dev, int *budget);
135#endif 138#endif
@@ -451,6 +454,9 @@ static int init_phy(struct net_device *dev)
451 454
452 phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface); 455 phydev = phy_connect(dev, phy_id, &adjust_link, 0, interface);
453 456
457 if (interface == PHY_INTERFACE_MODE_SGMII)
458 gfar_configure_serdes(dev);
459
454 if (IS_ERR(phydev)) { 460 if (IS_ERR(phydev)) {
455 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name); 461 printk(KERN_ERR "%s: Could not attach to PHY\n", dev->name);
456 return PTR_ERR(phydev); 462 return PTR_ERR(phydev);
@@ -465,6 +471,27 @@ static int init_phy(struct net_device *dev)
465 return 0; 471 return 0;
466} 472}
467 473
474static void gfar_configure_serdes(struct net_device *dev)
475{
476 struct gfar_private *priv = netdev_priv(dev);
477 struct gfar_mii __iomem *regs =
478 (void __iomem *)&priv->regs->gfar_mii_regs;
479
480 /* Initialise TBI i/f to communicate with serdes (lynx phy) */
481
482 /* Single clk mode, mii mode off(for aerdes communication) */
483 gfar_local_mdio_write(regs, TBIPA_VALUE, MII_TBICON, TBICON_CLK_SELECT);
484
485 /* Supported pause and full-duplex, no half-duplex */
486 gfar_local_mdio_write(regs, TBIPA_VALUE, MII_ADVERTISE,
487 ADVERTISE_1000XFULL | ADVERTISE_1000XPAUSE |
488 ADVERTISE_1000XPSE_ASYM);
489
490 /* ANEG enable, restart ANEG, full duplex mode, speed[1] set */
491 gfar_local_mdio_write(regs, TBIPA_VALUE, MII_BMCR, BMCR_ANENABLE |
492 BMCR_ANRESTART | BMCR_FULLDPLX | BMCR_SPEED1000);
493}
494
468static void init_registers(struct net_device *dev) 495static void init_registers(struct net_device *dev)
469{ 496{
470 struct gfar_private *priv = netdev_priv(dev); 497 struct gfar_private *priv = netdev_priv(dev);
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h
index 39e9e321fcbc..d8e779c102fa 100644
--- a/drivers/net/gianfar.h
+++ b/drivers/net/gianfar.h
@@ -136,6 +136,12 @@ extern const char gfar_driver_version[];
136#define MIIMCFG_RESET 0x80000000 136#define MIIMCFG_RESET 0x80000000
137#define MIIMIND_BUSY 0x00000001 137#define MIIMIND_BUSY 0x00000001
138 138
139/* TBI register addresses */
140#define MII_TBICON 0x11
141
142/* TBICON register bit fields */
143#define TBICON_CLK_SELECT 0x0020
144
139/* MAC register bits */ 145/* MAC register bits */
140#define MACCFG1_SOFT_RESET 0x80000000 146#define MACCFG1_SOFT_RESET 0x80000000
141#define MACCFG1_RESET_RX_MC 0x00080000 147#define MACCFG1_RESET_RX_MC 0x00080000
diff --git a/drivers/net/gianfar_mii.c b/drivers/net/gianfar_mii.c
index bcc6b82f4a33..5dd34a1a7b89 100644
--- a/drivers/net/gianfar_mii.c
+++ b/drivers/net/gianfar_mii.c
@@ -43,13 +43,18 @@
43#include "gianfar.h" 43#include "gianfar.h"
44#include "gianfar_mii.h" 44#include "gianfar_mii.h"
45 45
46/* Write value to the PHY at mii_id at register regnum, 46/*
47 * on the bus, waiting until the write is done before returning. 47 * Write value to the PHY at mii_id at register regnum,
48 * All PHY configuration is done through the TSEC1 MIIM regs */ 48 * on the bus attached to the local interface, which may be different from the
49int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value) 49 * generic mdio bus (tied to a single interface), waiting until the write is
50 * done before returning. This is helpful in programming interfaces like
51 * the TBI which control interfaces like onchip SERDES and are always tied to
52 * the local mdio pins, which may not be the same as system mdio bus, used for
53 * controlling the external PHYs, for example.
54 */
55int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id,
56 int regnum, u16 value)
50{ 57{
51 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
52
53 /* Set the PHY address and the register address we want to write */ 58 /* Set the PHY address and the register address we want to write */
54 gfar_write(&regs->miimadd, (mii_id << 8) | regnum); 59 gfar_write(&regs->miimadd, (mii_id << 8) | regnum);
55 60
@@ -63,12 +68,19 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
63 return 0; 68 return 0;
64} 69}
65 70
66/* Read the bus for PHY at addr mii_id, register regnum, and 71/*
67 * return the value. Clears miimcom first. All PHY 72 * Read the bus for PHY at addr mii_id, register regnum, and
68 * configuration has to be done through the TSEC1 MIIM regs */ 73 * return the value. Clears miimcom first. All PHY operation
69int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum) 74 * done on the bus attached to the local interface,
75 * which may be different from the generic mdio bus
76 * This is helpful in programming interfaces like
77 * the TBI which, inturn, control interfaces like onchip SERDES
78 * and are always tied to the local mdio pins, which may not be the
79 * same as system mdio bus, used for controlling the external PHYs, for eg.
80 */
81int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum)
82
70{ 83{
71 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
72 u16 value; 84 u16 value;
73 85
74 /* Set the PHY address and the register address we want to read */ 86 /* Set the PHY address and the register address we want to read */
@@ -88,6 +100,27 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
88 return value; 100 return value;
89} 101}
90 102
103/* Write value to the PHY at mii_id at register regnum,
104 * on the bus, waiting until the write is done before returning.
105 * All PHY configuration is done through the TSEC1 MIIM regs */
106int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
107{
108 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
109
110 /* Write to the local MII regs */
111 return(gfar_local_mdio_write(regs, mii_id, regnum, value));
112}
113
114/* Read the bus for PHY at addr mii_id, register regnum, and
115 * return the value. Clears miimcom first. All PHY
116 * configuration has to be done through the TSEC1 MIIM regs */
117int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
118{
119 struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
120
121 /* Read the local MII regs */
122 return(gfar_local_mdio_read(regs, mii_id, regnum));
123}
91 124
92/* Reset the MIIM registers, and wait for the bus to free */ 125/* Reset the MIIM registers, and wait for the bus to free */
93int gfar_mdio_reset(struct mii_bus *bus) 126int gfar_mdio_reset(struct mii_bus *bus)