| 1 | --- a/drivers/net/phy/Kconfig |
| 2 | +++ b/drivers/net/phy/Kconfig |
| 3 | @@ -51,6 +51,12 @@ config VITESSE_PHY |
| 4 | ---help--- |
| 5 | Currently supports the vsc8244 |
| 6 | |
| 7 | +config VITESSE_PHY_8601_SKEW |
| 8 | + bool "Enable skew timing to vsc8601" |
| 9 | + depends on VITESSE_PHY |
| 10 | + ---help--- |
| 11 | + Apply clock timing adjustments for vsc8601 |
| 12 | + |
| 13 | config SMSC_PHY |
| 14 | tristate "Drivers for SMSC PHYs" |
| 15 | ---help--- |
| 16 | --- a/drivers/net/phy/vitesse.c |
| 17 | +++ b/drivers/net/phy/vitesse.c |
| 18 | @@ -26,6 +26,11 @@ |
| 19 | #define MII_VSC8244_EXTCON1_TX_SKEW 0x0800 |
| 20 | #define MII_VSC8244_EXTCON1_RX_SKEW 0x0200 |
| 21 | |
| 22 | +/* EXT_CON1 Register values for VSC8601 */ |
| 23 | +#define MII_VSC8601_EXTCON1_INIT 0x0000 |
| 24 | +#define MII_VSC8601_EXTCON1_SKEW 0x0100 |
| 25 | +#define MII_VSC8601_EXTCON1_ACTIPHY 0x0020 |
| 26 | + |
| 27 | /* Vitesse Interrupt Mask Register */ |
| 28 | #define MII_VSC8244_IMASK 0x19 |
| 29 | #define MII_VSC8244_IMASK_IEN 0x8000 |
| 30 | @@ -88,6 +93,30 @@ static int vsc824x_config_init(struct ph |
| 31 | return err; |
| 32 | } |
| 33 | |
| 34 | +static int vsc8601_config_init(struct phy_device *phydev) |
| 35 | +{ |
| 36 | + int err; |
| 37 | + int extcon; |
| 38 | + |
| 39 | + err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, |
| 40 | + MII_VSC8244_AUXCONSTAT_INIT); |
| 41 | + |
| 42 | + if (err < 0) |
| 43 | + return err; |
| 44 | + |
| 45 | +#ifdef CONFIG_VITESSE_PHY_8601_SKEW |
| 46 | + extcon = phy_read(phydev, MII_VSC8244_EXT_CON1); |
| 47 | + if (err < 0) |
| 48 | + return err; |
| 49 | + |
| 50 | + extcon |= MII_VSC8601_EXTCON1_SKEW; |
| 51 | + |
| 52 | + err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon); |
| 53 | +#endif |
| 54 | + |
| 55 | + return err; |
| 56 | +} |
| 57 | + |
| 58 | static int vsc824x_ack_interrupt(struct phy_device *phydev) |
| 59 | { |
| 60 | int err = 0; |
| 61 | @@ -143,6 +172,21 @@ static struct phy_driver vsc8244_driver |
| 62 | .driver = { .owner = THIS_MODULE,}, |
| 63 | }; |
| 64 | |
| 65 | +/* Vitesse 8601 */ |
| 66 | +static struct phy_driver vsc8601_driver = { |
| 67 | + .phy_id = 0x00070420, |
| 68 | + .name = "Vitesse VSC8601", |
| 69 | + .phy_id_mask = 0x000ffff8, |
| 70 | + .features = PHY_GBIT_FEATURES, |
| 71 | + .flags = PHY_HAS_INTERRUPT, |
| 72 | + .config_init = &vsc8601_config_init, |
| 73 | + .config_aneg = &genphy_config_aneg, |
| 74 | + .read_status = &genphy_read_status, |
| 75 | + .ack_interrupt = &vsc824x_ack_interrupt, |
| 76 | + .config_intr = &vsc82xx_config_intr, |
| 77 | + .driver = { .owner = THIS_MODULE,}, |
| 78 | +}; |
| 79 | + |
| 80 | static int vsc8221_config_init(struct phy_device *phydev) |
| 81 | { |
| 82 | int err; |
| 83 | @@ -176,10 +220,23 @@ static int __init vsc82xx_init(void) |
| 84 | |
| 85 | err = phy_driver_register(&vsc8244_driver); |
| 86 | if (err < 0) |
| 87 | - return err; |
| 88 | + goto err; |
| 89 | + |
| 90 | err = phy_driver_register(&vsc8221_driver); |
| 91 | if (err < 0) |
| 92 | - phy_driver_unregister(&vsc8244_driver); |
| 93 | + goto err1; |
| 94 | + |
| 95 | + err = phy_driver_register(&vsc8601_driver); |
| 96 | + if (err < 0) |
| 97 | + goto err2; |
| 98 | + |
| 99 | + return 0; |
| 100 | + |
| 101 | +err2: |
| 102 | + phy_driver_unregister(&vsc8221_driver); |
| 103 | +err1: |
| 104 | + phy_driver_unregister(&vsc8244_driver); |
| 105 | +err: |
| 106 | return err; |
| 107 | } |
| 108 | |
| 109 | @@ -187,6 +244,7 @@ static void __exit vsc82xx_exit(void) |
| 110 | { |
| 111 | phy_driver_unregister(&vsc8244_driver); |
| 112 | phy_driver_unregister(&vsc8221_driver); |
| 113 | + phy_driver_unregister(&vsc8601_driver); |
| 114 | } |
| 115 | |
| 116 | module_init(vsc82xx_init); |
| 117 | |