Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 58354
b: refs/heads/master
c: d3c1287
h: refs/heads/master
v: v3
  • Loading branch information
Kapil Juneja authored and Jeff Garzik committed Jul 9, 2007
1 parent 99ea066 commit f3c0985
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 12 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0cefeebaf3da39d768bffcf62460fe2088e824ef
refs/heads/master: d3c12873c36005263286cf5660663c8c10f9d2b5
27 changes: 27 additions & 0 deletions trunk/drivers/net/gianfar.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions trunk/drivers/net/gianfar.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ extern const char gfar_driver_version[];
#define MIIMCFG_RESET 0x80000000
#define MIIMIND_BUSY 0x00000001

/* TBI register addresses */
#define MII_TBICON 0x11

/* TBICON register bit fields */
#define TBICON_CLK_SELECT 0x0020

/* MAC register bits */
#define MACCFG1_SOFT_RESET 0x80000000
#define MACCFG1_RESET_RX_MC 0x00080000
Expand Down
55 changes: 44 additions & 11 deletions trunk/drivers/net/gianfar_mii.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,18 @@
#include "gianfar.h"
#include "gianfar_mii.h"

/* Write value to the PHY at mii_id at register regnum,
* on the bus, waiting until the write is done before returning.
* All PHY configuration is done through the TSEC1 MIIM regs */
int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
/*
* Write value to the PHY at mii_id at register regnum,
* on the bus attached to the local interface, which may be different from the
* generic mdio bus (tied to a single interface), waiting until the write is
* done before returning. This is helpful in programming interfaces like
* the TBI which control interfaces like onchip SERDES and are always tied to
* the local mdio pins, which may not be the same as system mdio bus, used for
* controlling the external PHYs, for example.
*/
int gfar_local_mdio_write(struct gfar_mii *regs, int mii_id,
int regnum, u16 value)
{
struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;

/* Set the PHY address and the register address we want to write */
gfar_write(&regs->miimadd, (mii_id << 8) | regnum);

Expand All @@ -63,12 +68,19 @@ int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
return 0;
}

/* Read the bus for PHY at addr mii_id, register regnum, and
* return the value. Clears miimcom first. All PHY
* configuration has to be done through the TSEC1 MIIM regs */
int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
/*
* Read the bus for PHY at addr mii_id, register regnum, and
* return the value. Clears miimcom first. All PHY operation
* done on the bus attached to the local interface,
* which may be different from the generic mdio bus
* This is helpful in programming interfaces like
* the TBI which, inturn, control interfaces like onchip SERDES
* and are always tied to the local mdio pins, which may not be the
* same as system mdio bus, used for controlling the external PHYs, for eg.
*/
int gfar_local_mdio_read(struct gfar_mii *regs, int mii_id, int regnum)

{
struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;
u16 value;

/* Set the PHY address and the register address we want to read */
Expand All @@ -88,6 +100,27 @@ int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
return value;
}

/* Write value to the PHY at mii_id at register regnum,
* on the bus, waiting until the write is done before returning.
* All PHY configuration is done through the TSEC1 MIIM regs */
int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
{
struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;

/* Write to the local MII regs */
return(gfar_local_mdio_write(regs, mii_id, regnum, value));
}

/* Read the bus for PHY at addr mii_id, register regnum, and
* return the value. Clears miimcom first. All PHY
* configuration has to be done through the TSEC1 MIIM regs */
int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
struct gfar_mii __iomem *regs = (void __iomem *)bus->priv;

/* Read the local MII regs */
return(gfar_local_mdio_read(regs, mii_id, regnum));
}

/* Reset the MIIM registers, and wait for the bus to free */
int gfar_mdio_reset(struct mii_bus *bus)
Expand Down

0 comments on commit f3c0985

Please sign in to comment.