Merge git://git.denx.de/u-boot-net

This commit is contained in:
Tom Rini 2017-06-03 18:05:28 -04:00
commit 5cafcbab58
12 changed files with 209 additions and 62 deletions

View file

@ -22,6 +22,13 @@ menuconfig NETDEVICES
if NETDEVICES
config PHY_GIGE
bool "Enable GbE PHY status parsing and configuration"
help
Enables support for parsing the status output and for
configuring GbE PHYs (affects the inner workings of some
commands and miiphyutil.c).
config AG7XXX
bool "Atheros AG7xxx Ethernet MAC support"
depends on DM_ETH && ARCH_ATH79
@ -187,6 +194,7 @@ config SUN8I_EMAC
bool "Allwinner Sun8i Ethernet MAC support"
depends on DM_ETH
select PHYLIB
select PHY_GIGE
help
This driver supports the Allwinner based SUN8I/SUN50I Ethernet MAC.
It can be found in H3/A64/A83T based SoCs and compatible with both

View file

@ -612,21 +612,25 @@ static void cpsw_set_slave_mac(struct cpsw_slave *slave,
#endif
}
static void cpsw_slave_update_link(struct cpsw_slave *slave,
static int cpsw_slave_update_link(struct cpsw_slave *slave,
struct cpsw_priv *priv, int *link)
{
struct phy_device *phy;
u32 mac_control = 0;
int ret = -ENODEV;
phy = priv->phydev;
if (!phy)
return;
goto out;
phy_startup(phy);
*link = phy->link;
ret = phy_startup(phy);
if (ret)
goto out;
if (*link) { /* link up */
if (link)
*link = phy->link;
if (phy->link) { /* link up */
mac_control = priv->data.mac_control;
if (phy->speed == 1000)
mac_control |= GIGABITEN;
@ -637,7 +641,7 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
}
if (mac_control == slave->mac_control)
return;
goto out;
if (mac_control) {
printf("link up on port %d, speed %d, %s duplex\n",
@ -649,17 +653,20 @@ static void cpsw_slave_update_link(struct cpsw_slave *slave,
__raw_writel(mac_control, &slave->sliver->mac_control);
slave->mac_control = mac_control;
out:
return ret;
}
static int cpsw_update_link(struct cpsw_priv *priv)
{
int link = 0;
int ret = -ENODEV;
struct cpsw_slave *slave;
for_active_slave(slave, priv)
cpsw_slave_update_link(slave, priv, &link);
ret = cpsw_slave_update_link(slave, priv, NULL);
return link;
return ret;
}
static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
@ -822,7 +829,9 @@ static int _cpsw_init(struct cpsw_priv *priv, u8 *enetaddr)
for_active_slave(slave, priv)
cpsw_slave_init(slave, priv);
cpsw_update_link(priv);
ret = cpsw_update_link(priv);
if (ret)
goto out;
/* init descriptor pool */
for (i = 0; i < NUM_DESCS; i++) {
@ -897,7 +906,8 @@ static int _cpsw_init(struct cpsw_priv *priv, u8 *enetaddr)
}
}
return 0;
out:
return ret;
}
static void _cpsw_halt(struct cpsw_priv *priv)

View file

@ -18,6 +18,7 @@
#include <linux/compiler.h>
#include <linux/err.h>
#include <asm/io.h>
#include <power/regulator.h>
#include "designware.h"
DECLARE_GLOBAL_DATA_PTR;
@ -661,6 +662,22 @@ int designware_eth_probe(struct udevice *dev)
ulong ioaddr;
int ret;
#if defined(CONFIG_DM_REGULATOR)
struct udevice *phy_supply;
ret = device_get_supply_regulator(dev, "phy-supply",
&phy_supply);
if (ret) {
debug("%s: No phy supply\n", dev->name);
} else {
ret = regulator_set_enable(phy_supply, true);
if (ret) {
puts("Error enabling phy supply\n");
return ret;
}
}
#endif
#ifdef CONFIG_DM_PCI
/*
* If we are on PCI bus, either directly attached to a PCI root port,

View file

@ -66,12 +66,12 @@ phy_interface_t fman_port_enet_if(enum fm_port port)
if (port == FM1_DTSEC3)
if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC1) ==
FSL_CHASSIS2_RCWSR13_EC1_DTSEC3_RGMII) {
return PHY_INTERFACE_MODE_RGMII;
return PHY_INTERFACE_MODE_RGMII_TXID;
}
if (port == FM1_DTSEC4)
if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC2) ==
FSL_CHASSIS2_RCWSR13_EC2_DTSEC4_RGMII) {
return PHY_INTERFACE_MODE_RGMII;
return PHY_INTERFACE_MODE_RGMII_TXID;
}
/* handle SGMII */

View file

@ -72,12 +72,12 @@ phy_interface_t fman_port_enet_if(enum fm_port port)
if (port == FM1_DTSEC3)
if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC1) ==
FSL_CHASSIS2_RCWSR13_EC1_DTSEC3_RGMII)
return PHY_INTERFACE_MODE_RGMII;
return PHY_INTERFACE_MODE_RGMII_TXID;
if (port == FM1_DTSEC4)
if ((rcwsr13 & FSL_CHASSIS2_RCWSR13_EC2) ==
FSL_CHASSIS2_RCWSR13_EC2_DTSEC4_RGMII)
return PHY_INTERFACE_MODE_RGMII;
return PHY_INTERFACE_MODE_RGMII_TXID;
/* handle SGMII, only MAC 2/5/6/9/10 available */
switch (port) {

View file

@ -450,7 +450,6 @@ static void macb_phy_reset(struct macb_device *macb, const char *name)
name, status);
}
#ifdef CONFIG_MACB_SEARCH_PHY
static int macb_phy_find(struct macb_device *macb, const char *name)
{
int i;
@ -471,7 +470,6 @@ static int macb_phy_find(struct macb_device *macb, const char *name)
return 0;
}
#endif /* CONFIG_MACB_SEARCH_PHY */
#ifdef CONFIG_DM_ETH
static int macb_phy_init(struct udevice *dev, const char *name)
@ -488,11 +486,9 @@ static int macb_phy_init(struct macb_device *macb, const char *name)
int i;
arch_get_mdio_control(name);
#ifdef CONFIG_MACB_SEARCH_PHY
/* Auto-detect phy_addr */
if (!macb_phy_find(macb, name))
return 0;
#endif /* CONFIG_MACB_SEARCH_PHY */
/* Check if the PHY is up to snuff... */
phy_id = macb_mdio_read(macb, MII_PHYSID1);
@ -667,7 +663,8 @@ static int _macb_init(struct macb_device *macb, const char *name)
* to select interface between RMII and MII.
*/
#ifdef CONFIG_DM_ETH
if (macb->phy_interface == PHY_INTERFACE_MODE_RMII)
if ((macb->phy_interface == PHY_INTERFACE_MODE_RMII) ||
(macb->phy_interface == PHY_INTERFACE_MODE_RGMII))
gem_writel(macb, UR, GEM_BIT(RGMII));
else
gem_writel(macb, UR, 0);

View file

@ -442,7 +442,7 @@ do { \
/* MPCS registers */
#define PCS40G_COMMON_CONTROL 0x14
#define FORWARD_ERROR_CORRECTION_MASK BIT(1)
#define FORWARD_ERROR_CORRECTION_MASK BIT(10)
#define PCS_CLOCK_RESET 0x14c
#define TX_SD_CLK_RESET_MASK BIT(0)
@ -3251,7 +3251,7 @@ static int gop_xpcs_mode(struct mvpp2_port *port, int num_of_lanes)
/* configure XG MAC mode */
val = readl(port->priv->xpcs_base + MVPP22_XPCS_GLOBAL_CFG_0_REG);
val &= ~MVPP22_XPCS_PCSMODE_OFFS;
val &= ~MVPP22_XPCS_PCSMODE_MASK;
val &= ~MVPP22_XPCS_LANEACTIVE_MASK;
val |= (2 * lane) << MVPP22_XPCS_LANEACTIVE_OFFS;
writel(val, port->priv->xpcs_base + MVPP22_XPCS_GLOBAL_CFG_0_REG);
@ -4479,7 +4479,15 @@ static int mvpp2_rx_refill(struct mvpp2_port *port,
/* Set hw internals when starting port */
static void mvpp2_start_dev(struct mvpp2_port *port)
{
mvpp2_gmac_max_rx_size_set(port);
switch (port->phy_interface) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_SGMII:
mvpp2_gmac_max_rx_size_set(port);
default:
break;
}
mvpp2_txp_max_tx_size_set(port);
if (port->priv->hw_version == MVPP21)
@ -4574,11 +4582,16 @@ static int mvpp2_open(struct udevice *dev, struct mvpp2_port *port)
return err;
}
err = mvpp2_phy_connect(dev, port);
if (err < 0)
return err;
if (port->phy_node) {
err = mvpp2_phy_connect(dev, port);
if (err < 0)
return err;
mvpp2_link_event(port);
mvpp2_link_event(port);
} else {
mvpp2_egress_enable(port);
mvpp2_ingress_enable(port);
}
mvpp2_start_dev(port);
@ -4723,13 +4736,19 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
const char *phy_mode_str;
int phy_node;
u32 id;
u32 phyaddr;
u32 phyaddr = 0;
int phy_mode = -1;
phy_node = fdtdec_lookup_phandle(gd->fdt_blob, port_node, "phy");
if (phy_node < 0) {
dev_err(&pdev->dev, "missing phy\n");
return -ENODEV;
if (phy_node > 0) {
phyaddr = fdtdec_get_int(gd->fdt_blob, phy_node, "reg", 0);
if (phyaddr < 0) {
dev_err(&pdev->dev, "could not find phy address\n");
return -1;
}
} else {
phy_node = 0;
}
phy_mode_str = fdt_getprop(gd->fdt_blob, port_node, "phy-mode", NULL);
@ -4755,8 +4774,6 @@ static int phy_info_parse(struct udevice *dev, struct mvpp2_port *port)
port->phy_speed = fdtdec_get_int(gd->fdt_blob, port_node,
"phy-speed", 1000);
phyaddr = fdtdec_get_int(gd->fdt_blob, phy_node, "reg", 0);
port->id = id;
if (port->priv->hw_version == MVPP21)
port->first_rxq = port->id * rxq_number;
@ -5316,7 +5333,14 @@ static int mvpp2_start(struct udevice *dev)
/* Reconfigure parser accept the original MAC address */
mvpp2_prs_update_mac_da(port, port->dev_addr);
mvpp2_port_power_up(port);
switch (port->phy_interface) {
case PHY_INTERFACE_MODE_RGMII:
case PHY_INTERFACE_MODE_RGMII_ID:
case PHY_INTERFACE_MODE_SGMII:
mvpp2_port_power_up(port);
default:
break;
}
mvpp2_open(dev, port);
@ -5479,7 +5503,8 @@ static int mvpp2_probe(struct udevice *dev)
port->gop_id * MVPP22_PORT_OFFSET;
/* Set phy address of the port */
mvpp22_smi_phy_addr_cfg(port);
if(port->phy_node)
mvpp22_smi_phy_addr_cfg(port);
/* GoP Init */
gop_port_init(port);

View file

@ -117,15 +117,17 @@ static void pch_gbe_rx_descs_init(struct udevice *dev)
memset(rx_desc, 0, sizeof(struct pch_gbe_rx_desc) * PCH_GBE_DESC_NUM);
for (i = 0; i < PCH_GBE_DESC_NUM; i++)
rx_desc->buffer_addr = dm_pci_phys_to_mem(priv->dev,
(ulong)(priv->rx_buff[i]));
rx_desc[i].buffer_addr = dm_pci_virt_to_mem(priv->dev,
priv->rx_buff[i]);
writel(dm_pci_phys_to_mem(priv->dev, (ulong)rx_desc),
flush_dcache_range((ulong)rx_desc, (ulong)&rx_desc[PCH_GBE_DESC_NUM]);
writel(dm_pci_virt_to_mem(priv->dev, rx_desc),
&mac_regs->rx_dsc_base);
writel(sizeof(struct pch_gbe_rx_desc) * (PCH_GBE_DESC_NUM - 1),
&mac_regs->rx_dsc_size);
writel(dm_pci_phys_to_mem(priv->dev, (ulong)(rx_desc + 1)),
writel(dm_pci_virt_to_mem(priv->dev, rx_desc + 1),
&mac_regs->rx_dsc_sw_p);
}
@ -137,11 +139,13 @@ static void pch_gbe_tx_descs_init(struct udevice *dev)
memset(tx_desc, 0, sizeof(struct pch_gbe_tx_desc) * PCH_GBE_DESC_NUM);
writel(dm_pci_phys_to_mem(priv->dev, (ulong)tx_desc),
flush_dcache_range((ulong)tx_desc, (ulong)&tx_desc[PCH_GBE_DESC_NUM]);
writel(dm_pci_virt_to_mem(priv->dev, tx_desc),
&mac_regs->tx_dsc_base);
writel(sizeof(struct pch_gbe_tx_desc) * (PCH_GBE_DESC_NUM - 1),
&mac_regs->tx_dsc_size);
writel(dm_pci_phys_to_mem(priv->dev, (ulong)(tx_desc + 1)),
writel(dm_pci_virt_to_mem(priv->dev, tx_desc + 1),
&mac_regs->tx_dsc_sw_p);
}
@ -245,24 +249,28 @@ static int pch_gbe_send(struct udevice *dev, void *packet, int length)
u32 int_st;
ulong start;
flush_dcache_range((ulong)packet, (ulong)packet + length);
tx_head = &priv->tx_desc[0];
tx_desc = &priv->tx_desc[priv->tx_idx];
if (length < 64)
frame_ctrl |= PCH_GBE_TXD_CTRL_APAD;
tx_desc->buffer_addr = dm_pci_phys_to_mem(priv->dev, (ulong)packet);
tx_desc->buffer_addr = dm_pci_virt_to_mem(priv->dev, packet);
tx_desc->length = length;
tx_desc->tx_words_eob = length + 3;
tx_desc->tx_frame_ctrl = frame_ctrl;
tx_desc->dma_status = 0;
tx_desc->gbec_status = 0;
flush_dcache_range((ulong)tx_desc, (ulong)&tx_desc[1]);
/* Test the wrap-around condition */
if (++priv->tx_idx >= PCH_GBE_DESC_NUM)
priv->tx_idx = 0;
writel(dm_pci_phys_to_mem(priv->dev, (ulong)(tx_head + priv->tx_idx)),
writel(dm_pci_virt_to_mem(priv->dev, tx_head + priv->tx_idx),
&mac_regs->tx_dsc_sw_p);
start = get_timer(0);
@ -283,7 +291,8 @@ static int pch_gbe_recv(struct udevice *dev, int flags, uchar **packetp)
struct pch_gbe_priv *priv = dev_get_priv(dev);
struct pch_gbe_regs *mac_regs = priv->mac_regs;
struct pch_gbe_rx_desc *rx_desc;
ulong hw_desc, buffer_addr, length;
ulong hw_desc, length;
void *buffer;
rx_desc = &priv->rx_desc[priv->rx_idx];
@ -291,12 +300,16 @@ static int pch_gbe_recv(struct udevice *dev, int flags, uchar **packetp)
hw_desc = readl(&mac_regs->rx_dsc_hw_p_hld);
/* Just return if not receiving any packet */
if ((ulong)rx_desc == hw_desc)
if (virt_to_phys(rx_desc) == hw_desc)
return -EAGAIN;
buffer_addr = dm_pci_mem_to_phys(priv->dev, rx_desc->buffer_addr);
*packetp = (uchar *)buffer_addr;
/* Invalidate the descriptor */
invalidate_dcache_range((ulong)rx_desc, (ulong)&rx_desc[1]);
length = rx_desc->rx_words_eob - 3 - ETH_FCS_LEN;
buffer = dm_pci_mem_to_virt(priv->dev, rx_desc->buffer_addr, length, 0);
invalidate_dcache_range((ulong)buffer, (ulong)buffer + length);
*packetp = (uchar *)buffer;
return length;
}
@ -315,7 +328,7 @@ static int pch_gbe_free_pkt(struct udevice *dev, uchar *packet, int length)
if (++rx_swp >= PCH_GBE_DESC_NUM)
rx_swp = 0;
writel(dm_pci_phys_to_mem(priv->dev, (ulong)(rx_head + rx_swp)),
writel(dm_pci_virt_to_mem(priv->dev, rx_head + rx_swp),
&mac_regs->rx_dsc_sw_p);
return 0;
@ -422,6 +435,7 @@ int pch_gbe_probe(struct udevice *dev)
struct pch_gbe_priv *priv;
struct eth_pdata *plat = dev_get_platdata(dev);
void *iobase;
int err;
/*
* The priv structure contains the descriptors and frame buffers which
@ -444,6 +458,10 @@ int pch_gbe_probe(struct udevice *dev)
pch_gbe_mdio_init(dev->name, priv->mac_regs);
priv->bus = miiphy_get_dev_by_name(dev->name);
err = pch_gbe_reset(dev);
if (err)
return err;
return pch_gbe_phy_init(dev);
}

View file

@ -57,6 +57,40 @@ config PHY_MARVELL
config PHY_MICREL
bool "Micrel Ethernet PHYs support"
help
Enable support for the GbE PHYs manufactured by Micrel (now
a part of Microchip). This includes drivers for the KSZ804,
KSZ8031, KSZ8051, KSZ8081, KSZ8895, KSZ886x, KSZ8721
either/or KSZ9021 (see the "Micrel KSZ9021 family support"
config option for details), and KSZ9031 (if configured).
if PHY_MICREL
config PHY_MICREL_KSZ9021
bool "Micrel KSZ9021 family support"
select PHY_GIGE
help
Enable support for the Micrel KSZ9021 GbE PHY family. If
enabled, the extended register read/write for KSZ9021 PHYs
is supported through the 'mdio' command and any RGMII signal
delays configured in the device tree will be applied to the
PHY during initialisation.
Note that the KSZ9021 uses the same part number os the
KSZ8921BL, so enabling this option disables support for the
KSZ8721BL.
config PHY_MICREL_KSZ9031
bool "Micrel KSZ9031 family support"
select PHY_GIGE
help
Enable support for the Micrel KSZ9031 GbE PHY family. If
enabled, the extended register read/write for KSZ9021 PHYs
is supported through the 'mdio' command and any RGMII signal
delays configured in the device tree will be applied to the
PHY during initialisatioin.
endif # PHY_MICREL
config PHY_MSCC
bool "Microsemi Corp Ethernet PHYs support"

View file

@ -13,6 +13,8 @@
#define PHY_AUTONEGOTIATE_TIMEOUT 5000
#define MII_MARVELL_PHY_PAGE 22
/* 88E1011 PHY Status Register */
#define MIIM_88E1xxx_PHY_STATUS 0x11
#define MIIM_88E1xxx_PHYSTAT_SPEED 0xc000
@ -83,6 +85,11 @@
#define MIIM_88E1310_PHY_PAGE 22
/* 88E151x PHY defines */
/* Page 2 registers */
#define MIIM_88E151x_PHY_MSCR 21
#define MIIM_88E151x_RGMII_RX_DELAY BIT(5)
#define MIIM_88E151x_RGMII_TX_DELAY BIT(4)
#define MIIM_88E151x_RGMII_RXTX_DELAY (BIT(5) | BIT(4))
/* Page 3 registers */
#define MIIM_88E151x_LED_FUNC_CTRL 16
#define MIIM_88E151x_LED_FLD_SZ 4
@ -295,6 +302,8 @@ void m88e1518_phy_writebits(struct phy_device *phydev,
static int m88e1518_config(struct phy_device *phydev)
{
u16 reg;
/*
* As per Marvell Release Notes - Alaska 88E1510/88E1518/88E1512
* /88E1514 Rev A0, Errata Section 3.1
@ -331,7 +340,41 @@ static int m88e1518_config(struct phy_device *phydev)
udelay(100);
}
return m88e1111s_config(phydev);
if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
reg = phy_read(phydev, MDIO_DEVAD_NONE,
MIIM_88E1111_PHY_EXT_SR);
reg &= ~(MIIM_88E1111_HWCFG_MODE_MASK);
reg |= MIIM_88E1111_HWCFG_MODE_SGMII_NO_CLK;
reg |= MIIM_88E1111_HWCFG_FIBER_COPPER_AUTO;
phy_write(phydev, MDIO_DEVAD_NONE,
MIIM_88E1111_PHY_EXT_SR, reg);
}
if (phy_interface_is_rgmii(phydev)) {
phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, 2);
reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR);
reg &= ~MIIM_88E151x_RGMII_RXTX_DELAY;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID)
reg |= MIIM_88E151x_RGMII_RXTX_DELAY;
else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)
reg |= MIIM_88E151x_RGMII_RX_DELAY;
else if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)
reg |= MIIM_88E151x_RGMII_TX_DELAY;
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E151x_PHY_MSCR, reg);
phy_write(phydev, MDIO_DEVAD_NONE, MII_MARVELL_PHY_PAGE, 0);
}
/* soft reset */
phy_reset(phydev);
genphy_config_aneg(phydev);
genphy_restart_aneg(phydev);
return 0;
}
/* Marvell 88E1510 */

View file

@ -192,7 +192,7 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
int err;
err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
true, 20000, true);
true, 20000, false);
if (err)
return err;
@ -205,7 +205,7 @@ static u32 phy_setup_op(struct zynq_gem_priv *priv, u32 phy_addr, u32 regnum,
writel(mgtcr, &regs->phymntnc);
err = wait_for_bit(__func__, &regs->nwsr, ZYNQ_GEM_NWSR_MDIOIDLE_MASK,
true, 20000, true);
true, 20000, false);
if (err)
return err;
@ -407,10 +407,6 @@ static int zynq_gem_init(struct udevice *dev)
dummy_rx_bd->addr = ZYNQ_GEM_RXBUF_WRAP_MASK |
ZYNQ_GEM_RXBUF_NEW_MASK;
dummy_rx_bd->status = 0;
flush_dcache_range((ulong)&dummy_tx_bd, (ulong)&dummy_tx_bd +
sizeof(dummy_tx_bd));
flush_dcache_range((ulong)&dummy_rx_bd, (ulong)&dummy_rx_bd +
sizeof(dummy_rx_bd));
writel((ulong)dummy_tx_bd, &regs->transmit_q1_ptr);
writel((ulong)dummy_rx_bd, &regs->receive_q1_ptr);
@ -587,14 +583,12 @@ __weak int zynq_board_read_rom_ethaddr(unsigned char *ethaddr)
static int zynq_gem_read_rom_mac(struct udevice *dev)
{
int retval;
struct eth_pdata *pdata = dev_get_platdata(dev);
retval = zynq_board_read_rom_ethaddr(pdata->enetaddr);
if (retval == -ENOSYS)
retval = 0;
if (!pdata)
return -ENOSYS;
return retval;
return zynq_board_read_rom_ethaddr(pdata->enetaddr);
}
static int zynq_gem_miiphy_read(struct mii_dev *bus, int addr,

View file

@ -181,7 +181,7 @@ int eth_get_dev_index(void)
static int eth_write_hwaddr(struct udevice *dev)
{
struct eth_pdata *pdata = dev->platdata;
struct eth_pdata *pdata;
int ret = 0;
if (!dev || !device_active(dev))
@ -189,6 +189,7 @@ static int eth_write_hwaddr(struct udevice *dev)
/* seq is valid since the device is active */
if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) {
pdata = dev->platdata;
if (!is_valid_ethaddr(pdata->enetaddr)) {
printf("\nError: %s address %pM illegal value\n",
dev->name, pdata->enetaddr);