]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.10-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Mar 2022 12:37:27 +0000 (13:37 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 21 Mar 2022 12:37:27 +0000 (13:37 +0100)
added patches:
esp-fix-possible-buffer-overflow-in-esp-transformation.patch
net-usb-correct-phy-handling-of-smsc95xx.patch
net-usb-correct-reset-handling-of-smsc95xx.patch
smsc95xx-ignore-enodev-errors-when-device-is-unplugged.patch

queue-5.10/esp-fix-possible-buffer-overflow-in-esp-transformation.patch [new file with mode: 0644]
queue-5.10/net-usb-correct-phy-handling-of-smsc95xx.patch [new file with mode: 0644]
queue-5.10/net-usb-correct-reset-handling-of-smsc95xx.patch [new file with mode: 0644]
queue-5.10/series
queue-5.10/smsc95xx-ignore-enodev-errors-when-device-is-unplugged.patch [new file with mode: 0644]

diff --git a/queue-5.10/esp-fix-possible-buffer-overflow-in-esp-transformation.patch b/queue-5.10/esp-fix-possible-buffer-overflow-in-esp-transformation.patch
new file mode 100644 (file)
index 0000000..1f035a6
--- /dev/null
@@ -0,0 +1,95 @@
+From ebe48d368e97d007bfeb76fcb065d6cfc4c96645 Mon Sep 17 00:00:00 2001
+From: Steffen Klassert <steffen.klassert@secunet.com>
+Date: Mon, 7 Mar 2022 13:11:39 +0100
+Subject: esp: Fix possible buffer overflow in ESP transformation
+
+From: Steffen Klassert <steffen.klassert@secunet.com>
+
+commit ebe48d368e97d007bfeb76fcb065d6cfc4c96645 upstream.
+
+The maximum message size that can be send is bigger than
+the  maximum site that skb_page_frag_refill can allocate.
+So it is possible to write beyond the allocated buffer.
+
+Fix this by doing a fallback to COW in that case.
+
+v2:
+
+Avoid get get_order() costs as suggested by Linus Torvalds.
+
+Fixes: cac2661c53f3 ("esp4: Avoid skb_cow_data whenever possible")
+Fixes: 03e2a30f6a27 ("esp6: Avoid skb_cow_data whenever possible")
+Reported-by: valis <sec@valis.email>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+Signed-off-by: Tadeusz Struk <tadeusz.struk@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ include/net/esp.h  |    2 ++
+ include/net/sock.h |    1 +
+ net/ipv4/esp4.c    |    5 +++++
+ net/ipv6/esp6.c    |    5 +++++
+ 4 files changed, 13 insertions(+)
+
+--- a/include/net/esp.h
++++ b/include/net/esp.h
+@@ -4,6 +4,8 @@
+ #include <linux/skbuff.h>
++#define ESP_SKB_FRAG_MAXSIZE (PAGE_SIZE << SKB_FRAG_PAGE_ORDER)
++
+ struct ip_esp_hdr;
+ static inline struct ip_esp_hdr *ip_esp_hdr(const struct sk_buff *skb)
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2670,6 +2670,7 @@ extern int sysctl_optmem_max;
+ extern __u32 sysctl_wmem_default;
+ extern __u32 sysctl_rmem_default;
++#define SKB_FRAG_PAGE_ORDER   get_order(32768)
+ DECLARE_STATIC_KEY_FALSE(net_high_order_alloc_disable_key);
+ static inline int sk_get_wmem0(const struct sock *sk, const struct proto *proto)
+--- a/net/ipv4/esp4.c
++++ b/net/ipv4/esp4.c
+@@ -448,6 +448,7 @@ int esp_output_head(struct xfrm_state *x
+       struct page *page;
+       struct sk_buff *trailer;
+       int tailen = esp->tailen;
++      unsigned int allocsz;
+       /* this is non-NULL only with TCP/UDP Encapsulation */
+       if (x->encap) {
+@@ -457,6 +458,10 @@ int esp_output_head(struct xfrm_state *x
+                       return err;
+       }
++      allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
++      if (allocsz > ESP_SKB_FRAG_MAXSIZE)
++              goto cow;
++
+       if (!skb_cloned(skb)) {
+               if (tailen <= skb_tailroom(skb)) {
+                       nfrags = 1;
+--- a/net/ipv6/esp6.c
++++ b/net/ipv6/esp6.c
+@@ -483,6 +483,7 @@ int esp6_output_head(struct xfrm_state *
+       struct page *page;
+       struct sk_buff *trailer;
+       int tailen = esp->tailen;
++      unsigned int allocsz;
+       if (x->encap) {
+               int err = esp6_output_encap(x, skb, esp);
+@@ -491,6 +492,10 @@ int esp6_output_head(struct xfrm_state *
+                       return err;
+       }
++      allocsz = ALIGN(skb->data_len + tailen, L1_CACHE_BYTES);
++      if (allocsz > ESP_SKB_FRAG_MAXSIZE)
++              goto cow;
++
+       if (!skb_cloned(skb)) {
+               if (tailen <= skb_tailroom(skb)) {
+                       nfrags = 1;
diff --git a/queue-5.10/net-usb-correct-phy-handling-of-smsc95xx.patch b/queue-5.10/net-usb-correct-phy-handling-of-smsc95xx.patch
new file mode 100644 (file)
index 0000000..c2ada5c
--- /dev/null
@@ -0,0 +1,228 @@
+From a049a30fc27c1cb2e12889bbdbd463dbf750103a Mon Sep 17 00:00:00 2001
+From: Martyn Welch <martyn.welch@collabora.com>
+Date: Mon, 22 Nov 2021 18:44:45 +0000
+Subject: net: usb: Correct PHY handling of smsc95xx
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Martyn Welch <martyn.welch@collabora.com>
+
+commit a049a30fc27c1cb2e12889bbdbd463dbf750103a upstream.
+
+The smsc95xx driver is dropping phy speed settings and causing a stack
+trace at device unbind:
+
+[  536.379147] smsc95xx 2-1:1.0 eth1: unregister 'smsc95xx' usb-ci_hdrc.2-1, smsc95xx USB 2.0 Ethernet
+[  536.425029] ------------[ cut here ]------------
+[  536.429650] WARNING: CPU: 0 PID: 439 at fs/kernfs/dir.c:1535 kernfs_remove_by_name_ns+0xb8/0xc0
+[  536.438416] kernfs: can not remove 'attached_dev', no directory
+[  536.444363] Modules linked in: xts dm_crypt dm_mod atmel_mxt_ts smsc95xx usbnet
+[  536.451748] CPU: 0 PID: 439 Comm: sh Tainted: G        W         5.15.0 #1
+[  536.458636] Hardware name: Freescale i.MX53 (Device Tree Support)
+[  536.464735] Backtrace: 
+[  536.467190] [<80b1c904>] (dump_backtrace) from [<80b1cb48>] (show_stack+0x20/0x24)
+[  536.474787]  r7:000005ff r6:8035b294 r5:600f0013 r4:80d8af78
+[  536.480449] [<80b1cb28>] (show_stack) from [<80b1f764>] (dump_stack_lvl+0x48/0x54)
+[  536.488035] [<80b1f71c>] (dump_stack_lvl) from [<80b1f788>] (dump_stack+0x18/0x1c)
+[  536.495620]  r5:00000009 r4:80d9b820
+[  536.499198] [<80b1f770>] (dump_stack) from [<80124fac>] (__warn+0xfc/0x114)
+[  536.506187] [<80124eb0>] (__warn) from [<80b1d21c>] (warn_slowpath_fmt+0xa8/0xdc)
+[  536.513688]  r7:000005ff r6:80d9b820 r5:80d9b8e0 r4:83744000
+[  536.519349] [<80b1d178>] (warn_slowpath_fmt) from [<8035b294>] (kernfs_remove_by_name_ns+0xb8/0xc0)
+[  536.528416]  r9:00000001 r8:00000000 r7:824926dc r6:00000000 r5:80df6c2c r4:00000000
+[  536.536162] [<8035b1dc>] (kernfs_remove_by_name_ns) from [<80b1f56c>] (sysfs_remove_link+0x4c/0x50)
+[  536.545225]  r6:7f00f02c r5:80df6c2c r4:83306400
+[  536.549845] [<80b1f520>] (sysfs_remove_link) from [<806f9c8c>] (phy_detach+0xfc/0x11c)
+[  536.557780]  r5:82492000 r4:83306400
+[  536.561359] [<806f9b90>] (phy_detach) from [<806f9cf8>] (phy_disconnect+0x4c/0x58)
+[  536.568943]  r7:824926dc r6:7f00f02c r5:82492580 r4:83306400
+[  536.574604] [<806f9cac>] (phy_disconnect) from [<7f00a310>] (smsc95xx_disconnect_phy+0x30/0x38 [smsc95xx])
+[  536.584290]  r5:82492580 r4:82492580
+[  536.587868] [<7f00a2e0>] (smsc95xx_disconnect_phy [smsc95xx]) from [<7f001570>] (usbnet_stop+0x70/0x1a0 [usbnet])
+[  536.598161]  r5:82492580 r4:82492000
+[  536.601740] [<7f001500>] (usbnet_stop [usbnet]) from [<808baa70>] (__dev_close_many+0xb4/0x12c)
+[  536.610466]  r8:83744000 r7:00000000 r6:83744000 r5:83745b74 r4:82492000
+[  536.617170] [<808ba9bc>] (__dev_close_many) from [<808bab78>] (dev_close_many+0x90/0x120)
+[  536.625365]  r7:00000001 r6:83745b74 r5:83745b8c r4:82492000
+[  536.631026] [<808baae8>] (dev_close_many) from [<808bf408>] (unregister_netdevice_many+0x15c/0x704)
+[  536.640094]  r9:00000001 r8:81130b98 r7:83745b74 r6:83745bc4 r5:83745b8c r4:82492000
+[  536.647840] [<808bf2ac>] (unregister_netdevice_many) from [<808bfa50>] (unregister_netdevice_queue+0xa0/0xe8)
+[  536.657775]  r10:8112bcc0 r9:83306c00 r8:83306c80 r7:8291e420 r6:83744000 r5:00000000
+[  536.665608]  r4:82492000
+[  536.668143] [<808bf9b0>] (unregister_netdevice_queue) from [<808bfac0>] (unregister_netdev+0x28/0x30)
+[  536.677381]  r6:7f01003c r5:82492000 r4:82492000
+[  536.682000] [<808bfa98>] (unregister_netdev) from [<7f000b40>] (usbnet_disconnect+0x64/0xdc [usbnet])
+[  536.691241]  r5:82492000 r4:82492580
+[  536.694819] [<7f000adc>] (usbnet_disconnect [usbnet]) from [<8076b958>] (usb_unbind_interface+0x80/0x248)
+[  536.704406]  r5:7f01003c r4:83306c80
+[  536.707984] [<8076b8d8>] (usb_unbind_interface) from [<8061765c>] (device_release_driver_internal+0x1c4/0x1cc)
+[  536.718005]  r10:8112bcc0 r9:80dff1dc r8:83306c80 r7:83744000 r6:7f01003c r5:00000000
+[  536.725838]  r4:8291e420
+[  536.728373] [<80617498>] (device_release_driver_internal) from [<80617684>] (device_release_driver+0x20/0x24)
+[  536.738302]  r7:83744000 r6:810d4f4c r5:8291e420 r4:8176ae30
+[  536.743963] [<80617664>] (device_release_driver) from [<806156cc>] (bus_remove_device+0xf0/0x148)
+[  536.752858] [<806155dc>] (bus_remove_device) from [<80610018>] (device_del+0x198/0x41c)
+[  536.760880]  r7:83744000 r6:8116e2e4 r5:8291e464 r4:8291e420
+[  536.766542] [<8060fe80>] (device_del) from [<80768fe8>] (usb_disable_device+0xcc/0x1e0)
+[  536.774576]  r10:8112bcc0 r9:80dff1dc r8:00000001 r7:8112bc48 r6:8291e400 r5:00000001
+[  536.782410]  r4:83306c00
+[  536.784945] [<80768f1c>] (usb_disable_device) from [<80769c30>] (usb_set_configuration+0x514/0x8dc)
+[  536.794011]  r10:00000000 r9:00000000 r8:832c3600 r7:00000004 r6:810d5688 r5:00000000
+[  536.801844]  r4:83306c00
+[  536.804379] [<8076971c>] (usb_set_configuration) from [<80775fac>] (usb_generic_driver_disconnect+0x34/0x38)
+[  536.814236]  r10:832c3610 r9:83745ef8 r8:832c3600 r7:00000004 r6:810d5688 r5:83306c00
+[  536.822069]  r4:83306c00
+[  536.824605] [<80775f78>] (usb_generic_driver_disconnect) from [<8076b850>] (usb_unbind_device+0x30/0x70)
+[  536.834100]  r5:83306c00 r4:810d5688
+[  536.837678] [<8076b820>] (usb_unbind_device) from [<8061765c>] (device_release_driver_internal+0x1c4/0x1cc)
+[  536.847432]  r5:822fb480 r4:83306c80
+[  536.851009] [<80617498>] (device_release_driver_internal) from [<806176a8>] (device_driver_detach+0x20/0x24)
+[  536.860853]  r7:00000004 r6:810d4f4c r5:810d5688 r4:83306c80
+[  536.866515] [<80617688>] (device_driver_detach) from [<80614d98>] (unbind_store+0x70/0xe4)
+[  536.874793] [<80614d28>] (unbind_store) from [<80614118>] (drv_attr_store+0x30/0x3c)
+[  536.882554]  r7:00000000 r6:00000000 r5:83739200 r4:80614d28
+[  536.888217] [<806140e8>] (drv_attr_store) from [<8035cb68>] (sysfs_kf_write+0x48/0x54)
+[  536.896154]  r5:83739200 r4:806140e8
+[  536.899732] [<8035cb20>] (sysfs_kf_write) from [<8035be84>] (kernfs_fop_write_iter+0x11c/0x1d4)
+[  536.908446]  r5:83739200 r4:00000004
+[  536.912024] [<8035bd68>] (kernfs_fop_write_iter) from [<802b87fc>] (vfs_write+0x258/0x3e4)
+[  536.920317]  r10:00000000 r9:83745f58 r8:83744000 r7:00000000 r6:00000004 r5:00000000
+[  536.928151]  r4:82adacc0
+[  536.930687] [<802b85a4>] (vfs_write) from [<802b8b0c>] (ksys_write+0x74/0xf4)
+[  536.937842]  r10:00000004 r9:007767a0 r8:83744000 r7:00000000 r6:00000000 r5:82adacc0
+[  536.945676]  r4:82adacc0
+[  536.948213] [<802b8a98>] (ksys_write) from [<802b8ba4>] (sys_write+0x18/0x1c)
+[  536.955367]  r10:00000004 r9:83744000 r8:80100244 r7:00000004 r6:76f47b58 r5:76fc0350
+[  536.963200]  r4:00000004
+[  536.965735] [<802b8b8c>] (sys_write) from [<80100060>] (ret_fast_syscall+0x0/0x48)
+[  536.973320] Exception stack(0x83745fa8 to 0x83745ff0)
+[  536.978383] 5fa0:                   00000004 76fc0350 00000001 007767a0 00000004 00000000
+[  536.986569] 5fc0: 00000004 76fc0350 76f47b58 00000004 76f47c7c 76f48114 00000000 7e87991c
+[  536.994753] 5fe0: 00000498 7e879908 76e6dce8 76eca2e8
+[  536.999922] ---[ end trace 9b835d809816b435 ]---
+
+The driver should not be connecting and disconnecting the PHY when the
+device is opened and closed, it should be stopping and starting the PHY. The
+phy should be connected as part of binding and disconnected during
+unbinding.
+
+As this results in the PHY not being reset during open, link speed, etc.
+settings set prior to the link coming up are now not being lost.
+
+It is necessary for phy_stop() to only be called when the phydev still
+exists (resolving the above stack trace). When unbinding, ".unbind" will be
+called prior to ".stop", with phy_disconnect() already having called
+phy_stop() before the phydev becomes inaccessible.
+
+Signed-off-by: Martyn Welch <martyn.welch@collabora.com>
+Cc: Steve Glendinning <steve.glendinning@shawell.net>
+Cc: UNGLinuxDriver@microchip.com
+Cc: "David S. Miller" <davem@davemloft.net>
+Cc: Jakub Kicinski <kuba@kernel.org>
+Cc: stable@kernel.org # v5.15
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/smsc95xx.c |   55 +++++++++++++++++++++------------------------
+ 1 file changed, 26 insertions(+), 29 deletions(-)
+
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -1049,6 +1049,14 @@ static const struct net_device_ops smsc9
+       .ndo_set_features       = smsc95xx_set_features,
+ };
++static void smsc95xx_handle_link_change(struct net_device *net)
++{
++      struct usbnet *dev = netdev_priv(net);
++
++      phy_print_status(net->phydev);
++      usbnet_defer_kevent(dev, EVENT_LINK_CHANGE);
++}
++
+ static int smsc95xx_bind(struct usbnet *dev, struct usb_interface *intf)
+ {
+       struct smsc95xx_priv *pdata;
+@@ -1153,6 +1161,17 @@ static int smsc95xx_bind(struct usbnet *
+       dev->net->min_mtu = ETH_MIN_MTU;
+       dev->net->max_mtu = ETH_DATA_LEN;
+       dev->hard_mtu = dev->net->mtu + dev->net->hard_header_len;
++
++      ret = phy_connect_direct(dev->net, pdata->phydev,
++                               &smsc95xx_handle_link_change,
++                               PHY_INTERFACE_MODE_MII);
++      if (ret) {
++              netdev_err(dev->net, "can't attach PHY to %s\n", pdata->mdiobus->id);
++              goto unregister_mdio;
++      }
++
++      phy_attached_info(dev->net->phydev);
++
+       return 0;
+ unregister_mdio:
+@@ -1170,47 +1189,25 @@ static void smsc95xx_unbind(struct usbne
+ {
+       struct smsc95xx_priv *pdata = dev->driver_priv;
++      phy_disconnect(dev->net->phydev);
+       mdiobus_unregister(pdata->mdiobus);
+       mdiobus_free(pdata->mdiobus);
+       netif_dbg(dev, ifdown, dev->net, "free pdata\n");
+       kfree(pdata);
+ }
+-static void smsc95xx_handle_link_change(struct net_device *net)
+-{
+-      struct usbnet *dev = netdev_priv(net);
+-
+-      phy_print_status(net->phydev);
+-      usbnet_defer_kevent(dev, EVENT_LINK_CHANGE);
+-}
+-
+ static int smsc95xx_start_phy(struct usbnet *dev)
+ {
+-      struct smsc95xx_priv *pdata = dev->driver_priv;
+-      struct net_device *net = dev->net;
+-      int ret;
++      phy_start(dev->net->phydev);
+-      ret = smsc95xx_reset(dev);
+-      if (ret < 0)
+-              return ret;
+-
+-      ret = phy_connect_direct(net, pdata->phydev,
+-                               &smsc95xx_handle_link_change,
+-                               PHY_INTERFACE_MODE_MII);
+-      if (ret) {
+-              netdev_err(net, "can't attach PHY to %s\n", pdata->mdiobus->id);
+-              return ret;
+-      }
+-
+-      phy_attached_info(net->phydev);
+-      phy_start(net->phydev);
+       return 0;
+ }
+-static int smsc95xx_disconnect_phy(struct usbnet *dev)
++static int smsc95xx_stop(struct usbnet *dev)
+ {
+-      phy_stop(dev->net->phydev);
+-      phy_disconnect(dev->net->phydev);
++      if (dev->net->phydev)
++              phy_stop(dev->net->phydev);
++
+       return 0;
+ }
+@@ -1965,7 +1962,7 @@ static const struct driver_info smsc95xx
+       .unbind         = smsc95xx_unbind,
+       .link_reset     = smsc95xx_link_reset,
+       .reset          = smsc95xx_start_phy,
+-      .stop           = smsc95xx_disconnect_phy,
++      .stop           = smsc95xx_stop,
+       .rx_fixup       = smsc95xx_rx_fixup,
+       .tx_fixup       = smsc95xx_tx_fixup,
+       .status         = smsc95xx_status,
diff --git a/queue-5.10/net-usb-correct-reset-handling-of-smsc95xx.patch b/queue-5.10/net-usb-correct-reset-handling-of-smsc95xx.patch
new file mode 100644 (file)
index 0000000..dee146e
--- /dev/null
@@ -0,0 +1,41 @@
+From 0bf3885324a8599e3af4c7379b8d4f621c9bbffa Mon Sep 17 00:00:00 2001
+From: Markus Reichl <m.reichl@fivetechno.de>
+Date: Thu, 13 Jan 2022 21:01:11 +0100
+Subject: net: usb: Correct reset handling of smsc95xx
+
+From: Markus Reichl <m.reichl@fivetechno.de>
+
+commit 0bf3885324a8599e3af4c7379b8d4f621c9bbffa upstream.
+
+On boards with LAN9514 and no preconfigured MAC address we don't get an
+ip address from DHCP after commit a049a30fc27c ("net: usb: Correct PHY handling
+of smsc95xx") anymore. Adding an explicit reset before starting the phy
+fixes the issue.
+
+[1]
+https://lore.kernel.org/netdev/199eebbd6b97f52b9119c9fa4fd8504f8a34de18.camel@collabora.com/
+
+From: Gabriel Hojda <ghojda@yo2urs.ro>
+Fixes: a049a30fc27c ("net: usb: Correct PHY handling of smsc95xx")
+Signed-off-by: Gabriel Hojda <ghojda@yo2urs.ro>
+Signed-off-by: Markus Reichl <m.reichl@fivetechno.de>
+Tested-by: Alexander Stein <alexander.stein@ew.tq-group.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/smsc95xx.c |    3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -1961,7 +1961,8 @@ static const struct driver_info smsc95xx
+       .bind           = smsc95xx_bind,
+       .unbind         = smsc95xx_unbind,
+       .link_reset     = smsc95xx_link_reset,
+-      .reset          = smsc95xx_start_phy,
++      .reset          = smsc95xx_reset,
++      .check_connect  = smsc95xx_start_phy,
+       .stop           = smsc95xx_stop,
+       .rx_fixup       = smsc95xx_rx_fixup,
+       .tx_fixup       = smsc95xx_tx_fixup,
index f6831b649efa05ba363d017aee37c72a411418b1..0e1ac3d210b1f01d15746c163ea2f46e7b237675 100644 (file)
@@ -23,3 +23,7 @@ usb-usbtmc-fix-bug-in-pipe-direction-for-control-transfers.patch
 scsi-mpt3sas-page-fault-in-reply-q-processing.patch
 input-aiptek-properly-check-endpoint-type.patch
 perf-symbols-fix-symbol-size-calculation-condition.patch
+net-usb-correct-phy-handling-of-smsc95xx.patch
+net-usb-correct-reset-handling-of-smsc95xx.patch
+smsc95xx-ignore-enodev-errors-when-device-is-unplugged.patch
+esp-fix-possible-buffer-overflow-in-esp-transformation.patch
diff --git a/queue-5.10/smsc95xx-ignore-enodev-errors-when-device-is-unplugged.patch b/queue-5.10/smsc95xx-ignore-enodev-errors-when-device-is-unplugged.patch
new file mode 100644 (file)
index 0000000..c85d1f0
--- /dev/null
@@ -0,0 +1,137 @@
+From c70c453abcbf3ecbaadd4c3236a5119b8da365cf Mon Sep 17 00:00:00 2001
+From: Fabio Estevam <festevam@denx.de>
+Date: Sat, 5 Mar 2022 17:47:20 -0300
+Subject: smsc95xx: Ignore -ENODEV errors when device is unplugged
+
+From: Fabio Estevam <festevam@denx.de>
+
+commit c70c453abcbf3ecbaadd4c3236a5119b8da365cf upstream.
+
+According to Documentation/driver-api/usb/URB.rst when a device
+is unplugged usb_submit_urb() returns -ENODEV.
+
+This error code propagates all the way up to usbnet_read_cmd() and
+usbnet_write_cmd() calls inside the smsc95xx.c driver during
+Ethernet cable unplug, unbind or reboot.
+
+This causes the following errors to be shown on reboot, for example:
+
+ci_hdrc ci_hdrc.1: remove, state 1
+usb usb2: USB disconnect, device number 1
+usb 2-1: USB disconnect, device number 2
+usb 2-1.1: USB disconnect, device number 3
+smsc95xx 2-1.1:1.0 eth1: unregister 'smsc95xx' usb-ci_hdrc.1-1.1, smsc95xx USB 2.0 Ethernet
+smsc95xx 2-1.1:1.0 eth1: Failed to read reg index 0x00000114: -19
+smsc95xx 2-1.1:1.0 eth1: Error reading MII_ACCESS
+smsc95xx 2-1.1:1.0 eth1: __smsc95xx_mdio_read: MII is busy
+smsc95xx 2-1.1:1.0 eth1: Failed to read reg index 0x00000114: -19
+smsc95xx 2-1.1:1.0 eth1: Error reading MII_ACCESS
+smsc95xx 2-1.1:1.0 eth1: __smsc95xx_mdio_read: MII is busy
+smsc95xx 2-1.1:1.0 eth1: hardware isn't capable of remote wakeup
+usb 2-1.4: USB disconnect, device number 4
+ci_hdrc ci_hdrc.1: USB bus 2 deregistered
+ci_hdrc ci_hdrc.0: remove, state 4
+usb usb1: USB disconnect, device number 1
+ci_hdrc ci_hdrc.0: USB bus 1 deregistered
+imx2-wdt 30280000.watchdog: Device shutdown: Expect reboot!
+reboot: Restarting system
+
+Ignore the -ENODEV errors inside __smsc95xx_mdio_read() and
+__smsc95xx_phy_wait_not_busy() and do not print error messages
+when -ENODEV is returned.
+
+Fixes: a049a30fc27c ("net: usb: Correct PHY handling of smsc95xx")
+Signed-off-by: Fabio Estevam <festevam@denx.de>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Cc: Fabio Estevam <festevam@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/usb/smsc95xx.c |   28 ++++++++++++++++++++--------
+ 1 file changed, 20 insertions(+), 8 deletions(-)
+
+--- a/drivers/net/usb/smsc95xx.c
++++ b/drivers/net/usb/smsc95xx.c
+@@ -84,9 +84,10 @@ static int __must_check __smsc95xx_read_
+       ret = fn(dev, USB_VENDOR_REQUEST_READ_REGISTER, USB_DIR_IN
+                | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                0, index, &buf, 4);
+-      if (unlikely(ret < 0)) {
+-              netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n",
+-                          index, ret);
++      if (ret < 0) {
++              if (ret != -ENODEV)
++                      netdev_warn(dev->net, "Failed to read reg index 0x%08x: %d\n",
++                                  index, ret);
+               return ret;
+       }
+@@ -116,7 +117,7 @@ static int __must_check __smsc95xx_write
+       ret = fn(dev, USB_VENDOR_REQUEST_WRITE_REGISTER, USB_DIR_OUT
+                | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+                0, index, &buf, 4);
+-      if (unlikely(ret < 0))
++      if (ret < 0 && ret != -ENODEV)
+               netdev_warn(dev->net, "Failed to write reg index 0x%08x: %d\n",
+                           index, ret);
+@@ -159,6 +160,9 @@ static int __must_check __smsc95xx_phy_w
+       do {
+               ret = __smsc95xx_read_reg(dev, MII_ADDR, &val, in_pm);
+               if (ret < 0) {
++                      /* Ignore -ENODEV error during disconnect() */
++                      if (ret == -ENODEV)
++                              return 0;
+                       netdev_warn(dev->net, "Error reading MII_ACCESS\n");
+                       return ret;
+               }
+@@ -194,7 +198,8 @@ static int __smsc95xx_mdio_read(struct u
+       addr = mii_address_cmd(phy_id, idx, MII_READ_ | MII_BUSY_);
+       ret = __smsc95xx_write_reg(dev, MII_ADDR, addr, in_pm);
+       if (ret < 0) {
+-              netdev_warn(dev->net, "Error writing MII_ADDR\n");
++              if (ret != -ENODEV)
++                      netdev_warn(dev->net, "Error writing MII_ADDR\n");
+               goto done;
+       }
+@@ -206,7 +211,8 @@ static int __smsc95xx_mdio_read(struct u
+       ret = __smsc95xx_read_reg(dev, MII_DATA, &val, in_pm);
+       if (ret < 0) {
+-              netdev_warn(dev->net, "Error reading MII_DATA\n");
++              if (ret != -ENODEV)
++                      netdev_warn(dev->net, "Error reading MII_DATA\n");
+               goto done;
+       }
+@@ -214,6 +220,10 @@ static int __smsc95xx_mdio_read(struct u
+ done:
+       mutex_unlock(&dev->phy_mutex);
++
++      /* Ignore -ENODEV error during disconnect() */
++      if (ret == -ENODEV)
++              return 0;
+       return ret;
+ }
+@@ -235,7 +245,8 @@ static void __smsc95xx_mdio_write(struct
+       val = regval;
+       ret = __smsc95xx_write_reg(dev, MII_DATA, val, in_pm);
+       if (ret < 0) {
+-              netdev_warn(dev->net, "Error writing MII_DATA\n");
++              if (ret != -ENODEV)
++                      netdev_warn(dev->net, "Error writing MII_DATA\n");
+               goto done;
+       }
+@@ -243,7 +254,8 @@ static void __smsc95xx_mdio_write(struct
+       addr = mii_address_cmd(phy_id, idx, MII_WRITE_ | MII_BUSY_);
+       ret = __smsc95xx_write_reg(dev, MII_ADDR, addr, in_pm);
+       if (ret < 0) {
+-              netdev_warn(dev->net, "Error writing MII_ADDR\n");
++              if (ret != -ENODEV)
++                      netdev_warn(dev->net, "Error writing MII_ADDR\n");
+               goto done;
+       }