Merge branch 'master' of git://git.denx.de/u-boot-net

This commit is contained in:
Tom Rini 2016-08-15 16:38:39 -04:00
commit 2ef98d3316
50 changed files with 1325 additions and 515 deletions

View file

@ -15,6 +15,8 @@
#ifndef fec_h #ifndef fec_h
#define fec_h #define fec_h
#include <phy.h>
/* Buffer descriptors used FEC. /* Buffer descriptors used FEC.
*/ */
typedef struct cpm_buf_desc { typedef struct cpm_buf_desc {
@ -341,10 +343,9 @@ int fecpin_setclear(struct eth_device *dev, int setclear);
void __mii_init(void); void __mii_init(void);
uint mii_send(uint mii_cmd); uint mii_send(uint mii_cmd);
int mii_discover_phy(struct eth_device *dev); int mii_discover_phy(struct eth_device *dev);
int mcffec_miiphy_read(const char *devname, unsigned char addr, int mcffec_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg);
unsigned char reg, unsigned short *value); int mcffec_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
int mcffec_miiphy_write(const char *devname, unsigned char addr, u16 value);
unsigned char reg, unsigned short value);
#endif #endif
#endif /* fec_h */ #endif /* fec_h */

View file

@ -73,9 +73,9 @@ mac_fifo_t mac_fifo[NO_OF_FIFOS];
#define MAX_WAIT 1000 #define MAX_WAIT 1000
#if defined(CONFIG_CMD_MII) #if defined(CONFIG_CMD_MII)
int au1x00_miiphy_read(const char *devname, unsigned char addr, int au1x00_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
unsigned char reg, unsigned short * value)
{ {
unsigned short value = 0;
volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL); volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA); volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
u32 mii_control; u32 mii_control;
@ -102,12 +102,12 @@ int au1x00_miiphy_read(const char *devname, unsigned char addr,
return -1; return -1;
} }
} }
*value = *mii_data_reg; value = *mii_data_reg;
return 0; return value;
} }
int au1x00_miiphy_write(const char *devname, unsigned char addr, int au1x00_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
unsigned char reg, unsigned short value) u16 value)
{ {
volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL); volatile u32 *mii_control_reg = (volatile u32*)(ETH0_BASE+MAC_MII_CNTRL);
volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA); volatile u32 *mii_data_reg = (volatile u32*)(ETH0_BASE+MAC_MII_DATA);
@ -290,8 +290,17 @@ int au1x00_enet_initialize(bd_t *bis){
eth_register(dev); eth_register(dev);
#if defined(CONFIG_CMD_MII) #if defined(CONFIG_CMD_MII)
miiphy_register(dev->name, int retval;
au1x00_miiphy_read, au1x00_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = au1x00_miiphy_read;
mdiodev->write = au1x00_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
return 1; return 1;

View file

@ -379,8 +379,17 @@ int fec_initialize(bd_t *bis)
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \ #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \
&& defined(CONFIG_BITBANGMII) && defined(CONFIG_BITBANGMII)
miiphy_register(dev->name, int retval;
bb_miiphy_read, bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
} }

View file

@ -441,8 +441,17 @@ int fec_initialize(bd_t *bis)
#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \ #if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII)) \
&& defined(CONFIG_BITBANGMII) && defined(CONFIG_BITBANGMII)
miiphy_register(dev->name, int retval;
bb_miiphy_read, bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
} }

View file

@ -6,10 +6,12 @@
*/ */
#include <common.h> #include <common.h>
#include <malloc.h>
#include <commproc.h>
#include <net.h>
#include <command.h> #include <command.h>
#include <commproc.h>
#include <malloc.h>
#include <net.h>
#include <phy.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -47,10 +49,9 @@ DECLARE_GLOBAL_DATA_PTR;
static int mii_discover_phy(struct eth_device *dev); static int mii_discover_phy(struct eth_device *dev);
#endif #endif
int fec8xx_miiphy_read(const char *devname, unsigned char addr, int fec8xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg);
unsigned char reg, unsigned short *value); int fec8xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
int fec8xx_miiphy_write(const char *devname, unsigned char addr, u16 value);
unsigned char reg, unsigned short value);
static struct ether_fcc_info_s static struct ether_fcc_info_s
{ {
@ -170,8 +171,17 @@ int fec_initialize(bd_t *bis)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, int retval;
fec8xx_miiphy_read, fec8xx_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = fec8xx_miiphy_read;
mdiodev->write = fec8xx_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
} }
return 1; return 1;
@ -894,9 +904,9 @@ void mii_init (void)
* Otherwise they hang in mii_send() !!! Sorry! * Otherwise they hang in mii_send() !!! Sorry!
*****************************************************************************/ *****************************************************************************/
int fec8xx_miiphy_read(const char *devname, unsigned char addr, int fec8xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
unsigned char reg, unsigned short *value)
{ {
unsigned short value = 0;
short rdreg; /* register working value */ short rdreg; /* register working value */
#ifdef MII_DEBUG #ifdef MII_DEBUG
@ -904,15 +914,15 @@ int fec8xx_miiphy_read(const char *devname, unsigned char addr,
#endif #endif
rdreg = mii_send(mk_mii_read(addr, reg)); rdreg = mii_send(mk_mii_read(addr, reg));
*value = rdreg; value = rdreg;
#ifdef MII_DEBUG #ifdef MII_DEBUG
printf ("0x%04x\n", *value); printf ("0x%04x\n", value);
#endif #endif
return 0; return value;
} }
int fec8xx_miiphy_write(const char *devname, unsigned char addr, int fec8xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
unsigned char reg, unsigned short value) u16 value)
{ {
#ifdef MII_DEBUG #ifdef MII_DEBUG
printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr); printf ("miiphy_write(0x%x) @ 0x%x = ", reg, addr);

View file

@ -318,8 +318,7 @@ static int emac_miiphy_command(u8 addr, u8 reg, int cmd, u16 value)
return 0; return 0;
} }
int emac4xx_miiphy_read (const char *devname, unsigned char addr, unsigned char reg, int emac4xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
unsigned short *value)
{ {
unsigned long sta_reg; unsigned long sta_reg;
unsigned long emac_reg; unsigned long emac_reg;
@ -330,17 +329,15 @@ int emac4xx_miiphy_read (const char *devname, unsigned char addr, unsigned char
return -1; return -1;
sta_reg = in_be32((void *)EMAC0_STACR + emac_reg); sta_reg = in_be32((void *)EMAC0_STACR + emac_reg);
*value = sta_reg >> 16; return sta_reg >> 16;
return 0;
} }
/***********************************************************/ /***********************************************************/
/* write a phy reg and return the value with a rc */ /* write a phy reg and return the value with a rc */
/***********************************************************/ /***********************************************************/
int emac4xx_miiphy_write (const char *devname, unsigned char addr, unsigned char reg, int emac4xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
unsigned short value) u16 value)
{ {
return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value); return emac_miiphy_command(addr, reg, EMAC_STACR_WRITE, value);
} }

View file

@ -172,8 +172,17 @@ int last_stage_init(void)
print_fpga_info(); print_fpga_info();
miiphy_register(CONFIG_SYS_GBIT_MII_BUSNAME, int retval;
bb_miiphy_read, bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII_BUSNAME, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
for (k = 0; k < 32; ++k) for (k = 0; k < 32; ++k)
configure_gbit_phy(k); configure_gbit_phy(k);

View file

@ -405,8 +405,17 @@ int last_stage_init(void)
} }
if (!legacy && (feature_carrier_speed == CARRIER_SPEED_1G)) { if (!legacy && (feature_carrier_speed == CARRIER_SPEED_1G)) {
miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read, int retval;
bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) { for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
if ((mux_ch == 1) && !ch0_rgmii2_present) if ((mux_ch == 1) && !ch0_rgmii2_present)
continue; continue;
@ -437,8 +446,18 @@ int last_stage_init(void)
print_fpga_info(k, false); print_fpga_info(k, false);
osd_probe(k); osd_probe(k);
if (feature_carrier_speed == CARRIER_SPEED_1G) { if (feature_carrier_speed == CARRIER_SPEED_1G) {
miiphy_register(bb_miiphy_buses[k].name, int retval;
bb_miiphy_read, bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, bb_miiphy_buses[k].name,
MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
setup_88e1518(bb_miiphy_buses[k].name, 0); setup_88e1518(bb_miiphy_buses[k].name, 0);
} }
} }

View file

@ -246,8 +246,17 @@ int last_stage_init(void)
/* setup Gbit PHYs */ /* setup Gbit PHYs */
puts("TRANS: "); puts("TRANS: ");
puts(str_phys); puts(str_phys);
miiphy_register(CONFIG_SYS_GBIT_MII_BUSNAME, int retval;
bb_miiphy_read, bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII_BUSNAME, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
for (k = 0; k < 32; ++k) { for (k = 0; k < 32; ++k) {
configure_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k); configure_gbit_phy(CONFIG_SYS_GBIT_MII_BUSNAME, k);
@ -255,8 +264,16 @@ int last_stage_init(void)
putc(slash[k % 8]); putc(slash[k % 8]);
} }
miiphy_register(CONFIG_SYS_GBIT_MII1_BUSNAME, mdiodev = mdio_alloc();
bb_miiphy_read, bb_miiphy_write); if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, CONFIG_SYS_GBIT_MII1_BUSNAME, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
for (k = 0; k < 32; ++k) { for (k = 0; k < 32; ++k) {
configure_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k); configure_gbit_phy(CONFIG_SYS_GBIT_MII1_BUSNAME, k);

View file

@ -162,8 +162,17 @@ int last_stage_init(void)
} }
if (hw_type_cat) { if (hw_type_cat) {
miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read, int retval;
bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) { for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
if ((mux_ch == 1) && !ch0_rgmii2_present) if ((mux_ch == 1) && !ch0_rgmii2_present)
continue; continue;
@ -199,8 +208,18 @@ int last_stage_init(void)
osd_probe(k + 4); osd_probe(k + 4);
#endif #endif
if (hw_type_cat) { if (hw_type_cat) {
miiphy_register(bb_miiphy_buses[k].name, int retval;
bb_miiphy_read, bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, bb_miiphy_buses[k].name,
MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
setup_88e1514(bb_miiphy_buses[k].name, 0); setup_88e1514(bb_miiphy_buses[k].name, 0);
} }
} }

View file

@ -179,8 +179,17 @@ int last_stage_init(void)
} }
if (hw_type_cat) { if (hw_type_cat) {
miiphy_register(bb_miiphy_buses[0].name, bb_miiphy_read, int retval;
bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, bb_miiphy_buses[0].name, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) { for (mux_ch = 0; mux_ch < MAX_MUX_CHANNELS; ++mux_ch) {
if ((mux_ch == 1) && !ch0_sgmii2_present) if ((mux_ch == 1) && !ch0_sgmii2_present)
continue; continue;
@ -252,8 +261,18 @@ int last_stage_init(void)
dp501_probe(k, false); dp501_probe(k, false);
#endif #endif
if (hw_type_cat) { if (hw_type_cat) {
miiphy_register(bb_miiphy_buses[k].name, int retval;
bb_miiphy_read, bb_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, bb_miiphy_buses[k].name,
MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
setup_88e1514(bb_miiphy_buses[k].name, 0); setup_88e1514(bb_miiphy_buses[k].name, 0);
} }
} }

View file

@ -65,79 +65,6 @@ void miiphy_init(void)
current_mii = NULL; current_mii = NULL;
} }
static int legacy_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
{
unsigned short val;
int ret;
struct legacy_mii_dev *ldev = bus->priv;
ret = ldev->read(bus->name, addr, reg, &val);
return ret ? -1 : (int)val;
}
static int legacy_miiphy_write(struct mii_dev *bus, int addr, int devad,
int reg, u16 val)
{
struct legacy_mii_dev *ldev = bus->priv;
return ldev->write(bus->name, addr, reg, val);
}
/*****************************************************************************
*
* Register read and write MII access routines for the device <name>.
* This API is now deprecated. Please use mdio_alloc and mdio_register, instead.
*/
void miiphy_register(const char *name,
int (*read)(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value),
int (*write)(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value))
{
struct mii_dev *new_dev;
struct legacy_mii_dev *ldev;
BUG_ON(strlen(name) >= MDIO_NAME_LEN);
/* check if we have unique name */
new_dev = miiphy_get_dev_by_name(name);
if (new_dev) {
printf("miiphy_register: non unique device name '%s'\n", name);
return;
}
/* allocate memory */
new_dev = mdio_alloc();
ldev = malloc(sizeof(*ldev));
if (new_dev == NULL || ldev == NULL) {
printf("miiphy_register: cannot allocate memory for '%s'\n",
name);
free(ldev);
mdio_free(new_dev);
return;
}
/* initalize mii_dev struct fields */
new_dev->read = legacy_miiphy_read;
new_dev->write = legacy_miiphy_write;
strncpy(new_dev->name, name, MDIO_NAME_LEN);
new_dev->name[MDIO_NAME_LEN - 1] = 0;
ldev->read = read;
ldev->write = write;
new_dev->priv = ldev;
debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
new_dev->name, ldev->read, ldev->write);
/* add it to the list */
list_add_tail(&new_dev->link, &mii_devs);
if (!current_mii)
current_mii = new_dev;
}
struct mii_dev *mdio_alloc(void) struct mii_dev *mdio_alloc(void)
{ {
struct mii_dev *bus; struct mii_dev *bus;

View file

@ -6,5 +6,7 @@ CONFIG_TARGET_OPENRISC_GENERIC=y
CONFIG_CMD_DHCP=y CONFIG_CMD_DHCP=y
CONFIG_CMD_MII=y CONFIG_CMD_MII=y
CONFIG_CMD_PING=y CONFIG_CMD_PING=y
CONFIG_NETDEVICES=y
CONFIG_ETHOC=y
CONFIG_SYS_NS16550=y CONFIG_SYS_NS16550=y
# CONFIG_AUTOBOOT is not set # CONFIG_AUTOBOOT is not set

View file

@ -283,10 +283,9 @@ static void mal_err (struct eth_device *dev, unsigned long isr,
static void emac_err (struct eth_device *dev, unsigned long isr); static void emac_err (struct eth_device *dev, unsigned long isr);
extern int phy_setup_aneg (char *devname, unsigned char addr); extern int phy_setup_aneg (char *devname, unsigned char addr);
extern int emac4xx_miiphy_read (const char *devname, unsigned char addr, int emac4xx_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg);
unsigned char reg, unsigned short *value); int emac4xx_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
extern int emac4xx_miiphy_write (const char *devname, unsigned char addr, u16 value);
unsigned char reg, unsigned short value);
int board_emac_count(void); int board_emac_count(void);
@ -2015,8 +2014,17 @@ int ppc_4xx_eth_initialize (bd_t * bis)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, int retval;
emac4xx_miiphy_read, emac4xx_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = emac4xx_miiphy_read;
mdiodev->write = emac4xx_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
if (0 == virgin) { if (0 == virgin) {

View file

@ -124,6 +124,11 @@ config ETH_DESIGNWARE
100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to 100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to
provide the PHY (physical media interface). provide the PHY (physical media interface).
config ETHOC
bool "OpenCores 10/100 Mbps Ethernet MAC"
help
This MAC is present in OpenRISC and Xtensa XTFPGA boards.
config MVPP2 config MVPP2
bool "Marvell Armada 375 network interface support" bool "Marvell Armada 375 network interface support"
depends on ARMADA_375 depends on ARMADA_375

View file

@ -57,18 +57,19 @@ static int armdfec_phy_timeout(u32 *reg, u32 flag, int cond)
return !timeout; return !timeout;
} }
static int smi_reg_read(const char *devname, u8 phy_addr, u8 phy_reg, static int smi_reg_read(struct mii_dev *bus, int phy_addr, int devad,
u16 *value) int phy_reg)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); u16 value = 0;
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct armdfec_device *darmdfec = to_darmdfec(dev); struct armdfec_device *darmdfec = to_darmdfec(dev);
struct armdfec_reg *regs = darmdfec->regs; struct armdfec_reg *regs = darmdfec->regs;
u32 val; u32 val;
if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) { if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
val = readl(&regs->phyadr); val = readl(&regs->phyadr);
*value = val & 0x1f; value = val & 0x1f;
return 0; return value;
} }
/* check parameters */ /* check parameters */
@ -99,15 +100,15 @@ static int smi_reg_read(const char *devname, u8 phy_addr, u8 phy_reg,
return -1; return -1;
} }
val = readl(&regs->smi); val = readl(&regs->smi);
*value = val & 0xffff; value = val & 0xffff;
return 0; return value;
} }
static int smi_reg_write(const char *devname, static int smi_reg_write(struct mii_dev *bus, int phy_addr, int devad,
u8 phy_addr, u8 phy_reg, u16 value) int phy_reg, u16 value)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct armdfec_device *darmdfec = to_darmdfec(dev); struct armdfec_device *darmdfec = to_darmdfec(dev);
struct armdfec_reg *regs = darmdfec->regs; struct armdfec_reg *regs = darmdfec->regs;
@ -711,7 +712,17 @@ int armada100_fec_register(unsigned long base_addr)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, smi_reg_read, smi_reg_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = smi_reg_read;
mdiodev->write = smi_reg_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
return 0; return 0;

View file

@ -159,23 +159,23 @@ at91_emac_t *get_emacbase_by_name(const char *devname)
return (at91_emac_t *) netdev->iobase; return (at91_emac_t *) netdev->iobase;
} }
int at91emac_mii_read(const char *devname, unsigned char addr, int at91emac_mii_read(struct mii_dev *bus, int addr, int devad, int reg)
unsigned char reg, unsigned short *value)
{ {
unsigned short value = 0;
at91_emac_t *emac; at91_emac_t *emac;
emac = get_emacbase_by_name(devname); emac = get_emacbase_by_name(bus->name);
at91emac_read(emac , addr, reg, value); at91emac_read(emac , addr, reg, &value);
return 0; return value;
} }
int at91emac_mii_write(const char *devname, unsigned char addr, int at91emac_mii_write(struct mii_dev *bus, int addr, int devad, int reg,
unsigned char reg, unsigned short value) u16 value)
{ {
at91_emac_t *emac; at91_emac_t *emac;
emac = get_emacbase_by_name(devname); emac = get_emacbase_by_name(bus->name);
at91emac_write(emac, addr, reg, value); at91emac_write(emac, addr, reg, value);
return 0; return 0;
} }
@ -502,7 +502,17 @@ int at91emac_register(bd_t *bis, unsigned long iobase)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, at91emac_mii_read, at91emac_mii_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = at91emac_mii_read;
mdiodev->write = at91emac_mii_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
return 1; return 1;
} }

View file

@ -596,12 +596,10 @@ bool gmac_mii_busywait(unsigned int timeout)
return tmp & (1 << GMAC_MII_BUSY_SHIFT); return tmp & (1 << GMAC_MII_BUSY_SHIFT);
} }
int gmac_miiphy_read(const char *devname, unsigned char phyaddr, int gmac_miiphy_read(struct mii_dev *bus, int phyaddr, int devad, int reg)
unsigned char reg, unsigned short *value)
{ {
uint32_t tmp = 0; uint32_t tmp = 0;
u16 value = 0;
(void)devname;
/* Busy wait timeout is 1ms */ /* Busy wait timeout is 1ms */
if (gmac_mii_busywait(1000)) { if (gmac_mii_busywait(1000)) {
@ -621,18 +619,16 @@ int gmac_miiphy_read(const char *devname, unsigned char phyaddr,
return -1; return -1;
} }
*value = readl(GMAC_MII_DATA_ADDR) & 0xffff; value = readl(GMAC_MII_DATA_ADDR) & 0xffff;
debug("MII read data 0x%x\n", *value); debug("MII read data 0x%x\n", value);
return 0; return value;
} }
int gmac_miiphy_write(const char *devname, unsigned char phyaddr, int gmac_miiphy_write(struct mii_dev *bus, int phyaddr, int devad, int reg,
unsigned char reg, unsigned short value) u16 value)
{ {
uint32_t tmp = 0; uint32_t tmp = 0;
(void)devname;
/* Busy wait timeout is 1ms */ /* Busy wait timeout is 1ms */
if (gmac_mii_busywait(1000)) { if (gmac_mii_busywait(1000)) {
error("%s: Prepare MII write: MII/MDIO busy\n", __func__); error("%s: Prepare MII write: MII/MDIO busy\n", __func__);

View file

@ -244,7 +244,18 @@ int bcm_sf2_eth_register(bd_t *bis, u8 dev_num)
eth_register(dev); eth_register(dev);
#ifdef CONFIG_CMD_MII #ifdef CONFIG_CMD_MII
miiphy_register(dev->name, eth->miiphy_read, eth->miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = eth->miiphy_read;
mdiodev->write = eth->miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
/* Initialization */ /* Initialization */

View file

@ -54,10 +54,10 @@ struct eth_info {
struct phy_device *port[BCM_ETH_MAX_PORT_NUM]; struct phy_device *port[BCM_ETH_MAX_PORT_NUM];
int port_num; int port_num;
int (*miiphy_read)(const char *devname, unsigned char phyaddr, int (*miiphy_read)(struct mii_dev *bus, int phyaddr, int devad,
unsigned char reg, unsigned short *value); int reg);
int (*miiphy_write)(const char *devname, unsigned char phyaddr, int (*miiphy_write)(struct mii_dev *bus, int phyaddr, int devad,
unsigned char reg, unsigned short value); int reg, u16 value);
int (*mac_init)(struct eth_device *dev); int (*mac_init)(struct eth_device *dev);
int (*enable_mac)(void); int (*enable_mac)(void);

View file

@ -13,6 +13,7 @@
#include <command.h> #include <command.h>
#include <malloc.h> #include <malloc.h>
#include <miiphy.h> #include <miiphy.h>
#include <linux/mdio.h>
#include <linux/mii.h> #include <linux/mii.h>
#include <asm/blackfin.h> #include <asm/blackfin.h>
@ -72,18 +73,20 @@ static int bfin_miiphy_wait(void)
return 0; return 0;
} }
static int bfin_miiphy_read(const char *devname, uchar addr, uchar reg, ushort *val) static int bfin_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
{ {
ushort val = 0;
if (bfin_miiphy_wait()) if (bfin_miiphy_wait())
return 1; return 1;
bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STABUSY); bfin_write_EMAC_STAADD(SET_PHYAD(addr) | SET_REGAD(reg) | STABUSY);
if (bfin_miiphy_wait()) if (bfin_miiphy_wait())
return 1; return 1;
*val = bfin_read_EMAC_STADAT(); val = bfin_read_EMAC_STADAT();
return 0; return val;
} }
static int bfin_miiphy_write(const char *devname, uchar addr, uchar reg, ushort val) static int bfin_miiphy_write(struct mii_dev *bus, int addr, int devad,
int reg, u16 val)
{ {
if (bfin_miiphy_wait()) if (bfin_miiphy_wait())
return 1; return 1;
@ -113,7 +116,19 @@ int bfin_EMAC_initialize(bd_t *bis)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, bfin_miiphy_read, bfin_miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = bfin_miiphy_read;
mdiodev->write = bfin_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
dev->priv = mdiodev;
#endif #endif
return 0; return 0;
@ -222,8 +237,9 @@ static int bfin_EMAC_recv(struct eth_device *dev)
static int bfin_miiphy_init(struct eth_device *dev, int *opmode) static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
{ {
const unsigned short pins[] = CONFIG_BFIN_MAC_PINS; const unsigned short pins[] = CONFIG_BFIN_MAC_PINS;
u16 phydat; int phydat;
size_t count; size_t count;
struct mii_dev *mdiodev = dev->priv;
/* Enable PHY output */ /* Enable PHY output */
bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE); bfin_write_VR_CTL(bfin_read_VR_CTL() | CLKBUFOE);
@ -236,12 +252,15 @@ static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ))); bfin_write_EMAC_SYSCTL(RXDWA | RXCKS | SET_MDCDIV(MDC_FREQ_TO_DIV(CONFIG_PHY_CLOCK_FREQ)));
/* turn on auto-negotiation and wait for link to come up */ /* turn on auto-negotiation and wait for link to come up */
bfin_miiphy_write(dev->name, CONFIG_PHY_ADDR, MII_BMCR, BMCR_ANENABLE); bfin_miiphy_write(mdiodev, CONFIG_PHY_ADDR, MDIO_DEVAD_NONE, MII_BMCR,
BMCR_ANENABLE);
count = 0; count = 0;
while (1) { while (1) {
++count; ++count;
if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_BMSR, &phydat)) phydat = bfin_miiphy_read(mdiodev, CONFIG_PHY_ADDR,
return -1; MDIO_DEVAD_NONE, MII_BMSR);
if (phydat < 0)
return phydat;
if (phydat & BMSR_LSTATUS) if (phydat & BMSR_LSTATUS)
break; break;
if (count > 30000) { if (count > 30000) {
@ -252,8 +271,10 @@ static int bfin_miiphy_init(struct eth_device *dev, int *opmode)
} }
/* see what kind of link we have */ /* see what kind of link we have */
if (bfin_miiphy_read(dev->name, CONFIG_PHY_ADDR, MII_LPA, &phydat)) phydat = bfin_miiphy_read(mdiodev, CONFIG_PHY_ADDR, MDIO_DEVAD_NONE,
return -1; MII_LPA);
if (phydat < 0)
return phydat;
if (phydat & LPA_DUPLEX) if (phydat & LPA_DUPLEX)
*opmode = FDMODE; *opmode = FDMODE;
else else

View file

@ -243,11 +243,10 @@ int davinci_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data)
if (tmp & MDIO_USERACCESS0_ACK) { if (tmp & MDIO_USERACCESS0_ACK) {
*data = tmp & 0xffff; *data = tmp & 0xffff;
return(1); return 0;
} }
*data = -1; return -EIO;
return(0);
} }
/* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */ /* Write to a PHY register via MDIO inteface. Blocks until operation is complete. */
@ -268,7 +267,7 @@ int davinci_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data)
while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO)
; ;
return(1); return 0;
} }
/* PHY functions for a generic PHY */ /* PHY functions for a generic PHY */
@ -390,14 +389,20 @@ static int gen_auto_negotiate(int phy_addr)
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
static int davinci_mii_phy_read(const char *devname, unsigned char addr, unsigned char reg, unsigned short *value) static int davinci_mii_phy_read(struct mii_dev *bus, int addr, int devad,
int reg)
{ {
return(davinci_eth_phy_read(addr, reg, value) ? 0 : 1); unsigned short value = 0;
int retval = davinci_eth_phy_read(addr, reg, &value);
if (retval < 0)
return retval;
return value;
} }
static int davinci_mii_phy_write(const char *devname, unsigned char addr, unsigned char reg, unsigned short value) static int davinci_mii_phy_write(struct mii_dev *bus, int addr, int devad,
int reg, u16 value)
{ {
return(davinci_eth_phy_write(addr, reg, value) ? 0 : 1); return davinci_eth_phy_write(addr, reg, value);
} }
#endif #endif
@ -883,8 +888,17 @@ int davinci_emac_initialize(void)
debug("Ethernet PHY: %s\n", phy[i].name); debug("Ethernet PHY: %s\n", phy[i].name);
miiphy_register(phy[i].name, davinci_mii_phy_read, int retval;
davinci_mii_phy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, phy[i].name, MDIO_NAME_LEN);
mdiodev->read = davinci_mii_phy_read;
mdiodev->write = davinci_mii_phy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
} }
#if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \ #if defined(CONFIG_DRIVER_TI_EMAC_USE_RMII) && \

View file

@ -5513,7 +5513,8 @@ static int do_e1000(cmd_tbl_t *cmdtp, int flag,
struct udevice *dev; struct udevice *dev;
char name[30]; char name[30];
int ret; int ret;
#else #endif
#if !defined(CONFIG_DM_ETH) || defined(CONFIG_E1000_SPI)
struct e1000_hw *hw; struct e1000_hw *hw;
#endif #endif
int cardnum; int cardnum;
@ -5549,6 +5550,9 @@ static int do_e1000(cmd_tbl_t *cmdtp, int flag,
} }
#ifdef CONFIG_E1000_SPI #ifdef CONFIG_E1000_SPI
#ifdef CONFIG_DM_ETH
hw = dev_get_priv(dev);
#endif
/* Handle the "SPI" subcommand */ /* Handle the "SPI" subcommand */
if (!strcmp(argv[2], "spi")) if (!strcmp(argv[2], "spi"))
return do_e1000_spi(cmdtp, hw, argc - 3, argv + 3); return do_e1000_spi(cmdtp, hw, argc - 3, argv + 3);

View file

@ -94,17 +94,17 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
/* Make sure it has an SPI chip */ /* Make sure it has an SPI chip */
if (hw->eeprom.type != e1000_eeprom_spi) { if (hw->eeprom.type != e1000_eeprom_spi) {
E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n"); E1000_ERR(hw, "No attached SPI EEPROM found!\n");
return NULL; return NULL;
} }
/* Argument sanity checks */ /* Argument sanity checks */
if (cs != 0) { if (cs != 0) {
E1000_ERR(hw->nic, "No such SPI chip: %u\n", cs); E1000_ERR(hw, "No such SPI chip: %u\n", cs);
return NULL; return NULL;
} }
if (mode != SPI_MODE_0) { if (mode != SPI_MODE_0) {
E1000_ERR(hw->nic, "Only SPI MODE-0 is supported!\n"); E1000_ERR(hw, "Only SPI MODE-0 is supported!\n");
return NULL; return NULL;
} }
@ -124,7 +124,7 @@ int spi_claim_bus(struct spi_slave *spi)
struct e1000_hw *hw = e1000_hw_from_spi(spi); struct e1000_hw *hw = e1000_hw_from_spi(spi);
if (e1000_acquire_eeprom(hw)) { if (e1000_acquire_eeprom(hw)) {
E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
return -1; return -1;
} }
@ -342,41 +342,41 @@ static int do_e1000_spi_show(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
/* Extra sanity checks */ /* Extra sanity checks */
if (!length) { if (!length) {
E1000_ERR(hw->nic, "Requested zero-sized dump!\n"); E1000_ERR(hw, "Requested zero-sized dump!\n");
return 1; return 1;
} }
if ((0x10000 < length) || (0x10000 - length < offset)) { if ((0x10000 < length) || (0x10000 - length < offset)) {
E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n"); E1000_ERR(hw, "Can't dump past 0xFFFF!\n");
return 1; return 1;
} }
/* Allocate a buffer to hold stuff */ /* Allocate a buffer to hold stuff */
buffer = malloc(length); buffer = malloc(length);
if (!buffer) { if (!buffer) {
E1000_ERR(hw->nic, "Out of Memory!\n"); E1000_ERR(hw, "Out of Memory!\n");
return 1; return 1;
} }
/* Acquire the EEPROM and perform the dump */ /* Acquire the EEPROM and perform the dump */
if (e1000_acquire_eeprom(hw)) { if (e1000_acquire_eeprom(hw)) {
E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
free(buffer); free(buffer);
return 1; return 1;
} }
err = e1000_spi_eeprom_dump(hw, buffer, offset, length, true); err = e1000_spi_eeprom_dump(hw, buffer, offset, length, true);
e1000_release_eeprom(hw); e1000_release_eeprom(hw);
if (err) { if (err) {
E1000_ERR(hw->nic, "Interrupted!\n"); E1000_ERR(hw, "Interrupted!\n");
free(buffer); free(buffer);
return 1; return 1;
} }
/* Now hexdump the result */ /* Now hexdump the result */
printf("%s: ===== Intel e1000 EEPROM (0x%04hX - 0x%04hX) =====", printf("%s: ===== Intel e1000 EEPROM (0x%04hX - 0x%04hX) =====",
hw->nic->name, offset, offset + length - 1); hw->name, offset, offset + length - 1);
for (i = 0; i < length; i++) { for (i = 0; i < length; i++) {
if ((i & 0xF) == 0) if ((i & 0xF) == 0)
printf("\n%s: %04hX: ", hw->nic->name, offset + i); printf("\n%s: %04hX: ", hw->name, offset + i);
else if ((i & 0xF) == 0x8) else if ((i & 0xF) == 0x8)
printf(" "); printf(" ");
printf(" %02hx", buffer[i]); printf(" %02hx", buffer[i]);
@ -407,29 +407,29 @@ static int do_e1000_spi_dump(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
/* Extra sanity checks */ /* Extra sanity checks */
if (!length) { if (!length) {
E1000_ERR(hw->nic, "Requested zero-sized dump!\n"); E1000_ERR(hw, "Requested zero-sized dump!\n");
return 1; return 1;
} }
if ((0x10000 < length) || (0x10000 - length < offset)) { if ((0x10000 < length) || (0x10000 - length < offset)) {
E1000_ERR(hw->nic, "Can't dump past 0xFFFF!\n"); E1000_ERR(hw, "Can't dump past 0xFFFF!\n");
return 1; return 1;
} }
/* Acquire the EEPROM */ /* Acquire the EEPROM */
if (e1000_acquire_eeprom(hw)) { if (e1000_acquire_eeprom(hw)) {
E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
return 1; return 1;
} }
/* Perform the programming operation */ /* Perform the programming operation */
if (e1000_spi_eeprom_dump(hw, dest, offset, length, true) < 0) { if (e1000_spi_eeprom_dump(hw, dest, offset, length, true) < 0) {
E1000_ERR(hw->nic, "Interrupted!\n"); E1000_ERR(hw, "Interrupted!\n");
e1000_release_eeprom(hw); e1000_release_eeprom(hw);
return 1; return 1;
} }
e1000_release_eeprom(hw); e1000_release_eeprom(hw);
printf("%s: ===== EEPROM DUMP COMPLETE =====\n", hw->nic->name); printf("%s: ===== EEPROM DUMP COMPLETE =====\n", hw->name);
return 0; return 0;
} }
@ -452,19 +452,19 @@ static int do_e1000_spi_program(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
/* Acquire the EEPROM */ /* Acquire the EEPROM */
if (e1000_acquire_eeprom(hw)) { if (e1000_acquire_eeprom(hw)) {
E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
return 1; return 1;
} }
/* Perform the programming operation */ /* Perform the programming operation */
if (e1000_spi_eeprom_program(hw, source, offset, length, true) < 0) { if (e1000_spi_eeprom_program(hw, source, offset, length, true) < 0) {
E1000_ERR(hw->nic, "Interrupted!\n"); E1000_ERR(hw, "Interrupted!\n");
e1000_release_eeprom(hw); e1000_release_eeprom(hw);
return 1; return 1;
} }
e1000_release_eeprom(hw); e1000_release_eeprom(hw);
printf("%s: ===== EEPROM PROGRAMMED =====\n", hw->nic->name); printf("%s: ===== EEPROM PROGRAMMED =====\n", hw->name);
return 0; return 0;
} }
@ -488,19 +488,19 @@ static int do_e1000_spi_checksum(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
length = sizeof(uint16_t) * (EEPROM_CHECKSUM_REG + 1); length = sizeof(uint16_t) * (EEPROM_CHECKSUM_REG + 1);
buffer = malloc(length); buffer = malloc(length);
if (!buffer) { if (!buffer) {
E1000_ERR(hw->nic, "Unable to allocate EEPROM buffer!\n"); E1000_ERR(hw, "Unable to allocate EEPROM buffer!\n");
return 1; return 1;
} }
/* Acquire the EEPROM */ /* Acquire the EEPROM */
if (e1000_acquire_eeprom(hw)) { if (e1000_acquire_eeprom(hw)) {
E1000_ERR(hw->nic, "EEPROM SPI cannot be acquired!\n"); E1000_ERR(hw, "EEPROM SPI cannot be acquired!\n");
return 1; return 1;
} }
/* Read the EEPROM */ /* Read the EEPROM */
if (e1000_spi_eeprom_dump(hw, buffer, 0, length, true) < 0) { if (e1000_spi_eeprom_dump(hw, buffer, 0, length, true) < 0) {
E1000_ERR(hw->nic, "Interrupted!\n"); E1000_ERR(hw, "Interrupted!\n");
e1000_release_eeprom(hw); e1000_release_eeprom(hw);
return 1; return 1;
} }
@ -514,15 +514,15 @@ static int do_e1000_spi_checksum(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
/* Verify it! */ /* Verify it! */
if (checksum_reg == checksum) { if (checksum_reg == checksum) {
printf("%s: INFO: EEPROM checksum is correct! (0x%04hx)\n", printf("%s: INFO: EEPROM checksum is correct! (0x%04hx)\n",
hw->nic->name, checksum); hw->name, checksum);
e1000_release_eeprom(hw); e1000_release_eeprom(hw);
return 0; return 0;
} }
/* Hrm, verification failed, print an error */ /* Hrm, verification failed, print an error */
E1000_ERR(hw->nic, "EEPROM checksum is incorrect!\n"); E1000_ERR(hw, "EEPROM checksum is incorrect!\n");
E1000_ERR(hw->nic, " ...register was 0x%04hx, calculated 0x%04hx\n", E1000_ERR(hw, " ...register was 0x%04hx, calculated 0x%04hx\n",
checksum_reg, checksum); checksum_reg, checksum);
/* If they didn't ask us to update it, just return an error */ /* If they didn't ask us to update it, just return an error */
if (!upd) { if (!upd) {
@ -531,11 +531,11 @@ static int do_e1000_spi_checksum(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
} }
/* Ok, correct it! */ /* Ok, correct it! */
printf("%s: Reprogramming the EEPROM checksum...\n", hw->nic->name); printf("%s: Reprogramming the EEPROM checksum...\n", hw->name);
buffer[i] = cpu_to_le16(checksum); buffer[i] = cpu_to_le16(checksum);
if (e1000_spi_eeprom_program(hw, &buffer[i], i * sizeof(uint16_t), if (e1000_spi_eeprom_program(hw, &buffer[i], i * sizeof(uint16_t),
sizeof(uint16_t), true)) { sizeof(uint16_t), true)) {
E1000_ERR(hw->nic, "Interrupted!\n"); E1000_ERR(hw, "Interrupted!\n");
e1000_release_eeprom(hw); e1000_release_eeprom(hw);
return 1; return 1;
} }
@ -554,7 +554,8 @@ int do_e1000_spi(cmd_tbl_t *cmdtp, struct e1000_hw *hw,
/* Make sure it has an SPI chip */ /* Make sure it has an SPI chip */
if (hw->eeprom.type != e1000_eeprom_spi) { if (hw->eeprom.type != e1000_eeprom_spi) {
E1000_ERR(hw->nic, "No attached SPI EEPROM found!\n"); E1000_ERR(hw, "No attached SPI EEPROM found (%d)!\n",
hw->eeprom.type);
return 1; return 1;
} }

View file

@ -334,34 +334,35 @@ static struct eth_device* verify_phyaddr (const char *devname,
return dev; return dev;
} }
static int eepro100_miiphy_read(const char *devname, unsigned char addr, static int eepro100_miiphy_read(struct mii_dev *bus, int addr, int devad,
unsigned char reg, unsigned short *value) int reg)
{ {
unsigned short value = 0;
struct eth_device *dev; struct eth_device *dev;
dev = verify_phyaddr(devname, addr); dev = verify_phyaddr(bus->name, addr);
if (dev == NULL) if (dev == NULL)
return -1; return -1;
if (get_phyreg(dev, addr, reg, value) != 0) { if (get_phyreg(dev, addr, reg, &value) != 0) {
printf("%s: mii read timeout!\n", devname); printf("%s: mii read timeout!\n", bus->name);
return -1; return -1;
} }
return 0; return value;
} }
static int eepro100_miiphy_write(const char *devname, unsigned char addr, static int eepro100_miiphy_write(struct mii_dev *bus, int addr, int devad,
unsigned char reg, unsigned short value) int reg, u16 value)
{ {
struct eth_device *dev; struct eth_device *dev;
dev = verify_phyaddr(devname, addr); dev = verify_phyaddr(bus->name, addr);
if (dev == NULL) if (dev == NULL)
return -1; return -1;
if (set_phyreg(dev, addr, reg, value) != 0) { if (set_phyreg(dev, addr, reg, value) != 0) {
printf("%s: mii write timeout!\n", devname); printf("%s: mii write timeout!\n", bus->name);
return -1; return -1;
} }
@ -451,8 +452,17 @@ int eepro100_initialize (bd_t * bis)
#if defined (CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined (CONFIG_MII) || defined(CONFIG_CMD_MII)
/* register mii command access routines */ /* register mii command access routines */
miiphy_register(dev->name, int retval;
eepro100_miiphy_read, eepro100_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = eepro100_miiphy_read;
mdiodev->write = eepro100_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
card_number++; card_number++;

View file

@ -742,9 +742,10 @@ static int enc_initcheck(enc_dev_t *enc, const enum enc_initstate requiredstate)
* *
* This function is registered with miiphy_register(). * This function is registered with miiphy_register().
*/ */
int enc_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value) int enc_miiphy_read(struct mii_dev *bus, int phy_adr, int devad, int reg)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); u16 value = 0;
struct eth_device *dev = eth_get_dev_by_name(bus->name);
enc_dev_t *enc; enc_dev_t *enc;
if (!dev || phy_adr != 0) if (!dev || phy_adr != 0)
@ -757,9 +758,9 @@ int enc_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
enc_release_bus(enc); enc_release_bus(enc);
return -1; return -1;
} }
*value = enc_phy_read(enc, reg); value = enc_phy_read(enc, reg);
enc_release_bus(enc); enc_release_bus(enc);
return 0; return value;
} }
/* /*
@ -767,9 +768,10 @@ int enc_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value)
* *
* This function is registered with miiphy_register(). * This function is registered with miiphy_register().
*/ */
int enc_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) int enc_miiphy_write(struct mii_dev *bus, int phy_adr, int devad, int reg,
u16 value)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); struct eth_device *dev = eth_get_dev_by_name(bus->name);
enc_dev_t *enc; enc_dev_t *enc;
if (!dev || phy_adr != 0) if (!dev || phy_adr != 0)
@ -958,7 +960,17 @@ int enc28j60_initialize(unsigned int bus, unsigned int cs,
sprintf(dev->name, "enc%i.%i", bus, cs); sprintf(dev->name, "enc%i.%i", bus, cs);
eth_register(dev); eth_register(dev);
#if defined(CONFIG_CMD_MII) #if defined(CONFIG_CMD_MII)
miiphy_register(dev->name, enc_miiphy_read, enc_miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = enc_miiphy_read;
mdiodev->write = enc_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
return 0; return 0;
} }

View file

@ -30,10 +30,10 @@
#define GET_REGS(eth_dev) (GET_PRIV(eth_dev)->regs) #define GET_REGS(eth_dev) (GET_PRIV(eth_dev)->regs)
/* ep93xx_miiphy ops forward declarations */ /* ep93xx_miiphy ops forward declarations */
static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr, static int ep93xx_miiphy_read(struct mii_dev *bus, int addr, int devad,
unsigned char const reg, unsigned short * const value); int reg);
static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr, static int ep93xx_miiphy_write(struct mii_dev *bus, int addr, int devad,
unsigned char const reg, unsigned short const value); int reg, u16 value);
#if defined(EP93XX_MAC_DEBUG) #if defined(EP93XX_MAC_DEBUG)
/** /**
@ -421,7 +421,17 @@ eth_send_out:
#if defined(CONFIG_MII) #if defined(CONFIG_MII)
int ep93xx_miiphy_initialize(bd_t * const bd) int ep93xx_miiphy_initialize(bd_t * const bd)
{ {
miiphy_register("ep93xx_eth0", ep93xx_miiphy_read, ep93xx_miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, "ep93xx_eth0", MDIO_NAME_LEN);
mdiodev->read = ep93xx_miiphy_read;
mdiodev->write = ep93xx_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
return 0; return 0;
} }
#endif #endif
@ -542,9 +552,10 @@ eth_init_done:
/** /**
* Read a 16-bit value from an MII register. * Read a 16-bit value from an MII register.
*/ */
static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr, static int ep93xx_miiphy_read(struct mii_dev *bus, int addr, int devad,
unsigned char const reg, unsigned short * const value) int reg)
{ {
unsigned short value = 0;
struct mac_regs *mac = (struct mac_regs *)MAC_BASE; struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
int ret = -1; int ret = -1;
uint32_t self_ctl; uint32_t self_ctl;
@ -552,10 +563,9 @@ static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
debug("+ep93xx_miiphy_read"); debug("+ep93xx_miiphy_read");
/* Parameter checks */ /* Parameter checks */
BUG_ON(dev == NULL); BUG_ON(bus->name == NULL);
BUG_ON(addr > MII_ADDRESS_MAX); BUG_ON(addr > MII_ADDRESS_MAX);
BUG_ON(reg > MII_REGISTER_MAX); BUG_ON(reg > MII_REGISTER_MAX);
BUG_ON(value == NULL);
/* /*
* Save the current SelfCTL register value. Set MAC to suppress * Save the current SelfCTL register value. Set MAC to suppress
@ -579,7 +589,7 @@ static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
while (readl(&mac->miists) & MIISTS_BUSY) while (readl(&mac->miists) & MIISTS_BUSY)
; /* noop */ ; /* noop */
*value = (unsigned short)readl(&mac->miidata); value = (unsigned short)readl(&mac->miidata);
/* Restore the saved SelfCTL value and return. */ /* Restore the saved SelfCTL value and return. */
writel(self_ctl, &mac->selfctl); writel(self_ctl, &mac->selfctl);
@ -588,14 +598,16 @@ static int ep93xx_miiphy_read(const char * const dev, unsigned char const addr,
/* Fall through */ /* Fall through */
debug("-ep93xx_miiphy_read"); debug("-ep93xx_miiphy_read");
return ret; if (ret < 0)
return ret;
return value;
} }
/** /**
* Write a 16-bit value to an MII register. * Write a 16-bit value to an MII register.
*/ */
static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr, static int ep93xx_miiphy_write(struct mii_dev *bus, int addr, int devad,
unsigned char const reg, unsigned short const value) int reg, u16 value)
{ {
struct mac_regs *mac = (struct mac_regs *)MAC_BASE; struct mac_regs *mac = (struct mac_regs *)MAC_BASE;
int ret = -1; int ret = -1;
@ -604,7 +616,7 @@ static int ep93xx_miiphy_write(const char * const dev, unsigned char const addr,
debug("+ep93xx_miiphy_write"); debug("+ep93xx_miiphy_write");
/* Parameter checks */ /* Parameter checks */
BUG_ON(dev == NULL); BUG_ON(bus->name == NULL);
BUG_ON(addr > MII_ADDRESS_MAX); BUG_ON(addr > MII_ADDRESS_MAX);
BUG_ON(reg > MII_REGISTER_MAX); BUG_ON(reg > MII_REGISTER_MAX);

View file

@ -5,19 +5,20 @@
* Copyright (C) 2008-2009 Avionic Design GmbH * Copyright (C) 2008-2009 Avionic Design GmbH
* Thierry Reding <thierry.reding@avionic-design.de> * Thierry Reding <thierry.reding@avionic-design.de>
* Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw> * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
* Copyright (C) 2016 Cadence Design Systems Inc.
* *
* This program is free software; you can redistribute it and/or modify * SPDX-License-Identifier: GPL-2.0
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/ */
#include <common.h> #include <common.h>
#include <command.h> #include <dm/device.h>
#include <dm/platform_data/net_ethoc.h>
#include <linux/io.h>
#include <malloc.h> #include <malloc.h>
#include <net.h> #include <net.h>
#include <miiphy.h> #include <miiphy.h>
#include <asm/io.h>
#include <asm/cache.h> #include <asm/cache.h>
#include <wait_bit.h>
/* register offsets */ /* register offsets */
#define MODER 0x00 #define MODER 0x00
@ -162,6 +163,7 @@
#define ETHOC_BD_BASE 0x400 #define ETHOC_BD_BASE 0x400
#define ETHOC_TIMEOUT (HZ / 2) #define ETHOC_TIMEOUT (HZ / 2)
#define ETHOC_MII_TIMEOUT (1 + (HZ / 5)) #define ETHOC_MII_TIMEOUT (1 + (HZ / 5))
#define ETHOC_IOSIZE 0x54
/** /**
* struct ethoc - driver-private device structure * struct ethoc - driver-private device structure
@ -177,6 +179,14 @@ struct ethoc {
u32 dty_tx; u32 dty_tx;
u32 num_rx; u32 num_rx;
u32 cur_rx; u32 cur_rx;
void __iomem *iobase;
void __iomem *packet;
phys_addr_t packet_phys;
#ifdef CONFIG_PHYLIB
struct mii_dev *bus;
struct phy_device *phydev;
#endif
}; };
/** /**
@ -189,65 +199,68 @@ struct ethoc_bd {
u32 addr; u32 addr;
}; };
static inline u32 ethoc_read(struct eth_device *dev, size_t offset) static inline u32 *ethoc_reg(struct ethoc *priv, size_t offset)
{ {
return readl(dev->iobase + offset); return priv->iobase + offset;
} }
static inline void ethoc_write(struct eth_device *dev, size_t offset, u32 data) static inline u32 ethoc_read(struct ethoc *priv, size_t offset)
{ {
writel(data, dev->iobase + offset); return readl(ethoc_reg(priv, offset));
} }
static inline void ethoc_read_bd(struct eth_device *dev, int index, static inline void ethoc_write(struct ethoc *priv, size_t offset, u32 data)
{
writel(data, ethoc_reg(priv, offset));
}
static inline void ethoc_read_bd(struct ethoc *priv, int index,
struct ethoc_bd *bd) struct ethoc_bd *bd)
{ {
size_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd)); size_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
bd->stat = ethoc_read(dev, offset + 0); bd->stat = ethoc_read(priv, offset + 0);
bd->addr = ethoc_read(dev, offset + 4); bd->addr = ethoc_read(priv, offset + 4);
} }
static inline void ethoc_write_bd(struct eth_device *dev, int index, static inline void ethoc_write_bd(struct ethoc *priv, int index,
const struct ethoc_bd *bd) const struct ethoc_bd *bd)
{ {
size_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd)); size_t offset = ETHOC_BD_BASE + (index * sizeof(struct ethoc_bd));
ethoc_write(dev, offset + 0, bd->stat); ethoc_write(priv, offset + 0, bd->stat);
ethoc_write(dev, offset + 4, bd->addr); ethoc_write(priv, offset + 4, bd->addr);
} }
static int ethoc_set_mac_address(struct eth_device *dev) static int ethoc_write_hwaddr_common(struct ethoc *priv, u8 *mac)
{ {
u8 *mac = dev->enetaddr; ethoc_write(priv, MAC_ADDR0, (mac[2] << 24) | (mac[3] << 16) |
ethoc_write(dev, MAC_ADDR0, (mac[2] << 24) | (mac[3] << 16) |
(mac[4] << 8) | (mac[5] << 0)); (mac[4] << 8) | (mac[5] << 0));
ethoc_write(dev, MAC_ADDR1, (mac[0] << 8) | (mac[1] << 0)); ethoc_write(priv, MAC_ADDR1, (mac[0] << 8) | (mac[1] << 0));
return 0; return 0;
} }
static inline void ethoc_ack_irq(struct eth_device *dev, u32 mask) static inline void ethoc_ack_irq(struct ethoc *priv, u32 mask)
{ {
ethoc_write(dev, INT_SOURCE, mask); ethoc_write(priv, INT_SOURCE, mask);
} }
static inline void ethoc_enable_rx_and_tx(struct eth_device *dev) static inline void ethoc_enable_rx_and_tx(struct ethoc *priv)
{ {
u32 mode = ethoc_read(dev, MODER); u32 mode = ethoc_read(priv, MODER);
mode |= MODER_RXEN | MODER_TXEN; mode |= MODER_RXEN | MODER_TXEN;
ethoc_write(dev, MODER, mode); ethoc_write(priv, MODER, mode);
} }
static inline void ethoc_disable_rx_and_tx(struct eth_device *dev) static inline void ethoc_disable_rx_and_tx(struct ethoc *priv)
{ {
u32 mode = ethoc_read(dev, MODER); u32 mode = ethoc_read(priv, MODER);
mode &= ~(MODER_RXEN | MODER_TXEN); mode &= ~(MODER_RXEN | MODER_TXEN);
ethoc_write(dev, MODER, mode); ethoc_write(priv, MODER, mode);
} }
static int ethoc_init_ring(struct eth_device *dev) static int ethoc_init_ring(struct ethoc *priv)
{ {
struct ethoc *priv = (struct ethoc *)dev->priv;
struct ethoc_bd bd; struct ethoc_bd bd;
phys_addr_t addr = priv->packet_phys;
int i; int i;
priv->cur_tx = 0; priv->cur_tx = 0;
@ -256,66 +269,92 @@ static int ethoc_init_ring(struct eth_device *dev)
/* setup transmission buffers */ /* setup transmission buffers */
bd.stat = TX_BD_IRQ | TX_BD_CRC; bd.stat = TX_BD_IRQ | TX_BD_CRC;
bd.addr = 0;
for (i = 0; i < priv->num_tx; i++) { for (i = 0; i < priv->num_tx; i++) {
if (addr) {
bd.addr = addr;
addr += PKTSIZE_ALIGN;
}
if (i == priv->num_tx - 1) if (i == priv->num_tx - 1)
bd.stat |= TX_BD_WRAP; bd.stat |= TX_BD_WRAP;
ethoc_write_bd(dev, i, &bd); ethoc_write_bd(priv, i, &bd);
} }
bd.stat = RX_BD_EMPTY | RX_BD_IRQ; bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
for (i = 0; i < priv->num_rx; i++) { for (i = 0; i < priv->num_rx; i++) {
bd.addr = (u32)net_rx_packets[i]; if (addr) {
bd.addr = addr;
addr += PKTSIZE_ALIGN;
} else {
bd.addr = virt_to_phys(net_rx_packets[i]);
}
if (i == priv->num_rx - 1) if (i == priv->num_rx - 1)
bd.stat |= RX_BD_WRAP; bd.stat |= RX_BD_WRAP;
flush_dcache_range(bd.addr, bd.addr + PKTSIZE_ALIGN); flush_dcache_range((ulong)net_rx_packets[i],
ethoc_write_bd(dev, priv->num_tx + i, &bd); (ulong)net_rx_packets[i] + PKTSIZE_ALIGN);
ethoc_write_bd(priv, priv->num_tx + i, &bd);
} }
return 0; return 0;
} }
static int ethoc_reset(struct eth_device *dev) static int ethoc_reset(struct ethoc *priv)
{ {
u32 mode; u32 mode;
/* TODO: reset controller? */ /* TODO: reset controller? */
ethoc_disable_rx_and_tx(dev); ethoc_disable_rx_and_tx(priv);
/* TODO: setup registers */ /* TODO: setup registers */
/* enable FCS generation and automatic padding */ /* enable FCS generation and automatic padding */
mode = ethoc_read(dev, MODER); mode = ethoc_read(priv, MODER);
mode |= MODER_CRC | MODER_PAD; mode |= MODER_CRC | MODER_PAD;
ethoc_write(dev, MODER, mode); ethoc_write(priv, MODER, mode);
/* set full-duplex mode */ /* set full-duplex mode */
mode = ethoc_read(dev, MODER); mode = ethoc_read(priv, MODER);
mode |= MODER_FULLD; mode |= MODER_FULLD;
ethoc_write(dev, MODER, mode); ethoc_write(priv, MODER, mode);
ethoc_write(dev, IPGT, 0x15); ethoc_write(priv, IPGT, 0x15);
ethoc_ack_irq(dev, INT_MASK_ALL); ethoc_ack_irq(priv, INT_MASK_ALL);
ethoc_enable_rx_and_tx(dev); ethoc_enable_rx_and_tx(priv);
return 0; return 0;
} }
static int ethoc_init(struct eth_device *dev, bd_t * bd) static int ethoc_init_common(struct ethoc *priv)
{ {
struct ethoc *priv = (struct ethoc *)dev->priv; int ret = 0;
printf("ethoc\n");
priv->num_tx = 1; priv->num_tx = 1;
priv->num_rx = PKTBUFSRX; priv->num_rx = PKTBUFSRX;
ethoc_write(dev, TX_BD_NUM, priv->num_tx); ethoc_write(priv, TX_BD_NUM, priv->num_tx);
ethoc_init_ring(dev); ethoc_init_ring(priv);
ethoc_reset(dev); ethoc_reset(priv);
return 0; #ifdef CONFIG_PHYLIB
ret = phy_startup(priv->phydev);
if (ret) {
printf("Could not initialize PHY %s\n",
priv->phydev->dev->name);
return ret;
}
#endif
return ret;
}
static void ethoc_stop_common(struct ethoc *priv)
{
ethoc_disable_rx_and_tx(priv);
#ifdef CONFIG_PHYLIB
phy_shutdown(priv->phydev);
#endif
} }
static int ethoc_update_rx_stats(struct ethoc_bd *bd) static int ethoc_update_rx_stats(struct ethoc_bd *bd)
@ -353,37 +392,46 @@ static int ethoc_update_rx_stats(struct ethoc_bd *bd)
return ret; return ret;
} }
static int ethoc_rx(struct eth_device *dev, int limit) static int ethoc_rx_common(struct ethoc *priv, uchar **packetp)
{ {
struct ethoc *priv = (struct ethoc *)dev->priv; struct ethoc_bd bd;
int count; u32 i = priv->cur_rx % priv->num_rx;
u32 entry = priv->num_tx + i;
for (count = 0; count < limit; ++count) { ethoc_read_bd(priv, entry, &bd);
u32 entry; if (bd.stat & RX_BD_EMPTY)
struct ethoc_bd bd; return -EAGAIN;
entry = priv->num_tx + (priv->cur_rx % priv->num_rx); debug("%s(): RX buffer %d, %x received\n",
ethoc_read_bd(dev, entry, &bd); __func__, priv->cur_rx, bd.stat);
if (bd.stat & RX_BD_EMPTY) if (ethoc_update_rx_stats(&bd) == 0) {
break; int size = bd.stat >> 16;
debug("%s(): RX buffer %d, %x received\n", size -= 4; /* strip the CRC */
__func__, priv->cur_rx, bd.stat); if (priv->packet)
if (ethoc_update_rx_stats(&bd) == 0) { *packetp = priv->packet + entry * PKTSIZE_ALIGN;
int size = bd.stat >> 16; else
size -= 4; /* strip the CRC */ *packetp = net_rx_packets[i];
net_process_received_packet((void *)bd.addr, size); return size;
} } else {
return 0;
}
}
/* clear the buffer descriptor so it can be reused */ static int ethoc_is_new_packet_received(struct ethoc *priv)
flush_dcache_range(bd.addr, bd.addr + PKTSIZE_ALIGN); {
bd.stat &= ~RX_BD_STATS; u32 pending;
bd.stat |= RX_BD_EMPTY;
ethoc_write_bd(dev, entry, &bd); pending = ethoc_read(priv, INT_SOURCE);
priv->cur_rx++; ethoc_ack_irq(priv, pending);
if (pending & INT_MASK_BUSY)
debug("%s(): packet dropped\n", __func__);
if (pending & INT_MASK_RX) {
debug("%s(): rx irq\n", __func__);
return 1;
} }
return count; return 0;
} }
static int ethoc_update_tx_stats(struct ethoc_bd *bd) static int ethoc_update_tx_stats(struct ethoc_bd *bd)
@ -403,52 +451,57 @@ static int ethoc_update_tx_stats(struct ethoc_bd *bd)
return 0; return 0;
} }
static void ethoc_tx(struct eth_device *dev) static void ethoc_tx(struct ethoc *priv)
{ {
struct ethoc *priv = (struct ethoc *)dev->priv;
u32 entry = priv->dty_tx % priv->num_tx; u32 entry = priv->dty_tx % priv->num_tx;
struct ethoc_bd bd; struct ethoc_bd bd;
ethoc_read_bd(dev, entry, &bd); ethoc_read_bd(priv, entry, &bd);
if ((bd.stat & TX_BD_READY) == 0) if ((bd.stat & TX_BD_READY) == 0)
(void)ethoc_update_tx_stats(&bd); (void)ethoc_update_tx_stats(&bd);
} }
static int ethoc_send(struct eth_device *dev, void *packet, int length) static int ethoc_send_common(struct ethoc *priv, void *packet, int length)
{ {
struct ethoc *priv = (struct ethoc *)dev->priv;
struct ethoc_bd bd; struct ethoc_bd bd;
u32 entry; u32 entry;
u32 pending; u32 pending;
int tmo; int tmo;
entry = priv->cur_tx % priv->num_tx; entry = priv->cur_tx % priv->num_tx;
ethoc_read_bd(dev, entry, &bd); ethoc_read_bd(priv, entry, &bd);
if (unlikely(length < ETHOC_ZLEN)) if (unlikely(length < ETHOC_ZLEN))
bd.stat |= TX_BD_PAD; bd.stat |= TX_BD_PAD;
else else
bd.stat &= ~TX_BD_PAD; bd.stat &= ~TX_BD_PAD;
bd.addr = (u32)packet;
flush_dcache_range(bd.addr, bd.addr + length); if (priv->packet) {
void *p = priv->packet + entry * PKTSIZE_ALIGN;
memcpy(p, packet, length);
packet = p;
} else {
bd.addr = virt_to_phys(packet);
}
flush_dcache_range((ulong)packet, (ulong)packet + length);
bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK); bd.stat &= ~(TX_BD_STATS | TX_BD_LEN_MASK);
bd.stat |= TX_BD_LEN(length); bd.stat |= TX_BD_LEN(length);
ethoc_write_bd(dev, entry, &bd); ethoc_write_bd(priv, entry, &bd);
/* start transmit */ /* start transmit */
bd.stat |= TX_BD_READY; bd.stat |= TX_BD_READY;
ethoc_write_bd(dev, entry, &bd); ethoc_write_bd(priv, entry, &bd);
/* wait for transfer to succeed */ /* wait for transfer to succeed */
tmo = get_timer(0) + 5 * CONFIG_SYS_HZ; tmo = get_timer(0) + 5 * CONFIG_SYS_HZ;
while (1) { while (1) {
pending = ethoc_read(dev, INT_SOURCE); pending = ethoc_read(priv, INT_SOURCE);
ethoc_ack_irq(dev, pending & ~INT_MASK_RX); ethoc_ack_irq(priv, pending & ~INT_MASK_RX);
if (pending & INT_MASK_BUSY) if (pending & INT_MASK_BUSY)
debug("%s(): packet dropped\n", __func__); debug("%s(): packet dropped\n", __func__);
if (pending & INT_MASK_TX) { if (pending & INT_MASK_TX) {
ethoc_tx(dev); ethoc_tx(priv);
break; break;
} }
if (get_timer(0) >= tmo) { if (get_timer(0) >= tmo) {
@ -461,24 +514,290 @@ static int ethoc_send(struct eth_device *dev, void *packet, int length)
return 0; return 0;
} }
static int ethoc_free_pkt_common(struct ethoc *priv)
{
struct ethoc_bd bd;
u32 i = priv->cur_rx % priv->num_rx;
u32 entry = priv->num_tx + i;
void *src;
ethoc_read_bd(priv, entry, &bd);
if (priv->packet)
src = priv->packet + entry * PKTSIZE_ALIGN;
else
src = net_rx_packets[i];
/* clear the buffer descriptor so it can be reused */
flush_dcache_range((ulong)src,
(ulong)src + PKTSIZE_ALIGN);
bd.stat &= ~RX_BD_STATS;
bd.stat |= RX_BD_EMPTY;
ethoc_write_bd(priv, entry, &bd);
priv->cur_rx++;
return 0;
}
#ifdef CONFIG_PHYLIB
static int ethoc_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
{
struct ethoc *priv = bus->priv;
int rc;
ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(addr, reg));
ethoc_write(priv, MIICOMMAND, MIICOMMAND_READ);
rc = wait_for_bit(__func__, ethoc_reg(priv, MIISTATUS),
MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
if (rc == 0) {
u32 data = ethoc_read(priv, MIIRX_DATA);
/* reset MII command register */
ethoc_write(priv, MIICOMMAND, 0);
return data;
}
return rc;
}
static int ethoc_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
u16 val)
{
struct ethoc *priv = bus->priv;
int rc;
ethoc_write(priv, MIIADDRESS, MIIADDRESS_ADDR(addr, reg));
ethoc_write(priv, MIITX_DATA, val);
ethoc_write(priv, MIICOMMAND, MIICOMMAND_WRITE);
rc = wait_for_bit(__func__, ethoc_reg(priv, MIISTATUS),
MIISTATUS_BUSY, false, CONFIG_SYS_HZ, false);
if (rc == 0) {
/* reset MII command register */
ethoc_write(priv, MIICOMMAND, 0);
}
return rc;
}
static int ethoc_mdio_init(const char *name, struct ethoc *priv)
{
struct mii_dev *bus = mdio_alloc();
int ret;
if (!bus) {
printf("Failed to allocate MDIO bus\n");
return -ENOMEM;
}
bus->read = ethoc_mdio_read;
bus->write = ethoc_mdio_write;
snprintf(bus->name, sizeof(bus->name), "%s", name);
bus->priv = priv;
ret = mdio_register(bus);
if (ret < 0)
return ret;
priv->bus = miiphy_get_dev_by_name(name);
return 0;
}
static int ethoc_phy_init(struct ethoc *priv, void *dev)
{
struct phy_device *phydev;
int mask = 0xffffffff;
#ifdef CONFIG_PHY_ADDR
mask = 1 << CONFIG_PHY_ADDR;
#endif
phydev = phy_find_by_mask(priv->bus, mask, PHY_INTERFACE_MODE_MII);
if (!phydev)
return -ENODEV;
phy_connect_dev(phydev, dev);
phydev->supported &= PHY_BASIC_FEATURES;
phydev->advertising = phydev->supported;
priv->phydev = phydev;
phy_config(phydev);
return 0;
}
#else
static inline int ethoc_mdio_init(const char *name, struct ethoc *priv)
{
return 0;
}
static inline int ethoc_phy_init(struct ethoc *priv, void *dev)
{
return 0;
}
#endif
#ifdef CONFIG_DM_ETH
static int ethoc_write_hwaddr(struct udevice *dev)
{
struct ethoc_eth_pdata *pdata = dev_get_platdata(dev);
struct ethoc *priv = dev_get_priv(dev);
u8 *mac = pdata->eth_pdata.enetaddr;
return ethoc_write_hwaddr_common(priv, mac);
}
static int ethoc_send(struct udevice *dev, void *packet, int length)
{
return ethoc_send_common(dev_get_priv(dev), packet, length);
}
static int ethoc_free_pkt(struct udevice *dev, uchar *packet, int length)
{
return ethoc_free_pkt_common(dev_get_priv(dev));
}
static int ethoc_recv(struct udevice *dev, int flags, uchar **packetp)
{
struct ethoc *priv = dev_get_priv(dev);
if (flags & ETH_RECV_CHECK_DEVICE)
if (!ethoc_is_new_packet_received(priv))
return -EAGAIN;
return ethoc_rx_common(priv, packetp);
}
static int ethoc_start(struct udevice *dev)
{
return ethoc_init_common(dev_get_priv(dev));
}
static void ethoc_stop(struct udevice *dev)
{
ethoc_stop_common(dev_get_priv(dev));
}
static int ethoc_ofdata_to_platdata(struct udevice *dev)
{
struct ethoc_eth_pdata *pdata = dev_get_platdata(dev);
fdt_addr_t addr;
pdata->eth_pdata.iobase = dev_get_addr(dev);
addr = dev_get_addr_index(dev, 1);
if (addr != FDT_ADDR_T_NONE)
pdata->packet_base = addr;
return 0;
}
static int ethoc_probe(struct udevice *dev)
{
struct ethoc_eth_pdata *pdata = dev_get_platdata(dev);
struct ethoc *priv = dev_get_priv(dev);
priv->iobase = ioremap(pdata->eth_pdata.iobase, ETHOC_IOSIZE);
if (pdata->packet_base) {
priv->packet_phys = pdata->packet_base;
priv->packet = ioremap(pdata->packet_base,
(1 + PKTBUFSRX) * PKTSIZE_ALIGN);
}
ethoc_mdio_init(dev->name, priv);
ethoc_phy_init(priv, dev);
return 0;
}
static int ethoc_remove(struct udevice *dev)
{
struct ethoc *priv = dev_get_priv(dev);
#ifdef CONFIG_PHYLIB
free(priv->phydev);
mdio_unregister(priv->bus);
mdio_free(priv->bus);
#endif
iounmap(priv->iobase);
return 0;
}
static const struct eth_ops ethoc_ops = {
.start = ethoc_start,
.stop = ethoc_stop,
.send = ethoc_send,
.recv = ethoc_recv,
.free_pkt = ethoc_free_pkt,
.write_hwaddr = ethoc_write_hwaddr,
};
static const struct udevice_id ethoc_ids[] = {
{ .compatible = "opencores,ethoc" },
{ }
};
U_BOOT_DRIVER(ethoc) = {
.name = "ethoc",
.id = UCLASS_ETH,
.of_match = ethoc_ids,
.ofdata_to_platdata = ethoc_ofdata_to_platdata,
.probe = ethoc_probe,
.remove = ethoc_remove,
.ops = &ethoc_ops,
.priv_auto_alloc_size = sizeof(struct ethoc),
.platdata_auto_alloc_size = sizeof(struct ethoc_eth_pdata),
};
#else
static int ethoc_init(struct eth_device *dev, bd_t *bd)
{
struct ethoc *priv = (struct ethoc *)dev->priv;
return ethoc_init_common(priv);
}
static int ethoc_write_hwaddr(struct eth_device *dev)
{
struct ethoc *priv = (struct ethoc *)dev->priv;
u8 *mac = dev->enetaddr;
return ethoc_write_hwaddr_common(priv, mac);
}
static int ethoc_send(struct eth_device *dev, void *packet, int length)
{
return ethoc_send_common(dev->priv, packet, length);
}
static void ethoc_halt(struct eth_device *dev) static void ethoc_halt(struct eth_device *dev)
{ {
ethoc_disable_rx_and_tx(dev); ethoc_disable_rx_and_tx(dev->priv);
} }
static int ethoc_recv(struct eth_device *dev) static int ethoc_recv(struct eth_device *dev)
{ {
u32 pending; struct ethoc *priv = (struct ethoc *)dev->priv;
int count;
pending = ethoc_read(dev, INT_SOURCE); if (!ethoc_is_new_packet_received(priv))
ethoc_ack_irq(dev, pending); return 0;
if (pending & INT_MASK_BUSY)
debug("%s(): packet dropped\n", __func__); for (count = 0; count < PKTBUFSRX; ++count) {
if (pending & INT_MASK_RX) { uchar *packetp;
debug("%s(): rx irq\n", __func__); int size = ethoc_rx_common(priv, &packetp);
ethoc_rx(dev, PKTBUFSRX);
if (size < 0)
break;
if (size > 0)
net_process_received_packet(packetp, size);
ethoc_free_pkt_common(priv);
} }
return 0; return 0;
} }
@ -503,9 +822,16 @@ int ethoc_initialize(u8 dev_num, int base_addr)
dev->halt = ethoc_halt; dev->halt = ethoc_halt;
dev->send = ethoc_send; dev->send = ethoc_send;
dev->recv = ethoc_recv; dev->recv = ethoc_recv;
dev->write_hwaddr = ethoc_set_mac_address; dev->write_hwaddr = ethoc_write_hwaddr;
sprintf(dev->name, "%s-%hu", "ETHOC", dev_num); sprintf(dev->name, "%s-%hu", "ETHOC", dev_num);
priv->iobase = ioremap(dev->iobase, ETHOC_IOSIZE);
eth_register(dev); eth_register(dev);
ethoc_mdio_init(dev->name, priv);
ethoc_phy_init(priv, dev);
return 1; return 1;
} }
#endif

View file

@ -556,8 +556,17 @@ int mcdmafec_initialize(bd_t * bis)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, int retval;
mcffec_miiphy_read, mcffec_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = mcffec_miiphy_read;
mdiodev->write = mcffec_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
if (i > 0) if (i > 0)

View file

@ -364,32 +364,35 @@ static int ftmac110_recv(struct eth_device *dev)
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
static int ftmac110_mdio_read( static int ftmac110_mdio_read(struct mii_dev *bus, int addr, int devad,
const char *devname, uint8_t addr, uint8_t reg, uint16_t *value) int reg)
{ {
uint16_t value = 0;
int ret = 0; int ret = 0;
struct eth_device *dev; struct eth_device *dev;
dev = eth_get_dev_by_name(devname); dev = eth_get_dev_by_name(bus->name);
if (dev == NULL) { if (dev == NULL) {
printf("%s: no such device\n", devname); printf("%s: no such device\n", bus->name);
ret = -1; ret = -1;
} else { } else {
*value = mdio_read(dev, addr, reg); value = mdio_read(dev, addr, reg);
} }
return ret; if (ret < 0)
return ret;
return value;
} }
static int ftmac110_mdio_write( static int ftmac110_mdio_write(struct mii_dev *bus, int addr, int devad,
const char *devname, uint8_t addr, uint8_t reg, uint16_t value) int reg, u16 value)
{ {
int ret = 0; int ret = 0;
struct eth_device *dev; struct eth_device *dev;
dev = eth_get_dev_by_name(devname); dev = eth_get_dev_by_name(bus->name);
if (dev == NULL) { if (dev == NULL) {
printf("%s: no such device\n", devname); printf("%s: no such device\n", bus->name);
ret = -1; ret = -1;
} else { } else {
mdio_write(dev, addr, reg, value); mdio_write(dev, addr, reg, value);
@ -468,7 +471,17 @@ int ftmac110_initialize(bd_t *bis)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, ftmac110_mdio_read, ftmac110_mdio_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = ftmac110_mdio_read;
mdiodev->write = ftmac110_mdio_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
card_nr++; card_nr++;

View file

@ -226,9 +226,11 @@ DECLARE_GLOBAL_DATA_PTR;
* *
* Returns 16bit phy register value, or 0xffff on error * Returns 16bit phy register value, or 0xffff on error
*/ */
static int mii_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data) static int mii_reg_read(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); u16 data = 0;
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev);
struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs;
u32 mind_reg; u32 mind_reg;
@ -270,12 +272,12 @@ static int mii_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data)
return -EFAULT; return -EFAULT;
} }
*data = (u16) readl(&regs->mrdd); data = (u16) readl(&regs->mrdd);
debug("%s:(adr %d, off %d) => %04x\n", __func__, phy_adr, debug("%s:(adr %d, off %d) => %04x\n", __func__, phy_adr,
reg_ofs, *data); reg_ofs, data);
return 0; return data;
} }
/* /*
@ -284,9 +286,10 @@ static int mii_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 *data)
* Returns 0 if write succeed, -EINVAL on bad parameters * Returns 0 if write succeed, -EINVAL on bad parameters
* -ETIME on timeout * -ETIME on timeout
*/ */
static int mii_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) static int mii_reg_write(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs, u16 data)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev); struct lpc32xx_eth_device *dlpc32xx_eth = to_lpc32xx_eth(dev);
struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs; struct lpc32xx_eth_registers *regs = dlpc32xx_eth->regs;
u32 mind_reg; u32 mind_reg;
@ -333,25 +336,6 @@ static int mii_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
} }
#endif #endif
#if defined(CONFIG_PHYLIB)
int lpc32xx_eth_phy_read(struct mii_dev *bus, int phy_addr, int dev_addr,
int reg_addr)
{
u16 data;
int ret;
ret = mii_reg_read(bus->name, phy_addr, reg_addr, &data);
if (ret)
return ret;
return data;
}
int lpc32xx_eth_phy_write(struct mii_dev *bus, int phy_addr, int dev_addr,
int reg_addr, u16 data)
{
return mii_reg_write(bus->name, phy_addr, reg_addr, data);
}
#endif
/* /*
* Provide default Ethernet buffers base address if target did not. * Provide default Ethernet buffers base address if target did not.
* Locate buffers in SRAM at 0x00001000 to avoid cache issues and * Locate buffers in SRAM at 0x00001000 to avoid cache issues and
@ -580,8 +564,8 @@ int lpc32xx_eth_phylib_init(struct eth_device *dev, int phyid)
printf("mdio_alloc failed\n"); printf("mdio_alloc failed\n");
return -ENOMEM; return -ENOMEM;
} }
bus->read = lpc32xx_eth_phy_read; bus->read = mii_reg_read;
bus->write = lpc32xx_eth_phy_write; bus->write = mii_reg_write;
strcpy(bus->name, dev->name); strcpy(bus->name, dev->name);
ret = mdio_register(bus); ret = mdio_register(bus);
@ -645,7 +629,17 @@ int lpc32xx_eth_initialize(bd_t *bis)
#if defined(CONFIG_PHYLIB) #if defined(CONFIG_PHYLIB)
lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR); lpc32xx_eth_phylib_init(dev, CONFIG_PHY_ADDR);
#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, mii_reg_read, mii_reg_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = mii_reg_read;
mdiodev->write = mii_reg_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
return 0; return 0;

View file

@ -43,6 +43,8 @@
#include "macb.h" #include "macb.h"
DECLARE_GLOBAL_DATA_PTR;
#define MACB_RX_BUFFER_SIZE 4096 #define MACB_RX_BUFFER_SIZE 4096
#define MACB_RX_RING_SIZE (MACB_RX_BUFFER_SIZE / 128) #define MACB_RX_RING_SIZE (MACB_RX_BUFFER_SIZE / 128)
#define MACB_TX_RING_SIZE 16 #define MACB_TX_RING_SIZE 16
@ -108,6 +110,10 @@ struct macb_device {
#endif #endif
unsigned short phy_addr; unsigned short phy_addr;
struct mii_dev *bus; struct mii_dev *bus;
#ifdef CONFIG_DM_ETH
phy_interface_t phy_interface;
#endif
}; };
#ifndef CONFIG_DM_ETH #ifndef CONFIG_DM_ETH
#define to_macb(_nd) container_of(_nd, struct macb_device, netdev) #define to_macb(_nd) container_of(_nd, struct macb_device, netdev)
@ -199,39 +205,41 @@ void __weak arch_get_mdio_control(const char *name)
#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) #if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
int macb_miiphy_read(const char *devname, u8 phy_adr, u8 reg, u16 *value) int macb_miiphy_read(struct mii_dev *bus, int phy_adr, int devad, int reg)
{ {
u16 value = 0;
#ifdef CONFIG_DM_ETH #ifdef CONFIG_DM_ETH
struct udevice *dev = eth_get_dev_by_name(devname); struct udevice *dev = eth_get_dev_by_name(bus->name);
struct macb_device *macb = dev_get_priv(dev); struct macb_device *macb = dev_get_priv(dev);
#else #else
struct eth_device *dev = eth_get_dev_by_name(devname); struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct macb_device *macb = to_macb(dev); struct macb_device *macb = to_macb(dev);
#endif #endif
if (macb->phy_addr != phy_adr) if (macb->phy_addr != phy_adr)
return -1; return -1;
arch_get_mdio_control(devname); arch_get_mdio_control(bus->name);
*value = macb_mdio_read(macb, reg); value = macb_mdio_read(macb, reg);
return 0; return value;
} }
int macb_miiphy_write(const char *devname, u8 phy_adr, u8 reg, u16 value) int macb_miiphy_write(struct mii_dev *bus, int phy_adr, int devad, int reg,
u16 value)
{ {
#ifdef CONFIG_DM_ETH #ifdef CONFIG_DM_ETH
struct udevice *dev = eth_get_dev_by_name(devname); struct udevice *dev = eth_get_dev_by_name(bus->name);
struct macb_device *macb = dev_get_priv(dev); struct macb_device *macb = dev_get_priv(dev);
#else #else
struct eth_device *dev = eth_get_dev_by_name(devname); struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct macb_device *macb = to_macb(dev); struct macb_device *macb = to_macb(dev);
#endif #endif
if (macb->phy_addr != phy_adr) if (macb->phy_addr != phy_adr)
return -1; return -1;
arch_get_mdio_control(devname); arch_get_mdio_control(bus->name);
macb_mdio_write(macb, reg, value); macb_mdio_write(macb, reg, value);
return 0; return 0;
@ -434,7 +442,7 @@ static void macb_phy_reset(struct macb_device *macb, const char *name)
} }
#ifdef CONFIG_MACB_SEARCH_PHY #ifdef CONFIG_MACB_SEARCH_PHY
static int macb_phy_find(struct macb_device *macb) static int macb_phy_find(struct macb_device *macb, const char *name)
{ {
int i; int i;
u16 phy_id; u16 phy_id;
@ -444,21 +452,27 @@ static int macb_phy_find(struct macb_device *macb)
macb->phy_addr = i; macb->phy_addr = i;
phy_id = macb_mdio_read(macb, MII_PHYSID1); phy_id = macb_mdio_read(macb, MII_PHYSID1);
if (phy_id != 0xffff) { if (phy_id != 0xffff) {
printf("%s: PHY present at %d\n", macb->netdev.name, i); printf("%s: PHY present at %d\n", name, i);
return 1; return 1;
} }
} }
/* PHY isn't up to snuff */ /* PHY isn't up to snuff */
printf("%s: PHY not found\n", macb->netdev.name); printf("%s: PHY not found\n", name);
return 0; return 0;
} }
#endif /* CONFIG_MACB_SEARCH_PHY */ #endif /* CONFIG_MACB_SEARCH_PHY */
#ifdef CONFIG_DM_ETH
static int macb_phy_init(struct udevice *dev, const char *name)
#else
static int macb_phy_init(struct macb_device *macb, const char *name) static int macb_phy_init(struct macb_device *macb, const char *name)
#endif
{ {
#ifdef CONFIG_DM_ETH
struct macb_device *macb = dev_get_priv(dev);
#endif
#ifdef CONFIG_PHYLIB #ifdef CONFIG_PHYLIB
struct phy_device *phydev; struct phy_device *phydev;
#endif #endif
@ -470,7 +484,7 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
arch_get_mdio_control(name); arch_get_mdio_control(name);
#ifdef CONFIG_MACB_SEARCH_PHY #ifdef CONFIG_MACB_SEARCH_PHY
/* Auto-detect phy_addr */ /* Auto-detect phy_addr */
if (!macb_phy_find(macb)) if (!macb_phy_find(macb, name))
return 0; return 0;
#endif /* CONFIG_MACB_SEARCH_PHY */ #endif /* CONFIG_MACB_SEARCH_PHY */
@ -482,9 +496,14 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
} }
#ifdef CONFIG_PHYLIB #ifdef CONFIG_PHYLIB
#ifdef CONFIG_DM_ETH
phydev = phy_connect(macb->bus, macb->phy_addr, dev,
macb->phy_interface);
#else
/* need to consider other phy interface mode */ /* need to consider other phy interface mode */
phydev = phy_connect(macb->bus, macb->phy_addr, &macb->netdev, phydev = phy_connect(macb->bus, macb->phy_addr, &macb->netdev,
PHY_INTERFACE_MODE_RGMII); PHY_INTERFACE_MODE_RGMII);
#endif
if (!phydev) { if (!phydev) {
printf("phy_connect failed\n"); printf("phy_connect failed\n");
return -ENODEV; return -ENODEV;
@ -585,8 +604,15 @@ static int gmac_init_multi_queues(struct macb_device *macb)
return 0; return 0;
} }
#ifdef CONFIG_DM_ETH
static int _macb_init(struct udevice *dev, const char *name)
#else
static int _macb_init(struct macb_device *macb, const char *name) static int _macb_init(struct macb_device *macb, const char *name)
#endif
{ {
#ifdef CONFIG_DM_ETH
struct macb_device *macb = dev_get_priv(dev);
#endif
unsigned long paddr; unsigned long paddr;
int i; int i;
@ -634,13 +660,35 @@ static int _macb_init(struct macb_device *macb, const char *name)
* When the GMAC IP without GE feature, this bit is used * When the GMAC IP without GE feature, this bit is used
* to select interface between RMII and MII. * to select interface between RMII and MII.
*/ */
#ifdef CONFIG_DM_ETH
if (macb->phy_interface == PHY_INTERFACE_MODE_RMII)
gem_writel(macb, UR, GEM_BIT(RGMII));
else
gem_writel(macb, UR, 0);
#else
#if defined(CONFIG_RGMII) || defined(CONFIG_RMII) #if defined(CONFIG_RGMII) || defined(CONFIG_RMII)
gem_writel(macb, UR, GEM_BIT(RGMII)); gem_writel(macb, UR, GEM_BIT(RGMII));
#else #else
gem_writel(macb, UR, 0); gem_writel(macb, UR, 0);
#endif
#endif #endif
} else { } else {
/* choose RMII or MII mode. This depends on the board */ /* choose RMII or MII mode. This depends on the board */
#ifdef CONFIG_DM_ETH
#ifdef CONFIG_AT91FAMILY
if (macb->phy_interface == PHY_INTERFACE_MODE_RMII) {
macb_writel(macb, USRIO,
MACB_BIT(RMII) | MACB_BIT(CLKEN));
} else {
macb_writel(macb, USRIO, MACB_BIT(CLKEN));
}
#else
if (macb->phy_interface == PHY_INTERFACE_MODE_RMII)
macb_writel(macb, USRIO, 0);
else
macb_writel(macb, USRIO, MACB_BIT(MII));
#endif
#else
#ifdef CONFIG_RMII #ifdef CONFIG_RMII
#ifdef CONFIG_AT91FAMILY #ifdef CONFIG_AT91FAMILY
macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN)); macb_writel(macb, USRIO, MACB_BIT(RMII) | MACB_BIT(CLKEN));
@ -654,9 +702,14 @@ static int _macb_init(struct macb_device *macb, const char *name)
macb_writel(macb, USRIO, MACB_BIT(MII)); macb_writel(macb, USRIO, MACB_BIT(MII));
#endif #endif
#endif /* CONFIG_RMII */ #endif /* CONFIG_RMII */
#endif
} }
#ifdef CONFIG_DM_ETH
if (!macb_phy_init(dev, name))
#else
if (!macb_phy_init(macb, name)) if (!macb_phy_init(macb, name))
#endif
return -1; return -1;
/* Enable TX and RX */ /* Enable TX and RX */
@ -862,7 +915,17 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
eth_register(netdev); eth_register(netdev);
#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) #if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
miiphy_register(netdev->name, macb_miiphy_read, macb_miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, netdev->name, MDIO_NAME_LEN);
mdiodev->read = macb_miiphy_read;
mdiodev->write = macb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
macb->bus = miiphy_get_dev_by_name(netdev->name); macb->bus = miiphy_get_dev_by_name(netdev->name);
#endif #endif
return 0; return 0;
@ -873,9 +936,7 @@ int macb_eth_initialize(int id, void *regs, unsigned int phy_addr)
static int macb_start(struct udevice *dev) static int macb_start(struct udevice *dev)
{ {
struct macb_device *macb = dev_get_priv(dev); return _macb_init(dev, dev->name);
return _macb_init(macb, dev->name);
} }
static int macb_send(struct udevice *dev, void *packet, int length) static int macb_send(struct udevice *dev, void *packet, int length)
@ -933,11 +994,33 @@ static int macb_eth_probe(struct udevice *dev)
struct eth_pdata *pdata = dev_get_platdata(dev); struct eth_pdata *pdata = dev_get_platdata(dev);
struct macb_device *macb = dev_get_priv(dev); struct macb_device *macb = dev_get_priv(dev);
#ifdef CONFIG_DM_ETH
const char *phy_mode;
phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
if (phy_mode)
macb->phy_interface = phy_get_interface_by_name(phy_mode);
if (macb->phy_interface == -1) {
debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
return -EINVAL;
}
#endif
macb->regs = (void *)pdata->iobase; macb->regs = (void *)pdata->iobase;
_macb_eth_initialize(macb); _macb_eth_initialize(macb);
#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB) #if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
miiphy_register(dev->name, macb_miiphy_read, macb_miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = macb_miiphy_read;
mdiodev->write = macb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
macb->bus = miiphy_get_dev_by_name(dev->name); macb->bus = miiphy_get_dev_by_name(dev->name);
#endif #endif

View file

@ -595,8 +595,17 @@ int mcffec_initialize(bd_t * bis)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, int retval;
mcffec_miiphy_read, mcffec_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = mcffec_miiphy_read;
mdiodev->write = mcffec_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
if (i > 0) if (i > 0)
fec_info[i - 1].next = &fec_info[i]; fec_info[i - 1].next = &fec_info[i];

View file

@ -277,8 +277,7 @@ void __mii_init(void)
* Otherwise they hang in mii_send() !!! Sorry! * Otherwise they hang in mii_send() !!! Sorry!
*/ */
int mcffec_miiphy_read(const char *devname, unsigned char addr, unsigned char reg, int mcffec_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
unsigned short *value)
{ {
short rdreg; /* register working value */ short rdreg; /* register working value */
@ -287,28 +286,22 @@ int mcffec_miiphy_read(const char *devname, unsigned char addr, unsigned char re
#endif #endif
rdreg = mii_send(mk_mii_read(addr, reg)); rdreg = mii_send(mk_mii_read(addr, reg));
*value = rdreg;
#ifdef MII_DEBUG #ifdef MII_DEBUG
printf("0x%04x\n", *value); printf("0x%04x\n", rdreg);
#endif #endif
return 0; return rdreg;
} }
int mcffec_miiphy_write(const char *devname, unsigned char addr, unsigned char reg, int mcffec_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
unsigned short value) u16 value)
{ {
#ifdef MII_DEBUG #ifdef MII_DEBUG
printf("miiphy_write(0x%x) @ 0x%x = ", reg, addr); printf("miiphy_write(0x%x) @ 0x%x = 0x%04x\n", reg, addr, value);
#endif #endif
mii_send(mk_mii_write(addr, reg, value)); mii_send(mk_mii_write(addr, reg, value));
#ifdef MII_DEBUG
printf("0x%04x\n", value);
#endif
return 0; return 0;
} }

View file

@ -22,8 +22,10 @@ DECLARE_GLOBAL_DATA_PTR;
#error "CONFIG_MII has to be defined!" #error "CONFIG_MII has to be defined!"
#endif #endif
int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 * retVal); int fec512x_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
int fec512x_miiphy_write(const char *devname, u8 phyAddr, u8 regAddr, u16 data); int regAddr);
int fec512x_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
int regAddr, u16 data);
int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis); int mpc512x_fec_init_phy(struct eth_device *dev, bd_t * bis);
static uchar rx_buff[FEC_BUFFER_SIZE]; static uchar rx_buff[FEC_BUFFER_SIZE];
@ -639,8 +641,17 @@ int mpc512x_fec_initialize (bd_t * bis)
eth_register (dev); eth_register (dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register (dev->name, int retval;
fec512x_miiphy_read, fec512x_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = fec512x_miiphy_read;
mdiodev->write = fec512x_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
/* Clean up space FEC's MIB and FIFO RAM ...*/ /* Clean up space FEC's MIB and FIFO RAM ...*/
@ -670,8 +681,10 @@ int mpc512x_fec_initialize (bd_t * bis)
/* MII-interface related functions */ /* MII-interface related functions */
/********************************************************************/ /********************************************************************/
int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 *retVal) int fec512x_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
int regAddr)
{ {
u16 retVal = 0;
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
volatile fec512x_t *eth = &im->fec; volatile fec512x_t *eth = &im->fec;
u32 reg; /* convenient holder for the PHY register */ u32 reg; /* convenient holder for the PHY register */
@ -711,13 +724,14 @@ int fec512x_miiphy_read(const char *devname, u8 phyAddr, u8 regAddr, u16 *retVal
/* /*
* it's now safe to read the PHY's register * it's now safe to read the PHY's register
*/ */
*retVal = (u16) in_be32(&eth->mii_data); retVal = (u16) in_be32(&eth->mii_data);
return 0; return retVal;
} }
/********************************************************************/ /********************************************************************/
int fec512x_miiphy_write(const char *devname, u8 phyAddr, u8 regAddr, u16 data) int fec512x_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
int regAddr, u16 data)
{ {
volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR; volatile immap_t *im = (immap_t *) CONFIG_SYS_IMMR;
volatile fec512x_t *eth = &im->fec; volatile fec512x_t *eth = &im->fec;

View file

@ -35,8 +35,10 @@ typedef struct {
uint8 head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */ uint8 head[16]; /* MAC header(6 + 6 + 2) + 2(aligned) */
} NBUF; } NBUF;
int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 *retVal); int fec5xxx_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
int fec5xxx_miiphy_write(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 data); int regAddr);
int fec5xxx_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
int regAddr, u16 data);
static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis); static int mpc5xxx_fec_init_phy(struct eth_device *dev, bd_t * bis);
@ -917,8 +919,17 @@ int mpc5xxx_fec_initialize(bd_t * bis)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register (dev->name, int retval;
fec5xxx_miiphy_read, fec5xxx_miiphy_write); struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = fec5xxx_miiphy_read;
mdiodev->write = fec5xxx_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
/* /*
@ -941,8 +952,10 @@ int mpc5xxx_fec_initialize(bd_t * bis)
/* MII-interface related functions */ /* MII-interface related functions */
/********************************************************************/ /********************************************************************/
int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 * retVal) int fec5xxx_miiphy_read(struct mii_dev *bus, int phyAddr, int devad,
int regAddr)
{ {
uint16 retVal = 0;
ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC; ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
uint32 reg; /* convenient holder for the PHY register */ uint32 reg; /* convenient holder for the PHY register */
uint32 phy; /* convenient holder for the PHY */ uint32 phy; /* convenient holder for the PHY */
@ -977,13 +990,14 @@ int fec5xxx_miiphy_read(const char *devname, uint8 phyAddr, uint8 regAddr, uint1
/* /*
* it's now safe to read the PHY's register * it's now safe to read the PHY's register
*/ */
*retVal = (uint16) eth->mii_data; retVal = (uint16) eth->mii_data;
return 0; return retVal;
} }
/********************************************************************/ /********************************************************************/
int fec5xxx_miiphy_write(const char *devname, uint8 phyAddr, uint8 regAddr, uint16 data) int fec5xxx_miiphy_write(struct mii_dev *bus, int phyAddr, int devad,
int regAddr, u16 data)
{ {
ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC; ethernet_regs *eth = (ethernet_regs *)MPC5XXX_FEC;
uint32 reg; /* convenient holder for the PHY register */ uint32 reg; /* convenient holder for the PHY register */

View file

@ -48,9 +48,11 @@ DECLARE_GLOBAL_DATA_PTR;
* *
* Returns 16bit phy register value, or 0xffff on error * Returns 16bit phy register value, or 0xffff on error
*/ */
static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data) static int smi_reg_read(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); u16 data = 0;
struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct mvgbe_device *dmvgbe = to_mvgbe(dev); struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs; struct mvgbe_registers *regs = dmvgbe->regs;
u32 smi_reg; u32 smi_reg;
@ -60,8 +62,8 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
if (phy_adr == MV_PHY_ADR_REQUEST && if (phy_adr == MV_PHY_ADR_REQUEST &&
reg_ofs == MV_PHY_ADR_REQUEST) { reg_ofs == MV_PHY_ADR_REQUEST) {
/* */ /* */
*data = (u16) (MVGBE_REG_RD(regs->phyadr) & PHYADR_MASK); data = (u16) (MVGBE_REG_RD(regs->phyadr) & PHYADR_MASK);
return 0; return data;
} }
/* check parameters */ /* check parameters */
if (phy_adr > PHYADR_MASK) { if (phy_adr > PHYADR_MASK) {
@ -111,12 +113,12 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
for (timeout = 0; timeout < MVGBE_PHY_SMI_TIMEOUT; timeout++) for (timeout = 0; timeout < MVGBE_PHY_SMI_TIMEOUT; timeout++)
; ;
*data = (u16) (MVGBE_REG_RD(MVGBE_SMI_REG) & MVGBE_PHY_SMI_DATA_MASK); data = (u16) (MVGBE_REG_RD(MVGBE_SMI_REG) & MVGBE_PHY_SMI_DATA_MASK);
debug("%s:(adr %d, off %d) value= %04x\n", __func__, phy_adr, reg_ofs, debug("%s:(adr %d, off %d) value= %04x\n", __func__, phy_adr, reg_ofs,
*data); data);
return 0; return data;
} }
/* /*
@ -125,9 +127,10 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
* Returns 0 if write succeed, -EINVAL on bad parameters * Returns 0 if write succeed, -EINVAL on bad parameters
* -ETIME on timeout * -ETIME on timeout
*/ */
static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data) static int smi_reg_write(struct mii_dev *bus, int phy_adr, int devad,
int reg_ofs, u16 data)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); struct eth_device *dev = eth_get_dev_by_name(bus->name);
struct mvgbe_device *dmvgbe = to_mvgbe(dev); struct mvgbe_device *dmvgbe = to_mvgbe(dev);
struct mvgbe_registers *regs = dmvgbe->regs; struct mvgbe_registers *regs = dmvgbe->regs;
u32 smi_reg; u32 smi_reg;
@ -785,7 +788,17 @@ error1:
#if defined(CONFIG_PHYLIB) #if defined(CONFIG_PHYLIB)
mvgbe_phylib_init(dev, PHY_BASE_ADR + devnum); mvgbe_phylib_init(dev, PHY_BASE_ADR + devnum);
#elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #elif defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, smi_reg_read, smi_reg_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = smi_reg_read;
mdiodev->write = smi_reg_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
/* Set phy address of the port */ /* Set phy address of the port */
miiphy_write(dev->name, MV_PHY_ADR_REQUEST, miiphy_write(dev->name, MV_PHY_ADR_REQUEST,
MV_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum); MV_PHY_ADR_REQUEST, PHY_BASE_ADR + devnum);

View file

@ -230,24 +230,18 @@ static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
* Returns: * Returns:
* 0 on success * 0 on success
*/ */
int bb_miiphy_read(const char *devname, unsigned char addr, int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg)
unsigned char reg, unsigned short *value)
{ {
short rdreg; /* register working value */ short rdreg; /* register working value */
int v; int v;
int j; /* counter */ int j; /* counter */
struct bb_miiphy_bus *bus; struct bb_miiphy_bus *bus;
bus = bb_miiphy_getbus(devname); bus = bb_miiphy_getbus(miidev->name);
if (bus == NULL) { if (bus == NULL) {
return -1; return -1;
} }
if (value == NULL) {
puts("NULL value pointer\n");
return -1;
}
miiphy_pre (bus, 1, addr, reg); miiphy_pre (bus, 1, addr, reg);
/* tri-state our MDIO I/O pin so we can read */ /* tri-state our MDIO I/O pin so we can read */
@ -267,8 +261,7 @@ int bb_miiphy_read(const char *devname, unsigned char addr,
bus->set_mdc(bus, 1); bus->set_mdc(bus, 1);
bus->delay(bus); bus->delay(bus);
} }
/* There is no PHY, set value to 0xFFFF and return */ /* There is no PHY, return */
*value = 0xFFFF;
return -1; return -1;
} }
@ -294,13 +287,11 @@ int bb_miiphy_read(const char *devname, unsigned char addr,
bus->set_mdc(bus, 1); bus->set_mdc(bus, 1);
bus->delay(bus); bus->delay(bus);
*value = rdreg;
#ifdef DEBUG #ifdef DEBUG
printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value); printf("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, rdreg);
#endif #endif
return 0; return rdreg;
} }
@ -311,13 +302,13 @@ int bb_miiphy_read(const char *devname, unsigned char addr,
* Returns: * Returns:
* 0 on success * 0 on success
*/ */
int bb_miiphy_write (const char *devname, unsigned char addr, int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,
unsigned char reg, unsigned short value) u16 value)
{ {
struct bb_miiphy_bus *bus; struct bb_miiphy_bus *bus;
int j; /* counter */ int j; /* counter */
bus = bb_miiphy_getbus(devname); bus = bb_miiphy_getbus(miidev->name);
if (bus == NULL) { if (bus == NULL) {
/* Bus not found! */ /* Bus not found! */
return -1; return -1;

View file

@ -566,7 +566,17 @@ int sh_eth_initialize(bd_t *bd)
eth_register(dev); eth_register(dev);
bb_miiphy_buses[0].priv = eth; bb_miiphy_buses[0].priv = eth;
miiphy_register(dev->name, bb_miiphy_read, bb_miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = bb_miiphy_read;
mdiodev->write = bb_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr)) if (!eth_getenv_enetaddr("ethaddr", dev->enetaddr))
puts("Please set MAC address\n"); puts("Please set MAC address\n");

View file

@ -219,20 +219,27 @@ static int smc911x_rx(struct eth_device *dev)
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
/* wrapper for smc911x_eth_phy_read */ /* wrapper for smc911x_eth_phy_read */
static int smc911x_miiphy_read(const char *devname, u8 phy, u8 reg, u16 *val) static int smc911x_miiphy_read(struct mii_dev *bus, int phy, int devad,
int reg)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); u16 val = 0;
if (dev) struct eth_device *dev = eth_get_dev_by_name(bus->name);
return smc911x_eth_phy_read(dev, phy, reg, val); if (dev) {
return -1; int retval = smc911x_eth_phy_read(dev, phy, reg, &val);
if (retval < 0)
return retval;
return val;
}
return -ENODEV;
} }
/* wrapper for smc911x_eth_phy_write */ /* wrapper for smc911x_eth_phy_write */
static int smc911x_miiphy_write(const char *devname, u8 phy, u8 reg, u16 val) static int smc911x_miiphy_write(struct mii_dev *bus, int phy, int devad,
int reg, u16 val)
{ {
struct eth_device *dev = eth_get_dev_by_name(devname); struct eth_device *dev = eth_get_dev_by_name(bus->name);
if (dev) if (dev)
return smc911x_eth_phy_write(dev, phy, reg, val); return smc911x_eth_phy_write(dev, phy, reg, val);
return -1; return -ENODEV;
} }
#endif #endif
@ -276,7 +283,17 @@ int smc911x_initialize(u8 dev_num, int base_addr)
eth_register(dev); eth_register(dev);
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, smc911x_miiphy_read, smc911x_miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = smc911x_miiphy_read;
mdiodev->write = smc911x_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
return 1; return 1;

View file

@ -623,20 +623,20 @@ static int uec_miiphy_find_dev_by_name(const char *devname)
* Returns: * Returns:
* 0 on success * 0 on success
*/ */
static int uec_miiphy_read(const char *devname, unsigned char addr, static int uec_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
unsigned char reg, unsigned short *value)
{ {
unsigned short value = 0;
int devindex = 0; int devindex = 0;
if (devname == NULL || value == NULL) { if (bus->name == NULL) {
debug("%s: NULL pointer given\n", __FUNCTION__); debug("%s: NULL pointer given\n", __FUNCTION__);
} else { } else {
devindex = uec_miiphy_find_dev_by_name(devname); devindex = uec_miiphy_find_dev_by_name(bus->name);
if (devindex >= 0) { if (devindex >= 0) {
*value = uec_read_phy_reg(devlist[devindex], addr, reg); value = uec_read_phy_reg(devlist[devindex], addr, reg);
} }
} }
return 0; return value;
} }
/* /*
@ -645,15 +645,15 @@ static int uec_miiphy_read(const char *devname, unsigned char addr,
* Returns: * Returns:
* 0 on success * 0 on success
*/ */
static int uec_miiphy_write(const char *devname, unsigned char addr, static int uec_miiphy_write(struct mii_dev *bus, int addr, int devad, int reg,
unsigned char reg, unsigned short value) u16 value)
{ {
int devindex = 0; int devindex = 0;
if (devname == NULL) { if (bus->name == NULL) {
debug("%s: NULL pointer given\n", __FUNCTION__); debug("%s: NULL pointer given\n", __FUNCTION__);
} else { } else {
devindex = uec_miiphy_find_dev_by_name(devname); devindex = uec_miiphy_find_dev_by_name(bus->name);
if (devindex >= 0) { if (devindex >= 0) {
uec_write_phy_reg(devlist[devindex], addr, reg, value); uec_write_phy_reg(devlist[devindex], addr, reg, value);
} }
@ -1399,7 +1399,17 @@ int uec_initialize(bd_t *bis, uec_info_t *uec_info)
} }
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) #if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
miiphy_register(dev->name, uec_miiphy_read, uec_miiphy_write); int retval;
struct mii_dev *mdiodev = mdio_alloc();
if (!mdiodev)
return -ENOMEM;
strncpy(mdiodev->name, dev->name, MDIO_NAME_LEN);
mdiodev->read = uec_miiphy_read;
mdiodev->write = uec_miiphy_write;
retval = mdio_register(mdiodev);
if (retval < 0)
return retval;
#endif #endif
return 1; return 1;

View file

@ -391,8 +391,8 @@ static int smsc95xx_write_hwaddr_common(struct usb_device *udev,
struct smsc95xx_private *priv, struct smsc95xx_private *priv,
unsigned char *enetaddr) unsigned char *enetaddr)
{ {
u32 addr_lo = __get_unaligned_le32(&enetaddr[0]); u32 addr_lo = get_unaligned_le32(&enetaddr[0]);
u32 addr_hi = __get_unaligned_le16(&enetaddr[4]); u32 addr_hi = get_unaligned_le16(&enetaddr[4]);
int ret; int ret;
/* set hardware address */ /* set hardware address */

View file

@ -95,6 +95,7 @@
/* Ethernet */ /* Ethernet */
#define CONFIG_MACB #define CONFIG_MACB
#define CONFIG_PHYLIB
#define CONFIG_RMII #define CONFIG_RMII
#define CONFIG_NET_RETRY_COUNT 20 #define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_AT91_WANTS_COMMON_PHY #define CONFIG_AT91_WANTS_COMMON_PHY

View file

@ -44,7 +44,6 @@
/* /*
* Ethernet * Ethernet
*/ */
#define CONFIG_ETHOC
#define CONFIG_SYS_ETHOC_BASE 0x92000000 #define CONFIG_SYS_ETHOC_BASE 0x92000000
#define CONFIG_BOOTFILE "boot.img" #define CONFIG_BOOTFILE "boot.img"

View file

@ -122,6 +122,7 @@
* *
*/ */
#define CONFIG_MACB #define CONFIG_MACB
#define CONFIG_PHYLIB
#define CONFIG_USB_HOST_ETHER #define CONFIG_USB_HOST_ETHER
#define CONFIG_USB_ETHER_ASIX #define CONFIG_USB_ETHER_ASIX
#define CONFIG_USB_ETHER_MCS7830 #define CONFIG_USB_ETHER_MCS7830

View file

@ -56,6 +56,7 @@
/* Ethernet */ /* Ethernet */
#define CONFIG_MACB #define CONFIG_MACB
#define CONFIG_PHYLIB
#define CONFIG_RMII #define CONFIG_RMII
#define CONFIG_NET_RETRY_COUNT 20 #define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_RESET_PHY_R #define CONFIG_RESET_PHY_R

View file

@ -99,6 +99,7 @@
/* Ethernet */ /* Ethernet */
#define CONFIG_MACB #define CONFIG_MACB
#define CONFIG_PHYLIB
#define CONFIG_RMII #define CONFIG_RMII
#define CONFIG_AT91_WANTS_COMMON_PHY #define CONFIG_AT91_WANTS_COMMON_PHY

View file

@ -0,0 +1,21 @@
/*
* Copyright (C) 2016 Cadence Design Systems Inc.
*
* SPDX-License-Identifier: GPL-2.0
*/
#ifndef _ETHOC_H
#define _ETHOC_H
#include <net.h>
#ifdef CONFIG_DM_ETH
struct ethoc_eth_pdata {
struct eth_pdata eth_pdata;
phys_addr_t packet_base;
};
#endif
#endif /* _ETHOC_H */

View file

@ -21,13 +21,6 @@
#include <net.h> #include <net.h>
#include <phy.h> #include <phy.h>
struct legacy_mii_dev {
int (*read)(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value);
int (*write)(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value);
};
int miiphy_read(const char *devname, unsigned char addr, unsigned char reg, int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
unsigned short *value); unsigned short *value);
int miiphy_write(const char *devname, unsigned char addr, unsigned char reg, int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
@ -44,12 +37,6 @@ int miiphy_link(const char *devname, unsigned char addr);
void miiphy_init(void); void miiphy_init(void);
void miiphy_register(const char *devname,
int (*read)(const char *devname, unsigned char addr,
unsigned char reg, unsigned short *value),
int (*write)(const char *devname, unsigned char addr,
unsigned char reg, unsigned short value));
int miiphy_set_current_dev(const char *devname); int miiphy_set_current_dev(const char *devname);
const char *miiphy_get_current_dev(void); const char *miiphy_get_current_dev(void);
struct mii_dev *mdio_get_current_dev(void); struct mii_dev *mdio_get_current_dev(void);
@ -86,10 +73,9 @@ extern struct bb_miiphy_bus bb_miiphy_buses[];
extern int bb_miiphy_buses_num; extern int bb_miiphy_buses_num;
void bb_miiphy_init(void); void bb_miiphy_init(void);
int bb_miiphy_read(const char *devname, unsigned char addr, int bb_miiphy_read(struct mii_dev *miidev, int addr, int devad, int reg);
unsigned char reg, unsigned short *value); int bb_miiphy_write(struct mii_dev *miidev, int addr, int devad, int reg,
int bb_miiphy_write(const char *devname, unsigned char addr, u16 value);
unsigned char reg, unsigned short value);
#endif #endif
/* phy seed setup */ /* phy seed setup */

View file

@ -0,0 +1,142 @@
/// Use mdio_alloc and mdio_register instead of miiphy_register
///
//# Stop using the oldest mii interface in drivers
//
// Confidence: High
// Copyright: (C) 2016 Joe Hershberger. GPLv2.
// Comments:
// Options: --include-headers --recursive-includes --local-includes -I include
@ mii_reg @
expression devname;
identifier readfunc, writefunc;
@@
+ int retval;
- miiphy_register(devname, readfunc, writefunc);
+ struct mii_dev *mdiodev = mdio_alloc();
+ if (!mdiodev) return -ENOMEM;
+ strncpy(mdiodev->name, devname, MDIO_NAME_LEN);
+ mdiodev->read = readfunc;
+ mdiodev->write = writefunc;
+
+ retval = mdio_register(mdiodev);
+ if (retval < 0) return retval;
@ update_read_sig @
identifier mii_reg.readfunc;
identifier name0, addr0, reg0, output;
type addrT, outputT;
@@
- readfunc (
- const char *name0,
- addrT addr0,
- addrT reg0,
- outputT *output
- )
+ readfunc (
+ struct mii_dev *bus,
+ int addr0,
+ int devad,
+ int reg0
+ )
{
...
}
@ update_read_impl @
identifier mii_reg.readfunc;
identifier update_read_sig.output;
type update_read_sig.outputT;
constant c;
identifier retvar;
expression E;
@@
readfunc (...)
{
+ outputT output = 0;
...
(
- return 0;
+ return *output;
|
return c;
|
- return retvar;
+ if (retvar < 0)
+ return retvar;
+ return *output;
|
- return E;
+ int retval = E;
+ if (retval < 0)
+ return retval;
+ return *output;
)
}
@ update_read_impl2 @
identifier mii_reg.readfunc;
identifier update_read_sig.output;
@@
readfunc (...)
{
<...
(
- *output
+ output
|
- output
+ &output
)
...>
}
@ update_read_name @
identifier mii_reg.readfunc;
identifier update_read_sig.name0;
@@
readfunc (...) {
<...
- name0
+ bus->name
...>
}
@ update_write_sig @
identifier mii_reg.writefunc;
identifier name0, addr0, reg0, value0;
type addrT, valueT;
typedef u16;
@@
- writefunc (
- const char *name0,
- addrT addr0,
- addrT reg0,
- valueT value0
- )
+ writefunc (
+ struct mii_dev *bus,
+ int addr0,
+ int devad,
+ int reg0,
+ u16 value0
+ )
{
...
}
@ update_write_name @
identifier mii_reg.writefunc;
identifier update_write_sig.name0;
@@
writefunc (...) {
<...
- name0
+ bus->name
...>
}