This is a note to let you know that I've just added the patch titled Revert "usbnet: smsc95xx: Forward PHY interrupts to PHY driver to avoid polling" to the 5.15-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch and it can be found in the queue-5.15 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From foo@baz Mon Aug 29 10:10:59 AM CEST 2022 From: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> Date: Mon, 29 Aug 2022 10:07:09 +0200 Subject: Revert "usbnet: smsc95xx: Forward PHY interrupts to PHY driver to avoid polling" From: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> This reverts commit eaf3a094d8924ecb0baacf6df62ae1c6a96083cf which is upstream commit 1ce8b37241ed291af56f7a49bbdbf20c08728e88. It is reported to cause problems, so drop it from the 5.15.y tree until the root cause can be determined. Reported-by: Lukas Wunner <lukas@xxxxxxxxx> Cc: Oleksij Rempel <o.rempel@xxxxxxxxxxxxxx> Cc: Ferry Toth <fntoth@xxxxxxxxx> Cc: Andrew Lunn <andrew@xxxxxxx> Cc: Andre Edich <andre.edich@xxxxxxxxxxxxx> Cc: David S. Miller <davem@xxxxxxxxxxxxx> Cc: Sasha Levin <sashal@xxxxxxxxxx> Link: https://lore.kernel.org/r/20220826132137.GA24932@xxxxxxxxx Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- drivers/net/usb/smsc95xx.c | 113 ++++++++++++++++++++------------------------- 1 file changed, 52 insertions(+), 61 deletions(-) --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -18,8 +18,6 @@ #include <linux/usb/usbnet.h> #include <linux/slab.h> #include <linux/of_net.h> -#include <linux/irq.h> -#include <linux/irqdomain.h> #include <linux/mdio.h> #include <linux/phy.h> #include "smsc95xx.h" @@ -53,9 +51,6 @@ #define SUSPEND_ALLMODES (SUSPEND_SUSPEND0 | SUSPEND_SUSPEND1 | \ SUSPEND_SUSPEND2 | SUSPEND_SUSPEND3) -#define SMSC95XX_NR_IRQS (1) /* raise to 12 for GPIOs */ -#define PHY_HWIRQ (SMSC95XX_NR_IRQS - 1) - struct smsc95xx_priv { u32 mac_cr; u32 hash_hi; @@ -64,9 +59,6 @@ struct smsc95xx_priv { spinlock_t mac_cr_lock; u8 features; u8 suspend_flags; - struct irq_chip irqchip; - struct irq_domain *irqdomain; - struct fwnode_handle *irqfwnode; struct mii_bus *mdiobus; struct phy_device *phydev; }; @@ -603,8 +595,6 @@ static void smsc95xx_mac_update_fulldupl static void smsc95xx_status(struct usbnet *dev, struct urb *urb) { - struct smsc95xx_priv *pdata = dev->driver_priv; - unsigned long flags; u32 intdata; if (urb->actual_length != 4) { @@ -616,15 +606,11 @@ static void smsc95xx_status(struct usbne intdata = get_unaligned_le32(urb->transfer_buffer); netif_dbg(dev, link, dev->net, "intdata: 0x%08X\n", intdata); - local_irq_save(flags); - if (intdata & INT_ENP_PHY_INT_) - generic_handle_domain_irq(pdata->irqdomain, PHY_HWIRQ); + ; else netdev_warn(dev->net, "unexpected interrupt, intdata=0x%08X\n", intdata); - - local_irq_restore(flags); } /* Enable or disable Tx & Rx checksum offload engines */ @@ -1086,9 +1072,8 @@ static int smsc95xx_bind(struct usbnet * { struct smsc95xx_priv *pdata; bool is_internal_phy; - char usb_path[64]; - int ret, phy_irq; u32 val; + int ret; printk(KERN_INFO SMSC_CHIPNAME " v" SMSC_DRIVER_VERSION "\n"); @@ -1128,38 +1113,10 @@ static int smsc95xx_bind(struct usbnet * if (ret) goto free_pdata; - /* create irq domain for use by PHY driver and GPIO consumers */ - usb_make_path(dev->udev, usb_path, sizeof(usb_path)); - pdata->irqfwnode = irq_domain_alloc_named_fwnode(usb_path); - if (!pdata->irqfwnode) { - ret = -ENOMEM; - goto free_pdata; - } - - pdata->irqdomain = irq_domain_create_linear(pdata->irqfwnode, - SMSC95XX_NR_IRQS, - &irq_domain_simple_ops, - pdata); - if (!pdata->irqdomain) { - ret = -ENOMEM; - goto free_irqfwnode; - } - - phy_irq = irq_create_mapping(pdata->irqdomain, PHY_HWIRQ); - if (!phy_irq) { - ret = -ENOENT; - goto remove_irqdomain; - } - - pdata->irqchip = dummy_irq_chip; - pdata->irqchip.name = SMSC_CHIPNAME; - irq_set_chip_and_handler_name(phy_irq, &pdata->irqchip, - handle_simple_irq, "phy"); - pdata->mdiobus = mdiobus_alloc(); if (!pdata->mdiobus) { ret = -ENOMEM; - goto dispose_irq; + goto free_pdata; } ret = smsc95xx_read_reg(dev, HW_CFG, &val); @@ -1192,7 +1149,6 @@ static int smsc95xx_bind(struct usbnet * goto unregister_mdio; } - pdata->phydev->irq = phy_irq; pdata->phydev->is_internal = is_internal_phy; /* detect device revision as different features may be available */ @@ -1235,15 +1191,6 @@ unregister_mdio: free_mdio: mdiobus_free(pdata->mdiobus); -dispose_irq: - irq_dispose_mapping(phy_irq); - -remove_irqdomain: - irq_domain_remove(pdata->irqdomain); - -free_irqfwnode: - irq_domain_free_fwnode(pdata->irqfwnode); - free_pdata: kfree(pdata); return ret; @@ -1256,9 +1203,6 @@ static void smsc95xx_unbind(struct usbne phy_disconnect(dev->net->phydev); mdiobus_unregister(pdata->mdiobus); mdiobus_free(pdata->mdiobus); - irq_dispose_mapping(irq_find_mapping(pdata->irqdomain, PHY_HWIRQ)); - irq_domain_remove(pdata->irqdomain); - irq_domain_free_fwnode(pdata->irqfwnode); netif_dbg(dev, ifdown, dev->net, "free pdata\n"); kfree(pdata); } @@ -1283,6 +1227,29 @@ static u32 smsc_crc(const u8 *buffer, si return crc << ((filter % 2) * 16); } +static int smsc95xx_enable_phy_wakeup_interrupts(struct usbnet *dev, u16 mask) +{ + int ret; + + netdev_dbg(dev->net, "enabling PHY wakeup interrupts\n"); + + /* read to clear */ + ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_SRC); + if (ret < 0) + return ret; + + /* enable interrupt source */ + ret = smsc95xx_mdio_read_nopm(dev, PHY_INT_MASK); + if (ret < 0) + return ret; + + ret |= mask; + + smsc95xx_mdio_write_nopm(dev, PHY_INT_MASK, ret); + + return 0; +} + static int smsc95xx_link_ok_nopm(struct usbnet *dev) { int ret; @@ -1449,6 +1416,7 @@ static int smsc95xx_enter_suspend3(struc static int smsc95xx_autosuspend(struct usbnet *dev, u32 link_up) { struct smsc95xx_priv *pdata = dev->driver_priv; + int ret; if (!netif_running(dev->net)) { /* interface is ifconfig down so fully power down hw */ @@ -1467,10 +1435,27 @@ static int smsc95xx_autosuspend(struct u } netdev_dbg(dev->net, "autosuspend entering SUSPEND1\n"); + + /* enable PHY wakeup events for if cable is attached */ + ret = smsc95xx_enable_phy_wakeup_interrupts(dev, + PHY_INT_MASK_ANEG_COMP_); + if (ret < 0) { + netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); + return ret; + } + netdev_info(dev->net, "entering SUSPEND1 mode\n"); return smsc95xx_enter_suspend1(dev); } + /* enable PHY wakeup events so we remote wakeup if cable is pulled */ + ret = smsc95xx_enable_phy_wakeup_interrupts(dev, + PHY_INT_MASK_LINK_DOWN_); + if (ret < 0) { + netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); + return ret; + } + netdev_dbg(dev->net, "autosuspend entering SUSPEND3\n"); return smsc95xx_enter_suspend3(dev); } @@ -1536,6 +1521,13 @@ static int smsc95xx_suspend(struct usb_i } if (pdata->wolopts & WAKE_PHY) { + ret = smsc95xx_enable_phy_wakeup_interrupts(dev, + (PHY_INT_MASK_ANEG_COMP_ | PHY_INT_MASK_LINK_DOWN_)); + if (ret < 0) { + netdev_warn(dev->net, "error enabling PHY wakeup ints\n"); + goto done; + } + /* if link is down then configure EDPD and enter SUSPEND1, * otherwise enter SUSPEND0 below */ @@ -1769,12 +1761,11 @@ static int smsc95xx_resume(struct usb_in return ret; } - phy_init_hw(pdata->phydev); - ret = usbnet_resume(intf); if (ret < 0) netdev_warn(dev->net, "usbnet_resume error\n"); + phy_init_hw(pdata->phydev); return ret; } Patches currently in stable-queue which might be from gregkh@xxxxxxxxxxxxxxxxxxx are queue-5.15/btrfs-replace-btrfs_max_extent_size-with-fs_info-max_extent_size.patch queue-5.15/block-add-bdev_max_segments-helper.patch queue-5.15/block-add-a-bdev_max_zone_append_sectors-helper.patch queue-5.15/cgroup-fix-race-condition-at-rebind_subsystems.patch queue-5.15/xen-privcmd-fix-error-exit-of-privcmd_ioctl_dm_op.patch queue-5.15/kernel-sys_ni-add-compat-entry-for-fadvise64_64.patch queue-5.15/asm-generic-sections-refactor-memory_intersects.patch queue-5.15/audit-fix-potential-double-free-on-error-path-from-fsnotify_add_inode_mark.patch queue-5.15/x86-entry-move-cld-to-the-start-of-the-idtentry-macro.patch queue-5.15/btrfs-replace-drop-assert-for-suspended-replace.patch queue-5.15/parisc-fix-exception-handler-for-fldw-and-fstw-instructions.patch queue-5.15/btrfs-fix-possible-memory-leak-in-btrfs_get_dev_args_from_path.patch queue-5.15/revert-memcg-cleanup-racy-sum-avoidance-code.patch queue-5.15/revert-usbnet-smsc95xx-forward-phy-interrupts-to-phy-driver-to-avoid-polling.patch queue-5.15/x86-nospec-unwreck-the-rsb-stuffing.patch queue-5.15/drivers-base-fix-userspace-break-from-using-bin_attr.patch queue-5.15/btrfs-add-info-when-mount-fails-due-to-stale-replace-target.patch queue-5.15/nouveau-explicitly-wait-on-the-fence-in-nouveau_bo_move_m2mf.patch queue-5.15/s390-fix-double-free-of-gs-and-ri-cbs-on-fork-failure.patch queue-5.15/x86-unwind-orc-unwind-ftrace-trampolines-with-correct-orc-entry.patch queue-5.15/eth-sun-cassini-remove-dead-code.patch queue-5.15/s390-mm-do-not-trigger-write-fault-when-vma-does-not-allow-vm_write.patch queue-5.15/acpi-processor-remove-freq-qos-request-for-all-cpus.patch queue-5.15/btrfs-fix-silent-failure-when-deleting-root-reference.patch queue-5.15/mm-damon-dbgfs-avoid-duplicate-context-directory-creation.patch queue-5.15/btrfs-check-if-root-is-readonly-while-setting-security-xattr.patch queue-5.15/smb3-missing-inode-locks-in-punch-hole.patch queue-5.15/revert-usbnet-smsc95xx-fix-deadlock-on-runtime-resume.patch queue-5.15/writeback-avoid-use-after-free-after-removing-device.patch queue-5.15/riscv-traps-add-missing-prototype.patch queue-5.15/perf-x86-lbr-enable-the-branch-type-for-the-arch-lbr-by-default.patch queue-5.15/loop-check-for-overflow-while-configuring-loop.patch queue-5.15/io_uring-fix-issue-with-io_write-not-always-undoing-sb_start_write.patch queue-5.15/bootmem-remove-the-vmemmap-pages-from-kmemleak-in-put_page_bootmem.patch queue-5.15/fbdev-fbcon-properly-revert-changes-when-vc_resize-failed.patch queue-5.15/btrfs-convert-count_max_extents-to-use-fs_info-max_extent_size.patch queue-5.15/btrfs-zoned-revive-max_zone_append_bytes.patch queue-5.15/wifi-rtlwifi-remove-always-true-condition-pointed-out-by-gcc-12.patch queue-5.15/x86-bugs-add-unknown-reporting-for-mmio-stale-data.patch queue-5.15/parisc-make-config_64bit-available-for-arch-parisc64-only.patch