Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

net: usb: sr9700: remove code to drive nonexistent MII

This device does not have a MII, even though the driver
contains code to drive one (because it originated as a copy of the
dm9601 driver). It also only supports 10Mbps half-duplex
operation (the DM9601 registers to set the speed/duplex mode
are read-only). Remove all MII-related code and implement
sr9700_get_link_ksettings which returns hardcoded correct
information for the link speed and duplex mode. Also add
announcement of the link status like many other Ethernet
drivers have.

Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Link: https://patch.msgid.link/20260113040649.54248-1-enelsonmoore@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Ethan Nelson-Moore and committed by
Jakub Kicinski
171e8ed4 b7904046

+56 -125
+52 -118
drivers/net/usb/sr9700.c
··· 16 16 #include <linux/netdevice.h> 17 17 #include <linux/etherdevice.h> 18 18 #include <linux/ethtool.h> 19 - #include <linux/mii.h> 20 19 #include <linux/usb.h> 21 20 #include <linux/crc32.h> 22 21 #include <linux/usb/usbnet.h> ··· 68 69 value, reg, NULL, 0); 69 70 } 70 71 71 - static int wait_phy_eeprom_ready(struct usbnet *dev, int phy) 72 + static int wait_eeprom_ready(struct usbnet *dev) 72 73 { 73 74 int i; 74 75 75 - for (i = 0; i < SR_SHARE_TIMEOUT; i++) { 76 + for (i = 0; i < SR_EEPROM_TIMEOUT; i++) { 76 77 u8 tmp = 0; 77 78 int ret; 78 79 ··· 86 87 return 0; 87 88 } 88 89 89 - netdev_err(dev->net, "%s write timed out!\n", phy ? "phy" : "eeprom"); 90 + netdev_err(dev->net, "eeprom write timed out!\n"); 90 91 91 92 return -EIO; 92 93 } 93 94 94 - static int sr_share_read_word(struct usbnet *dev, int phy, u8 reg, 95 - __le16 *value) 95 + static int sr_read_eeprom_word(struct usbnet *dev, u8 reg, __le16 *value) 96 96 { 97 97 int ret; 98 98 99 99 mutex_lock(&dev->phy_mutex); 100 100 101 - sr_write_reg(dev, SR_EPAR, phy ? (reg | EPAR_PHY_ADR) : reg); 102 - sr_write_reg(dev, SR_EPCR, phy ? (EPCR_EPOS | EPCR_ERPRR) : EPCR_ERPRR); 101 + sr_write_reg(dev, SR_EPAR, reg); 102 + sr_write_reg(dev, SR_EPCR, EPCR_ERPRR); 103 103 104 - ret = wait_phy_eeprom_ready(dev, phy); 104 + ret = wait_eeprom_ready(dev); 105 105 if (ret < 0) 106 106 goto out_unlock; 107 107 108 108 sr_write_reg(dev, SR_EPCR, 0x0); 109 109 ret = sr_read(dev, SR_EPDR, 2, value); 110 110 111 - netdev_dbg(dev->net, "read shared %d 0x%02x returned 0x%04x, %d\n", 112 - phy, reg, *value, ret); 111 + netdev_dbg(dev->net, "read eeprom 0x%02x returned 0x%04x, %d\n", 112 + reg, *value, ret); 113 113 114 114 out_unlock: 115 115 mutex_unlock(&dev->phy_mutex); 116 116 return ret; 117 117 } 118 118 119 - static int sr_share_write_word(struct usbnet *dev, int phy, u8 reg, 120 - __le16 value) 119 + static int __maybe_unused sr_write_eeprom_word(struct usbnet *dev, u8 reg, 120 + __le16 value) 121 121 { 122 122 int ret; 123 123 ··· 126 128 if (ret < 0) 127 129 goto out_unlock; 128 130 129 - sr_write_reg(dev, SR_EPAR, phy ? (reg | EPAR_PHY_ADR) : reg); 130 - sr_write_reg(dev, SR_EPCR, phy ? (EPCR_WEP | EPCR_EPOS | EPCR_ERPRW) : 131 - (EPCR_WEP | EPCR_ERPRW)); 131 + sr_write_reg(dev, SR_EPAR, reg); 132 + sr_write_reg(dev, SR_EPCR, EPCR_WEP | EPCR_ERPRW); 132 133 133 - ret = wait_phy_eeprom_ready(dev, phy); 134 + ret = wait_eeprom_ready(dev); 134 135 if (ret < 0) 135 136 goto out_unlock; 136 137 ··· 138 141 out_unlock: 139 142 mutex_unlock(&dev->phy_mutex); 140 143 return ret; 141 - } 142 - 143 - static int sr_read_eeprom_word(struct usbnet *dev, u8 offset, void *value) 144 - { 145 - return sr_share_read_word(dev, 0, offset, value); 146 144 } 147 145 148 146 static int sr9700_get_eeprom_len(struct net_device *netdev) ··· 166 174 return ret; 167 175 } 168 176 169 - static int sr_mdio_read(struct net_device *netdev, int phy_id, int loc) 177 + static void sr9700_handle_link_change(struct net_device *netdev, bool link) 170 178 { 171 - struct usbnet *dev = netdev_priv(netdev); 172 - int err, res; 173 - __le16 word; 174 - int rc = 0; 175 - 176 - if (phy_id) { 177 - netdev_dbg(netdev, "Only internal phy supported\n"); 178 - return 0; 179 + if (netif_carrier_ok(netdev) != link) { 180 + if (link) { 181 + netif_carrier_on(netdev); 182 + netdev_info(netdev, "link up, 10Mbps, half-duplex\n"); 183 + } else { 184 + netif_carrier_off(netdev); 185 + netdev_info(netdev, "link down\n"); 186 + } 179 187 } 180 - 181 - /* Access NSR_LINKST bit for link status instead of MII_BMSR */ 182 - if (loc == MII_BMSR) { 183 - u8 value; 184 - 185 - err = sr_read_reg(dev, SR_NSR, &value); 186 - if (err < 0) 187 - return err; 188 - 189 - if (value & NSR_LINKST) 190 - rc = 1; 191 - } 192 - err = sr_share_read_word(dev, 1, loc, &word); 193 - if (err < 0) 194 - return err; 195 - 196 - if (rc == 1) 197 - res = le16_to_cpu(word) | BMSR_LSTATUS; 198 - else 199 - res = le16_to_cpu(word) & ~BMSR_LSTATUS; 200 - 201 - netdev_dbg(netdev, "sr_mdio_read() phy_id=0x%02x, loc=0x%02x, returns=0x%04x\n", 202 - phy_id, loc, res); 203 - 204 - return res; 205 - } 206 - 207 - static void sr_mdio_write(struct net_device *netdev, int phy_id, int loc, 208 - int val) 209 - { 210 - struct usbnet *dev = netdev_priv(netdev); 211 - __le16 res = cpu_to_le16(val); 212 - 213 - if (phy_id) { 214 - netdev_dbg(netdev, "Only internal phy supported\n"); 215 - return; 216 - } 217 - 218 - netdev_dbg(netdev, "sr_mdio_write() phy_id=0x%02x, loc=0x%02x, val=0x%04x\n", 219 - phy_id, loc, val); 220 - 221 - sr_share_write_word(dev, 1, loc, res); 222 188 } 223 189 224 190 static u32 sr9700_get_link(struct net_device *netdev) 225 191 { 226 192 struct usbnet *dev = netdev_priv(netdev); 227 193 u8 value = 0; 228 - int rc = 0; 194 + u32 link = 0; 229 195 230 - /* Get the Link Status directly */ 231 196 sr_read_reg(dev, SR_NSR, &value); 232 - if (value & NSR_LINKST) 233 - rc = 1; 197 + link = !!(value & NSR_LINKST); 234 198 235 - return rc; 199 + sr9700_handle_link_change(netdev, link); 200 + 201 + return link; 236 202 } 237 203 238 - static int sr9700_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd) 204 + /* 205 + * The device supports only 10Mbps half-duplex operation. It implements the 206 + * DM9601 speed/duplex status registers, but as the values are always the same, 207 + * using them would add unnecessary complexity. 208 + */ 209 + static int sr9700_get_link_ksettings(struct net_device *dev, 210 + struct ethtool_link_ksettings *cmd) 239 211 { 240 - struct usbnet *dev = netdev_priv(netdev); 212 + ethtool_link_ksettings_zero_link_mode(cmd, supported); 213 + ethtool_link_ksettings_add_link_mode(cmd, supported, 10baseT_Half); 214 + ethtool_link_ksettings_add_link_mode(cmd, supported, TP); 241 215 242 - return generic_mii_ioctl(&dev->mii, if_mii(rq), cmd, NULL); 216 + ethtool_link_ksettings_zero_link_mode(cmd, advertising); 217 + ethtool_link_ksettings_add_link_mode(cmd, advertising, 10baseT_Half); 218 + ethtool_link_ksettings_add_link_mode(cmd, advertising, TP); 219 + 220 + cmd->base.speed = SPEED_10; 221 + cmd->base.duplex = DUPLEX_HALF; 222 + cmd->base.port = PORT_TP; 223 + cmd->base.phy_address = 0; 224 + cmd->base.autoneg = AUTONEG_DISABLE; 225 + 226 + return 0; 243 227 } 244 228 245 229 static const struct ethtool_ops sr9700_ethtool_ops = { ··· 225 257 .set_msglevel = usbnet_set_msglevel, 226 258 .get_eeprom_len = sr9700_get_eeprom_len, 227 259 .get_eeprom = sr9700_get_eeprom, 228 - .nway_reset = usbnet_nway_reset, 229 - .get_link_ksettings = usbnet_get_link_ksettings_mii, 230 - .set_link_ksettings = usbnet_set_link_ksettings_mii, 260 + .get_link_ksettings = sr9700_get_link_ksettings, 231 261 }; 232 262 233 263 static void sr9700_set_multicast(struct net_device *netdev) ··· 284 318 .ndo_change_mtu = usbnet_change_mtu, 285 319 .ndo_get_stats64 = dev_get_tstats64, 286 320 .ndo_validate_addr = eth_validate_addr, 287 - .ndo_eth_ioctl = sr9700_ioctl, 288 321 .ndo_set_rx_mode = sr9700_set_multicast, 289 322 .ndo_set_mac_address = sr9700_set_mac_address, 290 323 }; ··· 291 326 static int sr9700_bind(struct usbnet *dev, struct usb_interface *intf) 292 327 { 293 328 struct net_device *netdev; 294 - struct mii_if_info *mii; 295 329 u8 addr[ETH_ALEN]; 296 330 int ret; 297 331 ··· 306 342 dev->hard_mtu = netdev->mtu + netdev->hard_header_len; 307 343 /* bulkin buffer is preferably not less than 3K */ 308 344 dev->rx_urb_size = 3072; 309 - 310 - mii = &dev->mii; 311 - mii->dev = netdev; 312 - mii->mdio_read = sr_mdio_read; 313 - mii->mdio_write = sr_mdio_write; 314 - mii->phy_id_mask = 0x1f; 315 - mii->reg_num_mask = 0x1f; 316 345 317 346 sr_write_reg(dev, SR_NCR, NCR_RST); 318 347 udelay(20); ··· 332 375 333 376 /* receive broadcast packets */ 334 377 sr9700_set_multicast(netdev); 335 - 336 - sr_mdio_write(netdev, mii->phy_id, MII_BMCR, BMCR_RESET); 337 - sr_mdio_write(netdev, mii->phy_id, MII_ADVERTISE, ADVERTISE_ALL | 338 - ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); 339 - mii_nway_restart(mii); 340 378 341 379 out: 342 380 return ret; ··· 436 484 437 485 static void sr9700_status(struct usbnet *dev, struct urb *urb) 438 486 { 439 - int link; 487 + bool link; 440 488 u8 *buf; 441 489 442 490 /* format: ··· 456 504 buf = urb->transfer_buffer; 457 505 458 506 link = !!(buf[0] & 0x40); 459 - if (netif_carrier_ok(dev->net) != link) { 460 - usbnet_link_change(dev, link, 1); 461 - netdev_dbg(dev->net, "Link Status is: %d\n", link); 462 - } 463 - } 464 - 465 - static int sr9700_link_reset(struct usbnet *dev) 466 - { 467 - struct ethtool_cmd ecmd; 468 - 469 - mii_check_media(&dev->mii, 1, 1); 470 - mii_ethtool_gset(&dev->mii, &ecmd); 471 - 472 - netdev_dbg(dev->net, "link_reset() speed: %d duplex: %d\n", 473 - ecmd.speed, ecmd.duplex); 474 - 475 - return 0; 507 + sr9700_handle_link_change(dev->net, link); 476 508 } 477 509 478 510 static const struct driver_info sr9700_driver_info = { ··· 466 530 .rx_fixup = sr9700_rx_fixup, 467 531 .tx_fixup = sr9700_tx_fixup, 468 532 .status = sr9700_status, 469 - .link_reset = sr9700_link_reset, 470 - .reset = sr9700_link_reset, 471 533 }; 472 534 473 535 static const struct usb_device_id products[] = {
+4 -7
drivers/net/usb/sr9700.h
··· 82 82 #define FCR_TXPEN (1 << 5) 83 83 #define FCR_TXPF (1 << 6) 84 84 #define FCR_TXP0 (1 << 7) 85 - /* Eeprom & Phy Control Reg */ 85 + /* Eeprom Control Reg */ 86 86 #define SR_EPCR 0x0B 87 87 #define EPCR_ERRE (1 << 0) 88 88 #define EPCR_ERPRW (1 << 1) 89 89 #define EPCR_ERPRR (1 << 2) 90 - #define EPCR_EPOS (1 << 3) 91 90 #define EPCR_WEP (1 << 4) 92 - /* Eeprom & Phy Address Reg */ 91 + /* Eeprom Address Reg */ 93 92 #define SR_EPAR 0x0C 94 93 #define EPAR_EROA (0x3F << 0) 95 - #define EPAR_PHY_ADR_MASK (0x03 << 6) 96 - #define EPAR_PHY_ADR (0x01 << 6) 97 - /* Eeprom & Phy Data Reg */ 94 + /* Eeprom Data Reg */ 98 95 #define SR_EPDR 0x0D /* 0x0D ~ 0x0E for Data Reg Low & High */ 99 96 /* Wakeup Control Reg */ 100 97 #define SR_WCR 0x0F ··· 156 159 #define SR_REQ_WR_REG (USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE) 157 160 158 161 /* parameters */ 159 - #define SR_SHARE_TIMEOUT 1000 162 + #define SR_EEPROM_TIMEOUT 1000 160 163 #define SR_EEPROM_LEN 256 161 164 #define SR_MCAST_SIZE 8 162 165 #define SR_MCAST_ADDR_FLAG 0x80