diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/Kconfig | 24 | ||||
-rw-r--r-- | drivers/net/ag7xxx.c | 45 | ||||
-rw-r--r-- | drivers/net/bcm-sf2-eth.h | 2 | ||||
-rw-r--r-- | drivers/net/phy/Kconfig | 46 | ||||
-rw-r--r-- | drivers/net/phy/Makefile | 3 | ||||
-rw-r--r-- | drivers/net/phy/broadcom.c | 64 | ||||
-rw-r--r-- | drivers/net/phy/fixed.c | 1 | ||||
-rw-r--r-- | drivers/net/phy/micrel_ksz8xxx.c | 200 | ||||
-rw-r--r-- | drivers/net/phy/micrel_ksz90x1.c (renamed from drivers/net/phy/micrel.c) | 403 | ||||
-rw-r--r-- | drivers/net/phy/phy.c | 7 | ||||
-rw-r--r-- | drivers/usb/eth/r8152.c | 4 |
11 files changed, 480 insertions, 319 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 736aab2..5ceea44 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -47,6 +47,30 @@ config ALTERA_TSE Please find details on the "Triple-Speed Ethernet MegaCore Function Resource Center" of Altera. +config BCM_SF2_ETH + bool "Broadcom SF2 (Starfighter2) Ethernet support" + select PHYLIB + help + This is an abstract framework which provides a generic interface + to MAC and DMA management for multiple Broadcom SoCs such as + Cygnus, NSP and bcm28155_ap platforms. + +config BCM_SF2_ETH_DEFAULT_PORT + int "Broadcom SF2 (Starfighter2) Ethernet default port number" + depends on BCM_SF2_ETH + default 0 + help + Default port number for the Starfighter2 ethernet driver. + +config BCM_SF2_ETH_GMAC + bool "Broadcom SF2 (Starfighter2) GMAC Ethernet support" + depends on BCM_SF2_ETH + help + This flag enables the ethernet support for Broadcom platforms with + GMAC such as Cygnus. This driver is based on the framework provided + by the BCM_SF2_ETH driver. + Say Y to any bcmcygnus based platforms. + config DWC_ETH_QOS bool "Synopsys DWC Ethernet QOS device support" depends on DM_ETH diff --git a/drivers/net/ag7xxx.c b/drivers/net/ag7xxx.c index cf60d11..00e6806 100644 --- a/drivers/net/ag7xxx.c +++ b/drivers/net/ag7xxx.c @@ -26,6 +26,7 @@ enum ag7xxx_model { AG7XXX_MODEL_AG934X, }; +/* MAC Configuration 1 */ #define AG7XXX_ETH_CFG1 0x00 #define AG7XXX_ETH_CFG1_SOFT_RST BIT(31) #define AG7XXX_ETH_CFG1_RX_RST BIT(19) @@ -34,6 +35,7 @@ enum ag7xxx_model { #define AG7XXX_ETH_CFG1_RX_EN BIT(2) #define AG7XXX_ETH_CFG1_TX_EN BIT(0) +/* MAC Configuration 2 */ #define AG7XXX_ETH_CFG2 0x04 #define AG7XXX_ETH_CFG2_IF_1000 BIT(9) #define AG7XXX_ETH_CFG2_IF_10_100 BIT(8) @@ -43,26 +45,34 @@ enum ag7xxx_model { #define AG7XXX_ETH_CFG2_PAD_CRC_EN BIT(2) #define AG7XXX_ETH_CFG2_FDX BIT(0) +/* MII Configuration */ #define AG7XXX_ETH_MII_MGMT_CFG 0x20 #define AG7XXX_ETH_MII_MGMT_CFG_RESET BIT(31) +/* MII Command */ #define AG7XXX_ETH_MII_MGMT_CMD 0x24 #define AG7XXX_ETH_MII_MGMT_CMD_READ 0x1 +/* MII Address */ #define AG7XXX_ETH_MII_MGMT_ADDRESS 0x28 #define AG7XXX_ETH_MII_MGMT_ADDRESS_SHIFT 8 +/* MII Control */ #define AG7XXX_ETH_MII_MGMT_CTRL 0x2c +/* MII Status */ #define AG7XXX_ETH_MII_MGMT_STATUS 0x30 +/* MII Indicators */ #define AG7XXX_ETH_MII_MGMT_IND 0x34 #define AG7XXX_ETH_MII_MGMT_IND_INVALID BIT(2) #define AG7XXX_ETH_MII_MGMT_IND_BUSY BIT(0) +/* STA Address 1 & 2 */ #define AG7XXX_ETH_ADDR1 0x40 #define AG7XXX_ETH_ADDR2 0x44 +/* ETH Configuration 0 - 5 */ #define AG7XXX_ETH_FIFO_CFG_0 0x48 #define AG7XXX_ETH_FIFO_CFG_1 0x4c #define AG7XXX_ETH_FIFO_CFG_2 0x50 @@ -70,18 +80,24 @@ enum ag7xxx_model { #define AG7XXX_ETH_FIFO_CFG_4 0x58 #define AG7XXX_ETH_FIFO_CFG_5 0x5c +/* DMA Transfer Control for Queue 0 */ #define AG7XXX_ETH_DMA_TX_CTRL 0x180 #define AG7XXX_ETH_DMA_TX_CTRL_TXE BIT(0) +/* Descriptor Address for Queue 0 Tx */ #define AG7XXX_ETH_DMA_TX_DESC 0x184 +/* DMA Tx Status */ #define AG7XXX_ETH_DMA_TX_STATUS 0x188 +/* Rx Control */ #define AG7XXX_ETH_DMA_RX_CTRL 0x18c #define AG7XXX_ETH_DMA_RX_CTRL_RXE BIT(0) +/* Pointer to Rx Descriptor */ #define AG7XXX_ETH_DMA_RX_DESC 0x190 +/* Rx Status */ #define AG7XXX_ETH_DMA_RX_STATUS 0x194 /* Custom register at 0x18070000 */ @@ -269,18 +285,33 @@ static int ag7xxx_switch_reg_write(struct mii_dev *bus, int reg, u32 val) return 0; } -static u16 ag7xxx_mdio_rw(struct mii_dev *bus, int addr, int reg, u32 val) +static int ag7xxx_mdio_rw(struct mii_dev *bus, int addr, int reg, u32 val) { u32 data; + unsigned long start; + int ret; + /* No idea if this is long enough or too long */ + int timeout_ms = 1000; /* Dummy read followed by PHY read/write command. */ - ag7xxx_switch_reg_read(bus, 0x98, &data); + ret = ag7xxx_switch_reg_read(bus, 0x98, &data); + if (ret < 0) + return ret; data = val | (reg << 16) | (addr << 21) | BIT(30) | BIT(31); - ag7xxx_switch_reg_write(bus, 0x98, data); + ret = ag7xxx_switch_reg_write(bus, 0x98, data); + if (ret < 0) + return ret; + + start = get_timer(0); /* Wait for operation to finish */ do { - ag7xxx_switch_reg_read(bus, 0x98, &data); + ret = ag7xxx_switch_reg_read(bus, 0x98, &data); + if (ret < 0) + return ret; + + if (get_timer(start) > timeout_ms) + return -ETIMEDOUT; } while (data & BIT(31)); return data & 0xffff; @@ -294,7 +325,11 @@ static int ag7xxx_mdio_read(struct mii_dev *bus, int addr, int devad, int reg) static int ag7xxx_mdio_write(struct mii_dev *bus, int addr, int devad, int reg, u16 val) { - ag7xxx_mdio_rw(bus, addr, reg, val); + int ret; + + ret = ag7xxx_mdio_rw(bus, addr, reg, val); + if (ret < 0) + return ret; return 0; } diff --git a/drivers/net/bcm-sf2-eth.h b/drivers/net/bcm-sf2-eth.h index c4e2e01..efeff15 100644 --- a/drivers/net/bcm-sf2-eth.h +++ b/drivers/net/bcm-sf2-eth.h @@ -20,8 +20,6 @@ /* Support 2 Ethernet ports now */ #define BCM_ETH_MAX_PORT_NUM 2 -#define CONFIG_BCM_SF2_ETH_DEFAULT_PORT 0 - enum { MAC_DMA_TX = 1, MAC_DMA_RX = 2 diff --git a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig index 0230852..4d02d8b 100644 --- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -67,38 +67,40 @@ config PHY_MICREL if PHY_MICREL config PHY_MICREL_KSZ9021 - bool "Micrel KSZ9021 family support" + bool 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. + select PHY_MICREL_KSZ90X1 config PHY_MICREL_KSZ9031 - bool "Micrel KSZ9031 family support" + bool + select PHY_GIGE + select PHY_MICREL_KSZ90X1 + +config PHY_MICREL_KSZ90X1 + bool "Micrel KSZ90x1 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 + Enable support for the Micrel KSZ9021 and KSZ9031 GbE PHYs. If + enabled, the extended register read/write for KSZ90x1 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. + PHY during initialization. -endif # PHY_MICREL + This should not be enabled at the same time with PHY_MICREL_KSZ8XXX + as the KSZ9021 and KS8721 share the same ID. -config PHY_MICREL_KSZ9021 - bool "Micrel KSZ9021 Ethernet PHYs support" - depends on PHY_MICREL +config PHY_MICREL_KSZ8XXX + bool "Micrel KSZ8xxx family support" + default y if !PHY_MICREL_KSZ90X1 help - KSZ9021 is a completely integrated triple speed (10Base-T/100Base-TX/1000Base-T) - Ethernet Physical Layer Transceiver for transmission and reception of data over - standard CAT-5 unshielded twisted pair (UTP) cable. + Enable support for the 8000 series GbE PHYs manufactured by Micrel + (now a part of Microchip). This includes drivers for the KSZ804, + KSZ8031, KSZ8051, KSZ8081, KSZ8895, KSZ886x, and KSZ8721. + + This should not be enabled at the same time with PHY_MICREL_KSZ90X1 + as the KSZ9021 and KS8721 share the same ID. + +endif # PHY_MICREL config PHY_MSCC bool "Microsemi Corp Ethernet PHYs support" diff --git a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile index 88c00a5..54f32f6 100644 --- a/drivers/net/phy/Makefile +++ b/drivers/net/phy/Makefile @@ -19,7 +19,8 @@ obj-$(CONFIG_PHY_DAVICOM) += davicom.o obj-$(CONFIG_PHY_ET1011C) += et1011c.o obj-$(CONFIG_PHY_LXT) += lxt.o obj-$(CONFIG_PHY_MARVELL) += marvell.o -obj-$(CONFIG_PHY_MICREL) += micrel.o +obj-$(CONFIG_PHY_MICREL_KSZ8XXX) += micrel_ksz8xxx.o +obj-$(CONFIG_PHY_MICREL_KSZ90X1) += micrel_ksz90x1.o obj-$(CONFIG_PHY_NATSEMI) += natsemi.o obj-$(CONFIG_PHY_REALTEK) += realtek.o obj-$(CONFIG_PHY_SMSC) += smsc.o diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c index 9871cc3..e4afa90 100644 --- a/drivers/net/phy/broadcom.c +++ b/drivers/net/phy/broadcom.c @@ -30,6 +30,29 @@ #define MIIM_BCM54XX_EXP_SEL_SSD 0x0e00 /* Secondary SerDes select */ #define MIIM_BCM54XX_EXP_SEL_ER 0x0f00 /* Expansion register select */ +#define MIIM_BCM_AUXCNTL_SHDWSEL_MISC 0x0007 +#define MIIM_BCM_AUXCNTL_ACTL_SMDSP_EN 0x0800 + +#define MIIM_BCM_CHANNEL_WIDTH 0x2000 + +static void bcm_phy_write_misc(struct phy_device *phydev, + u16 reg, u16 chl, u16 value) +{ + int reg_val; + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, + MIIM_BCM_AUXCNTL_SHDWSEL_MISC); + + reg_val = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL); + reg_val |= MIIM_BCM_AUXCNTL_ACTL_SMDSP_EN; + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, reg_val); + + reg_val = (chl * MIIM_BCM_CHANNEL_WIDTH) | reg; + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_SEL, reg_val); + + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54XX_EXP_DATA, value); +} + /* Broadcom BCM5461S */ static int bcm5461_config(struct phy_device *phydev) { @@ -152,11 +175,50 @@ static int bcm_cygnus_startup(struct phy_device *phydev) return genphy_parse_link(phydev); } +static void bcm_cygnus_afe(struct phy_device *phydev) +{ + /* ensures smdspclk is enabled */ + phy_write(phydev, MDIO_DEVAD_NONE, MIIM_BCM54xx_AUXCNTL, 0x0c30); + + /* AFE_VDAC_ICTRL_0 bit 7:4 Iq=1100 for 1g 10bt, normal modes */ + bcm_phy_write_misc(phydev, 0x39, 0x01, 0xA7C8); + + /* AFE_HPF_TRIM_OTHERS bit11=1, short cascode for all modes*/ + bcm_phy_write_misc(phydev, 0x3A, 0x00, 0x0803); + + /* AFE_TX_CONFIG_1 bit 7:4 Iq=1100 for test modes */ + bcm_phy_write_misc(phydev, 0x3A, 0x01, 0xA740); + + /* AFE TEMPSEN_OTHERS rcal_HT, rcal_LT 10000 */ + bcm_phy_write_misc(phydev, 0x3A, 0x03, 0x8400); + + /* AFE_FUTURE_RSV bit 2:0 rccal <2:0>=100 */ + bcm_phy_write_misc(phydev, 0x3B, 0x00, 0x0004); + + /* Adjust bias current trim to overcome digital offSet */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x02); + + /* make rcal=100, since rdb default is 000 */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B1); + phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0010); + + /* CORE_EXPB0, Reset R_CAL/RC_CAL Engine */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B0); + phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0010); + + /* CORE_EXPB0, Disable Reset R_CAL/RC_CAL Engine */ + phy_write(phydev, MDIO_DEVAD_NONE, 0x17, 0x00B0); + phy_write(phydev, MDIO_DEVAD_NONE, 0x15, 0x0000); +} + static int bcm_cygnus_config(struct phy_device *phydev) { genphy_config_aneg(phydev); - phy_reset(phydev); + /* AFE settings for PHY stability */ + bcm_cygnus_afe(phydev); + /* Forcing aneg after applying the AFE settings */ + genphy_restart_aneg(phydev); return 0; } diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c index df82356..e8e9099 100644 --- a/drivers/net/phy/fixed.c +++ b/drivers/net/phy/fixed.c @@ -34,7 +34,6 @@ int fixedphy_probe(struct phy_device *phydev) memset(priv, 0, sizeof(*priv)); phydev->priv = priv; - phydev->addr = 0; priv->link_speed = val; priv->duplex = fdtdec_get_bool(gd->fdt_blob, ofnode, "full-duplex"); diff --git a/drivers/net/phy/micrel_ksz8xxx.c b/drivers/net/phy/micrel_ksz8xxx.c new file mode 100644 index 0000000..ec628bb --- /dev/null +++ b/drivers/net/phy/micrel_ksz8xxx.c @@ -0,0 +1,200 @@ +/* + * Micrel PHY drivers + * + * SPDX-License-Identifier: GPL-2.0+ + * + * Copyright 2010-2011 Freescale Semiconductor, Inc. + * author Andy Fleming + * (C) 2012 NetModule AG, David Andrey, added KSZ9031 + */ +#include <config.h> +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <fdtdec.h> +#include <micrel.h> +#include <phy.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct phy_driver KSZ804_driver = { + .name = "Micrel KSZ804", + .uid = 0x221510, + .mask = 0xfffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +#define MII_KSZPHY_OMSO 0x16 +#define KSZPHY_OMSO_B_CAST_OFF (1 << 9) + +static int ksz_genconfig_bcastoff(struct phy_device *phydev) +{ + int ret; + + ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO); + if (ret < 0) + return ret; + + ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO, + ret | KSZPHY_OMSO_B_CAST_OFF); + if (ret < 0) + return ret; + + return genphy_config(phydev); +} + +static struct phy_driver KSZ8031_driver = { + .name = "Micrel KSZ8021/KSZ8031", + .uid = 0x221550, + .mask = 0xfffff0, + .features = PHY_BASIC_FEATURES, + .config = &ksz_genconfig_bcastoff, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +/** + * KSZ8051 + */ +#define MII_KSZ8051_PHY_OMSO 0x16 +#define MII_KSZ8051_PHY_OMSO_NAND_TREE_ON (1 << 5) + +static int ksz8051_config(struct phy_device *phydev) +{ + unsigned val; + + /* Disable NAND-tree */ + val = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO); + val &= ~MII_KSZ8051_PHY_OMSO_NAND_TREE_ON; + phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO, val); + + return genphy_config(phydev); +} + +static struct phy_driver KSZ8051_driver = { + .name = "Micrel KSZ8051", + .uid = 0x221550, + .mask = 0xfffff0, + .features = PHY_BASIC_FEATURES, + .config = &ksz8051_config, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +static struct phy_driver KSZ8081_driver = { + .name = "Micrel KSZ8081", + .uid = 0x221560, + .mask = 0xfffff0, + .features = PHY_BASIC_FEATURES, + .config = &ksz_genconfig_bcastoff, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +/** + * KSZ8895 + */ + +static unsigned short smireg_to_phy(unsigned short reg) +{ + return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5); +} + +static unsigned short smireg_to_reg(unsigned short reg) +{ + return reg & 0x1F; +} + +static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val) +{ + phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE, + smireg_to_reg(smireg), val); +} + +#if 0 +static int ksz8895_read_smireg(struct phy_device *phydev, int smireg) +{ + return phydev->bus->read(phydev->bus, smireg_to_phy(smireg), + MDIO_DEVAD_NONE, smireg_to_reg(smireg)); +} +#endif + +int ksz8895_config(struct phy_device *phydev) +{ + /* we are connected directly to the switch without + * dedicated PHY. SCONF1 == 001 */ + phydev->link = 1; + phydev->duplex = DUPLEX_FULL; + phydev->speed = SPEED_100; + + /* Force the switch to start */ + ksz8895_write_smireg(phydev, 1, 1); + + return 0; +} + +static int ksz8895_startup(struct phy_device *phydev) +{ + return 0; +} + +static struct phy_driver ksz8895_driver = { + .name = "Micrel KSZ8895/KSZ8864", + .uid = 0x221450, + .mask = 0xffffe1, + .features = PHY_BASIC_FEATURES, + .config = &ksz8895_config, + .startup = &ksz8895_startup, + .shutdown = &genphy_shutdown, +}; + +/* Micrel used the exact same part number for the KSZ9021. */ +static struct phy_driver KS8721_driver = { + .name = "Micrel KS8721BL", + .uid = 0x221610, + .mask = 0xfffff0, + .features = PHY_BASIC_FEATURES, + .config = &genphy_config, + .startup = &genphy_startup, + .shutdown = &genphy_shutdown, +}; + +int ksz886x_config(struct phy_device *phydev) +{ + /* we are connected directly to the switch without + * dedicated PHY. */ + phydev->link = 1; + phydev->duplex = DUPLEX_FULL; + phydev->speed = SPEED_100; + return 0; +} + +static int ksz886x_startup(struct phy_device *phydev) +{ + return 0; +} + +static struct phy_driver ksz886x_driver = { + .name = "Micrel KSZ886x Switch", + .uid = 0x00221430, + .mask = 0xfffff0, + .features = PHY_BASIC_FEATURES, + .config = &ksz886x_config, + .startup = &ksz886x_startup, + .shutdown = &genphy_shutdown, +}; + +int phy_micrel_ksz8xxx_init(void) +{ + phy_register(&KSZ804_driver); + phy_register(&KSZ8031_driver); + phy_register(&KSZ8051_driver); + phy_register(&KSZ8081_driver); + phy_register(&KS8721_driver); + phy_register(&ksz8895_driver); + phy_register(&ksz886x_driver); + return 0; +} diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel_ksz90x1.c index 0e4a4eb..20f8a55 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel_ksz90x1.c @@ -6,6 +6,8 @@ * Copyright 2010-2011 Freescale Semiconductor, Inc. * author Andy Fleming * (C) 2012 NetModule AG, David Andrey, added KSZ9031 + * (C) Copyright 2017 Adaptrum, Inc. + * Written by Alexandru Gagniuc <alex.g@adaptrum.com> for Adaptrum, Inc. */ #include <config.h> #include <common.h> @@ -17,157 +19,6 @@ DECLARE_GLOBAL_DATA_PTR; -static struct phy_driver KSZ804_driver = { - .name = "Micrel KSZ804", - .uid = 0x221510, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &genphy_config, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; - -#define MII_KSZPHY_OMSO 0x16 -#define KSZPHY_OMSO_B_CAST_OFF (1 << 9) - -static int ksz_genconfig_bcastoff(struct phy_device *phydev) -{ - int ret; - - ret = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO); - if (ret < 0) - return ret; - - ret = phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZPHY_OMSO, - ret | KSZPHY_OMSO_B_CAST_OFF); - if (ret < 0) - return ret; - - return genphy_config(phydev); -} - -static struct phy_driver KSZ8031_driver = { - .name = "Micrel KSZ8021/KSZ8031", - .uid = 0x221550, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &ksz_genconfig_bcastoff, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; - -/** - * KSZ8051 - */ -#define MII_KSZ8051_PHY_OMSO 0x16 -#define MII_KSZ8051_PHY_OMSO_NAND_TREE_ON (1 << 5) - -static int ksz8051_config(struct phy_device *phydev) -{ - unsigned val; - - /* Disable NAND-tree */ - val = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO); - val &= ~MII_KSZ8051_PHY_OMSO_NAND_TREE_ON; - phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ8051_PHY_OMSO, val); - - return genphy_config(phydev); -} - -static struct phy_driver KSZ8051_driver = { - .name = "Micrel KSZ8051", - .uid = 0x221550, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &ksz8051_config, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; - -static struct phy_driver KSZ8081_driver = { - .name = "Micrel KSZ8081", - .uid = 0x221560, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &ksz_genconfig_bcastoff, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; - -/** - * KSZ8895 - */ - -static unsigned short smireg_to_phy(unsigned short reg) -{ - return ((reg & 0xc0) >> 3) + 0x06 + ((reg & 0x20) >> 5); -} - -static unsigned short smireg_to_reg(unsigned short reg) -{ - return reg & 0x1F; -} - -static void ksz8895_write_smireg(struct phy_device *phydev, int smireg, int val) -{ - phydev->bus->write(phydev->bus, smireg_to_phy(smireg), MDIO_DEVAD_NONE, - smireg_to_reg(smireg), val); -} - -#if 0 -static int ksz8895_read_smireg(struct phy_device *phydev, int smireg) -{ - return phydev->bus->read(phydev->bus, smireg_to_phy(smireg), - MDIO_DEVAD_NONE, smireg_to_reg(smireg)); -} -#endif - -int ksz8895_config(struct phy_device *phydev) -{ - /* we are connected directly to the switch without - * dedicated PHY. SCONF1 == 001 */ - phydev->link = 1; - phydev->duplex = DUPLEX_FULL; - phydev->speed = SPEED_100; - - /* Force the switch to start */ - ksz8895_write_smireg(phydev, 1, 1); - - return 0; -} - -static int ksz8895_startup(struct phy_device *phydev) -{ - return 0; -} - -static struct phy_driver ksz8895_driver = { - .name = "Micrel KSZ8895/KSZ8864", - .uid = 0x221450, - .mask = 0xffffe1, - .features = PHY_BASIC_FEATURES, - .config = &ksz8895_config, - .startup = &ksz8895_startup, - .shutdown = &genphy_shutdown, -}; - -#ifndef CONFIG_PHY_MICREL_KSZ9021 -/* - * I can't believe Micrel used the exact same part number - * for the KSZ9021. Shame Micrel, Shame! - */ -static struct phy_driver KS8721_driver = { - .name = "Micrel KS8721BL", - .uid = 0x221610, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &genphy_config, - .startup = &genphy_startup, - .shutdown = &genphy_shutdown, -}; -#endif - - /* * KSZ9021 - KSZ9031 common */ @@ -178,6 +29,19 @@ static struct phy_driver KS8721_driver = { #define MIIM_KSZ90xx_PHYCTL_10 (1 << 4) #define MIIM_KSZ90xx_PHYCTL_DUPLEX (1 << 3) +/* KSZ9021 PHY Registers */ +#define MII_KSZ9021_EXTENDED_CTRL 0x0b +#define MII_KSZ9021_EXTENDED_DATAW 0x0c +#define MII_KSZ9021_EXTENDED_DATAR 0x0d + +#define CTRL1000_PREFER_MASTER (1 << 10) +#define CTRL1000_CONFIG_MASTER (1 << 11) +#define CTRL1000_MANUAL_CONFIG (1 << 12) + +/* KSZ9031 PHY Registers */ +#define MII_KSZ9031_MMD_ACCES_CTRL 0x0d +#define MII_KSZ9031_MMD_REG_DATA 0x0e + static int ksz90xx_startup(struct phy_device *phydev) { unsigned phy_ctl; @@ -204,7 +68,6 @@ static int ksz90xx_startup(struct phy_device *phydev) } /* Common OF config bits for KSZ9021 and KSZ9031 */ -#if defined(CONFIG_PHY_MICREL_KSZ9021) || defined(CONFIG_PHY_MICREL_KSZ9031) #ifdef CONFIG_DM_ETH struct ksz90x1_reg_field { const char *name; @@ -230,6 +93,19 @@ static const struct ksz90x1_reg_field ksz90x1_txd_grp[] = { { "txd2-skew-ps", 4, 8, 0x7 }, { "txd3-skew-ps", 4, 12, 0x7 }, }; +static const struct ksz90x1_reg_field ksz9021_clk_grp[] = { + { "txen-skew-ps", 4, 0, 0x7 }, { "txc-skew-ps", 4, 4, 0x7 }, + { "rxdv-skew-ps", 4, 8, 0x7 }, { "rxc-skew-ps", 4, 12, 0x7 }, +}; + +static const struct ksz90x1_reg_field ksz9031_ctl_grp[] = { + { "txen-skew-ps", 4, 0, 0x7 }, { "rxdv-skew-ps", 4, 4, 0x7 } +}; + +static const struct ksz90x1_reg_field ksz9031_clk_grp[] = { + { "rxc-skew-ps", 5, 0, 0xf }, { "txc-skew-ps", 5, 5, 0xf } +}; + static int ksz90x1_of_config_group(struct phy_device *phydev, struct ksz90x1_ofcfg *ofcfg) { @@ -267,29 +143,6 @@ static int ksz90x1_of_config_group(struct phy_device *phydev, return drv->writeext(phydev, 0, ofcfg->devad, ofcfg->reg, regval); } -#endif -#endif - -#ifdef CONFIG_PHY_MICREL_KSZ9021 -/* - * KSZ9021 - */ - -/* PHY Registers */ -#define MII_KSZ9021_EXTENDED_CTRL 0x0b -#define MII_KSZ9021_EXTENDED_DATAW 0x0c -#define MII_KSZ9021_EXTENDED_DATAR 0x0d - -#define CTRL1000_PREFER_MASTER (1 << 10) -#define CTRL1000_CONFIG_MASTER (1 << 11) -#define CTRL1000_MANUAL_CONFIG (1 << 12) - -#if defined(CONFIG_DM_ETH) && (defined(CONFIG_PHY_MICREL_KSZ9021) || \ - defined(CONFIG_PHY_MICREL_KSZ9031)) -static const struct ksz90x1_reg_field ksz9021_clk_grp[] = { - { "txen-skew-ps", 4, 0, 0x7 }, { "txc-skew-ps", 4, 4, 0x7 }, - { "rxdv-skew-ps", 4, 8, 0x7 }, { "rxc-skew-ps", 4, 12, 0x7 }, -}; static int ksz9021_of_config(struct phy_device *phydev) { @@ -308,20 +161,69 @@ static int ksz9021_of_config(struct phy_device *phydev) return 0; } -#else + +static int ksz9031_of_config(struct phy_device *phydev) +{ + struct ksz90x1_ofcfg ofcfg[] = { + { MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, 2, ksz9031_ctl_grp, 2 }, + { MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, 2, ksz90x1_rxd_grp, 4 }, + { MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, 2, ksz90x1_txd_grp, 4 }, + { MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, 2, ksz9031_clk_grp, 2 }, + }; + int i, ret = 0; + + for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { + ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); + if (ret) + return ret; + } + + return 0; +} + +static int ksz9031_center_flp_timing(struct phy_device *phydev) +{ + struct phy_driver *drv = phydev->drv; + int ret = 0; + + if (!drv || !drv->writeext) + return -EOPNOTSUPP; + + ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_LO, 0x1A80); + if (ret) + return ret; + + ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_HI, 0x6); + return ret; +} + +#else /* !CONFIG_DM_ETH */ static int ksz9021_of_config(struct phy_device *phydev) { return 0; } + +static int ksz9031_of_config(struct phy_device *phydev) +{ + return 0; +} + +static int ksz9031_center_flp_timing(struct phy_device *phydev) +{ + return 0; +} #endif +/* + * KSZ9021 + */ int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, u16 val) { /* extended registers */ phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000); + MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000); return phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9021_EXTENDED_DATAW, val); + MII_KSZ9021_EXTENDED_DATAW, val); } int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum) @@ -333,23 +235,22 @@ int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum) static int ksz9021_phy_extread(struct phy_device *phydev, int addr, int devaddr, - int regnum) + int regnum) { return ksz9021_phy_extended_read(phydev, regnum); } static int ksz9021_phy_extwrite(struct phy_device *phydev, int addr, - int devaddr, int regnum, u16 val) + int devaddr, int regnum, u16 val) { return ksz9021_phy_extended_write(phydev, regnum, val); } -/* Micrel ksz9021 */ static int ksz9021_config(struct phy_device *phydev) { unsigned ctrl1000 = 0; const unsigned master = CTRL1000_PREFER_MASTER | - CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG; + CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG; unsigned features = phydev->drv->features; int ret; @@ -359,13 +260,14 @@ static int ksz9021_config(struct phy_device *phydev) if (getenv("disable_giga")) features &= ~(SUPPORTED_1000baseT_Half | - SUPPORTED_1000baseT_Full); + SUPPORTED_1000baseT_Full); /* force master mode for 1000BaseT due to chip errata */ if (features & SUPPORTED_1000baseT_Half) ctrl1000 |= ADVERTISE_1000HALF | master; if (features & SUPPORTED_1000baseT_Full) ctrl1000 |= ADVERTISE_1000FULL | master; - phydev->advertising = phydev->supported = features; + phydev->advertising = features; + phydev->supported = features; phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000); genphy_config_aneg(phydev); genphy_restart_aneg(phydev); @@ -383,68 +285,10 @@ static struct phy_driver ksz9021_driver = { .writeext = &ksz9021_phy_extwrite, .readext = &ksz9021_phy_extread, }; -#endif -/** +/* * KSZ9031 */ -/* PHY Registers */ -#define MII_KSZ9031_MMD_ACCES_CTRL 0x0d -#define MII_KSZ9031_MMD_REG_DATA 0x0e - -#if defined(CONFIG_DM_ETH) && (defined(CONFIG_PHY_MICREL_KSZ9021) || \ - defined(CONFIG_PHY_MICREL_KSZ9031)) -static const struct ksz90x1_reg_field ksz9031_ctl_grp[] = - { { "txen-skew-ps", 4, 0, 0x7 }, { "rxdv-skew-ps", 4, 4, 0x7 } }; -static const struct ksz90x1_reg_field ksz9031_clk_grp[] = - { { "rxc-skew-ps", 5, 0, 0xf }, { "txc-skew-ps", 5, 5, 0xf } }; - -static int ksz9031_of_config(struct phy_device *phydev) -{ - struct ksz90x1_ofcfg ofcfg[] = { - { MII_KSZ9031_EXT_RGMII_CTRL_SIG_SKEW, 2, ksz9031_ctl_grp, 2 }, - { MII_KSZ9031_EXT_RGMII_RX_DATA_SKEW, 2, ksz90x1_rxd_grp, 4 }, - { MII_KSZ9031_EXT_RGMII_TX_DATA_SKEW, 2, ksz90x1_txd_grp, 4 }, - { MII_KSZ9031_EXT_RGMII_CLOCK_SKEW, 2, ksz9031_clk_grp, 2 }, - }; - int i, ret = 0; - - for (i = 0; i < ARRAY_SIZE(ofcfg); i++) { - ret = ksz90x1_of_config_group(phydev, &(ofcfg[i])); - if (ret) - return ret; - } - - return 0; -} - -static int ksz9031_center_flp_timing(struct phy_device *phydev) -{ - struct phy_driver *drv = phydev->drv; - int ret = 0; - - if (!drv || !drv->writeext) - return -EOPNOTSUPP; - - ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_LO, 0x1A80); - if (ret) - return ret; - - ret = drv->writeext(phydev, 0, 0, MII_KSZ9031_FLP_BURST_TX_HI, 0x6); - return ret; -} -#else -static int ksz9031_of_config(struct phy_device *phydev) -{ - return 0; -} -static int ksz9031_center_flp_timing(struct phy_device *phydev) -{ - return 0; -} -#endif - -/* Accessors to extended registers*/ int ksz9031_phy_extended_write(struct phy_device *phydev, int devaddr, int regnum, u16 mode, u16 val) { @@ -459,7 +303,7 @@ int ksz9031_phy_extended_write(struct phy_device *phydev, MII_KSZ9031_MMD_ACCES_CTRL, (mode | devaddr)); /*write the value*/ return phy_write(phydev, MDIO_DEVAD_NONE, - MII_KSZ9031_MMD_REG_DATA, val); + MII_KSZ9031_MMD_REG_DATA, val); } int ksz9031_phy_extended_read(struct phy_device *phydev, int devaddr, @@ -479,24 +323,52 @@ static int ksz9031_phy_extread(struct phy_device *phydev, int addr, int devaddr, { return ksz9031_phy_extended_read(phydev, devaddr, regnum, MII_KSZ9031_MOD_DATA_NO_POST_INC); -}; +} static int ksz9031_phy_extwrite(struct phy_device *phydev, int addr, int devaddr, int regnum, u16 val) { return ksz9031_phy_extended_write(phydev, devaddr, regnum, - MII_KSZ9031_MOD_DATA_POST_INC_RW, val); -}; + MII_KSZ9031_MOD_DATA_POST_INC_RW, val); +} static int ksz9031_config(struct phy_device *phydev) { int ret; + ret = ksz9031_of_config(phydev); if (ret) return ret; ret = ksz9031_center_flp_timing(phydev); if (ret) return ret; + + /* add an option to disable the gigabit feature of this PHY */ + if (getenv("disable_giga")) { + unsigned features; + unsigned bmcr; + + /* disable speed 1000 in features supported by the PHY */ + features = phydev->drv->features; + features &= ~(SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full); + phydev->advertising = phydev->supported = features; + + /* disable speed 1000 in Basic Control Register */ + bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR); + bmcr &= ~(1 << 6); + phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, bmcr); + + /* disable speed 1000 in 1000Base-T Control Register */ + phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, 0); + + /* start autoneg */ + genphy_config_aneg(phydev); + genphy_restart_aneg(phydev); + + return 0; + } + return genphy_config(phydev); } @@ -512,44 +384,9 @@ static struct phy_driver ksz9031_driver = { .readext = &ksz9031_phy_extread, }; -int ksz886x_config(struct phy_device *phydev) -{ - /* we are connected directly to the switch without - * dedicated PHY. */ - phydev->link = 1; - phydev->duplex = DUPLEX_FULL; - phydev->speed = SPEED_100; - return 0; -} - -static int ksz886x_startup(struct phy_device *phydev) +int phy_micrel_ksz90x1_init(void) { - return 0; -} - -static struct phy_driver ksz886x_driver = { - .name = "Micrel KSZ886x Switch", - .uid = 0x00221430, - .mask = 0xfffff0, - .features = PHY_BASIC_FEATURES, - .config = &ksz886x_config, - .startup = &ksz886x_startup, - .shutdown = &genphy_shutdown, -}; - -int phy_micrel_init(void) -{ - phy_register(&KSZ804_driver); - phy_register(&KSZ8031_driver); - phy_register(&KSZ8051_driver); - phy_register(&KSZ8081_driver); -#ifdef CONFIG_PHY_MICREL_KSZ9021 phy_register(&ksz9021_driver); -#else - phy_register(&KS8721_driver); -#endif phy_register(&ksz9031_driver); - phy_register(&ksz8895_driver); - phy_register(&ksz886x_driver); return 0; } diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 97e0bc0..5be51d7 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -488,8 +488,11 @@ int phy_init(void) #ifdef CONFIG_PHY_MARVELL phy_marvell_init(); #endif -#ifdef CONFIG_PHY_MICREL - phy_micrel_init(); +#ifdef CONFIG_PHY_MICREL_KSZ8XXX + phy_micrel_ksz8xxx_init(); +#endif +#ifdef CONFIG_PHY_MICREL_KSZ90X1 + phy_micrel_ksz90x1_init(); #endif #ifdef CONFIG_PHY_NATSEMI phy_natsemi_init(); diff --git a/drivers/usb/eth/r8152.c b/drivers/usb/eth/r8152.c index ed441f3..e09351b 100644 --- a/drivers/usb/eth/r8152.c +++ b/drivers/usb/eth/r8152.c @@ -26,7 +26,7 @@ struct r8152_dongle { unsigned short product; }; -static const struct r8152_dongle const r8152_dongles[] = { +static const struct r8152_dongle r8152_dongles[] = { /* Realtek */ { 0x0bda, 0x8050 }, { 0x0bda, 0x8152 }, @@ -59,7 +59,7 @@ struct r8152_version { bool gmii; }; -static const struct r8152_version const r8152_versions[] = { +static const struct r8152_version r8152_versions[] = { { 0x4c00, RTL_VER_01, 0 }, { 0x4c10, RTL_VER_02, 0 }, { 0x5c00, RTL_VER_03, 1 }, |