diff options
Diffstat (limited to 'drivers/net/usb/lan78xx.c')
-rw-r--r-- | drivers/net/usb/lan78xx.c | 109 |
1 files changed, 107 insertions, 2 deletions
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c index 019f758953fc..08f8703e4d54 100644 --- a/drivers/net/usb/lan78xx.c +++ b/drivers/net/usb/lan78xx.c | |||
@@ -40,7 +40,7 @@ | |||
40 | #define DRIVER_AUTHOR "WOOJUNG HUH <woojung.huh@microchip.com>" | 40 | #define DRIVER_AUTHOR "WOOJUNG HUH <woojung.huh@microchip.com>" |
41 | #define DRIVER_DESC "LAN78XX USB 3.0 Gigabit Ethernet Devices" | 41 | #define DRIVER_DESC "LAN78XX USB 3.0 Gigabit Ethernet Devices" |
42 | #define DRIVER_NAME "lan78xx" | 42 | #define DRIVER_NAME "lan78xx" |
43 | #define DRIVER_VERSION "1.0.5" | 43 | #define DRIVER_VERSION "1.0.6" |
44 | 44 | ||
45 | #define TX_TIMEOUT_JIFFIES (5 * HZ) | 45 | #define TX_TIMEOUT_JIFFIES (5 * HZ) |
46 | #define THROTTLE_JIFFIES (HZ / 8) | 46 | #define THROTTLE_JIFFIES (HZ / 8) |
@@ -67,6 +67,7 @@ | |||
67 | #define LAN78XX_USB_VENDOR_ID (0x0424) | 67 | #define LAN78XX_USB_VENDOR_ID (0x0424) |
68 | #define LAN7800_USB_PRODUCT_ID (0x7800) | 68 | #define LAN7800_USB_PRODUCT_ID (0x7800) |
69 | #define LAN7850_USB_PRODUCT_ID (0x7850) | 69 | #define LAN7850_USB_PRODUCT_ID (0x7850) |
70 | #define LAN7801_USB_PRODUCT_ID (0x7801) | ||
70 | #define LAN78XX_EEPROM_MAGIC (0x78A5) | 71 | #define LAN78XX_EEPROM_MAGIC (0x78A5) |
71 | #define LAN78XX_OTP_MAGIC (0x78F3) | 72 | #define LAN78XX_OTP_MAGIC (0x78F3) |
72 | 73 | ||
@@ -390,6 +391,7 @@ struct lan78xx_net { | |||
390 | u32 chipid; | 391 | u32 chipid; |
391 | u32 chiprev; | 392 | u32 chiprev; |
392 | struct mii_bus *mdiobus; | 393 | struct mii_bus *mdiobus; |
394 | phy_interface_t interface; | ||
393 | 395 | ||
394 | int fc_autoneg; | 396 | int fc_autoneg; |
395 | u8 fc_request_control; | 397 | u8 fc_request_control; |
@@ -400,6 +402,10 @@ struct lan78xx_net { | |||
400 | struct irq_domain_data domain_data; | 402 | struct irq_domain_data domain_data; |
401 | }; | 403 | }; |
402 | 404 | ||
405 | /* define external phy id */ | ||
406 | #define PHY_LAN8835 (0x0007C130) | ||
407 | #define PHY_KSZ9031RNX (0x00221620) | ||
408 | |||
403 | /* use ethtool to change the level for any given device */ | 409 | /* use ethtool to change the level for any given device */ |
404 | static int msg_level = -1; | 410 | static int msg_level = -1; |
405 | module_param(msg_level, int, 0); | 411 | module_param(msg_level, int, 0); |
@@ -1697,6 +1703,7 @@ static int lan78xx_mdiobus_read(struct mii_bus *bus, int phy_id, int idx) | |||
1697 | done: | 1703 | done: |
1698 | mutex_unlock(&dev->phy_mutex); | 1704 | mutex_unlock(&dev->phy_mutex); |
1699 | usb_autopm_put_interface(dev->intf); | 1705 | usb_autopm_put_interface(dev->intf); |
1706 | |||
1700 | return ret; | 1707 | return ret; |
1701 | } | 1708 | } |
1702 | 1709 | ||
@@ -1759,6 +1766,10 @@ static int lan78xx_mdio_init(struct lan78xx_net *dev) | |||
1759 | /* set to internal PHY id */ | 1766 | /* set to internal PHY id */ |
1760 | dev->mdiobus->phy_mask = ~(1 << 1); | 1767 | dev->mdiobus->phy_mask = ~(1 << 1); |
1761 | break; | 1768 | break; |
1769 | case ID_REV_CHIP_ID_7801_: | ||
1770 | /* scan thru PHYAD[2..0] */ | ||
1771 | dev->mdiobus->phy_mask = ~(0xFF); | ||
1772 | break; | ||
1762 | } | 1773 | } |
1763 | 1774 | ||
1764 | ret = mdiobus_register(dev->mdiobus); | 1775 | ret = mdiobus_register(dev->mdiobus); |
@@ -1933,6 +1944,47 @@ static void lan78xx_remove_irq_domain(struct lan78xx_net *dev) | |||
1933 | dev->domain_data.irqdomain = NULL; | 1944 | dev->domain_data.irqdomain = NULL; |
1934 | } | 1945 | } |
1935 | 1946 | ||
1947 | static int lan8835_fixup(struct phy_device *phydev) | ||
1948 | { | ||
1949 | int buf; | ||
1950 | int ret; | ||
1951 | struct lan78xx_net *dev = netdev_priv(phydev->attached_dev); | ||
1952 | |||
1953 | /* LED2/PME_N/IRQ_N/RGMII_ID pin to IRQ_N mode */ | ||
1954 | buf = phy_read_mmd_indirect(phydev, 0x8010, 3); | ||
1955 | buf &= ~0x1800; | ||
1956 | buf |= 0x0800; | ||
1957 | phy_write_mmd_indirect(phydev, 0x8010, 3, buf); | ||
1958 | |||
1959 | /* RGMII MAC TXC Delay Enable */ | ||
1960 | ret = lan78xx_write_reg(dev, MAC_RGMII_ID, | ||
1961 | MAC_RGMII_ID_TXC_DELAY_EN_); | ||
1962 | |||
1963 | /* RGMII TX DLL Tune Adjust */ | ||
1964 | ret = lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00); | ||
1965 | |||
1966 | dev->interface = PHY_INTERFACE_MODE_RGMII_TXID; | ||
1967 | |||
1968 | return 1; | ||
1969 | } | ||
1970 | |||
1971 | static int ksz9031rnx_fixup(struct phy_device *phydev) | ||
1972 | { | ||
1973 | struct lan78xx_net *dev = netdev_priv(phydev->attached_dev); | ||
1974 | |||
1975 | /* Micrel9301RNX PHY configuration */ | ||
1976 | /* RGMII Control Signal Pad Skew */ | ||
1977 | phy_write_mmd_indirect(phydev, 4, 2, 0x0077); | ||
1978 | /* RGMII RX Data Pad Skew */ | ||
1979 | phy_write_mmd_indirect(phydev, 5, 2, 0x7777); | ||
1980 | /* RGMII RX Clock Pad Skew */ | ||
1981 | phy_write_mmd_indirect(phydev, 8, 2, 0x1FF); | ||
1982 | |||
1983 | dev->interface = PHY_INTERFACE_MODE_RGMII_RXID; | ||
1984 | |||
1985 | return 1; | ||
1986 | } | ||
1987 | |||
1936 | static int lan78xx_phy_init(struct lan78xx_net *dev) | 1988 | static int lan78xx_phy_init(struct lan78xx_net *dev) |
1937 | { | 1989 | { |
1938 | int ret; | 1990 | int ret; |
@@ -1945,6 +1997,42 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) | |||
1945 | return -EIO; | 1997 | return -EIO; |
1946 | } | 1998 | } |
1947 | 1999 | ||
2000 | if ((dev->chipid == ID_REV_CHIP_ID_7800_) || | ||
2001 | (dev->chipid == ID_REV_CHIP_ID_7850_)) { | ||
2002 | phydev->is_internal = true; | ||
2003 | dev->interface = PHY_INTERFACE_MODE_GMII; | ||
2004 | |||
2005 | } else if (dev->chipid == ID_REV_CHIP_ID_7801_) { | ||
2006 | if (!phydev->drv) { | ||
2007 | netdev_err(dev->net, "no PHY driver found\n"); | ||
2008 | return -EIO; | ||
2009 | } | ||
2010 | |||
2011 | dev->interface = PHY_INTERFACE_MODE_RGMII; | ||
2012 | |||
2013 | /* external PHY fixup for KSZ9031RNX */ | ||
2014 | ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0, | ||
2015 | ksz9031rnx_fixup); | ||
2016 | if (ret < 0) { | ||
2017 | netdev_err(dev->net, "fail to register fixup\n"); | ||
2018 | return ret; | ||
2019 | } | ||
2020 | /* external PHY fixup for LAN8835 */ | ||
2021 | ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfffffff0, | ||
2022 | lan8835_fixup); | ||
2023 | if (ret < 0) { | ||
2024 | netdev_err(dev->net, "fail to register fixup\n"); | ||
2025 | return ret; | ||
2026 | } | ||
2027 | /* add more external PHY fixup here if needed */ | ||
2028 | |||
2029 | phydev->is_internal = false; | ||
2030 | } else { | ||
2031 | netdev_err(dev->net, "unknown ID found\n"); | ||
2032 | ret = -EIO; | ||
2033 | goto error; | ||
2034 | } | ||
2035 | |||
1948 | /* if phyirq is not set, use polling mode in phylib */ | 2036 | /* if phyirq is not set, use polling mode in phylib */ |
1949 | if (dev->domain_data.phyirq > 0) | 2037 | if (dev->domain_data.phyirq > 0) |
1950 | phydev->irq = dev->domain_data.phyirq; | 2038 | phydev->irq = dev->domain_data.phyirq; |
@@ -1957,7 +2045,7 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) | |||
1957 | 2045 | ||
1958 | ret = phy_connect_direct(dev->net, phydev, | 2046 | ret = phy_connect_direct(dev->net, phydev, |
1959 | lan78xx_link_status_change, | 2047 | lan78xx_link_status_change, |
1960 | PHY_INTERFACE_MODE_GMII); | 2048 | dev->interface); |
1961 | if (ret) { | 2049 | if (ret) { |
1962 | netdev_err(dev->net, "can't attach PHY to %s\n", | 2050 | netdev_err(dev->net, "can't attach PHY to %s\n", |
1963 | dev->mdiobus->id); | 2051 | dev->mdiobus->id); |
@@ -1982,6 +2070,12 @@ static int lan78xx_phy_init(struct lan78xx_net *dev) | |||
1982 | netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); | 2070 | netif_dbg(dev, ifup, dev->net, "phy initialised successfully"); |
1983 | 2071 | ||
1984 | return 0; | 2072 | return 0; |
2073 | |||
2074 | error: | ||
2075 | phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); | ||
2076 | phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); | ||
2077 | |||
2078 | return ret; | ||
1985 | } | 2079 | } |
1986 | 2080 | ||
1987 | static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size) | 2081 | static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size) |
@@ -2338,6 +2432,9 @@ static int lan78xx_reset(struct lan78xx_net *dev) | |||
2338 | } while ((buf & PMT_CTL_PHY_RST_) || !(buf & PMT_CTL_READY_)); | 2432 | } while ((buf & PMT_CTL_PHY_RST_) || !(buf & PMT_CTL_READY_)); |
2339 | 2433 | ||
2340 | ret = lan78xx_read_reg(dev, MAC_CR, &buf); | 2434 | ret = lan78xx_read_reg(dev, MAC_CR, &buf); |
2435 | /* LAN7801 only has RGMII mode */ | ||
2436 | if (dev->chipid == ID_REV_CHIP_ID_7801_) | ||
2437 | buf &= ~MAC_CR_GMII_EN_; | ||
2341 | buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; | 2438 | buf |= MAC_CR_AUTO_DUPLEX_ | MAC_CR_AUTO_SPEED_; |
2342 | ret = lan78xx_write_reg(dev, MAC_CR, buf); | 2439 | ret = lan78xx_write_reg(dev, MAC_CR, buf); |
2343 | 2440 | ||
@@ -2464,8 +2561,12 @@ static int lan78xx_stop(struct net_device *net) | |||
2464 | if (timer_pending(&dev->stat_monitor)) | 2561 | if (timer_pending(&dev->stat_monitor)) |
2465 | del_timer_sync(&dev->stat_monitor); | 2562 | del_timer_sync(&dev->stat_monitor); |
2466 | 2563 | ||
2564 | phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0); | ||
2565 | phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0); | ||
2566 | |||
2467 | phy_stop(net->phydev); | 2567 | phy_stop(net->phydev); |
2468 | phy_disconnect(net->phydev); | 2568 | phy_disconnect(net->phydev); |
2569 | |||
2469 | net->phydev = NULL; | 2570 | net->phydev = NULL; |
2470 | 2571 | ||
2471 | clear_bit(EVENT_DEV_OPEN, &dev->flags); | 2572 | clear_bit(EVENT_DEV_OPEN, &dev->flags); |
@@ -3888,6 +3989,10 @@ static const struct usb_device_id products[] = { | |||
3888 | /* LAN7850 USB Gigabit Ethernet Device */ | 3989 | /* LAN7850 USB Gigabit Ethernet Device */ |
3889 | USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7850_USB_PRODUCT_ID), | 3990 | USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7850_USB_PRODUCT_ID), |
3890 | }, | 3991 | }, |
3992 | { | ||
3993 | /* LAN7801 USB Gigabit Ethernet Device */ | ||
3994 | USB_DEVICE(LAN78XX_USB_VENDOR_ID, LAN7801_USB_PRODUCT_ID), | ||
3995 | }, | ||
3891 | {}, | 3996 | {}, |
3892 | }; | 3997 | }; |
3893 | MODULE_DEVICE_TABLE(usb, products); | 3998 | MODULE_DEVICE_TABLE(usb, products); |