| 1 | --- a/drivers/net/phy/Kconfig |
| 2 | +++ b/drivers/net/phy/Kconfig |
| 3 | @@ -69,6 +69,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 | @@ -56,6 +61,7 @@ |
| 31 | |
| 32 | #define PHY_ID_VSC8244 0x000fc6c0 |
| 33 | #define PHY_ID_VSC8221 0x000fc550 |
| 34 | +#define PHY_ID_VSC8601 0x00070420 |
| 35 | |
| 36 | MODULE_DESCRIPTION("Vitesse PHY driver"); |
| 37 | MODULE_AUTHOR("Kriston Carson"); |
| 38 | @@ -98,10 +104,34 @@ static int vsc824x_config_init(struct ph |
| 39 | return err; |
| 40 | } |
| 41 | |
| 42 | +static int vsc8601_config_init(struct phy_device *phydev) |
| 43 | +{ |
| 44 | + int err; |
| 45 | + int extcon; |
| 46 | + |
| 47 | + err = phy_write(phydev, MII_VSC8244_AUX_CONSTAT, |
| 48 | + MII_VSC8244_AUXCONSTAT_INIT); |
| 49 | + |
| 50 | + if (err < 0) |
| 51 | + return err; |
| 52 | + |
| 53 | +#ifdef CONFIG_VITESSE_PHY_8601_SKEW |
| 54 | + extcon = phy_read(phydev, MII_VSC8244_EXT_CON1); |
| 55 | + if (err < 0) |
| 56 | + return err; |
| 57 | + |
| 58 | + extcon |= MII_VSC8601_EXTCON1_SKEW; |
| 59 | + |
| 60 | + err = phy_write(phydev, MII_VSC8244_EXT_CON1, extcon); |
| 61 | +#endif |
| 62 | + |
| 63 | + return err; |
| 64 | +} |
| 65 | + |
| 66 | static int vsc824x_ack_interrupt(struct phy_device *phydev) |
| 67 | { |
| 68 | int err = 0; |
| 69 | - |
| 70 | + |
| 71 | /* |
| 72 | * Don't bother to ACK the interrupts if interrupts |
| 73 | * are disabled. The 824x cannot clear the interrupts |
| 74 | @@ -177,6 +207,19 @@ static struct phy_driver vsc82xx_driver[ |
| 75 | .ack_interrupt = &vsc824x_ack_interrupt, |
| 76 | .config_intr = &vsc82xx_config_intr, |
| 77 | .driver = { .owner = THIS_MODULE,}, |
| 78 | +}, { |
| 79 | + /* Vitesse 8601 */ |
| 80 | + .phy_id = PHY_ID_VSC8601, |
| 81 | + .name = "Vitesse VSC8601", |
| 82 | + .phy_id_mask = 0x000ffff8, |
| 83 | + .features = PHY_GBIT_FEATURES, |
| 84 | + .flags = PHY_HAS_INTERRUPT, |
| 85 | + .config_init = &vsc8601_config_init, |
| 86 | + .config_aneg = &genphy_config_aneg, |
| 87 | + .read_status = &genphy_read_status, |
| 88 | + .ack_interrupt = &vsc824x_ack_interrupt, |
| 89 | + .config_intr = &vsc82xx_config_intr, |
| 90 | + .driver = { .owner = THIS_MODULE,}, |
| 91 | } }; |
| 92 | |
| 93 | static int __init vsc82xx_init(void) |
| 94 | |