mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
[netdrvr gianfar] use new phy layer
Signed-off-by: Andy Fleming <afleming@freescale.com> Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
This commit is contained in:
committed by
Jeff Garzik
parent
acc4b985a6
commit
bb40dcbb0f
@@ -2075,6 +2075,8 @@ config SPIDER_NET
|
||||
config GIANFAR
|
||||
tristate "Gianfar Ethernet"
|
||||
depends on 85xx || 83xx
|
||||
select PHYLIB
|
||||
select PHYCONTROL
|
||||
help
|
||||
This driver supports the Gigabit TSEC on the MPC85xx
|
||||
family of chips, and the FEC on the 8540
|
||||
|
||||
@@ -13,7 +13,7 @@ obj-$(CONFIG_CHELSIO_T1) += chelsio/
|
||||
obj-$(CONFIG_BONDING) += bonding/
|
||||
obj-$(CONFIG_GIANFAR) += gianfar_driver.o
|
||||
|
||||
gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_phy.o
|
||||
gianfar_driver-objs := gianfar.o gianfar_ethtool.o gianfar_mii.o
|
||||
|
||||
#
|
||||
# link order important here
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,6 @@
|
||||
*
|
||||
* Still left to do:
|
||||
* -Add support for module parameters
|
||||
* -Add support for ethtool -s
|
||||
* -Add patch for ethtool phys id
|
||||
*/
|
||||
#ifndef __GIANFAR_H
|
||||
@@ -37,7 +36,8 @@
|
||||
#include <linux/skbuff.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
@@ -48,7 +48,8 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include "gianfar_phy.h"
|
||||
#include <linux/fsl_devices.h>
|
||||
#include "gianfar_mii.h"
|
||||
|
||||
/* The maximum number of packets to be handled in one call of gfar_poll */
|
||||
#define GFAR_DEV_WEIGHT 64
|
||||
@@ -73,7 +74,7 @@
|
||||
#define PHY_INIT_TIMEOUT 100000
|
||||
#define GFAR_PHY_CHANGE_TIME 2
|
||||
|
||||
#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.1, "
|
||||
#define DEVICE_NAME "%s: Gianfar Ethernet Controller Version 1.2, "
|
||||
#define DRV_NAME "gfar-enet"
|
||||
extern const char gfar_driver_name[];
|
||||
extern const char gfar_driver_version[];
|
||||
@@ -578,12 +579,7 @@ struct gfar {
|
||||
u32 hafdup; /* 0x.50c - Half Duplex Register */
|
||||
u32 maxfrm; /* 0x.510 - Maximum Frame Length Register */
|
||||
u8 res18[12];
|
||||
u32 miimcfg; /* 0x.520 - MII Management Configuration 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 */
|
||||
u8 gfar_mii_regs[24]; /* See gianfar_phy.h */
|
||||
u8 res19[4];
|
||||
u32 ifstat; /* 0x.53c - Interface Status Register */
|
||||
u32 macstnaddr1; /* 0x.540 - Station Address Part 1 Register */
|
||||
@@ -688,9 +684,6 @@ struct gfar_private {
|
||||
struct gfar *regs; /* Pointer to the GFAR memory mapped Registers */
|
||||
u32 *hash_regs[16];
|
||||
int hash_width;
|
||||
struct gfar *phyregs;
|
||||
struct work_struct tq;
|
||||
struct timer_list phy_info_timer;
|
||||
struct net_device_stats stats; /* linux network statistics */
|
||||
struct gfar_extra_stats extra_stats;
|
||||
spinlock_t lock;
|
||||
@@ -710,7 +703,8 @@ struct gfar_private {
|
||||
unsigned int interruptError;
|
||||
struct gianfar_platform_data *einfo;
|
||||
|
||||
struct gfar_mii_info *mii_info;
|
||||
struct phy_device *phydev;
|
||||
struct mii_bus *mii_bus;
|
||||
int oldspeed;
|
||||
int oldduplex;
|
||||
int oldlink;
|
||||
@@ -732,4 +726,12 @@ extern inline void gfar_write(volatile unsigned *addr, u32 val)
|
||||
|
||||
extern struct ethtool_ops *gfar_op_array[];
|
||||
|
||||
extern irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs);
|
||||
extern int startup_gfar(struct net_device *dev);
|
||||
extern void stop_gfar(struct net_device *dev);
|
||||
extern void gfar_halt(struct net_device *dev);
|
||||
extern void gfar_phy_test(struct mii_bus *bus, struct phy_device *phydev,
|
||||
int enable, u32 regnum, u32 read);
|
||||
void gfar_setup_stashing(struct net_device *dev);
|
||||
|
||||
#endif /* __GIANFAR_H */
|
||||
|
||||
@@ -39,17 +39,18 @@
|
||||
#include <asm/types.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include "gianfar.h"
|
||||
|
||||
#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0))
|
||||
|
||||
extern int startup_gfar(struct net_device *dev);
|
||||
extern void stop_gfar(struct net_device *dev);
|
||||
extern void gfar_halt(struct net_device *dev);
|
||||
extern void gfar_start(struct net_device *dev);
|
||||
extern int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit);
|
||||
|
||||
#define GFAR_MAX_COAL_USECS 0xffff
|
||||
#define GFAR_MAX_COAL_FRAMES 0xff
|
||||
static void gfar_fill_stats(struct net_device *dev, struct ethtool_stats *dummy,
|
||||
u64 * buf);
|
||||
static void gfar_gstrings(struct net_device *dev, u32 stringset, u8 * buf);
|
||||
@@ -182,38 +183,32 @@ static void gfar_gdrvinfo(struct net_device *dev, struct
|
||||
drvinfo->eedump_len = 0;
|
||||
}
|
||||
|
||||
|
||||
static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct gfar_private *priv = netdev_priv(dev);
|
||||
struct phy_device *phydev = priv->phydev;
|
||||
|
||||
if (NULL == phydev)
|
||||
return -ENODEV;
|
||||
|
||||
return phy_ethtool_sset(phydev, cmd);
|
||||
}
|
||||
|
||||
|
||||
/* Return the current settings in the ethtool_cmd structure */
|
||||
static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
|
||||
{
|
||||
struct gfar_private *priv = netdev_priv(dev);
|
||||
uint gigabit_support =
|
||||
priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
|
||||
SUPPORTED_1000baseT_Full : 0;
|
||||
uint gigabit_advert =
|
||||
priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
|
||||
ADVERTISED_1000baseT_Full: 0;
|
||||
struct phy_device *phydev = priv->phydev;
|
||||
|
||||
cmd->supported = (SUPPORTED_10baseT_Half
|
||||
| SUPPORTED_100baseT_Half
|
||||
| SUPPORTED_100baseT_Full
|
||||
| gigabit_support | SUPPORTED_Autoneg);
|
||||
|
||||
/* For now, we always advertise everything */
|
||||
cmd->advertising = (ADVERTISED_10baseT_Half
|
||||
| ADVERTISED_100baseT_Half
|
||||
| ADVERTISED_100baseT_Full
|
||||
| gigabit_advert | ADVERTISED_Autoneg);
|
||||
|
||||
cmd->speed = priv->mii_info->speed;
|
||||
cmd->duplex = priv->mii_info->duplex;
|
||||
cmd->port = PORT_MII;
|
||||
cmd->phy_address = priv->mii_info->mii_id;
|
||||
cmd->transceiver = XCVR_EXTERNAL;
|
||||
cmd->autoneg = AUTONEG_ENABLE;
|
||||
if (NULL == phydev)
|
||||
return -ENODEV;
|
||||
|
||||
cmd->maxtxpkt = priv->txcount;
|
||||
cmd->maxrxpkt = priv->rxcount;
|
||||
|
||||
return 0;
|
||||
return phy_ethtool_gset(phydev, cmd);
|
||||
}
|
||||
|
||||
/* Return the length of the register structure */
|
||||
@@ -241,14 +236,14 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv, unsigned int use
|
||||
unsigned int count;
|
||||
|
||||
/* The timer is different, depending on the interface speed */
|
||||
switch (priv->mii_info->speed) {
|
||||
case 1000:
|
||||
switch (priv->phydev->speed) {
|
||||
case SPEED_1000:
|
||||
count = GFAR_GBIT_TIME;
|
||||
break;
|
||||
case 100:
|
||||
case SPEED_100:
|
||||
count = GFAR_100_TIME;
|
||||
break;
|
||||
case 10:
|
||||
case SPEED_10:
|
||||
default:
|
||||
count = GFAR_10_TIME;
|
||||
break;
|
||||
@@ -265,14 +260,14 @@ static unsigned int gfar_ticks2usecs(struct gfar_private *priv, unsigned int tic
|
||||
unsigned int count;
|
||||
|
||||
/* The timer is different, depending on the interface speed */
|
||||
switch (priv->mii_info->speed) {
|
||||
case 1000:
|
||||
switch (priv->phydev->speed) {
|
||||
case SPEED_1000:
|
||||
count = GFAR_GBIT_TIME;
|
||||
break;
|
||||
case 100:
|
||||
case SPEED_100:
|
||||
count = GFAR_100_TIME;
|
||||
break;
|
||||
case 10:
|
||||
case SPEED_10:
|
||||
default:
|
||||
count = GFAR_10_TIME;
|
||||
break;
|
||||
@@ -292,6 +287,9 @@ static int gfar_gcoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
|
||||
if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (NULL == priv->phydev)
|
||||
return -ENODEV;
|
||||
|
||||
cvals->rx_coalesce_usecs = gfar_ticks2usecs(priv, priv->rxtime);
|
||||
cvals->rx_max_coalesced_frames = priv->rxcount;
|
||||
|
||||
@@ -348,6 +346,22 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
|
||||
else
|
||||
priv->rxcoalescing = 1;
|
||||
|
||||
if (NULL == priv->phydev)
|
||||
return -ENODEV;
|
||||
|
||||
/* Check the bounds of the values */
|
||||
if (cvals->rx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
|
||||
pr_info("Coalescing is limited to %d microseconds\n",
|
||||
GFAR_MAX_COAL_USECS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cvals->rx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
|
||||
pr_info("Coalescing is limited to %d frames\n",
|
||||
GFAR_MAX_COAL_FRAMES);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->rxtime = gfar_usecs2ticks(priv, cvals->rx_coalesce_usecs);
|
||||
priv->rxcount = cvals->rx_max_coalesced_frames;
|
||||
|
||||
@@ -358,6 +372,19 @@ static int gfar_scoalesce(struct net_device *dev, struct ethtool_coalesce *cvals
|
||||
else
|
||||
priv->txcoalescing = 1;
|
||||
|
||||
/* Check the bounds of the values */
|
||||
if (cvals->tx_coalesce_usecs > GFAR_MAX_COAL_USECS) {
|
||||
pr_info("Coalescing is limited to %d microseconds\n",
|
||||
GFAR_MAX_COAL_USECS);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (cvals->tx_max_coalesced_frames > GFAR_MAX_COAL_FRAMES) {
|
||||
pr_info("Coalescing is limited to %d frames\n",
|
||||
GFAR_MAX_COAL_FRAMES);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv->txtime = gfar_usecs2ticks(priv, cvals->tx_coalesce_usecs);
|
||||
priv->txcount = cvals->tx_max_coalesced_frames;
|
||||
|
||||
@@ -536,6 +563,7 @@ static void gfar_set_msglevel(struct net_device *dev, uint32_t data)
|
||||
|
||||
struct ethtool_ops gfar_ethtool_ops = {
|
||||
.get_settings = gfar_gsettings,
|
||||
.set_settings = gfar_ssettings,
|
||||
.get_drvinfo = gfar_gdrvinfo,
|
||||
.get_regs_len = gfar_reglen,
|
||||
.get_regs = gfar_get_regs,
|
||||
|
||||
219
drivers/net/gianfar_mii.c
Normal file
219
drivers/net/gianfar_mii.c
Normal file
@@ -0,0 +1,219 @@
|
||||
/*
|
||||
* drivers/net/gianfar_mii.c
|
||||
*
|
||||
* Gianfar Ethernet Driver -- MIIM bus implementation
|
||||
* Provides Bus interface for MIIM regs
|
||||
*
|
||||
* Author: Andy Fleming
|
||||
* Maintainer: Kumar Gala (kumar.gala@freescale.com)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/config.h>
|
||||
#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/version.h>
|
||||
#include <asm/ocp.h>
|
||||
#include <linux/crc32.h>
|
||||
#include <linux/mii.h>
|
||||
#include <linux/phy.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#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)
|
||||
{
|
||||
struct gfar_mii *regs = bus->priv;
|
||||
|
||||
/* Set the PHY address and the register address we want to write */
|
||||
gfar_write(®s->miimadd, (mii_id << 8) | regnum);
|
||||
|
||||
/* Write out the value we want */
|
||||
gfar_write(®s->miimcon, value);
|
||||
|
||||
/* Wait for the transaction to finish */
|
||||
while (gfar_read(®s->miimind) & MIIMIND_BUSY)
|
||||
cpu_relax();
|
||||
|
||||
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)
|
||||
{
|
||||
struct gfar_mii *regs = bus->priv;
|
||||
u16 value;
|
||||
|
||||
/* Set the PHY address and the register address we want to read */
|
||||
gfar_write(®s->miimadd, (mii_id << 8) | regnum);
|
||||
|
||||
/* Clear miimcom, and then initiate a read */
|
||||
gfar_write(®s->miimcom, 0);
|
||||
gfar_write(®s->miimcom, MII_READ_COMMAND);
|
||||
|
||||
/* Wait for the transaction to finish */
|
||||
while (gfar_read(®s->miimind) & (MIIMIND_NOTVALID | MIIMIND_BUSY))
|
||||
cpu_relax();
|
||||
|
||||
/* Grab the value of the register from miimstat */
|
||||
value = gfar_read(®s->miimstat);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the MIIM registers, and wait for the bus to free */
|
||||
int gfar_mdio_reset(struct mii_bus *bus)
|
||||
{
|
||||
struct gfar_mii *regs = bus->priv;
|
||||
unsigned int timeout = PHY_INIT_TIMEOUT;
|
||||
|
||||
spin_lock_bh(&bus->mdio_lock);
|
||||
|
||||
/* Reset the management interface */
|
||||
gfar_write(®s->miimcfg, MIIMCFG_RESET);
|
||||
|
||||
/* Setup the MII Mgmt clock speed */
|
||||
gfar_write(®s->miimcfg, MIIMCFG_INIT_VALUE);
|
||||
|
||||
/* Wait until the bus is free */
|
||||
while ((gfar_read(®s->miimind) & MIIMIND_BUSY) &&
|
||||
timeout--)
|
||||
cpu_relax();
|
||||
|
||||
spin_unlock_bh(&bus->mdio_lock);
|
||||
|
||||
if(timeout <= 0) {
|
||||
printk(KERN_ERR "%s: The MII Bus is stuck!\n",
|
||||
bus->name);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int gfar_mdio_probe(struct device *dev)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
struct gianfar_mdio_data *pdata;
|
||||
struct gfar_mii *regs;
|
||||
struct mii_bus *new_bus;
|
||||
int err = 0;
|
||||
|
||||
if (NULL == dev)
|
||||
return -EINVAL;
|
||||
|
||||
new_bus = kmalloc(sizeof(struct mii_bus), GFP_KERNEL);
|
||||
|
||||
if (NULL == new_bus)
|
||||
return -ENOMEM;
|
||||
|
||||
new_bus->name = "Gianfar MII Bus",
|
||||
new_bus->read = &gfar_mdio_read,
|
||||
new_bus->write = &gfar_mdio_write,
|
||||
new_bus->reset = &gfar_mdio_reset,
|
||||
new_bus->id = pdev->id;
|
||||
|
||||
pdata = (struct gianfar_mdio_data *)pdev->dev.platform_data;
|
||||
|
||||
if (NULL == pdata) {
|
||||
printk(KERN_ERR "gfar mdio %d: Missing platform data!\n", pdev->id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Set the PHY base address */
|
||||
regs = (struct gfar_mii *) ioremap(pdata->paddr,
|
||||
sizeof (struct gfar_mii));
|
||||
|
||||
if (NULL == regs) {
|
||||
err = -ENOMEM;
|
||||
goto reg_map_fail;
|
||||
}
|
||||
|
||||
new_bus->priv = regs;
|
||||
|
||||
new_bus->irq = pdata->irq;
|
||||
|
||||
new_bus->dev = dev;
|
||||
dev_set_drvdata(dev, new_bus);
|
||||
|
||||
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((void *) regs);
|
||||
reg_map_fail:
|
||||
kfree(new_bus);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
|
||||
int gfar_mdio_remove(struct device *dev)
|
||||
{
|
||||
struct mii_bus *bus = dev_get_drvdata(dev);
|
||||
|
||||
mdiobus_unregister(bus);
|
||||
|
||||
dev_set_drvdata(dev, NULL);
|
||||
|
||||
iounmap((void *) (&bus->priv));
|
||||
bus->priv = NULL;
|
||||
kfree(bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_driver gianfar_mdio_driver = {
|
||||
.name = "fsl-gianfar_mdio",
|
||||
.bus = &platform_bus_type,
|
||||
.probe = gfar_mdio_probe,
|
||||
.remove = gfar_mdio_remove,
|
||||
};
|
||||
|
||||
int __init gfar_mdio_init(void)
|
||||
{
|
||||
return driver_register(&gianfar_mdio_driver);
|
||||
}
|
||||
|
||||
void __exit gfar_mdio_exit(void)
|
||||
{
|
||||
driver_unregister(&gianfar_mdio_driver);
|
||||
}
|
||||
45
drivers/net/gianfar_mii.h
Normal file
45
drivers/net/gianfar_mii.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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 (kumar.gala@freescale.com)
|
||||
*
|
||||
* 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
|
||||
|
||||
#define MIIMIND_BUSY 0x00000001
|
||||
#define MIIMIND_NOTVALID 0x00000004
|
||||
|
||||
#define MII_READ_COMMAND 0x00000001
|
||||
|
||||
#define GFAR_SUPPORTED (SUPPORTED_10baseT_Half \
|
||||
| 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 __init gfar_mdio_init(void);
|
||||
void __exit gfar_mdio_exit(void);
|
||||
#endif /* GIANFAR_PHY_H */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,213 +0,0 @@
|
||||
/*
|
||||
* drivers/net/gianfar_phy.h
|
||||
*
|
||||
* Gianfar Ethernet Driver -- PHY handling
|
||||
* Driver for FEC on MPC8540 and TSEC on MPC8540/MPC8560
|
||||
* Based on 8260_io/fcc_enet.c
|
||||
*
|
||||
* Author: Andy Fleming
|
||||
* Maintainer: Kumar Gala (kumar.gala@freescale.com)
|
||||
*
|
||||
* 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_PHY_H
|
||||
#define __GIANFAR_PHY_H
|
||||
|
||||
#define MII_end ((u32)-2)
|
||||
#define MII_read ((u32)-1)
|
||||
|
||||
#define MIIMIND_BUSY 0x00000001
|
||||
#define MIIMIND_NOTVALID 0x00000004
|
||||
|
||||
#define GFAR_AN_TIMEOUT 2000
|
||||
|
||||
/* 1000BT control (Marvell & BCM54xx at least) */
|
||||
#define MII_1000BASETCONTROL 0x09
|
||||
#define MII_1000BASETCONTROL_FULLDUPLEXCAP 0x0200
|
||||
#define MII_1000BASETCONTROL_HALFDUPLEXCAP 0x0100
|
||||
|
||||
/* Cicada Extended Control Register 1 */
|
||||
#define MII_CIS8201_EXT_CON1 0x17
|
||||
#define MII_CIS8201_EXTCON1_INIT 0x0000
|
||||
|
||||
/* Cicada Interrupt Mask Register */
|
||||
#define MII_CIS8201_IMASK 0x19
|
||||
#define MII_CIS8201_IMASK_IEN 0x8000
|
||||
#define MII_CIS8201_IMASK_SPEED 0x4000
|
||||
#define MII_CIS8201_IMASK_LINK 0x2000
|
||||
#define MII_CIS8201_IMASK_DUPLEX 0x1000
|
||||
#define MII_CIS8201_IMASK_MASK 0xf000
|
||||
|
||||
/* Cicada Interrupt Status Register */
|
||||
#define MII_CIS8201_ISTAT 0x1a
|
||||
#define MII_CIS8201_ISTAT_STATUS 0x8000
|
||||
#define MII_CIS8201_ISTAT_SPEED 0x4000
|
||||
#define MII_CIS8201_ISTAT_LINK 0x2000
|
||||
#define MII_CIS8201_ISTAT_DUPLEX 0x1000
|
||||
|
||||
/* Cicada Auxiliary Control/Status Register */
|
||||
#define MII_CIS8201_AUX_CONSTAT 0x1c
|
||||
#define MII_CIS8201_AUXCONSTAT_INIT 0x0004
|
||||
#define MII_CIS8201_AUXCONSTAT_DUPLEX 0x0020
|
||||
#define MII_CIS8201_AUXCONSTAT_SPEED 0x0018
|
||||
#define MII_CIS8201_AUXCONSTAT_GBIT 0x0010
|
||||
#define MII_CIS8201_AUXCONSTAT_100 0x0008
|
||||
|
||||
/* 88E1011 PHY Status Register */
|
||||
#define MII_M1011_PHY_SPEC_STATUS 0x11
|
||||
#define MII_M1011_PHY_SPEC_STATUS_1000 0x8000
|
||||
#define MII_M1011_PHY_SPEC_STATUS_100 0x4000
|
||||
#define MII_M1011_PHY_SPEC_STATUS_SPD_MASK 0xc000
|
||||
#define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX 0x2000
|
||||
#define MII_M1011_PHY_SPEC_STATUS_RESOLVED 0x0800
|
||||
#define MII_M1011_PHY_SPEC_STATUS_LINK 0x0400
|
||||
|
||||
#define MII_M1011_IEVENT 0x13
|
||||
#define MII_M1011_IEVENT_CLEAR 0x0000
|
||||
|
||||
#define MII_M1011_IMASK 0x12
|
||||
#define MII_M1011_IMASK_INIT 0x6400
|
||||
#define MII_M1011_IMASK_CLEAR 0x0000
|
||||
|
||||
#define MII_DM9161_SCR 0x10
|
||||
#define MII_DM9161_SCR_INIT 0x0610
|
||||
|
||||
/* DM9161 Specified Configuration and Status Register */
|
||||
#define MII_DM9161_SCSR 0x11
|
||||
#define MII_DM9161_SCSR_100F 0x8000
|
||||
#define MII_DM9161_SCSR_100H 0x4000
|
||||
#define MII_DM9161_SCSR_10F 0x2000
|
||||
#define MII_DM9161_SCSR_10H 0x1000
|
||||
|
||||
/* DM9161 Interrupt Register */
|
||||
#define MII_DM9161_INTR 0x15
|
||||
#define MII_DM9161_INTR_PEND 0x8000
|
||||
#define MII_DM9161_INTR_DPLX_MASK 0x0800
|
||||
#define MII_DM9161_INTR_SPD_MASK 0x0400
|
||||
#define MII_DM9161_INTR_LINK_MASK 0x0200
|
||||
#define MII_DM9161_INTR_MASK 0x0100
|
||||
#define MII_DM9161_INTR_DPLX_CHANGE 0x0010
|
||||
#define MII_DM9161_INTR_SPD_CHANGE 0x0008
|
||||
#define MII_DM9161_INTR_LINK_CHANGE 0x0004
|
||||
#define MII_DM9161_INTR_INIT 0x0000
|
||||
#define MII_DM9161_INTR_STOP \
|
||||
(MII_DM9161_INTR_DPLX_MASK | MII_DM9161_INTR_SPD_MASK \
|
||||
| MII_DM9161_INTR_LINK_MASK | MII_DM9161_INTR_MASK)
|
||||
|
||||
/* DM9161 10BT Configuration/Status */
|
||||
#define MII_DM9161_10BTCSR 0x12
|
||||
#define MII_DM9161_10BTCSR_INIT 0x7800
|
||||
|
||||
#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | \
|
||||
SUPPORTED_10baseT_Full | \
|
||||
SUPPORTED_100baseT_Half | \
|
||||
SUPPORTED_100baseT_Full | \
|
||||
SUPPORTED_Autoneg | \
|
||||
SUPPORTED_TP | \
|
||||
SUPPORTED_MII)
|
||||
|
||||
#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \
|
||||
SUPPORTED_1000baseT_Half | \
|
||||
SUPPORTED_1000baseT_Full)
|
||||
|
||||
#define MII_READ_COMMAND 0x00000001
|
||||
|
||||
#define MII_INTERRUPT_DISABLED 0x0
|
||||
#define MII_INTERRUPT_ENABLED 0x1
|
||||
/* Taken from mii_if_info and sungem_phy.h */
|
||||
struct gfar_mii_info {
|
||||
/* Information about the PHY type */
|
||||
/* And management functions */
|
||||
struct phy_info *phyinfo;
|
||||
|
||||
/* forced speed & duplex (no autoneg)
|
||||
* partner speed & duplex & pause (autoneg)
|
||||
*/
|
||||
int speed;
|
||||
int duplex;
|
||||
int pause;
|
||||
|
||||
/* The most recently read link state */
|
||||
int link;
|
||||
|
||||
/* Enabled Interrupts */
|
||||
u32 interrupts;
|
||||
|
||||
u32 advertising;
|
||||
int autoneg;
|
||||
int mii_id;
|
||||
|
||||
/* private data pointer */
|
||||
/* For use by PHYs to maintain extra state */
|
||||
void *priv;
|
||||
|
||||
/* Provided by host chip */
|
||||
struct net_device *dev;
|
||||
|
||||
/* A lock to ensure that only one thing can read/write
|
||||
* the MDIO bus at a time */
|
||||
spinlock_t mdio_lock;
|
||||
|
||||
/* Provided by ethernet driver */
|
||||
int (*mdio_read) (struct net_device *dev, int mii_id, int reg);
|
||||
void (*mdio_write) (struct net_device *dev, int mii_id, int reg, int val);
|
||||
};
|
||||
|
||||
/* struct phy_info: a structure which defines attributes for a PHY
|
||||
*
|
||||
* id will contain a number which represents the PHY. During
|
||||
* startup, the driver will poll the PHY to find out what its
|
||||
* UID--as defined by registers 2 and 3--is. The 32-bit result
|
||||
* gotten from the PHY will be ANDed with phy_id_mask to
|
||||
* discard any bits which may change based on revision numbers
|
||||
* unimportant to functionality
|
||||
*
|
||||
* There are 6 commands which take a gfar_mii_info structure.
|
||||
* Each PHY must declare config_aneg, and read_status.
|
||||
*/
|
||||
struct phy_info {
|
||||
u32 phy_id;
|
||||
char *name;
|
||||
unsigned int phy_id_mask;
|
||||
u32 features;
|
||||
|
||||
/* Called to initialize the PHY */
|
||||
int (*init)(struct gfar_mii_info *mii_info);
|
||||
|
||||
/* Called to suspend the PHY for power */
|
||||
int (*suspend)(struct gfar_mii_info *mii_info);
|
||||
|
||||
/* Reconfigures autonegotiation (or disables it) */
|
||||
int (*config_aneg)(struct gfar_mii_info *mii_info);
|
||||
|
||||
/* Determines the negotiated speed and duplex */
|
||||
int (*read_status)(struct gfar_mii_info *mii_info);
|
||||
|
||||
/* Clears any pending interrupts */
|
||||
int (*ack_interrupt)(struct gfar_mii_info *mii_info);
|
||||
|
||||
/* Enables or disables interrupts */
|
||||
int (*config_intr)(struct gfar_mii_info *mii_info);
|
||||
|
||||
/* Clears up any memory if needed */
|
||||
void (*close)(struct gfar_mii_info *mii_info);
|
||||
};
|
||||
|
||||
struct phy_info *get_phy_info(struct gfar_mii_info *mii_info);
|
||||
int read_phy_reg(struct net_device *dev, int mii_id, int regnum);
|
||||
void write_phy_reg(struct net_device *dev, int mii_id, int regnum, int value);
|
||||
void mii_clear_phy_interrupt(struct gfar_mii_info *mii_info);
|
||||
void mii_configure_phy_interrupt(struct gfar_mii_info *mii_info, u32 interrupts);
|
||||
|
||||
struct dm9161_private {
|
||||
struct timer_list timer;
|
||||
int resetdone;
|
||||
};
|
||||
|
||||
#endif /* GIANFAR_PHY_H */
|
||||
Reference in New Issue
Block a user