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

This commit is contained in:
Tom Rini 2017-02-09 11:56:35 -05:00
commit e1a71f8b33
23 changed files with 872 additions and 94 deletions

View file

@ -67,7 +67,7 @@
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
ti,min-output-imepdance;
ti,min-output-impedance;
};
dp83867_1: ethernet-phy@3 {
@ -75,6 +75,6 @@
ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_25_NS>;
ti,tx-internal-delay = <DP83867_RGMIIDCTL_250_PS>;
ti,fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_8_B_NIB>;
ti,min-output-imepdance;
ti,min-output-impedance;
};
};

View file

@ -473,7 +473,7 @@ void fdt_fixup_ethernet(void *fdt)
char *tmp, *end;
char mac[16];
const char *path;
unsigned char mac_addr[6];
unsigned char mac_addr[ARP_HLEN];
int offset;
if (fdt_path_offset(fdt, "/aliases") < 0)

View file

@ -58,3 +58,4 @@ CONFIG_G_DNL_VENDOR_NUM=0x0451
CONFIG_G_DNL_PRODUCT_NUM=0xd022
CONFIG_RSA=y
CONFIG_SPL_OF_LIBFDT=y
CONFIG_PHY_MSCC=y

View file

@ -1,3 +1,5 @@
source "drivers/net/phy/Kconfig"
config DM_ETH
bool "Enable Driver Model for Ethernet drivers"
depends on DM
@ -8,32 +10,6 @@ config DM_ETH
This is currently implemented in net/eth.c
Look in include/net.h for details.
config PHYLIB
bool "Ethernet PHY (physical media interface) support"
help
Enable Ethernet PHY (physical media interface) support.
config RTL8211X_PHY_FORCE_MASTER
bool "Ethernet PHY RTL8211x: force 1000BASE-T master mode"
depends on PHYLIB
help
Force master mode for 1000BASE-T on RTl8211x PHYs (except for RTL8211F).
This can work around link stability and data corruption issues on gigabit
links which can occur in slave mode on certain PHYs, e.g. on the
RTL8211C(L).
Please note that two directly connected devices (i.e. via crossover cable)
will not be able to establish a link between each other if they both force
master mode. Multiple devices forcing master mode when connected by a
network switch do not pose a problem as the switch configures its affected
ports into slave mode.
This option only affects gigabit links. If you must establish a direct
connection between two devices which both force master mode, try forcing
the link speed to 100MBit/s.
If unsure, say N.
menuconfig NETDEVICES
bool "Network device support"
depends on NET
@ -155,6 +131,16 @@ config MVPP2
This driver supports the network interface units in the
Marvell ARMADA 375 SoC.
config MACB
bool "Cadence MACB/GEM Ethernet Interface"
depends on DM_ETH
select PHYLIB
help
The Cadence MACB ethernet interface is found on many Atmel
AT91 and SAMA5 parts. This driver also supports the Cadence
GEM (Gigabit Ethernet MAC) found in some ARM SoC devices.
Say Y to include support for the MACB/GEM chip.
config PCH_GBE
bool "Intel Platform Controller Hub EG20T GMAC driver"
depends on DM_ETH && DM_PCI

View file

@ -764,6 +764,7 @@ static const struct udevice_id designware_eth_ids[] = {
{ .compatible = "allwinner,sun7i-a20-gmac" },
{ .compatible = "altr,socfpga-stmmac" },
{ .compatible = "amlogic,meson6-dwmac" },
{ .compatible = "amlogic,meson-gx-dwmac" },
{ .compatible = "st,stm32-dwmac" },
{ }
};

View file

@ -1240,7 +1240,6 @@ static int fecmxc_probe(struct udevice *dev)
}
fec_reg_setup(priv);
fec_set_dev_name((char *)dev->name, dev_id);
priv->dev_id = (dev_id == -1) ? 0 : dev_id;
return 0;

View file

@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <clk.h>
#include <dm.h>
/*
@ -112,6 +113,7 @@ struct macb_device {
struct mii_dev *bus;
#ifdef CONFIG_DM_ETH
unsigned long pclk_rate;
phy_interface_t phy_interface;
#endif
};
@ -754,7 +756,11 @@ static int _macb_write_hwaddr(struct macb_device *macb, unsigned char *enetaddr)
static u32 macb_mdc_clk_div(int id, struct macb_device *macb)
{
u32 config;
#ifdef CONFIG_DM_ETH
unsigned long macb_hz = macb->pclk_rate;
#else
unsigned long macb_hz = get_macb_pclk_rate(id);
#endif
if (macb_hz < 20000000)
config = MACB_BF(CLK, MACB_CLK_DIV8);
@ -771,7 +777,12 @@ static u32 macb_mdc_clk_div(int id, struct macb_device *macb)
static u32 gem_mdc_clk_div(int id, struct macb_device *macb)
{
u32 config;
#ifdef CONFIG_DM_ETH
unsigned long macb_hz = macb->pclk_rate;
#else
unsigned long macb_hz = get_macb_pclk_rate(id);
#endif
if (macb_hz < 20000000)
config = GEM_BF(CLK, GEM_CLK_DIV8);
@ -991,13 +1002,36 @@ static const struct eth_ops macb_eth_ops = {
.write_hwaddr = macb_write_hwaddr,
};
static int macb_enable_clk(struct udevice *dev)
{
struct macb_device *macb = dev_get_priv(dev);
struct clk clk;
ulong clk_rate;
int ret;
ret = clk_get_by_index(dev, 0, &clk);
if (ret)
return -EINVAL;
ret = clk_enable(&clk);
if (ret)
return ret;
clk_rate = clk_get_rate(&clk);
if (!clk_rate)
return -EINVAL;
macb->pclk_rate = clk_rate;
return 0;
}
static int macb_eth_probe(struct udevice *dev)
{
struct eth_pdata *pdata = dev_get_platdata(dev);
struct macb_device *macb = dev_get_priv(dev);
#ifdef CONFIG_DM_ETH
const char *phy_mode;
int ret;
phy_mode = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), "phy-mode",
NULL);
@ -1007,11 +1041,15 @@ static int macb_eth_probe(struct udevice *dev)
debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
return -EINVAL;
}
#endif
macb->regs = (void *)pdata->iobase;
ret = macb_enable_clk(dev);
if (ret)
return ret;
_macb_eth_initialize(macb);
#if defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
int retval;
struct mii_dev *mdiodev = mdio_alloc();

93
drivers/net/phy/Kconfig Normal file
View file

@ -0,0 +1,93 @@
config BITBANGMII
bool "Bit-banged ethernet MII management channel support"
config MV88E6352_SWITCH
bool "Marvell 88E6352 switch support"
menuconfig PHYLIB
bool "Ethernet PHY (physical media interface) support"
help
Enable Ethernet PHY (physical media interface) support.
if PHYLIB
config MV88E61XX_SWITCH
bool "Marvel MV88E61xx Ethernet switch PHY support."
config PHYLIB_10G
bool "Generic 10G PHY support"
config PHY_AQUANTIA
bool "Aquantia Ethernet PHYs support"
config PHY_ATHEROS
bool "Atheros Ethernet PHYs support"
config PHY_BROADCOM
bool "Broadcom Ethernet PHYs support"
config PHY_CORTINA
bool "Cortina Ethernet PHYs support"
config PHY_DAVICOM
bool "Davicom Ethernet PHYs support"
config PHY_ET1011C
bool "LSI TruePHY ET1011C support"
config PHY_LXT
bool "LXT971 Ethernet PHY support"
config PHY_MARVELL
bool "Marvell Ethernet PHYs support"
config PHY_MICREL
bool "Micrel Ethernet PHYs support"
config PHY_MSCC
bool "Microsemi Corp Ethernet PHYs support"
config PHY_NATSEMI
bool "National Semiconductor Ethernet PHYs support"
config PHY_REALTEK
bool "Realtek Ethernet PHYs support"
config RTL8211X_PHY_FORCE_MASTER
bool "Ethernet PHY RTL8211x: force 1000BASE-T master mode"
depends on PHY_REALTEK
help
Force master mode for 1000BASE-T on RTl8211x PHYs (except for RTL8211F).
This can work around link stability and data corruption issues on gigabit
links which can occur in slave mode on certain PHYs, e.g. on the
RTL8211C(L).
Please note that two directly connected devices (i.e. via crossover cable)
will not be able to establish a link between each other if they both force
master mode. Multiple devices forcing master mode when connected by a
network switch do not pose a problem as the switch configures its affected
ports into slave mode.
This option only affects gigabit links. If you must establish a direct
connection between two devices which both force master mode, try forcing
the link speed to 100MBit/s.
If unsure, say N.
config PHY_SMSC
bool "Microchip(SMSC) Ethernet PHYs support"
config PHY_TERANETICS
bool "Teranetics Ethernet PHYs support"
config PHY_TI
bool "Texas Instruments Ethernet PHYs support"
config PHY_VITESSE
bool "Vitesse Ethernet PHYs support"
config PHY_XILINX
bool "Xilinx Ethernet PHYs support"
endif #PHYLIB

View file

@ -27,3 +27,4 @@ obj-$(CONFIG_PHY_TERANETICS) += teranetics.o
obj-$(CONFIG_PHY_TI) += ti.o
obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o
obj-$(CONFIG_PHY_VITESSE) += vitesse.o
obj-$(CONFIG_PHY_MSCC) += mscc.o

View file

@ -82,6 +82,21 @@
#define MIIM_88E1310_PHY_RGMII_CTRL 21
#define MIIM_88E1310_PHY_PAGE 22
/* 88E151x PHY defines */
/* Page 3 registers */
#define MIIM_88E151x_LED_FUNC_CTRL 16
#define MIIM_88E151x_LED_FLD_SZ 4
#define MIIM_88E151x_LED0_OFFS (0 * MIIM_88E151x_LED_FLD_SZ)
#define MIIM_88E151x_LED1_OFFS (1 * MIIM_88E151x_LED_FLD_SZ)
#define MIIM_88E151x_LED0_ACT 3
#define MIIM_88E151x_LED1_100_1000_LINK 6
#define MIIM_88E151x_LED_TIMER_CTRL 18
#define MIIM_88E151x_INT_EN_OFFS 7
/* Page 18 registers */
#define MIIM_88E151x_GENERAL_CTRL 20
#define MIIM_88E151x_MODE_SGMII 1
#define MIIM_88E151x_RESET_OFFS 15
/* Marvell 88E1011S */
static int m88e1011s_config(struct phy_device *phydev)
{
@ -177,10 +192,7 @@ static int m88e1111s_config(struct phy_device *phydev)
{
int reg;
if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
if (phy_interface_is_rgmii(phydev)) {
reg = phy_read(phydev,
MDIO_DEVAD_NONE, MIIM_88E1111_PHY_EXT_CR);
if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
@ -289,7 +301,7 @@ static int m88e1518_config(struct phy_device *phydev)
*/
/* EEE initialization */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x00ff);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x00ff);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x214B);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2144);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0x0C28);
@ -298,21 +310,23 @@ static int m88e1518_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x214D);
phy_write(phydev, MDIO_DEVAD_NONE, 17, 0xCC0C);
phy_write(phydev, MDIO_DEVAD_NONE, 16, 0x2159);
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0x0000);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0x0000);
/* SGMII-to-Copper mode initialization */
if (phydev->interface == PHY_INTERFACE_MODE_SGMII) {
/* Select page 18 */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 18);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 18);
/* In reg 20, write MODE[2:0] = 0x1 (SGMII to Copper) */
m88e1518_phy_writebits(phydev, 20, 0, 3, 1);
m88e1518_phy_writebits(phydev, MIIM_88E151x_GENERAL_CTRL,
0, 3, MIIM_88E151x_MODE_SGMII);
/* PHY reset is necessary after changing MODE[2:0] */
m88e1518_phy_writebits(phydev, 20, 15, 1, 1);
m88e1518_phy_writebits(phydev, MIIM_88E151x_GENERAL_CTRL,
MIIM_88E151x_RESET_OFFS, 1, 1);
/* Reset page selection */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0);
udelay(100);
}
@ -324,17 +338,25 @@ static int m88e1518_config(struct phy_device *phydev)
static int m88e1510_config(struct phy_device *phydev)
{
/* Select page 3 */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 3);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE,
MIIM_88E1118_PHY_LED_PAGE);
/* Enable INTn output on LED[2] */
m88e1518_phy_writebits(phydev, 18, 7, 1, 1);
m88e1518_phy_writebits(phydev, MIIM_88E151x_LED_TIMER_CTRL,
MIIM_88E151x_INT_EN_OFFS, 1, 1);
/* Configure LEDs */
m88e1518_phy_writebits(phydev, 16, 0, 4, 3); /* LED[0]:0011 (ACT) */
m88e1518_phy_writebits(phydev, 16, 4, 4, 6); /* LED[1]:0110 (LINK) */
/* LED[0]:0011 (ACT) */
m88e1518_phy_writebits(phydev, MIIM_88E151x_LED_FUNC_CTRL,
MIIM_88E151x_LED0_OFFS, MIIM_88E151x_LED_FLD_SZ,
MIIM_88E151x_LED0_ACT);
/* LED[1]:0110 (LINK 100/1000 Mbps) */
m88e1518_phy_writebits(phydev, MIIM_88E151x_LED_FUNC_CTRL,
MIIM_88E151x_LED1_OFFS, MIIM_88E151x_LED_FLD_SZ,
MIIM_88E151x_LED1_100_1000_LINK);
/* Reset page selection */
phy_write(phydev, MDIO_DEVAD_NONE, 22, 0);
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_88E1118_PHY_PAGE, 0);
return m88e1518_config(phydev);
}
@ -596,17 +618,22 @@ static struct phy_driver M88E1149S_driver = {
static struct phy_driver M88E1510_driver = {
.name = "Marvell 88E1510",
.uid = 0x1410dd0,
.mask = 0xffffff0,
.mask = 0xfffffff,
.features = PHY_GBIT_FEATURES,
.config = &m88e1510_config,
.startup = &m88e1011s_startup,
.shutdown = &genphy_shutdown,
};
/*
* This supports:
* 88E1518, uid 0x1410dd1
* 88E1512, uid 0x1410dd4
*/
static struct phy_driver M88E1518_driver = {
.name = "Marvell 88E1518",
.uid = 0x1410dd1,
.mask = 0xffffff0,
.uid = 0x1410dd0,
.mask = 0xffffffa,
.features = PHY_GBIT_FEATURES,
.config = &m88e1518_config,
.startup = &m88e1011s_startup,

508
drivers/net/phy/mscc.c Normal file
View file

@ -0,0 +1,508 @@
/*
* Microsemi PHY drivers
*
* SPDX-License-Identifier: The MIT License (MIT)
*
* Copyright (c) 2016 Microsemi Corporation
*
* Author: John Haechten
*
*/
#include <miiphy.h>
#include <bitfield.h>
/* Microsemi PHY ID's */
#define PHY_ID_VSC8530 0x00070560
#define PHY_ID_VSC8531 0x00070570
#define PHY_ID_VSC8540 0x00070760
#define PHY_ID_VSC8541 0x00070770
/* Microsemi VSC85xx PHY Register Pages */
#define MSCC_EXT_PAGE_ACCESS 31 /* Page Access Register */
#define MSCC_PHY_PAGE_STD 0x0000 /* Standard registers */
#define MSCC_PHY_PAGE_EXT1 0x0001 /* Extended registers - page 1 */
#define MSCC_PHY_PAGE_EXT2 0x0002 /* Extended registers - page 2 */
#define MSCC_PHY_PAGE_EXT3 0x0003 /* Extended registers - page 3 */
#define MSCC_PHY_PAGE_EXT4 0x0004 /* Extended registers - page 4 */
#define MSCC_PHY_PAGE_GPIO 0x0010 /* GPIO registers */
#define MSCC_PHY_PAGE_TEST 0x2A30 /* TEST Page registers */
#define MSCC_PHY_PAGE_TR 0x52B5 /* Token Ring Page registers */
/* Std Page Register 28 - PHY AUX Control/Status */
#define MIIM_AUX_CNTRL_STAT_REG 28
#define MIIM_AUX_CNTRL_STAT_ACTIPHY_TO (0x0004)
#define MIIM_AUX_CNTRL_STAT_F_DUPLEX (0x0020)
#define MIIM_AUX_CNTRL_STAT_SPEED_MASK (0x0018)
#define MIIM_AUX_CNTRL_STAT_SPEED_POS (3)
#define MIIM_AUX_CNTRL_STAT_SPEED_10M (0x0)
#define MIIM_AUX_CNTRL_STAT_SPEED_100M (0x1)
#define MIIM_AUX_CNTRL_STAT_SPEED_1000M (0x2)
/* Std Page Register 23 - Extended PHY CTRL_1 */
#define MSCC_PHY_EXT_PHY_CNTL_1_REG 23
#define MAC_IF_SELECTION_MASK (0x1800)
#define MAC_IF_SELECTION_GMII (0)
#define MAC_IF_SELECTION_RMII (1)
#define MAC_IF_SELECTION_RGMII (2)
#define MAC_IF_SELECTION_POS (11)
#define MAC_IF_SELECTION_WIDTH (2)
/* Extended Page 2 Register 20E2 */
#define MSCC_PHY_RGMII_CNTL_REG 20
#define VSC_FAST_LINK_FAIL2_ENA_MASK (0x8000)
#define RX_CLK_OUT_MASK (0x0800)
#define RX_CLK_OUT_POS (11)
#define RX_CLK_OUT_WIDTH (1)
#define RX_CLK_OUT_NORMAL (0)
#define RX_CLK_OUT_DISABLE (1)
#define RGMII_RX_CLK_DELAY_POS (4)
#define RGMII_RX_CLK_DELAY_WIDTH (3)
#define RGMII_RX_CLK_DELAY_MASK (0x0070)
#define RGMII_TX_CLK_DELAY_POS (0)
#define RGMII_TX_CLK_DELAY_WIDTH (3)
#define RGMII_TX_CLK_DELAY_MASK (0x0007)
/* Extended Page 2 Register 27E2 */
#define MSCC_PHY_WOL_MAC_CONTROL 27
#define EDGE_RATE_CNTL_POS (5)
#define EDGE_RATE_CNTL_WIDTH (3)
#define EDGE_RATE_CNTL_MASK (0x00E0)
#define RMII_CLK_OUT_ENABLE_POS (4)
#define RMII_CLK_OUT_ENABLE_WIDTH (1)
#define RMII_CLK_OUT_ENABLE_MASK (0x10)
/* Token Ring Page 0x52B5 Registers */
#define MSCC_PHY_REG_TR_ADDR_16 16
#define MSCC_PHY_REG_TR_DATA_17 17
#define MSCC_PHY_REG_TR_DATA_18 18
/* Token Ring - Read Value in */
#define MSCC_PHY_TR_16_READ (0xA000)
/* Token Ring - Write Value out */
#define MSCC_PHY_TR_16_WRITE (0x8000)
/* Token Ring Registers */
#define MSCC_PHY_TR_LINKDETCTRL_POS (3)
#define MSCC_PHY_TR_LINKDETCTRL_WIDTH (2)
#define MSCC_PHY_TR_LINKDETCTRL_VAL (3)
#define MSCC_PHY_TR_LINKDETCTRL_MASK (0x0018)
#define MSCC_PHY_TR_LINKDETCTRL_ADDR (0x07F8)
#define MSCC_PHY_TR_VGATHRESH100_POS (0)
#define MSCC_PHY_TR_VGATHRESH100_WIDTH (7)
#define MSCC_PHY_TR_VGATHRESH100_VAL (0x0018)
#define MSCC_PHY_TR_VGATHRESH100_MASK (0x007f)
#define MSCC_PHY_TR_VGATHRESH100_ADDR (0x0FA4)
#define MSCC_PHY_TR_VGAGAIN10_U_POS (0)
#define MSCC_PHY_TR_VGAGAIN10_U_WIDTH (1)
#define MSCC_PHY_TR_VGAGAIN10_U_MASK (0x0001)
#define MSCC_PHY_TR_VGAGAIN10_U_VAL (0)
#define MSCC_PHY_TR_VGAGAIN10_L_POS (12)
#define MSCC_PHY_TR_VGAGAIN10_L_WIDTH (4)
#define MSCC_PHY_TR_VGAGAIN10_L_MASK (0xf000)
#define MSCC_PHY_TR_VGAGAIN10_L_VAL (0x0001)
#define MSCC_PHY_TR_VGAGAIN10_ADDR (0x0F92)
/* General Timeout Values */
#define MSCC_PHY_RESET_TIMEOUT (100)
#define MSCC_PHY_MICRO_TIMEOUT (500)
/* RGMII/GMII Clock Delay (Skew) Options */ enum vsc_phy_rgmii_skew {
VSC_PHY_RGMII_DELAY_200_PS,
VSC_PHY_RGMII_DELAY_800_PS,
VSC_PHY_RGMII_DELAY_1100_PS,
VSC_PHY_RGMII_DELAY_1700_PS,
VSC_PHY_RGMII_DELAY_2000_PS,
VSC_PHY_RGMII_DELAY_2300_PS,
VSC_PHY_RGMII_DELAY_2600_PS,
VSC_PHY_RGMII_DELAY_3400_PS,
};
/* MAC i/f Clock Edge Rage Control (Slew), See Reg27E2 */ enum
vsc_phy_clk_slew {
VSC_PHY_CLK_SLEW_RATE_0,
VSC_PHY_CLK_SLEW_RATE_1,
VSC_PHY_CLK_SLEW_RATE_2,
VSC_PHY_CLK_SLEW_RATE_3,
VSC_PHY_CLK_SLEW_RATE_4,
VSC_PHY_CLK_SLEW_RATE_5,
VSC_PHY_CLK_SLEW_RATE_6,
VSC_PHY_CLK_SLEW_RATE_7,
};
static int mscc_vsc8531_vsc8541_init_scripts(struct phy_device *phydev)
{
u16 reg_val;
/* Set to Access Token Ring Registers */
phy_write(phydev, MDIO_DEVAD_NONE,
MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_TR);
/* Update LinkDetectCtrl default to optimized values */
/* Determined during Silicon Validation Testing */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
(MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_READ));
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_LINKDETCTRL_POS,
MSCC_PHY_TR_LINKDETCTRL_WIDTH,
MSCC_PHY_TR_LINKDETCTRL_VAL);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
(MSCC_PHY_TR_LINKDETCTRL_ADDR | MSCC_PHY_TR_16_WRITE));
/* Update VgaThresh100 defaults to optimized values */
/* Determined during Silicon Validation Testing */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
(MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_READ));
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGATHRESH100_POS,
MSCC_PHY_TR_VGATHRESH100_WIDTH,
MSCC_PHY_TR_VGATHRESH100_VAL);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
(MSCC_PHY_TR_VGATHRESH100_ADDR | MSCC_PHY_TR_16_WRITE));
/* Update VgaGain10 defaults to optimized values */
/* Determined during Silicon Validation Testing */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
(MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_READ));
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18);
reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_U_POS,
MSCC_PHY_TR_VGAGAIN10_U_WIDTH,
MSCC_PHY_TR_VGAGAIN10_U_VAL);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_18, reg_val);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17);
reg_val = bitfield_replace(reg_val, MSCC_PHY_TR_VGAGAIN10_L_POS,
MSCC_PHY_TR_VGAGAIN10_L_WIDTH,
MSCC_PHY_TR_VGAGAIN10_L_VAL);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_DATA_17, reg_val);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_REG_TR_ADDR_16,
(MSCC_PHY_TR_VGAGAIN10_ADDR | MSCC_PHY_TR_16_WRITE));
/* Set back to Access Standard Page Registers */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
return 0;
}
static int mscc_parse_status(struct phy_device *phydev)
{
u16 speed;
u16 mii_reg;
mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_AUX_CNTRL_STAT_REG);
if (mii_reg & MIIM_AUX_CNTRL_STAT_F_DUPLEX)
phydev->duplex = DUPLEX_FULL;
else
phydev->duplex = DUPLEX_HALF;
speed = mii_reg & MIIM_AUX_CNTRL_STAT_SPEED_MASK;
speed = speed >> MIIM_AUX_CNTRL_STAT_SPEED_POS;
switch (speed) {
case MIIM_AUX_CNTRL_STAT_SPEED_1000M:
phydev->speed = SPEED_1000;
break;
case MIIM_AUX_CNTRL_STAT_SPEED_100M:
phydev->speed = SPEED_100;
break;
case MIIM_AUX_CNTRL_STAT_SPEED_10M:
phydev->speed = SPEED_10;
break;
default:
phydev->speed = SPEED_10;
break;
}
return 0;
}
static int mscc_startup(struct phy_device *phydev)
{
int retval;
retval = genphy_update_link(phydev);
if (retval)
return retval;
return mscc_parse_status(phydev);
}
static int mscc_phy_soft_reset(struct phy_device *phydev)
{
int retval = 0;
u16 timeout = MSCC_PHY_RESET_TIMEOUT;
u16 reg_val = 0;
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, (reg_val | BMCR_RESET));
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
while ((reg_val & BMCR_RESET) && (timeout > 0)) {
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
timeout--;
udelay(1000); /* 1 ms */
}
if (timeout == 0) {
printf("MSCC PHY Soft_Reset Error: mac i/f = 0x%x\n",
phydev->interface);
retval = -ETIME;
}
return retval;
}
static int vsc8531_vsc8541_mac_config(struct phy_device *phydev)
{
u16 reg_val = 0;
u16 mac_if = 0;
u16 rx_clk_out = 0;
/* For VSC8530/31 the only MAC modes are RMII/RGMII. */
/* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
/* Setup MAC Configuration */
switch (phydev->interface) {
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
/* Set Reg23.12:11=0 */
mac_if = MAC_IF_SELECTION_GMII;
/* Set Reg20E2.11=1 */
rx_clk_out = RX_CLK_OUT_DISABLE;
break;
case PHY_INTERFACE_MODE_RMII:
/* Set Reg23.12:11=1 */
mac_if = MAC_IF_SELECTION_RMII;
/* Set Reg20E2.11=0 */
rx_clk_out = RX_CLK_OUT_NORMAL;
break;
case PHY_INTERFACE_MODE_RGMII:
/* Set Reg23.12:11=2 */
mac_if = MAC_IF_SELECTION_RGMII;
/* Set Reg20E2.11=0 */
rx_clk_out = RX_CLK_OUT_NORMAL;
break;
default:
printf("MSCC PHY - INVALID MAC i/f Config: mac i/f = 0x%x\n",
phydev->interface);
return -EINVAL;
}
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
MSCC_PHY_EXT_PHY_CNTL_1_REG);
/* Set MAC i/f bits Reg23.12:11 */
reg_val = bitfield_replace(reg_val, MAC_IF_SELECTION_POS,
MAC_IF_SELECTION_WIDTH, mac_if);
/* Update Reg23.12:11 */
phy_write(phydev, MDIO_DEVAD_NONE,
MSCC_PHY_EXT_PHY_CNTL_1_REG, reg_val);
/* Setup ExtPg_2 Register Access */
phy_write(phydev, MDIO_DEVAD_NONE,
MSCC_EXT_PAGE_ACCESS, MSCC_PHY_PAGE_EXT2);
/* Read Reg20E2 */
reg_val = phy_read(phydev, MDIO_DEVAD_NONE,
MSCC_PHY_RGMII_CNTL_REG);
reg_val = bitfield_replace(reg_val, RX_CLK_OUT_POS,
RX_CLK_OUT_WIDTH, rx_clk_out);
/* Update Reg20E2.11 */
phy_write(phydev, MDIO_DEVAD_NONE,
MSCC_PHY_RGMII_CNTL_REG, reg_val);
/* Before leaving - Change back to Std Page Register Access */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
return 0;
}
static int vsc8531_config(struct phy_device *phydev)
{
int retval = -EINVAL;
u16 reg_val;
u16 rmii_clk_out;
enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
/* For VSC8530/31 and VSC8540/41 the init scripts are the same */
mscc_vsc8531_vsc8541_init_scripts(phydev);
/* For VSC8530/31 the only MAC modes are RMII/RGMII. */
switch (phydev->interface) {
case PHY_INTERFACE_MODE_RMII:
case PHY_INTERFACE_MODE_RGMII:
retval = vsc8531_vsc8541_mac_config(phydev);
if (retval != 0)
return retval;
retval = mscc_phy_soft_reset(phydev);
if (retval != 0)
return retval;
break;
default:
printf("PHY 8530/31 MAC i/f Config Error: mac i/f = 0x%x\n",
phydev->interface);
return -EINVAL;
}
/* Default RMII Clk Output to 0=OFF/1=ON */
rmii_clk_out = 0;
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_EXT2);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
/* Reg20E2 - Update RGMII RX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
/* Reg20E2 - Update RGMII TX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
/* Reg27E2 - Update Clk Slew Rate. */
reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
EDGE_RATE_CNTL_WIDTH, edge_rate);
/* Reg27E2 - Update RMII Clk Out. */
reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
/* Update Reg27E2 */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
return genphy_config_aneg(phydev);
}
static int vsc8541_config(struct phy_device *phydev)
{
int retval = -EINVAL;
u16 reg_val;
u16 rmii_clk_out;
enum vsc_phy_rgmii_skew rx_clk_skew = VSC_PHY_RGMII_DELAY_1700_PS;
enum vsc_phy_rgmii_skew tx_clk_skew = VSC_PHY_RGMII_DELAY_800_PS;
enum vsc_phy_clk_slew edge_rate = VSC_PHY_CLK_SLEW_RATE_4;
/* For VSC8530/31 and VSC8540/41 the init scripts are the same */
mscc_vsc8531_vsc8541_init_scripts(phydev);
/* For VSC8540/41 the only MAC modes are (G)MII and RMII/RGMII. */
switch (phydev->interface) {
case PHY_INTERFACE_MODE_MII:
case PHY_INTERFACE_MODE_GMII:
case PHY_INTERFACE_MODE_RMII:
case PHY_INTERFACE_MODE_RGMII:
retval = vsc8531_vsc8541_mac_config(phydev);
if (retval != 0)
return retval;
retval = mscc_phy_soft_reset(phydev);
if (retval != 0)
return retval;
break;
default:
printf("PHY 8541 MAC i/f config Error: mac i/f = 0x%x\n",
phydev->interface);
return -EINVAL;
}
/* Default RMII Clk Output to 0=OFF/1=ON */
rmii_clk_out = 0;
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_EXT2);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG);
/* Reg20E2 - Update RGMII RX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_RX_CLK_DELAY_POS,
RGMII_RX_CLK_DELAY_WIDTH, rx_clk_skew);
/* Reg20E2 - Update RGMII TX_Clk Skews. */
reg_val = bitfield_replace(reg_val, RGMII_TX_CLK_DELAY_POS,
RGMII_TX_CLK_DELAY_WIDTH, tx_clk_skew);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_RGMII_CNTL_REG, reg_val);
reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL);
/* Reg27E2 - Update Clk Slew Rate. */
reg_val = bitfield_replace(reg_val, EDGE_RATE_CNTL_POS,
EDGE_RATE_CNTL_WIDTH, edge_rate);
/* Reg27E2 - Update RMII Clk Out. */
reg_val = bitfield_replace(reg_val, RMII_CLK_OUT_ENABLE_POS,
RMII_CLK_OUT_ENABLE_WIDTH, rmii_clk_out);
/* Update Reg27E2 */
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_PHY_WOL_MAC_CONTROL, reg_val);
phy_write(phydev, MDIO_DEVAD_NONE, MSCC_EXT_PAGE_ACCESS,
MSCC_PHY_PAGE_STD);
return genphy_config_aneg(phydev);
}
static struct phy_driver VSC8530_driver = {
.name = "Microsemi VSC8530",
.uid = PHY_ID_VSC8530,
.mask = 0x000ffff0,
.features = PHY_BASIC_FEATURES,
.config = &vsc8531_config,
.startup = &mscc_startup,
.shutdown = &genphy_shutdown,
};
static struct phy_driver VSC8531_driver = {
.name = "Microsemi VSC8531",
.uid = PHY_ID_VSC8531,
.mask = 0x000ffff0,
.features = PHY_GBIT_FEATURES,
.config = &vsc8531_config,
.startup = &mscc_startup,
.shutdown = &genphy_shutdown,
};
static struct phy_driver VSC8540_driver = {
.name = "Microsemi VSC8540",
.uid = PHY_ID_VSC8540,
.mask = 0x000ffff0,
.features = PHY_BASIC_FEATURES,
.config = &vsc8541_config,
.startup = &mscc_startup,
.shutdown = &genphy_shutdown,
};
static struct phy_driver VSC8541_driver = {
.name = "Microsemi VSC8541",
.uid = PHY_ID_VSC8541,
.mask = 0x000ffff0,
.features = PHY_GBIT_FEATURES,
.config = &vsc8541_config,
.startup = &mscc_startup,
.shutdown = &genphy_shutdown,
};
int phy_mscc_init(void)
{
phy_register(&VSC8530_driver);
phy_register(&VSC8531_driver);
phy_register(&VSC8540_driver);
phy_register(&VSC8541_driver);
return 0;
}

View file

@ -512,6 +512,9 @@ int phy_init(void)
#ifdef CONFIG_PHY_XILINX
phy_xilinx_init();
#endif
#ifdef CONFIG_PHY_MSCC
phy_mscc_init();
#endif
return 0;
}

View file

@ -27,6 +27,7 @@ DECLARE_GLOBAL_DATA_PTR;
/* Extended Registers */
#define DP83867_RGMIICTL 0x0032
#define DP83867_RGMIIDCTL 0x0086
#define DP83867_IO_MUX_CFG 0x0170
#define DP83867_SW_RESET BIT(15)
#define DP83867_SW_RESTART BIT(14)
@ -84,10 +85,17 @@ DECLARE_GLOBAL_DATA_PTR;
#define DEFAULT_TX_ID_DELAY DP83867_RGMIIDCTL_2_75_NS
#define DEFAULT_FIFO_DEPTH DP83867_PHYCR_FIFO_DEPTH_4_B_NIB
/* IO_MUX_CFG bits */
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL 0x1f
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX 0x0
#define DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN 0x1f
struct dp83867_private {
int rx_id_delay;
int tx_id_delay;
int fifo_depth;
int io_impedance;
};
/**
@ -166,6 +174,15 @@ static int dp83867_of_init(struct phy_device *phydev)
{
struct dp83867_private *dp83867 = phydev->priv;
struct udevice *dev = phydev->dev;
int node = dev->of_offset;
const void *fdt = gd->fdt_blob;
if (fdtdec_get_bool(fdt, node, "ti,max-output-impedance"))
dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MAX;
else if (fdtdec_get_bool(fdt, node, "ti,min-output-impedance"))
dp83867->io_impedance = DP83867_IO_MUX_CFG_IO_IMPEDANCE_MIN;
else
dp83867->io_impedance = -EINVAL;
dp83867->rx_id_delay = fdtdec_get_uint(gd->fdt_blob, dev_of_offset(dev),
"ti,rx-internal-delay", -1);
@ -186,6 +203,7 @@ static int dp83867_of_init(struct phy_device *phydev)
dp83867->rx_id_delay = DEFAULT_RX_ID_DELAY;
dp83867->tx_id_delay = DEFAULT_TX_ID_DELAY;
dp83867->fifo_depth = DEFAULT_FIFO_DEPTH;
dp83867->io_impedance = -EINVAL;
return 0;
}
@ -246,8 +264,7 @@ static int dp83867_config(struct phy_device *phydev)
phy_write(phydev, MDIO_DEVAD_NONE, MII_DP83867_BISCR, 0x0);
}
if ((phydev->interface >= PHY_INTERFACE_MODE_RGMII_ID) &&
(phydev->interface <= PHY_INTERFACE_MODE_RGMII_RXID)) {
if (phy_interface_is_rgmii(phydev)) {
val = phy_read_mmd_indirect(phydev, DP83867_RGMIICTL,
DP83867_DEVADDR, phydev->addr);
@ -269,6 +286,19 @@ static int dp83867_config(struct phy_device *phydev)
phy_write_mmd_indirect(phydev, DP83867_RGMIIDCTL,
DP83867_DEVADDR, phydev->addr, delay);
if (dp83867->io_impedance >= 0) {
val = phy_read_mmd_indirect(phydev,
DP83867_IO_MUX_CFG,
DP83867_DEVADDR,
phydev->addr);
val &= ~DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
val |= dp83867->io_impedance &
DP83867_IO_MUX_CFG_IO_IMPEDANCE_CTRL;
phy_write_mmd_indirect(phydev, DP83867_IO_MUX_CFG,
DP83867_DEVADDR, phydev->addr,
val);
}
}
genphy_config_aneg(phydev);

View file

@ -127,9 +127,7 @@ static int cis8204_config(struct phy_device *phydev)
genphy_config_aneg(phydev);
if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
(phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID))
if (phy_interface_is_rgmii(phydev))
phy_write(phydev, MDIO_DEVAD_NONE, MIIM_CIS8204_EPHY_CON,
MIIM_CIS8204_EPHYCON_INIT |
MIIM_CIS8204_EPHYCON_RGMII);

View file

@ -38,6 +38,14 @@
#define PKTALIGN ARCH_DMA_MINALIGN
/* ARP hardware address length */
#define ARP_HLEN 6
/*
* The size of a MAC address in string form, each digit requires two chars
* and five separator characters to form '00:00:00:00:00:00'.
*/
#define ARP_HLEN_ASCII (ARP_HLEN * 2) + (ARP_HLEN - 1)
/* IPv4 addresses are always 32 bits in size */
struct in_addr {
__be32 s_addr;
@ -90,7 +98,7 @@ enum eth_state_t {
*/
struct eth_pdata {
phys_addr_t iobase;
unsigned char enetaddr[6];
unsigned char enetaddr[ARP_HLEN];
int phy_interface;
int max_speed;
};
@ -160,8 +168,9 @@ void eth_halt_state_only(void); /* Set passive state */
#ifndef CONFIG_DM_ETH
struct eth_device {
char name[16];
unsigned char enetaddr[6];
#define ETH_NAME_LEN 16
char name[ETH_NAME_LEN];
unsigned char enetaddr[ARP_HLEN];
phys_addr_t iobase;
int state;
@ -300,8 +309,8 @@ u32 ether_crc(size_t len, unsigned char const *p);
*/
struct ethernet_hdr {
u8 et_dest[6]; /* Destination node */
u8 et_src[6]; /* Source node */
u8 et_dest[ARP_HLEN]; /* Destination node */
u8 et_src[ARP_HLEN]; /* Source node */
u16 et_protlen; /* Protocol or length */
};
@ -311,8 +320,8 @@ struct ethernet_hdr {
#define ETH_FCS_LEN 4 /* Octets in the FCS */
struct e802_hdr {
u8 et_dest[6]; /* Destination node */
u8 et_src[6]; /* Source node */
u8 et_dest[ARP_HLEN]; /* Destination node */
u8 et_src[ARP_HLEN]; /* Source node */
u16 et_protlen; /* Protocol or length */
u8 et_dsap; /* 802 DSAP */
u8 et_ssap; /* 802 SSAP */
@ -330,8 +339,8 @@ struct e802_hdr {
* Virtual LAN Ethernet header
*/
struct vlan_ethernet_hdr {
u8 vet_dest[6]; /* Destination node */
u8 vet_src[6]; /* Source node */
u8 vet_dest[ARP_HLEN]; /* Destination node */
u8 vet_src[ARP_HLEN]; /* Source node */
u16 vet_vlan_type; /* PROT_VLAN */
u16 vet_tag; /* TAG of VLAN */
u16 vet_type; /* protocol type */
@ -405,7 +414,6 @@ struct arp_hdr {
# define ARP_ETHER 1 /* Ethernet hardware address */
u16 ar_pro; /* Format of protocol address */
u8 ar_hln; /* Length of hardware address */
# define ARP_HLEN 6
u8 ar_pln; /* Length of protocol address */
# define ARP_PLEN 4
u16 ar_op; /* Operation */
@ -514,16 +522,16 @@ extern char net_nis_domain[32]; /* Our IS domain */
extern char net_hostname[32]; /* Our hostname */
extern char net_root_path[64]; /* Our root path */
/** END OF BOOTP EXTENTIONS **/
extern u8 net_ethaddr[6]; /* Our ethernet address */
extern u8 net_server_ethaddr[6]; /* Boot server enet address */
extern u8 net_ethaddr[ARP_HLEN]; /* Our ethernet address */
extern u8 net_server_ethaddr[ARP_HLEN]; /* Boot server enet address */
extern struct in_addr net_ip; /* Our IP addr (0 = unknown) */
extern struct in_addr net_server_ip; /* Server IP addr (0 = unknown) */
extern uchar *net_tx_packet; /* THE transmit packet */
extern uchar *net_rx_packets[PKTBUFSRX]; /* Receive packets */
extern uchar *net_rx_packet; /* Current receive packet */
extern int net_rx_packet_len; /* Current rx packet length */
extern const u8 net_bcast_ethaddr[6]; /* Ethernet broadcast address */
extern const u8 net_null_ethaddr[6];
extern const u8 net_bcast_ethaddr[ARP_HLEN]; /* Ethernet broadcast address */
extern const u8 net_null_ethaddr[ARP_HLEN];
#define VLAN_NONE 4095 /* untagged */
#define VLAN_IDMASK 0x0fff /* mask of valid vlan id */
@ -562,9 +570,9 @@ extern ushort cdp_appliance_vlan; /* CDP returned appliance VLAN */
*/
static inline int is_cdp_packet(const uchar *ethaddr)
{
extern const u8 net_cdp_ethaddr[6];
extern const u8 net_cdp_ethaddr[ARP_HLEN];
return memcmp(ethaddr, net_cdp_ethaddr, 6) == 0;
return memcmp(ethaddr, net_cdp_ethaddr, ARP_HLEN) == 0;
}
#endif

View file

@ -266,6 +266,7 @@ int phy_teranetics_init(void);
int phy_ti_init(void);
int phy_vitesse_init(void);
int phy_xilinx_init(void);
int phy_mscc_init(void);
int board_phy_config(struct phy_device *phydev);
int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id);

View file

@ -9,6 +9,9 @@
#ifndef _UBOOT_CRC_H
#define _UBOOT_CRC_H
/* lib/crc8.c */
unsigned int crc8(unsigned int crc_start, const unsigned char *vptr, int len);
/* lib/crc32.c */
uint32_t crc32 (uint32_t, const unsigned char *, uint);
uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint);

View file

@ -230,7 +230,7 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op,
eth_write_hwaddr(dev);
break;
case env_op_delete:
memset(pdata->enetaddr, 0, 6);
memset(pdata->enetaddr, 0, ARP_HLEN);
}
}
@ -458,7 +458,7 @@ static int eth_post_probe(struct udevice *dev)
{
struct eth_device_priv *priv = dev->uclass_priv;
struct eth_pdata *pdata = dev->platdata;
unsigned char env_enetaddr[6];
unsigned char env_enetaddr[ARP_HLEN];
#if defined(CONFIG_NEEDS_MANUAL_RELOC)
struct eth_ops *ops = eth_get_ops(dev);
@ -497,17 +497,17 @@ static int eth_post_probe(struct udevice *dev)
eth_getenv_enetaddr_by_index("eth", dev->seq, env_enetaddr);
if (!is_zero_ethaddr(env_enetaddr)) {
if (!is_zero_ethaddr(pdata->enetaddr) &&
memcmp(pdata->enetaddr, env_enetaddr, 6)) {
memcmp(pdata->enetaddr, env_enetaddr, ARP_HLEN)) {
printf("\nWarning: %s MAC addresses don't match:\n",
dev->name);
printf("Address in SROM is %pM\n",
printf("Address in ROM is %pM\n",
pdata->enetaddr);
printf("Address in environment is %pM\n",
env_enetaddr);
}
/* Override the ROM MAC address */
memcpy(pdata->enetaddr, env_enetaddr, 6);
memcpy(pdata->enetaddr, env_enetaddr, ARP_HLEN);
} else if (is_valid_ethaddr(pdata->enetaddr)) {
eth_setenv_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);
printf("\nWarning: %s using MAC address from ROM\n",
@ -535,7 +535,7 @@ static int eth_pre_remove(struct udevice *dev)
eth_get_ops(dev)->stop(dev);
/* clear the MAC address */
memset(pdata->enetaddr, 0, 6);
memset(pdata->enetaddr, 0, ARP_HLEN);
return 0;
}

View file

@ -32,7 +32,7 @@ int eth_getenv_enetaddr(const char *name, uchar *enetaddr)
int eth_setenv_enetaddr(const char *name, const uchar *enetaddr)
{
char buf[20];
char buf[ARP_HLEN_ASCII + 1];
sprintf(buf, "%pM", enetaddr);

View file

@ -121,7 +121,7 @@ static int on_ethaddr(const char *name, const char *value, enum env_op op,
eth_write_hwaddr(dev, "eth", dev->index);
break;
case env_op_delete:
memset(dev->enetaddr, 0, 6);
memset(dev->enetaddr, 0, ARP_HLEN);
}
}
dev = dev->next;
@ -134,14 +134,14 @@ U_BOOT_ENV_CALLBACK(ethaddr, on_ethaddr);
int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
int eth_number)
{
unsigned char env_enetaddr[6];
unsigned char env_enetaddr[ARP_HLEN];
int ret = 0;
eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr);
if (!is_zero_ethaddr(env_enetaddr)) {
if (!is_zero_ethaddr(dev->enetaddr) &&
memcmp(dev->enetaddr, env_enetaddr, 6)) {
memcmp(dev->enetaddr, env_enetaddr, ARP_HLEN)) {
printf("\nWarning: %s MAC addresses don't match:\n",
dev->name);
printf("Address in SROM is %pM\n",
@ -150,7 +150,7 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
env_enetaddr);
}
memcpy(dev->enetaddr, env_enetaddr, 6);
memcpy(dev->enetaddr, env_enetaddr, ARP_HLEN);
} else if (is_valid_ethaddr(dev->enetaddr)) {
eth_setenv_enetaddr_by_index(base_name, eth_number,
dev->enetaddr);
@ -299,7 +299,7 @@ int eth_initialize(void)
*/
int eth_mcast_join(struct in_addr mcast_ip, int join)
{
u8 mcast_mac[6];
u8 mcast_mac[ARP_HLEN];
if (!eth_current || !eth_current->mcast)
return -1;
mcast_mac[5] = htonl(mcast_ip.s_addr) & 0xff;

1
tools/.gitignore vendored
View file

@ -6,6 +6,7 @@
/fit_check_sign
/fit_info
/gen_eth_addr
/gen_ethaddr_crc
/ifdtool
/img2srec
/kwboot

View file

@ -42,6 +42,10 @@ envcrc-objs := envcrc.o lib/crc32.o common/env_embedded.o lib/sha1.o
hostprogs-$(CONFIG_CMD_NET) += gen_eth_addr
HOSTCFLAGS_gen_eth_addr.o := -pedantic
hostprogs-$(CONFIG_CMD_NET) += gen_ethaddr_crc
gen_ethaddr_crc-objs := gen_ethaddr_crc.o lib/crc8.o
HOSTCFLAGS_gen_ethaddr_crc.o := -pedantic
hostprogs-$(CONFIG_CMD_LOADS) += img2srec
HOSTCFLAGS_img2srec.o := -pedantic
@ -195,6 +199,7 @@ fdtgrep-objs += $(LIBFDT_OBJS) fdtgrep.o
# that won't build on some weird host compiler -- though there are lots of
# exceptions for files that aren't complaint.
HOSTCFLAGS_crc32.o := -pedantic
HOSTCFLAGS_crc8.o := -pedantic
HOSTCFLAGS_md5.o := -pedantic
HOSTCFLAGS_sha1.o := -pedantic
HOSTCFLAGS_sha256.o := -pedantic

75
tools/gen_ethaddr_crc.c Normal file
View file

@ -0,0 +1,75 @@
/*
* (C) Copyright 2016
* Olliver Schinagl <oliver@schinagl.nl>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <u-boot/crc.h>
#define ARP_HLEN 6 /* Length of hardware address */
#define ARP_HLEN_ASCII (ARP_HLEN * 2) + (ARP_HLEN - 1) /* with separators */
#define ARP_HLEN_LAZY (ARP_HLEN * 2) /* separatorless hardware address length */
uint8_t nibble_to_hex(const char *nibble, bool lo)
{
return (strtol(nibble, NULL, 16) << (lo ? 0 : 4)) & (lo ? 0x0f : 0xf0);
}
int process_mac(const char *mac_address)
{
uint8_t ethaddr[ARP_HLEN + 1] = { 0x00 };
uint_fast8_t i = 0;
while (*mac_address != '\0') {
char nibble[2] = { 0x00, '\n' }; /* for strtol */
nibble[0] = *mac_address++;
if (isxdigit(nibble[0])) {
if (isupper(nibble[0]))
nibble[0] = tolower(nibble[0]);
ethaddr[i >> 1] |= nibble_to_hex(nibble, (i % 2) != 0);
i++;
}
}
for (i = 0; i < ARP_HLEN; i++)
printf("%.2x", ethaddr[i]);
printf("%.2x\n", crc8(0, ethaddr, ARP_HLEN));
return 0;
}
void print_usage(char *cmdname)
{
printf("Usage: %s <mac_address>\n", cmdname);
puts("<mac_address> may be with or without separators.");
puts("Valid seperators are ':' and '-'.");
puts("<mac_address> digits are in base 16.\n");
}
int main(int argc, char *argv[])
{
if (argc < 2) {
print_usage(argv[0]);
return 1;
}
if (!((strlen(argv[1]) == ARP_HLEN_ASCII) || (strlen(argv[1]) == ARP_HLEN_LAZY))) {
puts("The MAC address is not valid.\n");
print_usage(argv[0]);
return 1;
}
if (process_mac(argv[1])) {
puts("Failed to calculate the MAC's checksum.");
return 1;
}
return 0;
}