--- a/drivers/net/phy/Kconfig +++ b/drivers/net/phy/Kconfig @@ -59,6 +59,12 @@ config VITESSE_PHY ---help--- Currently supports the vsc8244 +config VITESSE_PHY_8601_SKEW + bool "Enable skew timing to vsc8601" + depends on VITESSE_PHY + ---help--- + Apply clock timing adjustments for vsc8601 + config SMSC_PHY tristate "Drivers for SMSC PHYs" ---help--- --- a/drivers/net/phy/vitesse.c +++ b/drivers/net/phy/vitesse.c @@ -26,6 +26,11 @@ #define MII_VSC8244_EXTCON1_TX_SKEW 0x0800 #define MII_VSC8244_EXTCON1_RX_SKEW 0x0200 +/* EXT_CON1 Register values for VSC8601 */ +#define MII_VSC8601_EXTCON1_INIT 0x0000 +#define MII_VSC8601_EXTCON1_SKEW 0x0100 +#define MII_VSC8601_EXTCON1_ACTIPHY 0x0020 + /* Vitesse Interrupt Mask Register */ #define MII_VSC8244_IMASK 0x19 #define MII_VSC8244_IMASK_IEN 0x8000 @@ -98,6 +103,30 @@ static int vsc824x_config_init(struct ph return err; } +static int vsc8601_config_init(struct phy_device *phydev) +{ + int err; + int extcon; + + err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, + MII_VSC8244_AUXCONSTAT_INIT); + + if (err < 0) + return err; + +#ifdef CONFIG_VITESSE_PHY_8601_SKEW + extcon = phy_read(phydev, MII_VSC8244_EXT_CON1); + if (err < 0) + return err; + + extcon |= MII_VSC8601_EXTCON1_SKEW; + + err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon); +#endif + + return err; +} + static int vsc824x_ack_interrupt(struct phy_device *phydev) { int err = 0; @@ -153,6 +182,21 @@ static struct phy_driver vsc8244_driver .driver = { .owner = THIS_MODULE,}, }; +/* Vitesse 8601 */ +static struct phy_driver vsc8601_driver = { + .phy_id = 0x00070420, + .name = "Vitesse VSC8601", + .phy_id_mask = 0x000ffff8, + .features = PHY_GBIT_FEATURES, + .flags = PHY_HAS_INTERRUPT, + .config_init = &vsc8601_config_init, + .config_aneg = &genphy_config_aneg, + .read_status = &genphy_read_status, + .ack_interrupt = &vsc824x_ack_interrupt, + .config_intr = &vsc82xx_config_intr, + .driver = { .owner = THIS_MODULE,}, +}; + static int vsc8221_config_init(struct phy_device *phydev) { int err; @@ -186,10 +230,23 @@ static int __init vsc82xx_init(void) err = phy_driver_register(&vsc8244_driver); if (err < 0) - return err; + goto err; + err = phy_driver_register(&vsc8221_driver); if (err < 0) - phy_driver_unregister(&vsc8244_driver); + goto err1; + + err = phy_driver_register(&vsc8601_driver); + if (err < 0) + goto err2; + + return 0; + +err2: + phy_driver_unregister(&vsc8221_driver); +err1: + phy_driver_unregister(&vsc8244_driver); +err: return err; } @@ -197,6 +254,7 @@ static void __exit vsc82xx_exit(void) { phy_driver_unregister(&vsc8244_driver); phy_driver_unregister(&vsc8221_driver); + phy_driver_unregister(&vsc8601_driver); } module_init(vsc82xx_init);