^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /***************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 2007-2008 SMSC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/kmod.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/ethtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/mii.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/bitrev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/crc16.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/usb/usbnet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/of_net.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/mdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "smsc95xx.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define SMSC_CHIPNAME "smsc95xx"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define SMSC_DRIVER_VERSION "2.0.0"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define HS_USB_PKT_SIZE (512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define FS_USB_PKT_SIZE (64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define DEFAULT_HS_BURST_CAP_SIZE (16 * 1024 + 5 * HS_USB_PKT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define DEFAULT_FS_BURST_CAP_SIZE (6 * 1024 + 33 * FS_USB_PKT_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define DEFAULT_BULK_IN_DELAY (0x00002000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define MAX_SINGLE_PACKET_SIZE (2048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define LAN95XX_EEPROM_MAGIC (0x9500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define EEPROM_MAC_OFFSET (0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define DEFAULT_TX_CSUM_ENABLE (true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define DEFAULT_RX_CSUM_ENABLE (true)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define SMSC95XX_INTERNAL_PHY_ID (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define SMSC95XX_TX_OVERHEAD (8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define SMSC95XX_TX_OVERHEAD_CSUM (12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define SUPPORTED_WAKE (WAKE_PHY | WAKE_UCAST | WAKE_BCAST | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) WAKE_MCAST | WAKE_ARP | WAKE_MAGIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define FEATURE_8_WAKEUP_FILTERS (0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define FEATURE_PHY_NLP_CROSSOVER (0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define FEATURE_REMOTE_WAKEUP (0x04)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define SUSPEND_SUSPEND0 (0x01)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define SUSPEND_SUSPEND1 (0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define SUSPEND_SUSPEND2 (0x04)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define SUSPEND_SUSPEND3 (0x08)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) struct smsc95xx_priv {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) u32 mac_cr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) u32 hash_hi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) u32 hash_lo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) u32 wolopts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) spinlock_t mac_cr_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) u8 features;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) u8 suspend_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct mii_bus *mdiobus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct phy_device *phydev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static bool turbo_mode = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) module_param(turbo_mode, bool, 0644);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) static int __must_check __smsc95xx_read_reg(struct usbnet *dev, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) u32 *data, int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) u32 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int (*fn)(struct usbnet *, u8, u8, u16, u16, void *, u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) BUG_ON(!dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (!in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) fn = usbnet_read_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) fn = usbnet_read_cmd_nopm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) 0, index, &buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) index, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) le32_to_cpus(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) *data = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) static int __must_check __smsc95xx_write_reg(struct usbnet *dev, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) u32 data, int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u32 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int (*fn)(struct usbnet *, u8, u8, u16, u16, const void *, u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) BUG_ON(!dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) fn = usbnet_write_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) fn = usbnet_write_cmd_nopm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) buf = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) cpu_to_le32s(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) ret = fn(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, USB_DIR_OUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 0, index, &buf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (ret < 0 && ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) netdev_warn(dev->net, "Failed to write reg index 0x%08x: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) index, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static int __must_check smsc95xx_read_reg_nopm(struct usbnet *dev, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u32 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) return __smsc95xx_read_reg(dev, index, data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) static int __must_check smsc95xx_write_reg_nopm(struct usbnet *dev, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return __smsc95xx_write_reg(dev, index, data, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u32 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return __smsc95xx_read_reg(dev, index, data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) static int __must_check smsc95xx_write_reg(struct usbnet *dev, u32 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) return __smsc95xx_write_reg(dev, index, data, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* Loop until the read is completed with timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * called with phy_mutex held */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) static int __must_check __smsc95xx_phy_wait_not_busy(struct usbnet *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) unsigned long start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) ret = __smsc95xx_read_reg(dev, MII_ADDR, &val, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /* Ignore -ENODEV error during disconnect() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (ret == -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) netdev_warn(dev->net, "Error reading MII_ACCESS\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!(val & MII_BUSY_))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) } while (!time_after(jiffies, start_time + HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static u32 mii_address_cmd(int phy_id, int idx, u16 op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) return (phy_id & 0x1f) << 11 | (idx & 0x1f) << 6 | op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static int __smsc95xx_mdio_read(struct usbnet *dev, int phy_id, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) u32 val, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) /* confirm MII not busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) ret = __smsc95xx_phy_wait_not_busy(dev, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) netdev_warn(dev->net, "%s: MII is busy\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* set the address, index & direction (read from PHY) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) addr = mii_address_cmd(phy_id, idx, MII_READ_ | MII_BUSY_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ret = __smsc95xx_write_reg(dev, MII_ADDR, addr, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) if (ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) netdev_warn(dev->net, "Error writing MII_ADDR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ret = __smsc95xx_phy_wait_not_busy(dev, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) netdev_warn(dev->net, "Timed out reading MII reg %02X\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ret = __smsc95xx_read_reg(dev, MII_DATA, &val, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) netdev_warn(dev->net, "Error reading MII_DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) ret = (u16)(val & 0xFFFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* Ignore -ENODEV error during disconnect() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (ret == -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) static void __smsc95xx_mdio_write(struct usbnet *dev, int phy_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) int idx, int regval, int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) u32 val, addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) mutex_lock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* confirm MII not busy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) ret = __smsc95xx_phy_wait_not_busy(dev, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) netdev_warn(dev->net, "%s: MII is busy\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) val = regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = __smsc95xx_write_reg(dev, MII_DATA, val, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) netdev_warn(dev->net, "Error writing MII_DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* set the address, index & direction (write to PHY) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) addr = mii_address_cmd(phy_id, idx, MII_WRITE_ | MII_BUSY_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) ret = __smsc95xx_write_reg(dev, MII_ADDR, addr, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (ret != -ENODEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) netdev_warn(dev->net, "Error writing MII_ADDR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ret = __smsc95xx_phy_wait_not_busy(dev, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) netdev_warn(dev->net, "Timed out writing MII reg %02X\n", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) mutex_unlock(&dev->phy_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static int smsc95xx_mdio_read_nopm(struct usbnet *dev, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) return __smsc95xx_mdio_read(dev, pdata->phydev->mdio.addr, idx, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) static void smsc95xx_mdio_write_nopm(struct usbnet *dev, int idx, int regval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) __smsc95xx_mdio_write(dev, pdata->phydev->mdio.addr, idx, regval, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static int smsc95xx_mdiobus_read(struct mii_bus *bus, int phy_id, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) struct usbnet *dev = bus->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) return __smsc95xx_mdio_read(dev, phy_id, idx, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) static int smsc95xx_mdiobus_write(struct mii_bus *bus, int phy_id, int idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) u16 regval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) struct usbnet *dev = bus->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) __smsc95xx_mdio_write(dev, phy_id, idx, regval, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) static int __must_check smsc95xx_wait_eeprom(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) unsigned long start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) ret = smsc95xx_read_reg(dev, E2P_CMD, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) netdev_warn(dev->net, "Error reading E2P_CMD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (!(val & E2P_CMD_BUSY_) || (val & E2P_CMD_TIMEOUT_))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) } while (!time_after(jiffies, start_time + HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (val & (E2P_CMD_TIMEOUT_ | E2P_CMD_BUSY_)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) netdev_warn(dev->net, "EEPROM read operation timeout\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) static int __must_check smsc95xx_eeprom_confirm_not_busy(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) unsigned long start_time = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) ret = smsc95xx_read_reg(dev, E2P_CMD, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) netdev_warn(dev->net, "Error reading E2P_CMD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) if (!(val & E2P_CMD_BUSY_))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) udelay(40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) } while (!time_after(jiffies, start_time + HZ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) netdev_warn(dev->net, "EEPROM is busy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static int smsc95xx_read_eeprom(struct usbnet *dev, u32 offset, u32 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) BUG_ON(!dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) BUG_ON(!data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ret = smsc95xx_eeprom_confirm_not_busy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) for (i = 0; i < length; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) val = E2P_CMD_BUSY_ | E2P_CMD_READ_ | (offset & E2P_CMD_ADDR_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) ret = smsc95xx_write_reg(dev, E2P_CMD, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) netdev_warn(dev->net, "Error writing E2P_CMD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) ret = smsc95xx_wait_eeprom(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) ret = smsc95xx_read_reg(dev, E2P_DATA, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) netdev_warn(dev->net, "Error reading E2P_DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) data[i] = val & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) offset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) static int smsc95xx_write_eeprom(struct usbnet *dev, u32 offset, u32 length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) BUG_ON(!dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) BUG_ON(!data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) ret = smsc95xx_eeprom_confirm_not_busy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* Issue write/erase enable command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) val = E2P_CMD_BUSY_ | E2P_CMD_EWEN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ret = smsc95xx_write_reg(dev, E2P_CMD, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) netdev_warn(dev->net, "Error writing E2P_DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) ret = smsc95xx_wait_eeprom(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) for (i = 0; i < length; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /* Fill data register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) val = data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ret = smsc95xx_write_reg(dev, E2P_DATA, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) netdev_warn(dev->net, "Error writing E2P_DATA\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Send "write" command */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) val = E2P_CMD_BUSY_ | E2P_CMD_WRITE_ | (offset & E2P_CMD_ADDR_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) ret = smsc95xx_write_reg(dev, E2P_CMD, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) netdev_warn(dev->net, "Error writing E2P_CMD\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) ret = smsc95xx_wait_eeprom(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) offset++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static int __must_check smsc95xx_write_reg_async(struct usbnet *dev, u16 index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) u32 data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) const u16 size = 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) u32 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) buf = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) cpu_to_le32s(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) ret = usbnet_write_cmd_async(dev, USB_VENDOR_REQUEST_WRITE_REGISTER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) USB_DIR_OUT | USB_TYPE_VENDOR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) USB_RECIP_DEVICE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 0, index, &buf, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) netdev_warn(dev->net, "Error write async cmd, sts=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) /* returns hash bit number for given MAC address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) * example:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * 01 00 5E 00 00 01 -> returns bit number 31 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) static unsigned int smsc95xx_hash(char addr[ETH_ALEN])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return (ether_crc(ETH_ALEN, addr) >> 26) & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) static void smsc95xx_set_multicast(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pdata->hash_hi = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) pdata->hash_lo = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) spin_lock_irqsave(&pdata->mac_cr_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) if (dev->net->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) netif_dbg(dev, drv, dev->net, "promiscuous mode enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) pdata->mac_cr |= MAC_CR_PRMS_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) pdata->mac_cr &= ~(MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) } else if (dev->net->flags & IFF_ALLMULTI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) netif_dbg(dev, drv, dev->net, "receive all multicast enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) pdata->mac_cr |= MAC_CR_MCPAS_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_HPFILT_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) } else if (!netdev_mc_empty(dev->net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct netdev_hw_addr *ha;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) pdata->mac_cr |= MAC_CR_HPFILT_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) pdata->mac_cr &= ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) netdev_for_each_mc_addr(ha, netdev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) u32 bitnum = smsc95xx_hash(ha->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) u32 mask = 0x01 << (bitnum & 0x1F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (bitnum & 0x20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) pdata->hash_hi |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) pdata->hash_lo |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) pdata->hash_hi, pdata->hash_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) netif_dbg(dev, drv, dev->net, "receive own packets only\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) pdata->mac_cr &=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) ~(MAC_CR_PRMS_ | MAC_CR_MCPAS_ | MAC_CR_HPFILT_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /* Initiate async writes, as we can't wait for completion here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ret = smsc95xx_write_reg_async(dev, HASHH, pdata->hash_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) netdev_warn(dev->net, "failed to initiate async write to HASHH\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) ret = smsc95xx_write_reg_async(dev, HASHL, pdata->hash_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) netdev_warn(dev->net, "failed to initiate async write to HASHL\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) ret = smsc95xx_write_reg_async(dev, MAC_CR, pdata->mac_cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) netdev_warn(dev->net, "failed to initiate async write to MAC_CR\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) static int smsc95xx_phy_update_flowcontrol(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) u32 flow = 0, afc_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) bool tx_pause, rx_pause;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) int ret = smsc95xx_read_reg(dev, AFC_CFG, &afc_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) if (pdata->phydev->duplex == DUPLEX_FULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) phy_get_pause(pdata->phydev, &tx_pause, &rx_pause);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) if (rx_pause)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) flow = 0xFFFF0002;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) if (tx_pause) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) afc_cfg |= 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) flow |= 0xFFFF0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) afc_cfg &= ~0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) netif_dbg(dev, link, dev->net, "rx pause %s, tx pause %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) rx_pause ? "enabled" : "disabled",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) tx_pause ? "enabled" : "disabled");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) netif_dbg(dev, link, dev->net, "half duplex\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) afc_cfg |= 0xF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ret = smsc95xx_write_reg(dev, FLOW, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return smsc95xx_write_reg(dev, AFC_CFG, afc_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) static int smsc95xx_link_reset(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) ret = smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) spin_lock_irqsave(&pdata->mac_cr_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) if (pdata->phydev->duplex != DUPLEX_FULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) pdata->mac_cr &= ~MAC_CR_FDPX_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) pdata->mac_cr |= MAC_CR_RCVOWN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) pdata->mac_cr &= ~MAC_CR_RCVOWN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) pdata->mac_cr |= MAC_CR_FDPX_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ret = smsc95xx_phy_update_flowcontrol(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) netdev_warn(dev->net, "Error updating PHY flow control\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) static void smsc95xx_status(struct usbnet *dev, struct urb *urb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) u32 intdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) if (urb->actual_length != 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) netdev_warn(dev->net, "unexpected urb length %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) urb->actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) intdata = get_unaligned_le32(urb->transfer_buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (intdata & INT_ENP_PHY_INT_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) usbnet_defer_kevent(dev, EVENT_LINK_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) intdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /* Enable or disable Tx & Rx checksum offload engines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) static int smsc95xx_set_features(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) netdev_features_t features)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) u32 read_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) ret = smsc95xx_read_reg(dev, COE_CR, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (features & NETIF_F_IP_CSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) read_buf |= Tx_COE_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) read_buf &= ~Tx_COE_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (features & NETIF_F_RXCSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) read_buf |= Rx_COE_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) read_buf &= ~Rx_COE_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) ret = smsc95xx_write_reg(dev, COE_CR, read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) netif_dbg(dev, hw, dev->net, "COE_CR = 0x%08x\n", read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) static int smsc95xx_ethtool_get_eeprom_len(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) return MAX_EEPROM_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) static int smsc95xx_ethtool_get_eeprom(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) struct ethtool_eeprom *ee, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) ee->magic = LAN95XX_EEPROM_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) return smsc95xx_read_eeprom(dev, ee->offset, ee->len, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) static int smsc95xx_ethtool_set_eeprom(struct net_device *netdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) struct ethtool_eeprom *ee, u8 *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (ee->magic != LAN95XX_EEPROM_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) netdev_warn(dev->net, "EEPROM: magic value mismatch, magic = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) ee->magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) return smsc95xx_write_eeprom(dev, ee->offset, ee->len, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) static int smsc95xx_ethtool_getregslen(struct net_device *netdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /* all smsc95xx registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) return COE_CR - ID_REV + sizeof(u32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) smsc95xx_ethtool_getregs(struct net_device *netdev, struct ethtool_regs *regs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) void *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) struct usbnet *dev = netdev_priv(netdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) unsigned int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) u32 *data = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) retval = smsc95xx_read_reg(dev, ID_REV, ®s->version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) netdev_warn(netdev, "REGS: cannot read ID_REV\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) for (i = ID_REV, j = 0; i <= COE_CR; i += (sizeof(u32)), j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) retval = smsc95xx_read_reg(dev, i, &data[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (retval < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) netdev_warn(netdev, "REGS: cannot read reg[%x]\n", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) static void smsc95xx_ethtool_get_wol(struct net_device *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) struct ethtool_wolinfo *wolinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) wolinfo->supported = SUPPORTED_WAKE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) wolinfo->wolopts = pdata->wolopts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) static int smsc95xx_ethtool_set_wol(struct net_device *net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct ethtool_wolinfo *wolinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) if (wolinfo->wolopts & ~SUPPORTED_WAKE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) pdata->wolopts = wolinfo->wolopts & SUPPORTED_WAKE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) ret = device_set_wakeup_enable(&dev->udev->dev, pdata->wolopts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) netdev_warn(dev->net, "device_set_wakeup_enable error %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) static u32 smsc95xx_get_link(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) phy_read_status(net->phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) return net->phydev->link;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) static const struct ethtool_ops smsc95xx_ethtool_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) .get_link = smsc95xx_get_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) .nway_reset = phy_ethtool_nway_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) .get_drvinfo = usbnet_get_drvinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) .get_msglevel = usbnet_get_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) .set_msglevel = usbnet_set_msglevel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) .get_eeprom_len = smsc95xx_ethtool_get_eeprom_len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) .get_eeprom = smsc95xx_ethtool_get_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) .set_eeprom = smsc95xx_ethtool_set_eeprom,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) .get_regs_len = smsc95xx_ethtool_getregslen,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) .get_regs = smsc95xx_ethtool_getregs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) .get_wol = smsc95xx_ethtool_get_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .set_wol = smsc95xx_ethtool_set_wol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .get_link_ksettings = phy_ethtool_get_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .set_link_ksettings = phy_ethtool_set_link_ksettings,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) .get_ts_info = ethtool_op_get_ts_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) static int smsc95xx_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (!netif_running(netdev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) return phy_mii_ioctl(netdev->phydev, rq, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) static void smsc95xx_init_mac_address(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* maybe the boot loader passed the MAC address in devicetree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (!eth_platform_get_mac_address(&dev->udev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) dev->net->dev_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) if (is_valid_ether_addr(dev->net->dev_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* device tree values are valid so use them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) netif_dbg(dev, ifup, dev->net, "MAC address read from the device tree\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* try reading mac address from EEPROM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) dev->net->dev_addr) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (is_valid_ether_addr(dev->net->dev_addr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) /* eeprom values are valid so use them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) netif_dbg(dev, ifup, dev->net, "MAC address read from EEPROM\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /* no useful static MAC address found. generate a random one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) eth_hw_addr_random(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) netif_dbg(dev, ifup, dev->net, "MAC address set to eth_random_addr\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) static int smsc95xx_set_mac_address(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) u32 addr_lo = dev->net->dev_addr[0] | dev->net->dev_addr[1] << 8 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) dev->net->dev_addr[2] << 16 | dev->net->dev_addr[3] << 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) u32 addr_hi = dev->net->dev_addr[4] | dev->net->dev_addr[5] << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ret = smsc95xx_write_reg(dev, ADDRL, addr_lo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) return smsc95xx_write_reg(dev, ADDRH, addr_hi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) /* starts the TX path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) static int smsc95xx_start_tx_path(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /* Enable Tx at MAC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) spin_lock_irqsave(&pdata->mac_cr_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) pdata->mac_cr |= MAC_CR_TXEN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) ret = smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) /* Enable Tx at SCSRs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) return smsc95xx_write_reg(dev, TX_CFG, TX_CFG_ON_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) /* Starts the Receive path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static int smsc95xx_start_rx_path(struct usbnet *dev, int in_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) spin_lock_irqsave(&pdata->mac_cr_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) pdata->mac_cr |= MAC_CR_RXEN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return __smsc95xx_write_reg(dev, MAC_CR, pdata->mac_cr, in_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) static int smsc95xx_reset(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) u32 read_buf, write_buf, burst_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) int ret = 0, timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) ret = smsc95xx_write_reg(dev, HW_CFG, HW_CFG_LRST_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) timeout++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) } while ((read_buf & HW_CFG_LRST_) && (timeout < 100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (timeout >= 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) netdev_warn(dev->net, "timeout waiting for completion of Lite Reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) ret = smsc95xx_write_reg(dev, PM_CTRL, PM_CTL_PHY_RST_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) timeout = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) msleep(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) ret = smsc95xx_read_reg(dev, PM_CTRL, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) timeout++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) } while ((read_buf & PM_CTL_PHY_RST_) && (timeout < 100));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) if (timeout >= 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) netdev_warn(dev->net, "timeout waiting for PHY Reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) ret = smsc95xx_set_mac_address(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) netif_dbg(dev, ifup, dev->net, "MAC Address: %pM\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) dev->net->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG : 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) read_buf |= HW_CFG_BIR_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) netif_dbg(dev, ifup, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) "Read Value from HW_CFG after writing HW_CFG_BIR_: 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) if (!turbo_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) burst_cap = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) dev->rx_urb_size = MAX_SINGLE_PACKET_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) } else if (dev->udev->speed == USB_SPEED_HIGH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) burst_cap = DEFAULT_HS_BURST_CAP_SIZE / HS_USB_PKT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) dev->rx_urb_size = DEFAULT_HS_BURST_CAP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) burst_cap = DEFAULT_FS_BURST_CAP_SIZE / FS_USB_PKT_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) dev->rx_urb_size = DEFAULT_FS_BURST_CAP_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) netif_dbg(dev, ifup, dev->net, "rx_urb_size=%ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) (ulong)dev->rx_urb_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) ret = smsc95xx_write_reg(dev, BURST_CAP, burst_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ret = smsc95xx_read_reg(dev, BURST_CAP, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) netif_dbg(dev, ifup, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) "Read Value from BURST_CAP after writing: 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) ret = smsc95xx_write_reg(dev, BULK_IN_DLY, DEFAULT_BULK_IN_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) ret = smsc95xx_read_reg(dev, BULK_IN_DLY, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) netif_dbg(dev, ifup, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) "Read Value from BULK_IN_DLY after writing: 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) netif_dbg(dev, ifup, dev->net, "Read Value from HW_CFG: 0x%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (turbo_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) read_buf |= (HW_CFG_MEF_ | HW_CFG_BCE_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) read_buf &= ~HW_CFG_RXDOFF_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) /* set Rx data offset=2, Make IP header aligns on word boundary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) read_buf |= NET_IP_ALIGN << 9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) ret = smsc95xx_write_reg(dev, HW_CFG, read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) ret = smsc95xx_read_reg(dev, HW_CFG, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) netif_dbg(dev, ifup, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) "Read Value from HW_CFG after writing: 0x%08x\n", read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) ret = smsc95xx_write_reg(dev, INT_STS, INT_STS_CLEAR_ALL_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) ret = smsc95xx_read_reg(dev, ID_REV, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) /* Configure GPIO pins as LED outputs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) LED_GPIO_CFG_FDX_LED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) /* Init Tx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) ret = smsc95xx_write_reg(dev, FLOW, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) ret = smsc95xx_write_reg(dev, AFC_CFG, AFC_CFG_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /* Don't need mac_cr_lock during initialisation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) ret = smsc95xx_read_reg(dev, MAC_CR, &pdata->mac_cr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) /* Init Rx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) /* Set Vlan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ret = smsc95xx_write_reg(dev, VLAN1, (u32)ETH_P_8021Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /* Enable or disable checksum offload engines */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) ret = smsc95xx_set_features(dev->net, dev->net->features);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) netdev_warn(dev->net, "Failed to set checksum offload features\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) smsc95xx_set_multicast(dev->net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) ret = smsc95xx_read_reg(dev, INT_EP_CTL, &read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* enable PHY interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) read_buf |= INT_EP_CTL_PHY_INT_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) ret = smsc95xx_write_reg(dev, INT_EP_CTL, read_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) ret = smsc95xx_start_tx_path(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) netdev_warn(dev->net, "Failed to start TX path\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) ret = smsc95xx_start_rx_path(dev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) netdev_warn(dev->net, "Failed to start RX path\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) netif_dbg(dev, ifup, dev->net, "smsc95xx_reset, return 0\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) static const struct net_device_ops smsc95xx_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) .ndo_open = usbnet_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) .ndo_stop = usbnet_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) .ndo_start_xmit = usbnet_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) .ndo_tx_timeout = usbnet_tx_timeout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) .ndo_change_mtu = usbnet_change_mtu,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) .ndo_get_stats64 = usbnet_get_stats64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) .ndo_set_mac_address = eth_mac_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) .ndo_validate_addr = eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) .ndo_do_ioctl = smsc95xx_ioctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) .ndo_set_rx_mode = smsc95xx_set_multicast,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) .ndo_set_features = smsc95xx_set_features,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) static void smsc95xx_handle_link_change(struct net_device *net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) struct usbnet *dev = netdev_priv(net);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) phy_print_status(net->phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) usbnet_defer_kevent(dev, EVENT_LINK_CHANGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) struct smsc95xx_priv *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) bool is_internal_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) ret = usbnet_get_endpoints(dev, intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) netdev_warn(dev->net, "usbnet_get_endpoints failed: %d\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (!pdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) dev->driver_priv = pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) spin_lock_init(&pdata->mac_cr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) /* LAN95xx devices do not alter the computed checksum of 0 to 0xffff.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * RFC 2460, ipv6 UDP calculated checksum yields a result of zero must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * be changed to 0xffff. RFC 768, ipv4 UDP computed checksum is zero,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * it is transmitted as all ones. The zero transmitted checksum means
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) * transmitter generated no checksum. Hence, enable csum offload only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * for ipv4 packets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) if (DEFAULT_TX_CSUM_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) dev->net->features |= NETIF_F_IP_CSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) if (DEFAULT_RX_CSUM_ENABLE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) dev->net->features |= NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) dev->net->hw_features = NETIF_F_IP_CSUM | NETIF_F_RXCSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) set_bit(EVENT_NO_IP_ALIGN, &dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) smsc95xx_init_mac_address(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* Init all registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) ret = smsc95xx_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) goto free_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) pdata->mdiobus = mdiobus_alloc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) if (!pdata->mdiobus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) goto free_pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ret = smsc95xx_read_reg(dev, HW_CFG, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) goto free_mdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) is_internal_phy = !(val & HW_CFG_PSEL_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (is_internal_phy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) pdata->mdiobus->phy_mask = ~(1u << SMSC95XX_INTERNAL_PHY_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) pdata->mdiobus->priv = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) pdata->mdiobus->read = smsc95xx_mdiobus_read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) pdata->mdiobus->write = smsc95xx_mdiobus_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) pdata->mdiobus->name = "smsc95xx-mdiobus";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) pdata->mdiobus->parent = &dev->udev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) snprintf(pdata->mdiobus->id, ARRAY_SIZE(pdata->mdiobus->id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) "usb-%03d:%03d", dev->udev->bus->busnum, dev->udev->devnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) ret = mdiobus_register(pdata->mdiobus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) netdev_err(dev->net, "Could not register MDIO bus\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) goto free_mdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) pdata->phydev = phy_find_first(pdata->mdiobus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) if (!pdata->phydev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) netdev_err(dev->net, "no PHY found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) goto unregister_mdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) pdata->phydev->is_internal = is_internal_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) /* detect device revision as different features may be available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) ret = smsc95xx_read_reg(dev, ID_REV, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) goto unregister_mdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) val >>= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) if ((val == ID_REV_CHIP_ID_9500A_) || (val == ID_REV_CHIP_ID_9530_) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) (val == ID_REV_CHIP_ID_89530_) || (val == ID_REV_CHIP_ID_9730_))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) pdata->features = (FEATURE_8_WAKEUP_FILTERS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) FEATURE_PHY_NLP_CROSSOVER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) FEATURE_REMOTE_WAKEUP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) else if (val == ID_REV_CHIP_ID_9512_)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) pdata->features = FEATURE_8_WAKEUP_FILTERS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) dev->net->netdev_ops = &smsc95xx_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) dev->net->ethtool_ops = &smsc95xx_ethtool_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) dev->net->flags |= IFF_MULTICAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) dev->net->hard_header_len += SMSC95XX_TX_OVERHEAD_CSUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) dev->net->min_mtu = ETH_MIN_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) dev->net->max_mtu = ETH_DATA_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) ret = phy_connect_direct(dev->net, pdata->phydev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) &smsc95xx_handle_link_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) PHY_INTERFACE_MODE_MII);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) netdev_err(dev->net, "can't attach PHY to %s\n", pdata->mdiobus->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) goto unregister_mdio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) phy_attached_info(dev->net->phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) unregister_mdio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) mdiobus_unregister(pdata->mdiobus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) free_mdio:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) mdiobus_free(pdata->mdiobus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) free_pdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) kfree(pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) static void smsc95xx_unbind(struct usbnet *dev, struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) phy_disconnect(dev->net->phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) mdiobus_unregister(pdata->mdiobus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) mdiobus_free(pdata->mdiobus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) netif_dbg(dev, ifdown, dev->net, "free pdata\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) kfree(pdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) static int smsc95xx_start_phy(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) phy_start(dev->net->phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) static int smsc95xx_stop(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) if (dev->net->phydev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) phy_stop(dev->net->phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) static u32 smsc_crc(const u8 *buffer, size_t len, int filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) u32 crc = bitrev16(crc16(0xFFFF, buffer, len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) return crc << ((filter % 2) * 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) static int smsc95xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) /* read to clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_SRC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) /* enable interrupt source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) ret |= mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) smsc95xx_mdio_write_nopm(dev, PHY_INT_MASK, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) static int smsc95xx_link_ok_nopm(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) /* first, a dummy read, needed to latch some MII phys */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) ret = smsc95xx_mdio_read_nopm(dev, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) ret = smsc95xx_mdio_read_nopm(dev, MII_BMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) return !!(ret & BMSR_LSTATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) static int smsc95xx_enter_suspend0(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) val &= (~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) val |= PM_CTL_SUS_MODE_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) /* clear wol status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) val &= ~PM_CTL_WUPS_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) val |= PM_CTL_WUPS_WOL_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /* enable energy detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (pdata->wolopts & WAKE_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) val |= PM_CTL_WUPS_ED_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) /* read back PM_CTRL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) pdata->suspend_flags |= SUSPEND_SUSPEND0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) static int smsc95xx_enter_suspend1(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /* reconfigure link pulse detection timing for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) * compatibility with non-standard link partners
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) if (pdata->features & FEATURE_PHY_NLP_CROSSOVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) smsc95xx_mdio_write_nopm(dev, PHY_EDPD_CONFIG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) PHY_EDPD_CONFIG_DEFAULT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /* enable energy detect power-down mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) ret = smsc95xx_mdio_read_nopm(dev, PHY_MODE_CTRL_STS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) ret |= MODE_CTRL_STS_EDPWRDOWN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) smsc95xx_mdio_write_nopm(dev, PHY_MODE_CTRL_STS, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) /* enter SUSPEND1 mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) val |= PM_CTL_SUS_MODE_1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) /* clear wol status, enable energy detection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) val &= ~PM_CTL_WUPS_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) val |= (PM_CTL_WUPS_ED_ | PM_CTL_ED_EN_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) pdata->suspend_flags |= SUSPEND_SUSPEND1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) static int smsc95xx_enter_suspend2(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) val |= PM_CTL_SUS_MODE_2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) pdata->suspend_flags |= SUSPEND_SUSPEND2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) static int smsc95xx_enter_suspend3(struct usbnet *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) ret = smsc95xx_read_reg_nopm(dev, RX_FIFO_INF, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) if (val & RX_FIFO_INF_USED_) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) netdev_info(dev->net, "rx fifo not empty in autosuspend\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) val &= ~(PM_CTL_SUS_MODE_ | PM_CTL_WUPS_ | PM_CTL_PHY_RST_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) val |= PM_CTL_SUS_MODE_3 | PM_CTL_RES_CLR_WKP_STS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) /* clear wol status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) val &= ~PM_CTL_WUPS_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) val |= PM_CTL_WUPS_WOL_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) pdata->suspend_flags |= SUSPEND_SUSPEND3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) if (!netif_running(dev->net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) /* interface is ifconfig down so fully power down hw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) netdev_dbg(dev->net, "autosuspend entering SUSPEND2\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) return smsc95xx_enter_suspend2(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) if (!link_up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) /* link is down so enter EDPD mode, but only if device can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) * reliably resume from it. This check should be redundant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) * as current FEATURE_REMOTE_WAKEUP parts also support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) * FEATURE_PHY_NLP_CROSSOVER but it's included for clarity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (!(pdata->features & FEATURE_PHY_NLP_CROSSOVER)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) netdev_warn(dev->net, "EDPD not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) netdev_dbg(dev->net, "autosuspend entering SUSPEND1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) /* enable PHY wakeup events for if cable is attached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) ret = smsc95xx_enable_phy_wakeup_interrupts(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) PHY_INT_MASK_ANEG_COMP_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) netdev_info(dev->net, "entering SUSPEND1 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) return smsc95xx_enter_suspend1(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) /* enable PHY wakeup events so we remote wakeup if cable is pulled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) ret = smsc95xx_enable_phy_wakeup_interrupts(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) PHY_INT_MASK_LINK_DOWN_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) return smsc95xx_enter_suspend3(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) static int smsc95xx_suspend(struct usb_interface *intf, pm_message_t message)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) struct usbnet *dev = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) u32 val, link_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) ret = usbnet_suspend(intf, message);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) netdev_warn(dev->net, "usbnet_suspend error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) if (pdata->suspend_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) netdev_warn(dev->net, "error during last resume\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) pdata->suspend_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) /* determine if link is up using only _nopm functions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) link_up = smsc95xx_link_ok_nopm(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) if (message.event == PM_EVENT_AUTO_SUSPEND &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) (pdata->features & FEATURE_REMOTE_WAKEUP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) ret = smsc95xx_autosuspend(dev, link_up);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) /* if we get this far we're not autosuspending */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) /* if no wol options set, or if link is down and we're not waking on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) * PHY activity, enter lowest power SUSPEND2 mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) if (!(pdata->wolopts & SUPPORTED_WAKE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) !(link_up || (pdata->wolopts & WAKE_PHY))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) netdev_info(dev->net, "entering SUSPEND2 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) /* disable energy detect (link up) & wake up events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) val &= ~(WUCSR_MPEN_ | WUCSR_WAKE_EN_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) ret = smsc95xx_write_reg_nopm(dev, WUCSR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) val &= ~(PM_CTL_ED_EN_ | PM_CTL_WOL_EN_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) ret = smsc95xx_enter_suspend2(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) if (pdata->wolopts & WAKE_PHY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) ret = smsc95xx_enable_phy_wakeup_interrupts(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) (PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_LINK_DOWN_));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) netdev_warn(dev->net, "error enabling PHY wakeup ints\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) /* if link is down then configure EDPD and enter SUSPEND1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) * otherwise enter SUSPEND0 below
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) if (!link_up) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) netdev_info(dev->net, "entering SUSPEND1 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) ret = smsc95xx_enter_suspend1(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) u32 *filter_mask = kcalloc(32, sizeof(u32), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) u32 command[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) u32 offset[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) u32 crc[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) int wuff_filter_count =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) (pdata->features & FEATURE_8_WAKEUP_FILTERS) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) LAN9500A_WUFF_NUM : LAN9500_WUFF_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) int i, filter = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) if (!filter_mask) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) netdev_warn(dev->net, "Unable to allocate filter_mask\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) memset(command, 0, sizeof(command));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) memset(offset, 0, sizeof(offset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) memset(crc, 0, sizeof(crc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) if (pdata->wolopts & WAKE_BCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) const u8 bcast[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) netdev_info(dev->net, "enabling broadcast detection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) filter_mask[filter * 4] = 0x003F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) filter_mask[filter * 4 + 1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) filter_mask[filter * 4 + 2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) filter_mask[filter * 4 + 3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) command[filter/4] |= 0x05UL << ((filter % 4) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) offset[filter/4] |= 0x00 << ((filter % 4) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) crc[filter/2] |= smsc_crc(bcast, 6, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) filter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) if (pdata->wolopts & WAKE_MCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) const u8 mcast[] = {0x01, 0x00, 0x5E};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) netdev_info(dev->net, "enabling multicast detection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) filter_mask[filter * 4] = 0x0007;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) filter_mask[filter * 4 + 1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) filter_mask[filter * 4 + 2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) filter_mask[filter * 4 + 3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) command[filter/4] |= 0x09UL << ((filter % 4) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) offset[filter/4] |= 0x00 << ((filter % 4) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) crc[filter/2] |= smsc_crc(mcast, 3, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) filter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) if (pdata->wolopts & WAKE_ARP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) const u8 arp[] = {0x08, 0x06};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) netdev_info(dev->net, "enabling ARP detection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) filter_mask[filter * 4] = 0x0003;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) filter_mask[filter * 4 + 1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) filter_mask[filter * 4 + 2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) filter_mask[filter * 4 + 3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) command[filter/4] |= 0x05UL << ((filter % 4) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) offset[filter/4] |= 0x0C << ((filter % 4) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) crc[filter/2] |= smsc_crc(arp, 2, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) filter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) if (pdata->wolopts & WAKE_UCAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) netdev_info(dev->net, "enabling unicast detection\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) filter_mask[filter * 4] = 0x003F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) filter_mask[filter * 4 + 1] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) filter_mask[filter * 4 + 2] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) filter_mask[filter * 4 + 3] = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) command[filter/4] |= 0x01UL << ((filter % 4) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) offset[filter/4] |= 0x00 << ((filter % 4) * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) crc[filter/2] |= smsc_crc(dev->net->dev_addr, ETH_ALEN, filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) filter++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) for (i = 0; i < (wuff_filter_count * 4); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) ret = smsc95xx_write_reg_nopm(dev, WUFF, filter_mask[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) kfree(filter_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) kfree(filter_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) for (i = 0; i < (wuff_filter_count / 4); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) ret = smsc95xx_write_reg_nopm(dev, WUFF, command[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) for (i = 0; i < (wuff_filter_count / 4); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) ret = smsc95xx_write_reg_nopm(dev, WUFF, offset[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) for (i = 0; i < (wuff_filter_count / 2); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) ret = smsc95xx_write_reg_nopm(dev, WUFF, crc[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) /* clear any pending pattern match packet status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) val |= WUCSR_WUFR_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) ret = smsc95xx_write_reg_nopm(dev, WUCSR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) if (pdata->wolopts & WAKE_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) /* clear any pending magic packet status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) val |= WUCSR_MPR_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) ret = smsc95xx_write_reg_nopm(dev, WUCSR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) /* enable/disable wakeup sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) if (pdata->wolopts & (WAKE_BCAST | WAKE_MCAST | WAKE_ARP | WAKE_UCAST)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) netdev_info(dev->net, "enabling pattern match wakeup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) val |= WUCSR_WAKE_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) netdev_info(dev->net, "disabling pattern match wakeup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) val &= ~WUCSR_WAKE_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (pdata->wolopts & WAKE_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) netdev_info(dev->net, "enabling magic packet wakeup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) val |= WUCSR_MPEN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) netdev_info(dev->net, "disabling magic packet wakeup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) val &= ~WUCSR_MPEN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) ret = smsc95xx_write_reg_nopm(dev, WUCSR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) /* enable wol wakeup source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) val |= PM_CTL_WOL_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) /* phy energy detect wakeup source */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) if (pdata->wolopts & WAKE_PHY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) val |= PM_CTL_ED_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) /* enable receiver to enable frame reception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) smsc95xx_start_rx_path(dev, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) /* some wol options are enabled, so enter SUSPEND0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) netdev_info(dev->net, "entering SUSPEND0 mode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) ret = smsc95xx_enter_suspend0(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) * TODO: resume() might need to handle the suspend failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) * in system sleep
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) if (ret && PMSG_IS_AUTO(message))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) usbnet_resume(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) static int smsc95xx_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) struct usbnet *dev = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) struct smsc95xx_priv *pdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) u8 suspend_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) BUG_ON(!dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) suspend_flags = pdata->suspend_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) netdev_dbg(dev->net, "resume suspend_flags=0x%02x\n", suspend_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) /* do this first to ensure it's cleared even in error case */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) pdata->suspend_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) if (suspend_flags & SUSPEND_ALLMODES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) /* clear wake-up sources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) ret = smsc95xx_read_reg_nopm(dev, WUCSR, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) val &= ~(WUCSR_WAKE_EN_ | WUCSR_MPEN_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) ret = smsc95xx_write_reg_nopm(dev, WUCSR, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) /* clear wake-up status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) ret = smsc95xx_read_reg_nopm(dev, PM_CTRL, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) val &= ~PM_CTL_WOL_EN_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) val |= PM_CTL_WUPS_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) ret = smsc95xx_write_reg_nopm(dev, PM_CTRL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) ret = usbnet_resume(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) netdev_warn(dev->net, "usbnet_resume error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) phy_init_hw(pdata->phydev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) static int smsc95xx_reset_resume(struct usb_interface *intf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) struct usbnet *dev = usb_get_intfdata(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) ret = smsc95xx_reset(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) return smsc95xx_resume(intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) static void smsc95xx_rx_csum_offload(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) skb->csum = *(u16 *)(skb_tail_pointer(skb) - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) skb->ip_summed = CHECKSUM_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) skb_trim(skb, skb->len - 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) static int smsc95xx_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) /* This check is no longer done by usbnet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) if (skb->len < dev->net->hard_header_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) while (skb->len > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) u32 header, align_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) struct sk_buff *ax_skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) unsigned char *packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) u16 size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) header = get_unaligned_le32(skb->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) skb_pull(skb, 4 + NET_IP_ALIGN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) packet = skb->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) /* get the packet length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) size = (u16)((header & RX_STS_FL_) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) align_count = (4 - ((size + NET_IP_ALIGN) % 4)) % 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) if (unlikely(header & RX_STS_ES_)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) netif_dbg(dev, rx_err, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) "Error header=0x%08x\n", header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) dev->net->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) dev->net->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) if (header & RX_STS_CRC_) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) dev->net->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) if (header & (RX_STS_TL_ | RX_STS_RF_))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) dev->net->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) if ((header & RX_STS_LE_) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) (!(header & RX_STS_FT_)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) dev->net->stats.rx_length_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) /* ETH_FRAME_LEN + 4(CRC) + 2(COE) + 4(Vlan) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) if (unlikely(size > (ETH_FRAME_LEN + 12))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) netif_dbg(dev, rx_err, dev->net,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) "size err header=0x%08x\n", header);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) /* last frame in this batch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) if (skb->len == size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) if (dev->net->features & NETIF_F_RXCSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) smsc95xx_rx_csum_offload(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) skb_trim(skb, skb->len - 4); /* remove fcs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) skb->truesize = size + sizeof(struct sk_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) ax_skb = skb_clone(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) if (unlikely(!ax_skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) netdev_warn(dev->net, "Error allocating skb\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) ax_skb->len = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) ax_skb->data = packet;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) skb_set_tail_pointer(ax_skb, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) if (dev->net->features & NETIF_F_RXCSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) smsc95xx_rx_csum_offload(ax_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) ax_skb->truesize = size + sizeof(struct sk_buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) usbnet_skb_return(dev, ax_skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) skb_pull(skb, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) /* padding bytes before the next frame starts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) if (skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) skb_pull(skb, align_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) static u32 smsc95xx_calc_csum_preamble(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) u16 low_16 = (u16)skb_checksum_start_offset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) u16 high_16 = low_16 + skb->csum_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) return (high_16 << 16) | low_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) /* The TX CSUM won't work if the checksum lies in the last 4 bytes of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) * transmission. This is fairly unlikely, only seems to trigger with some
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) * short TCP ACK packets sent.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) * Note, this calculation should probably check for the alignment of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) * data as well, but a straight check for csum being in the last four bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) * of the packet should be ok for now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) static bool smsc95xx_can_tx_checksum(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) unsigned int len = skb->len - skb_checksum_start_offset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) if (skb->len <= 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) return skb->csum_offset < (len - (4 + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) static struct sk_buff *smsc95xx_tx_fixup(struct usbnet *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) struct sk_buff *skb, gfp_t flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) bool csum = skb->ip_summed == CHECKSUM_PARTIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) int overhead = csum ? SMSC95XX_TX_OVERHEAD_CSUM : SMSC95XX_TX_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) u32 tx_cmd_a, tx_cmd_b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) void *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) /* We do not advertise SG, so skbs should be already linearized */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) BUG_ON(skb_shinfo(skb)->nr_frags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) /* Make writable and expand header space by overhead if required */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) if (skb_cow_head(skb, overhead)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) /* Must deallocate here as returning NULL to indicate error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) * means the skb won't be deallocated in the caller.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) dev_kfree_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) tx_cmd_b = (u32)skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) tx_cmd_a = tx_cmd_b | TX_CMD_A_FIRST_SEG_ | TX_CMD_A_LAST_SEG_;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) if (csum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) if (!smsc95xx_can_tx_checksum(skb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) /* workaround - hardware tx checksum does not work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) * properly with extremely small packets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) long csstart = skb_checksum_start_offset(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) __wsum calc = csum_partial(skb->data + csstart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) skb->len - csstart, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) *((__sum16 *)(skb->data + csstart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) + skb->csum_offset)) = csum_fold(calc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) csum = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) u32 csum_preamble = smsc95xx_calc_csum_preamble(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) ptr = skb_push(skb, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) put_unaligned_le32(csum_preamble, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) tx_cmd_a += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) tx_cmd_b += 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) tx_cmd_b |= TX_CMD_B_CSUM_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) ptr = skb_push(skb, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) put_unaligned_le32(tx_cmd_a, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) put_unaligned_le32(tx_cmd_b, ptr+4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) return skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) static int smsc95xx_manage_power(struct usbnet *dev, int on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) struct smsc95xx_priv *pdata = dev->driver_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) dev->intf->needs_remote_wakeup = on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) if (pdata->features & FEATURE_REMOTE_WAKEUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) /* this chip revision isn't capable of remote wakeup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) netdev_info(dev->net, "hardware isn't capable of remote wakeup\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) usb_autopm_get_interface_no_resume(dev->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) usb_autopm_put_interface(dev->intf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) static const struct driver_info smsc95xx_info = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) .description = "smsc95xx USB 2.0 Ethernet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) .bind = smsc95xx_bind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) .unbind = smsc95xx_unbind,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) .link_reset = smsc95xx_link_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) .reset = smsc95xx_reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) .check_connect = smsc95xx_start_phy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) .stop = smsc95xx_stop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) .rx_fixup = smsc95xx_rx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) .tx_fixup = smsc95xx_tx_fixup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) .status = smsc95xx_status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) .manage_power = smsc95xx_manage_power,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) .flags = FLAG_ETHER | FLAG_SEND_ZLP | FLAG_LINK_INTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) static const struct usb_device_id products[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) /* SMSC9500 USB Ethernet Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) USB_DEVICE(0x0424, 0x9500),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) /* SMSC9505 USB Ethernet Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) USB_DEVICE(0x0424, 0x9505),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) /* SMSC9500A USB Ethernet Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) USB_DEVICE(0x0424, 0x9E00),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) /* SMSC9505A USB Ethernet Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) USB_DEVICE(0x0424, 0x9E01),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) /* SMSC9512/9514 USB Hub & Ethernet Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) USB_DEVICE(0x0424, 0xec00),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) /* SMSC9500 USB Ethernet Device (SAL10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) USB_DEVICE(0x0424, 0x9900),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) /* SMSC9505 USB Ethernet Device (SAL10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) USB_DEVICE(0x0424, 0x9901),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) /* SMSC9500A USB Ethernet Device (SAL10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) USB_DEVICE(0x0424, 0x9902),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) /* SMSC9505A USB Ethernet Device (SAL10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) USB_DEVICE(0x0424, 0x9903),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) /* SMSC9512/9514 USB Hub & Ethernet Device (SAL10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) USB_DEVICE(0x0424, 0x9904),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) /* SMSC9500A USB Ethernet Device (HAL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) USB_DEVICE(0x0424, 0x9905),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) /* SMSC9505A USB Ethernet Device (HAL) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) USB_DEVICE(0x0424, 0x9906),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) /* SMSC9500 USB Ethernet Device (Alternate ID) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) USB_DEVICE(0x0424, 0x9907),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) /* SMSC9500A USB Ethernet Device (Alternate ID) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) USB_DEVICE(0x0424, 0x9908),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) /* SMSC9512/9514 USB Hub & Ethernet Device (Alternate ID) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) USB_DEVICE(0x0424, 0x9909),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) /* SMSC LAN9530 USB Ethernet Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) USB_DEVICE(0x0424, 0x9530),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) /* SMSC LAN9730 USB Ethernet Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) USB_DEVICE(0x0424, 0x9730),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) /* SMSC LAN89530 USB Ethernet Device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) USB_DEVICE(0x0424, 0x9E08),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) .driver_info = (unsigned long) &smsc95xx_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) { }, /* END */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) MODULE_DEVICE_TABLE(usb, products);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) static struct usb_driver smsc95xx_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) .name = "smsc95xx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) .id_table = products,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) .probe = usbnet_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) .suspend = smsc95xx_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) .resume = smsc95xx_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) .reset_resume = smsc95xx_reset_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) .disconnect = usbnet_disconnect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) .disable_hub_initiated_lpm = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) .supports_autosuspend = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) module_usb_driver(smsc95xx_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) MODULE_AUTHOR("Nancy Lin");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) MODULE_AUTHOR("Steve Glendinning <steve.glendinning@shawell.net>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) MODULE_DESCRIPTION("SMSC95XX USB 2.0 Ethernet Devices");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) MODULE_LICENSE("GPL");