Commit 1577ecef authored by Andy Fleming's avatar Andy Fleming Committed by David S. Miller

netdev: Merge UCC and gianfar MDIO bus drivers

The MDIO bus drivers for the UCC and gianfar ethernet controllers are
essentially the same.  There's no reason to duplicate that much code.
Signed-off-by: default avatarAndy Fleming <afleming@freescale.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 9c46f6d4
...@@ -2272,9 +2272,17 @@ config GELIC_WIRELESS_OLD_PSK_INTERFACE ...@@ -2272,9 +2272,17 @@ config GELIC_WIRELESS_OLD_PSK_INTERFACE
If unsure, say N. If unsure, say N.
config FSL_PQ_MDIO
tristate "Freescale PQ MDIO"
depends on FSL_SOC
select PHYLIB
help
This driver supports the MDIO bus used by the gianfar and UCC drivers.
config GIANFAR config GIANFAR
tristate "Gianfar Ethernet" tristate "Gianfar Ethernet"
depends on FSL_SOC depends on FSL_SOC
select FSL_PQ_MDIO
select PHYLIB select PHYLIB
select CRC32 select CRC32
help help
...@@ -2284,6 +2292,7 @@ config GIANFAR ...@@ -2284,6 +2292,7 @@ config GIANFAR
config UCC_GETH config UCC_GETH
tristate "Freescale QE Gigabit Ethernet" tristate "Freescale QE Gigabit Ethernet"
depends on QUICC_ENGINE depends on QUICC_ENGINE
select FSL_PQ_MDIO
select PHYLIB select PHYLIB
help help
This driver supports the Gigabit Ethernet mode of the QUICC Engine, This driver supports the Gigabit Ethernet mode of the QUICC Engine,
......
...@@ -24,11 +24,12 @@ obj-$(CONFIG_JME) += jme.o ...@@ -24,11 +24,12 @@ obj-$(CONFIG_JME) += jme.o
gianfar_driver-objs := gianfar.o \ gianfar_driver-objs := gianfar.o \
gianfar_ethtool.o \ gianfar_ethtool.o \
gianfar_mii.o \
gianfar_sysfs.o gianfar_sysfs.o
obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
ucc_geth_driver-objs := ucc_geth.o ucc_geth_mii.o ucc_geth_ethtool.o ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
obj-$(CONFIG_FSL_PQ_MDIO) += fsl_pq_mdio.o
# #
# link order important here # link order important here
......
This diff is collapsed.
/*
* Freescale PowerQUICC MDIO Driver -- MII Management Bus Implementation
* Driver for the MDIO bus controller on Freescale PowerQUICC processors
*
* Author: Andy Fleming
*
* Copyright (c) 2002-2004,2008 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#ifndef __FSL_PQ_MDIO_H
#define __FSL_PQ_MDIO_H
#define MIIMIND_BUSY 0x00000001
#define MIIMIND_NOTVALID 0x00000004
#define MIIMCFG_INIT_VALUE 0x00000007
#define MIIMCFG_RESET 0x80000000
#define MII_READ_COMMAND 0x00000001
struct fsl_pq_mdio {
u32 miimcfg; /* MII management configuration reg */
u32 miimcom; /* MII management command reg */
u32 miimadd; /* MII management address reg */
u32 miimcon; /* MII management control reg */
u32 miimstat; /* MII management status reg */
u32 miimind; /* MII management indication reg */
u8 reserved[28]; /* Space holder */
u32 utbipar; /* TBI phy address reg (only on UCC) */
} __attribute__ ((packed));
int fsl_pq_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
int fsl_pq_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int fsl_pq_local_mdio_write(struct fsl_pq_mdio __iomem *regs, int mii_id,
int regnum, u16 value);
int fsl_pq_local_mdio_read(struct fsl_pq_mdio __iomem *regs, int mii_id, int regnum);
int __init fsl_pq_mdio_init(void);
void fsl_pq_mdio_exit(void);
void fsl_pq_mdio_bus_name(char *name, struct device_node *np);
#endif /* FSL_PQ_MDIO_H */
...@@ -93,7 +93,7 @@ ...@@ -93,7 +93,7 @@
#include <linux/of.h> #include <linux/of.h>
#include "gianfar.h" #include "gianfar.h"
#include "gianfar_mii.h" #include "fsl_pq_mdio.h"
#define TX_TIMEOUT (1*HZ) #define TX_TIMEOUT (1*HZ)
#undef BRIEF_GFAR_ERRORS #undef BRIEF_GFAR_ERRORS
...@@ -253,7 +253,7 @@ static int gfar_of_init(struct net_device *dev) ...@@ -253,7 +253,7 @@ static int gfar_of_init(struct net_device *dev)
of_node_put(phy); of_node_put(phy);
of_node_put(mdio); of_node_put(mdio);
gfar_mdio_bus_name(bus_name, mdio); fsl_pq_mdio_bus_name(bus_name, mdio);
snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x", snprintf(priv->phy_bus_id, sizeof(priv->phy_bus_id), "%s:%02x",
bus_name, *id); bus_name, *id);
} }
...@@ -1829,6 +1829,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) ...@@ -1829,6 +1829,8 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit)
skb_put(skb, pkt_len); skb_put(skb, pkt_len);
dev->stats.rx_bytes += pkt_len; dev->stats.rx_bytes += pkt_len;
if (in_irq() || irqs_disabled())
printk("Interrupt problem!\n");
gfar_process_frame(dev, skb, amount_pull); gfar_process_frame(dev, skb, amount_pull);
} else { } else {
...@@ -2302,23 +2304,12 @@ static struct of_platform_driver gfar_driver = { ...@@ -2302,23 +2304,12 @@ static struct of_platform_driver gfar_driver = {
static int __init gfar_init(void) static int __init gfar_init(void)
{ {
int err = gfar_mdio_init(); return of_register_platform_driver(&gfar_driver);
if (err)
return err;
err = of_register_platform_driver(&gfar_driver);
if (err)
gfar_mdio_exit();
return err;
} }
static void __exit gfar_exit(void) static void __exit gfar_exit(void)
{ {
of_unregister_platform_driver(&gfar_driver); of_unregister_platform_driver(&gfar_driver);
gfar_mdio_exit();
} }
module_init(gfar_init); module_init(gfar_init);
......
...@@ -46,7 +46,6 @@ ...@@ -46,7 +46,6 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
#include <linux/fsl_devices.h> #include <linux/fsl_devices.h>
#include "gianfar_mii.h"
/* The maximum number of packets to be handled in one call of gfar_poll */ /* The maximum number of packets to be handled in one call of gfar_poll */
#define GFAR_DEV_WEIGHT 64 #define GFAR_DEV_WEIGHT 64
...@@ -126,9 +125,12 @@ extern const char gfar_driver_version[]; ...@@ -126,9 +125,12 @@ extern const char gfar_driver_version[];
#define DEFAULT_RX_COALESCE 0 #define DEFAULT_RX_COALESCE 0
#define DEFAULT_RXCOUNT 0 #define DEFAULT_RXCOUNT 0
#define MIIMCFG_INIT_VALUE 0x00000007 #define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
#define MIIMCFG_RESET 0x80000000 | SUPPORTED_10baseT_Full \
#define MIIMIND_BUSY 0x00000001 | SUPPORTED_100baseT_Half \
| SUPPORTED_100baseT_Full \
| SUPPORTED_Autoneg \
| SUPPORTED_MII)
/* TBI register addresses */ /* TBI register addresses */
#define MII_TBICON 0x11 #define MII_TBICON 0x11
...@@ -826,9 +828,6 @@ extern void gfar_halt(struct net_device *dev); ...@@ -826,9 +828,6 @@ extern void gfar_halt(struct net_device *dev);
extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev, extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
int enable, u32 regnum, u32 read); int enable, u32 regnum, u32 read);
void gfar_init_sysfs(struct net_device *dev); void gfar_init_sysfs(struct net_device *dev);
int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
int regnum, u16 value);
int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
extern const struct ethtool_ops gfar_ethtool_ops; extern const struct ethtool_ops gfar_ethtool_ops;
......
/*
* drivers/net/gianfar_mii.h
*
* Gianfar Ethernet Driver -- MII Management Bus Implementation
* Driver for the MDIO bus controller in the Gianfar register space
*
* Author: Andy Fleming
* Maintainer: Kumar Gala
*
* Copyright (c) 2002-2004 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#ifndef __GIANFAR_MII_H
#define __GIANFAR_MII_H
struct gfar_private; /* forward ref */
#define MIIMIND_BUSY 0x00000001
#define MIIMIND_NOTVALID 0x00000004
#define MII_READ_COMMAND 0x00000001
#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
| SUPPORTED_10baseT_Full \
| SUPPORTED_100baseT_Half \
| SUPPORTED_100baseT_Full \
| SUPPORTED_Autoneg \
| SUPPORTED_MII)
struct gfar_mii {
u32 miimcfg; /* 0x.520 - MII Management Config Register */
u32 miimcom; /* 0x.524 - MII Management Command Register */
u32 miimadd; /* 0x.528 - MII Management Address Register */
u32 miimcon; /* 0x.52c - MII Management Control Register */
u32 miimstat; /* 0x.530 - MII Management Status Register */
u32 miimind; /* 0x.534 - MII Management Indicator Register */
};
int gfar_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
int gfar_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int gfar_local_mdio_write(struct gfar_mii __iomem *regs, int mii_id,
int regnum, u16 value);
int gfar_local_mdio_read(struct gfar_mii __iomem *regs, int mii_id, int regnum);
struct mii_bus *gfar_get_miibus(const struct gfar_private *priv);
int __init gfar_mdio_init(void);
void gfar_mdio_exit(void);
void gfar_mdio_bus_name(char *name, struct device_node *np);
#endif /* GIANFAR_PHY_H */
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#include <asm/ucc_fast.h> #include <asm/ucc_fast.h>
#include "ucc_geth.h" #include "ucc_geth.h"
#include "ucc_geth_mii.h" #include "fsl_pq_mdio.h"
#undef DEBUG #undef DEBUG
...@@ -1557,7 +1557,7 @@ static int init_phy(struct net_device *dev) ...@@ -1557,7 +1557,7 @@ static int init_phy(struct net_device *dev)
of_node_put(phy); of_node_put(phy);
of_node_put(mdio); of_node_put(mdio);
uec_mdio_bus_name(bus_name, mdio); fsl_pq_mdio_bus_name(bus_name, mdio);
snprintf(phy_id, sizeof(phy_id), "%s:%02x", snprintf(phy_id, sizeof(phy_id), "%s:%02x",
bus_name, *id); bus_name, *id);
...@@ -3657,7 +3657,8 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma ...@@ -3657,7 +3657,8 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
if (err) if (err)
return -1; return -1;
snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "%x", res.start); snprintf(ug_info->mdio_bus, MII_BUS_ID_SIZE, "%x",
res.start&0xfffff);
} }
/* get the phy interface type, or default to MII */ /* get the phy interface type, or default to MII */
...@@ -3803,11 +3804,6 @@ static int __init ucc_geth_init(void) ...@@ -3803,11 +3804,6 @@ static int __init ucc_geth_init(void)
{ {
int i, ret; int i, ret;
ret = uec_mdio_init();
if (ret)
return ret;
if (netif_msg_drv(&debug)) if (netif_msg_drv(&debug))
printk(KERN_INFO "ucc_geth: " DRV_DESC "\n"); printk(KERN_INFO "ucc_geth: " DRV_DESC "\n");
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
...@@ -3816,16 +3812,12 @@ static int __init ucc_geth_init(void) ...@@ -3816,16 +3812,12 @@ static int __init ucc_geth_init(void)
ret = of_register_platform_driver(&ucc_geth_driver); ret = of_register_platform_driver(&ucc_geth_driver);
if (ret)
uec_mdio_exit();
return ret; return ret;
} }
static void __exit ucc_geth_exit(void) static void __exit ucc_geth_exit(void)
{ {
of_unregister_platform_driver(&ucc_geth_driver); of_unregister_platform_driver(&ucc_geth_driver);
uec_mdio_exit();
} }
module_init(ucc_geth_init); module_init(ucc_geth_init);
......
...@@ -28,8 +28,6 @@ ...@@ -28,8 +28,6 @@
#include <asm/ucc.h> #include <asm/ucc.h>
#include <asm/ucc_fast.h> #include <asm/ucc_fast.h>
#include "ucc_geth_mii.h"
#define DRV_DESC "QE UCC Gigabit Ethernet Controller" #define DRV_DESC "QE UCC Gigabit Ethernet Controller"
#define DRV_NAME "ucc_geth" #define DRV_NAME "ucc_geth"
#define DRV_VERSION "1.1" #define DRV_VERSION "1.1"
...@@ -184,6 +182,18 @@ struct ucc_geth { ...@@ -184,6 +182,18 @@ struct ucc_geth {
#define UCCE_RX_EVENTS (UCCE_RXF | UCC_GETH_UCCE_BSY) #define UCCE_RX_EVENTS (UCCE_RXF | UCC_GETH_UCCE_BSY)
#define UCCE_TX_EVENTS (UCCE_TXB | UCC_GETH_UCCE_TXE) #define UCCE_TX_EVENTS (UCCE_TXB | UCC_GETH_UCCE_TXE)
/* TBI defines */
#define ENET_TBI_MII_CR 0x00 /* Control */
#define ENET_TBI_MII_SR 0x01 /* Status */
#define ENET_TBI_MII_ANA 0x04 /* AN advertisement */
#define ENET_TBI_MII_ANLPBPA 0x05 /* AN link partner base page ability */
#define ENET_TBI_MII_ANEX 0x06 /* AN expansion */
#define ENET_TBI_MII_ANNPT 0x07 /* AN next page transmit */
#define ENET_TBI_MII_ANLPANP 0x08 /* AN link partner ability next page */
#define ENET_TBI_MII_EXST 0x0F /* Extended status */
#define ENET_TBI_MII_JD 0x10 /* Jitter diagnostics */
#define ENET_TBI_MII_TBICON 0x11 /* TBI control */
/* UCC GETH MACCFG1 (MAC Configuration 1 Register) */ /* UCC GETH MACCFG1 (MAC Configuration 1 Register) */
#define MACCFG1_FLOW_RX 0x00000020 /* Flow Control #define MACCFG1_FLOW_RX 0x00000020 /* Flow Control
Rx */ Rx */
......
...@@ -39,7 +39,6 @@ ...@@ -39,7 +39,6 @@
#include <asm/types.h> #include <asm/types.h>
#include "ucc_geth.h" #include "ucc_geth.h"
#include "ucc_geth_mii.h"
static char hw_stat_gstrings[][ETH_GSTRING_LEN] = { static char hw_stat_gstrings[][ETH_GSTRING_LEN] = {
"tx-64-frames", "tx-64-frames",
......
/*
* drivers/net/ucc_geth_mii.c
*
* QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
* Provides Bus interface for MII Management regs in the UCC register space
*
* Copyright (C) 2007 Freescale Semiconductor, Inc.
*
* Authors: Li Yang <leoli@freescale.com>
* Kim Phillips <kim.phillips@freescale.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/crc32.h>
#include <linux/mii.h>
#include <linux/phy.h>
#include <linux/fsl_devices.h>
#include <linux/of_platform.h>
#include <asm/io.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
#include <asm/ucc.h>
#include "ucc_geth_mii.h"
#include "ucc_geth.h"
#define DEBUG
#ifdef DEBUG
#define vdbg(format, arg...) printk(KERN_DEBUG , format "\n" , ## arg)
#else
#define vdbg(format, arg...) do {} while(0)
#endif
#define MII_DRV_DESC "QE UCC Ethernet Controller MII Bus"
#define MII_DRV_NAME "fsl-uec_mdio"
/* Write value to the PHY for this device to the register at regnum, */
/* waiting until the write is done before it returns. All PHY */
/* configuration has to be done through the master UEC MIIM regs */
int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value)
{
struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
/* Setting up the MII Mangement Address Register */
out_be32(&regs->miimadd,
(mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
/* Setting up the MII Mangement Control Register with the value */
out_be32(&regs->miimcon, value);
/* Wait till MII management write is complete */
while ((in_be32(&regs->miimind)) & MIIMIND_BUSY)
cpu_relax();
return 0;
}
/* Reads from register regnum in the PHY for device dev, */
/* returning the value. Clears miimcom first. All PHY */
/* configuration has to be done through the TSEC1 MIIM regs */
int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
{
struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
u16 value;
/* Setting up the MII Mangement Address Register */
out_be32(&regs->miimadd,
(mii_id << MIIMADD_PHY_ADDRESS_SHIFT) | regnum);
/* Clear miimcom, perform an MII management read cycle */
out_be32(&regs->miimcom, 0);
out_be32(&regs->miimcom, MIIMCOM_READ_CYCLE);
/* Wait till MII management write is complete */
while ((in_be32(&regs->miimind)) & (MIIMIND_BUSY | MIIMIND_NOT_VALID))
cpu_relax();
/* Read MII management status */
value = in_be32(&regs->miimstat);
return value;
}
/* Reset the MIIM registers, and wait for the bus to free */
static int uec_mdio_reset(struct mii_bus *bus)
{
struct ucc_mii_mng __iomem *regs = (void __iomem *)bus->priv;
unsigned int timeout = PHY_INIT_TIMEOUT;
mutex_lock(&bus->mdio_lock);
/* Reset the management interface */
out_be32(&regs->miimcfg, MIIMCFG_RESET_MANAGEMENT);
/* Setup the MII Mgmt clock speed */
out_be32(&regs->miimcfg, MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112);
/* Wait until the bus is free */
while ((in_be32(&regs->miimind) & MIIMIND_BUSY) && timeout--)
cpu_relax();
mutex_unlock(&bus->mdio_lock);
if (timeout <= 0) {
printk(KERN_ERR "%s: The MII Bus is stuck!\n", bus->name);
return -EBUSY;
}
return 0;
}
static int uec_mdio_probe(struct of_device *ofdev, const struct of_device_id *match)
{
struct device *device = &ofdev->dev;
struct device_node *np = ofdev->node, *tempnp = NULL;
struct device_node *child = NULL;
struct ucc_mii_mng __iomem *regs;
struct mii_bus *new_bus;
struct resource res;
int k, err = 0;
new_bus = mdiobus_alloc();
if (NULL == new_bus)
return -ENOMEM;
new_bus->name = "UCC Ethernet Controller MII Bus";
new_bus->read = &uec_mdio_read;
new_bus->write = &uec_mdio_write;
new_bus->reset = &uec_mdio_reset;
memset(&res, 0, sizeof(res));
err = of_address_to_resource(np, 0, &res);
if (err)
goto reg_map_fail;
uec_mdio_bus_name(new_bus->id, np);
new_bus->irq = kmalloc(32 * sizeof(int), GFP_KERNEL);
if (NULL == new_bus->irq) {
err = -ENOMEM;
goto reg_map_fail;
}
for (k = 0; k < 32; k++)
new_bus->irq[k] = PHY_POLL;
while ((child = of_get_next_child(np, child)) != NULL) {
int irq = irq_of_parse_and_map(child, 0);
if (irq != NO_IRQ) {
const u32 *id = of_get_property(child, "reg", NULL);
new_bus->irq[*id] = irq;
}
}
/* Set the base address */
regs = ioremap(res.start, sizeof(struct ucc_mii_mng));
if (NULL == regs) {
err = -ENOMEM;
goto ioremap_fail;
}
new_bus->priv = (void __force *)regs;
new_bus->parent = device;
dev_set_drvdata(device, new_bus);
/* Read MII management master from device tree */
while ((tempnp = of_find_compatible_node(tempnp, "network", "ucc_geth"))
!= NULL) {
struct resource tempres;
err = of_address_to_resource(tempnp, 0, &tempres);
if (err)
goto bus_register_fail;
/* if our mdio regs fall within this UCC regs range */
if ((res.start >= tempres.start) &&
(res.end <= tempres.end)) {
/* set this UCC to be the MII master */
const u32 *id;
id = of_get_property(tempnp, "cell-index", NULL);
if (!id) {
id = of_get_property(tempnp, "device-id", NULL);
if (!id)
goto bus_register_fail;
}
ucc_set_qe_mux_mii_mng(*id - 1);
/* assign the TBI an address which won't
* conflict with the PHYs */
out_be32(&regs->utbipar, UTBIPAR_INIT_TBIPA);
break;
}
}
err = mdiobus_register(new_bus);
if (0 != err) {
printk(KERN_ERR "%s: Cannot register as MDIO bus\n",
new_bus->name);
goto bus_register_fail;
}
return 0;
bus_register_fail:
iounmap(regs);
ioremap_fail:
kfree(new_bus->irq);
reg_map_fail:
mdiobus_free(new_bus);
return err;
}
static int uec_mdio_remove(struct of_device *ofdev)
{
struct device *device = &ofdev->dev;
struct mii_bus *bus = dev_get_drvdata(device);
mdiobus_unregister(bus);
dev_set_drvdata(device, NULL);
iounmap((void __iomem *)bus->priv);
bus->priv = NULL;
mdiobus_free(bus);
return 0;
}
static struct of_device_id uec_mdio_match[] = {
{
.type = "mdio",
.compatible = "ucc_geth_phy",
},
{
.compatible = "fsl,ucc-mdio",
},
{},
};
static struct of_platform_driver uec_mdio_driver = {
.name = MII_DRV_NAME,
.probe = uec_mdio_probe,
.remove = uec_mdio_remove,
.match_table = uec_mdio_match,
};
int __init uec_mdio_init(void)
{
return of_register_platform_driver(&uec_mdio_driver);
}
/* called from __init ucc_geth_init, therefore can not be __exit */
void uec_mdio_exit(void)
{
of_unregister_platform_driver(&uec_mdio_driver);
}
void uec_mdio_bus_name(char *name, struct device_node *np)
{
const u32 *reg;
reg = of_get_property(np, "reg", NULL);
snprintf(name, MII_BUS_ID_SIZE, "%s@%x", np->name, reg ? *reg : 0);
}
/*
* drivers/net/ucc_geth_mii.h
*
* QE UCC Gigabit Ethernet Driver -- MII Management Bus Implementation
* Provides Bus interface for MII Management regs in the UCC register space
*
* Copyright (C) 2007 Freescale Semiconductor, Inc.
*
* Authors: Li Yang <leoli@freescale.com>
* Kim Phillips <kim.phillips@freescale.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
*/
#ifndef __UEC_MII_H
#define __UEC_MII_H
/* UCC GETH MIIMCFG (MII Management Configuration Register) */
#define MIIMCFG_RESET_MANAGEMENT 0x80000000 /* Reset
management */
#define MIIMCFG_NO_PREAMBLE 0x00000010 /* Preamble
suppress */
#define MIIMCFG_CLOCK_DIVIDE_SHIFT (31 - 31) /* clock divide
<< shift */
#define MIIMCFG_CLOCK_DIVIDE_MAX 0xf /* max clock divide */
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_2 0x00000000
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_4 0x00000001
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_6 0x00000002
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_8 0x00000003
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_10 0x00000004
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_14 0x00000005
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_16 0x00000008
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_20 0x00000006
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_28 0x00000007
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_32 0x00000009
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_48 0x0000000a
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_64 0x0000000b
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_80 0x0000000c
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_112 0x0000000d
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_160 0x0000000e
#define MIIMCFG_MANAGEMENT_CLOCK_DIVIDE_BY_224 0x0000000f
/* UCC GETH MIIMCOM (MII Management Command Register) */
#define MIIMCOM_SCAN_CYCLE 0x00000002 /* Scan cycle */
#define MIIMCOM_READ_CYCLE 0x00000001 /* Read cycle */
/* UCC GETH MIIMADD (MII Management Address Register) */
#define MIIMADD_PHY_ADDRESS_SHIFT (31 - 23) /* PHY Address
<< shift */
#define MIIMADD_PHY_REGISTER_SHIFT (31 - 31) /* PHY Register
<< shift */
/* UCC GETH MIIMCON (MII Management Control Register) */
#define MIIMCON_PHY_CONTROL_SHIFT (31 - 31) /* PHY Control
<< shift */
#define MIIMCON_PHY_STATUS_SHIFT (31 - 31) /* PHY Status
<< shift */
/* UCC GETH MIIMIND (MII Management Indicator Register) */
#define MIIMIND_NOT_VALID 0x00000004 /* Not valid */
#define MIIMIND_SCAN 0x00000002 /* Scan in
progress */
#define MIIMIND_BUSY 0x00000001
/* Initial TBI Physical Address */
#define UTBIPAR_INIT_TBIPA 0x1f
struct ucc_mii_mng {
u32 miimcfg; /* MII management configuration reg */
u32 miimcom; /* MII management command reg */
u32 miimadd; /* MII management address reg */
u32 miimcon; /* MII management control reg */
u32 miimstat; /* MII management status reg */
u32 miimind; /* MII management indication reg */
u8 notcare[28]; /* Space holder */
u32 utbipar; /* TBI phy address reg */
} __attribute__ ((packed));
/* TBI / MII Set Register */
enum enet_tbi_mii_reg {
ENET_TBI_MII_CR = 0x00, /* Control */
ENET_TBI_MII_SR = 0x01, /* Status */
ENET_TBI_MII_ANA = 0x04, /* AN advertisement */
ENET_TBI_MII_ANLPBPA = 0x05, /* AN link partner base page ability */
ENET_TBI_MII_ANEX = 0x06, /* AN expansion */
ENET_TBI_MII_ANNPT = 0x07, /* AN next page transmit */
ENET_TBI_MII_ANLPANP = 0x08, /* AN link partner ability next page */
ENET_TBI_MII_EXST = 0x0F, /* Extended status */
ENET_TBI_MII_JD = 0x10, /* Jitter diagnostics */
ENET_TBI_MII_TBICON = 0x11 /* TBI control */
};
int uec_mdio_read(struct mii_bus *bus, int mii_id, int regnum);
int uec_mdio_write(struct mii_bus *bus, int mii_id, int regnum, u16 value);
int __init uec_mdio_init(void);
void uec_mdio_exit(void);
void uec_mdio_bus_name(char *name, struct device_node *np);
#endif /* __UEC_MII_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment