summaryrefslogtreecommitdiff
path: root/drivers/net/phy/miiphybb.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/phy/miiphybb.c')
-rw-r--r--drivers/net/phy/miiphybb.c216
1 files changed, 90 insertions, 126 deletions
diff --git a/drivers/net/phy/miiphybb.c b/drivers/net/phy/miiphybb.c
index 553af2c1032..76463da7299 100644
--- a/drivers/net/phy/miiphybb.c
+++ b/drivers/net/phy/miiphybb.c
@@ -14,40 +14,16 @@
#include <ioports.h>
#include <ppc_asm.tmpl>
-#include <malloc.h>
#include <miiphy.h>
#include <asm/global_data.h>
-static inline struct bb_miiphy_bus *bb_miiphy_getbus(struct mii_dev *miidev)
-{
- return container_of(miidev, struct bb_miiphy_bus, mii);
-}
-
-struct bb_miiphy_bus *bb_miiphy_alloc(void)
-{
- struct bb_miiphy_bus *bus;
-
- bus = malloc(sizeof(*bus));
- if (!bus)
- return bus;
-
- mdio_init(&bus->mii);
-
- return bus;
-}
-
-void bb_miiphy_free(struct bb_miiphy_bus *bus)
-{
- free(bus);
-}
-
/*****************************************************************************
*
* Utility to send the preamble, address, and register (common to read
* and write).
*/
-static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
- unsigned char addr, unsigned char reg)
+static void miiphy_pre(struct mii_dev *miidev, const struct bb_miiphy_bus_ops *ops,
+ char read, unsigned char addr, unsigned char reg)
{
int j;
@@ -59,62 +35,62 @@ static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
* but it is safer and will be much more robust.
*/
- bus->mdio_active(bus);
- bus->set_mdio(bus, 1);
+ ops->mdio_active(miidev);
+ ops->set_mdio(miidev, 1);
for (j = 0; j < 32; j++) {
- bus->set_mdc(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
}
/* send the start bit (01) and the read opcode (10) or write (10) */
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, read);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, !read);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, read);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, !read);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
/* send the PHY address */
for (j = 0; j < 5; j++) {
- bus->set_mdc(bus, 0);
+ ops->set_mdc(miidev, 0);
if ((addr & 0x10) == 0) {
- bus->set_mdio(bus, 0);
+ ops->set_mdio(miidev, 0);
} else {
- bus->set_mdio(bus, 1);
+ ops->set_mdio(miidev, 1);
}
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
addr <<= 1;
}
/* send the register address */
for (j = 0; j < 5; j++) {
- bus->set_mdc(bus, 0);
+ ops->set_mdc(miidev, 0);
if ((reg & 0x10) == 0) {
- bus->set_mdio(bus, 0);
+ ops->set_mdio(miidev, 0);
} else {
- bus->set_mdio(bus, 1);
+ ops->set_mdio(miidev, 1);
}
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
reg <<= 1;
}
}
@@ -126,62 +102,57 @@ static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
* Returns:
* 0 on success
*/
-int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg)
+int bb_miiphy_read(struct mii_dev *miidev, const struct bb_miiphy_bus_ops *ops,
+ int addr, int devad, int reg)
{
unsigned short rdreg; /* register working value */
int v;
int j; /* counter */
- struct bb_miiphy_bus *bus;
- bus = bb_miiphy_getbus(miidev);
- if (bus == NULL) {
- return -1;
- }
-
- miiphy_pre (bus, 1, addr, reg);
+ miiphy_pre(miidev, ops, 1, addr, reg);
/* tri-state our MDIO I/O pin so we can read */
- bus->set_mdc(bus, 0);
- bus->mdio_tristate(bus);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->mdio_tristate(miidev);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
/* check the turnaround bit: the PHY should be driving it to zero */
- bus->get_mdio(bus, &v);
+ ops->get_mdio(miidev, &v);
if (v != 0) {
/* puts ("PHY didn't drive TA low\n"); */
for (j = 0; j < 32; j++) {
- bus->set_mdc(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
}
/* There is no PHY, return */
return -1;
}
- bus->set_mdc(bus, 0);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
/* read 16 bits of register data, MSB first */
rdreg = 0;
for (j = 0; j < 16; j++) {
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
rdreg <<= 1;
- bus->get_mdio(bus, &v);
+ ops->get_mdio(miidev, &v);
rdreg |= (v & 0x1);
- bus->set_mdc(bus, 0);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
}
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
debug("%s[%s](0x%x) @ 0x%x = 0x%04x\n", __func__, miidev->name, reg, addr, rdreg);
@@ -195,54 +166,47 @@ int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg)
* Returns:
* 0 on success
*/
-int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,
- u16 value)
+int bb_miiphy_write(struct mii_dev *miidev, const struct bb_miiphy_bus_ops *ops,
+ int addr, int devad, int reg, u16 value)
{
- struct bb_miiphy_bus *bus;
int j; /* counter */
- bus = bb_miiphy_getbus(miidev);
- if (bus == NULL) {
- /* Bus not found! */
- return -1;
- }
-
- miiphy_pre (bus, 0, addr, reg);
+ miiphy_pre(miidev, ops, 0, addr, reg);
/* send the turnaround (10) */
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
- bus->set_mdc(bus, 0);
- bus->set_mdio(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->set_mdio(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
/* write 16 bits of register data, MSB first */
for (j = 0; j < 16; j++) {
- bus->set_mdc(bus, 0);
+ ops->set_mdc(miidev, 0);
if ((value & 0x00008000) == 0) {
- bus->set_mdio(bus, 0);
+ ops->set_mdio(miidev, 0);
} else {
- bus->set_mdio(bus, 1);
+ ops->set_mdio(miidev, 1);
}
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
value <<= 1;
}
/*
* Tri-state the MDIO line.
*/
- bus->mdio_tristate(bus);
- bus->set_mdc(bus, 0);
- bus->delay(bus);
- bus->set_mdc(bus, 1);
- bus->delay(bus);
+ ops->mdio_tristate(miidev);
+ ops->set_mdc(miidev, 0);
+ ops->delay(miidev);
+ ops->set_mdc(miidev, 1);
+ ops->delay(miidev);
return 0;
}