]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
net: usb: smsc95xx: fix changing LED_SEL bit value updated from EEPROM
authorParthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
Thu, 23 May 2024 08:53:14 +0000 (14:23 +0530)
committerPaolo Abeni <pabeni@redhat.com>
Mon, 27 May 2024 10:48:23 +0000 (12:48 +0200)
LED Select (LED_SEL) bit in the LED General Purpose IO Configuration
register is used to determine the functionality of external LED pins
(Speed Indicator, Link and Activity Indicator, Full Duplex Link
Indicator). The default value for this bit is 0 when no EEPROM is
present. If a EEPROM is present, the default value is the value of the
LED Select bit in the Configuration Flags of the EEPROM. A USB Reset or
Lite Reset (LRST) will cause this bit to be restored to the image value
last loaded from EEPROM, or to be set to 0 if no EEPROM is present.

While configuring the dual purpose GPIO/LED pins to LED outputs in the
LED General Purpose IO Configuration register, the LED_SEL bit is changed
as 0 and resulting the configured value from the EEPROM is cleared. The
issue is fixed by using read-modify-write approach.

Fixes: f293501c61c5 ("smsc95xx: configure LED outputs")
Signed-off-by: Parthiban Veerasooran <Parthiban.Veerasooran@microchip.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Woojung Huh <woojung.huh@microchip.com>
Link: https://lore.kernel.org/r/20240523085314.167650-1-Parthiban.Veerasooran@microchip.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
drivers/net/usb/smsc95xx.c

index cbea246664795f27618908838b37384e8f3b67d0..8e82184be5e7d9954b83aae904a37bb7eda175bb 100644 (file)
@@ -879,7 +879,7 @@ static int smsc95xx_start_rx_path(struct usbnet *dev)
 static int smsc95xx_reset(struct usbnet *dev)
 {
        struct smsc95xx_priv *pdata = dev->driver_priv;
-       u32 read_buf, write_buf, burst_cap;
+       u32 read_buf, burst_cap;
        int ret = 0, timeout;
 
        netif_dbg(dev, ifup, dev->net, "entering smsc95xx_reset\n");
@@ -1003,10 +1003,13 @@ static int smsc95xx_reset(struct usbnet *dev)
                return ret;
        netif_dbg(dev, ifup, dev->net, "ID_REV = 0x%08x\n", read_buf);
 
+       ret = smsc95xx_read_reg(dev, LED_GPIO_CFG, &read_buf);
+       if (ret < 0)
+               return ret;
        /* Configure GPIO pins as LED outputs */
-       write_buf = LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
-               LED_GPIO_CFG_FDX_LED;
-       ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, write_buf);
+       read_buf |= LED_GPIO_CFG_SPD_LED | LED_GPIO_CFG_LNK_LED |
+                   LED_GPIO_CFG_FDX_LED;
+       ret = smsc95xx_write_reg(dev, LED_GPIO_CFG, read_buf);
        if (ret < 0)
                return ret;