commit:     fdd5a720e6058faea8253988229ff8f5e367a006
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Wed Apr 21 11:41:54 2021 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Wed Apr 21 11:41:54 2021 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=fdd5a720

Linux patch 5.4.114

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README              |    4 +
 1113_linux-5.4.114.patch | 2749 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 2753 insertions(+)

diff --git a/0000_README b/0000_README
index 4792b10..95ce3e1 100644
--- a/0000_README
+++ b/0000_README
@@ -495,6 +495,10 @@ Patch:  1112_linux-5.4.113.patch
 From:   http://www.kernel.org
 Desc:   Linux 5.4.113
 
+Patch:  1113_linux-5.4.114.patch
+From:   http://www.kernel.org
+Desc:   Linux 5.4.114
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1113_linux-5.4.114.patch b/1113_linux-5.4.114.patch
new file mode 100644
index 0000000..4b1fb51
--- /dev/null
+++ b/1113_linux-5.4.114.patch
@@ -0,0 +1,2749 @@
+diff --git a/Makefile b/Makefile
+index 7fe00a93c870c..355e05ba065cb 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 5
+ PATCHLEVEL = 4
+-SUBLEVEL = 113
++SUBLEVEL = 114
+ EXTRAVERSION =
+ NAME = Kleptomaniac Octopus
+ 
+diff --git a/arch/arc/kernel/signal.c b/arch/arc/kernel/signal.c
+index 3d57ed0d85350..4045180510939 100644
+--- a/arch/arc/kernel/signal.c
++++ b/arch/arc/kernel/signal.c
+@@ -96,7 +96,7 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs 
*regs,
+                            sizeof(sf->uc.uc_mcontext.regs.scratch));
+       err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
+ 
+-      return err;
++      return err ? -EFAULT : 0;
+ }
+ 
+ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user 
*sf)
+@@ -110,7 +110,7 @@ static int restore_usr_regs(struct pt_regs *regs, struct 
rt_sigframe __user *sf)
+                               &(sf->uc.uc_mcontext.regs.scratch),
+                               sizeof(sf->uc.uc_mcontext.regs.scratch));
+       if (err)
+-              return err;
++              return -EFAULT;
+ 
+       set_current_blocked(&set);
+       regs->bta       = uregs.scratch.bta;
+diff --git a/arch/arm/boot/dts/omap4.dtsi b/arch/arm/boot/dts/omap4.dtsi
+index 904852006b9b1..0a36b8fe3fa92 100644
+--- a/arch/arm/boot/dts/omap4.dtsi
++++ b/arch/arm/boot/dts/omap4.dtsi
+@@ -22,6 +22,11 @@
+               i2c1 = &i2c2;
+               i2c2 = &i2c3;
+               i2c3 = &i2c4;
++              mmc0 = &mmc1;
++              mmc1 = &mmc2;
++              mmc2 = &mmc3;
++              mmc3 = &mmc4;
++              mmc4 = &mmc5;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+diff --git a/arch/arm/boot/dts/omap44xx-clocks.dtsi 
b/arch/arm/boot/dts/omap44xx-clocks.dtsi
+index e9d9c8460682c..68ab6a95f222d 100644
+--- a/arch/arm/boot/dts/omap44xx-clocks.dtsi
++++ b/arch/arm/boot/dts/omap44xx-clocks.dtsi
+@@ -770,14 +770,6 @@
+               ti,max-div = <2>;
+       };
+ 
+-      sha2md5_fck: sha2md5_fck@15c8 {
+-              #clock-cells = <0>;
+-              compatible = "ti,gate-clock";
+-              clocks = <&l3_div_ck>;
+-              ti,bit-shift = <1>;
+-              reg = <0x15c8>;
+-      };
+-
+       usb_phy_cm_clk32k: usb_phy_cm_clk32k@640 {
+               #clock-cells = <0>;
+               compatible = "ti,gate-clock";
+diff --git a/arch/arm/boot/dts/omap5.dtsi b/arch/arm/boot/dts/omap5.dtsi
+index 041646fabb2db..3b56e993326d0 100644
+--- a/arch/arm/boot/dts/omap5.dtsi
++++ b/arch/arm/boot/dts/omap5.dtsi
+@@ -25,6 +25,11 @@
+               i2c2 = &i2c3;
+               i2c3 = &i2c4;
+               i2c4 = &i2c5;
++              mmc0 = &mmc1;
++              mmc1 = &mmc2;
++              mmc2 = &mmc3;
++              mmc3 = &mmc4;
++              mmc4 = &mmc5;
+               serial0 = &uart1;
+               serial1 = &uart2;
+               serial2 = &uart3;
+diff --git a/arch/arm/mach-footbridge/cats-pci.c 
b/arch/arm/mach-footbridge/cats-pci.c
+index 0b2fd7e2e9b42..90b1e9be430e9 100644
+--- a/arch/arm/mach-footbridge/cats-pci.c
++++ b/arch/arm/mach-footbridge/cats-pci.c
+@@ -15,14 +15,14 @@
+ #include <asm/mach-types.h>
+ 
+ /* cats host-specific stuff */
+-static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
++static int irqmap_cats[] = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 };
+ 
+ static u8 cats_no_swizzle(struct pci_dev *dev, u8 *pin)
+ {
+       return 0;
+ }
+ 
+-static int __init cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++static int cats_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ {
+       if (dev->irq >= 255)
+               return -1;      /* not a valid interrupt. */
+diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c 
b/arch/arm/mach-footbridge/ebsa285-pci.c
+index 6f28aaa9ca79b..c3f280d08fa7f 100644
+--- a/arch/arm/mach-footbridge/ebsa285-pci.c
++++ b/arch/arm/mach-footbridge/ebsa285-pci.c
+@@ -14,9 +14,9 @@
+ #include <asm/mach/pci.h>
+ #include <asm/mach-types.h>
+ 
+-static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI 
};
++static int irqmap_ebsa285[] = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI };
+ 
+-static int __init ebsa285_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
++static int ebsa285_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ {
+       if (dev->vendor == PCI_VENDOR_ID_CONTAQ &&
+           dev->device == PCI_DEVICE_ID_CONTAQ_82C693)
+diff --git a/arch/arm/mach-footbridge/netwinder-pci.c 
b/arch/arm/mach-footbridge/netwinder-pci.c
+index 9473aa0305e5f..e8304392074b8 100644
+--- a/arch/arm/mach-footbridge/netwinder-pci.c
++++ b/arch/arm/mach-footbridge/netwinder-pci.c
+@@ -18,7 +18,7 @@
+  * We now use the slot ID instead of the device identifiers to select
+  * which interrupt is routed where.
+  */
+-static int __init netwinder_map_irq(const struct pci_dev *dev, u8 slot, u8 
pin)
++static int netwinder_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ {
+       switch (slot) {
+       case 0:  /* host bridge */
+diff --git a/arch/arm/mach-footbridge/personal-pci.c 
b/arch/arm/mach-footbridge/personal-pci.c
+index 4391e433a4b2f..9d19aa98a663e 100644
+--- a/arch/arm/mach-footbridge/personal-pci.c
++++ b/arch/arm/mach-footbridge/personal-pci.c
+@@ -14,13 +14,12 @@
+ #include <asm/mach/pci.h>
+ #include <asm/mach-types.h>
+ 
+-static int irqmap_personal_server[] __initdata = {
++static int irqmap_personal_server[] = {
+       IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0,
+       IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI
+ };
+ 
+-static int __init personal_server_map_irq(const struct pci_dev *dev, u8 slot,
+-      u8 pin)
++static int personal_server_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+ {
+       unsigned char line;
+ 
+diff --git a/arch/arm/mach-keystone/keystone.c 
b/arch/arm/mach-keystone/keystone.c
+index 638808c4e1224..697adedaced49 100644
+--- a/arch/arm/mach-keystone/keystone.c
++++ b/arch/arm/mach-keystone/keystone.c
+@@ -62,7 +62,7 @@ static void __init keystone_init(void)
+ static long long __init keystone_pv_fixup(void)
+ {
+       long long offset;
+-      phys_addr_t mem_start, mem_end;
++      u64 mem_start, mem_end;
+ 
+       mem_start = memblock_start_of_DRAM();
+       mem_end = memblock_end_of_DRAM();
+@@ -75,7 +75,7 @@ static long long __init keystone_pv_fixup(void)
+       if (mem_start < KEYSTONE_HIGH_PHYS_START ||
+           mem_end   > KEYSTONE_HIGH_PHYS_END) {
+               pr_crit("Invalid address space for memory (%08llx-%08llx)\n",
+-                      (u64)mem_start, (u64)mem_end);
++                      mem_start, mem_end);
+               return 0;
+       }
+ 
+diff --git a/arch/arm/mach-omap1/ams-delta-fiq-handler.S 
b/arch/arm/mach-omap1/ams-delta-fiq-handler.S
+index 14a6c3eb32985..f745a65d3bd7a 100644
+--- a/arch/arm/mach-omap1/ams-delta-fiq-handler.S
++++ b/arch/arm/mach-omap1/ams-delta-fiq-handler.S
+@@ -15,6 +15,7 @@
+ #include <linux/platform_data/gpio-omap.h>
+ 
+ #include <asm/assembler.h>
++#include <asm/irq.h>
+ 
+ #include "ams-delta-fiq.h"
+ #include "board-ams-delta.h"
+diff --git a/arch/arm/probes/uprobes/core.c b/arch/arm/probes/uprobes/core.c
+index c4b49b322e8a8..f5f790c6e5f89 100644
+--- a/arch/arm/probes/uprobes/core.c
++++ b/arch/arm/probes/uprobes/core.c
+@@ -204,7 +204,7 @@ unsigned long uprobe_get_swbp_addr(struct pt_regs *regs)
+ static struct undef_hook uprobes_arm_break_hook = {
+       .instr_mask     = 0x0fffffff,
+       .instr_val      = (UPROBE_SWBP_ARM_INSN & 0x0fffffff),
+-      .cpsr_mask      = MODE_MASK,
++      .cpsr_mask      = (PSR_T_BIT | MODE_MASK),
+       .cpsr_val       = USR_MODE,
+       .fn             = uprobe_trap_handler,
+ };
+@@ -212,7 +212,7 @@ static struct undef_hook uprobes_arm_break_hook = {
+ static struct undef_hook uprobes_arm_ss_hook = {
+       .instr_mask     = 0x0fffffff,
+       .instr_val      = (UPROBE_SS_ARM_INSN & 0x0fffffff),
+-      .cpsr_mask      = MODE_MASK,
++      .cpsr_mask      = (PSR_T_BIT | MODE_MASK),
+       .cpsr_val       = USR_MODE,
+       .fn             = uprobe_trap_handler,
+ };
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
+index 72d6961dc3128..8d15164f2a3c6 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
+@@ -11,3 +11,7 @@
+       compatible = "pine64,pine64-lts", "allwinner,sun50i-r18",
+                    "allwinner,sun50i-a64";
+ };
++
++&mmc0 {
++      cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 push-push switch */
++};
+diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
+index d935e3028fcb6..19e5b7e298fdf 100644
+--- a/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
++++ b/arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
+@@ -57,7 +57,7 @@
+       vmmc-supply = <&reg_dcdc1>;
+       disable-wp;
+       bus-width = <4>;
+-      cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
++      cd-gpios = <&pio 5 6 GPIO_ACTIVE_HIGH>; /* PF6 push-pull switch */
+       status = "okay";
+ };
+ 
+diff --git a/arch/arm64/include/asm/alternative.h 
b/arch/arm64/include/asm/alternative.h
+index 619db9b4c9d5c..3cb3c4ab3ea56 100644
+--- a/arch/arm64/include/asm/alternative.h
++++ b/arch/arm64/include/asm/alternative.h
+@@ -119,9 +119,9 @@ static inline void apply_alternatives_module(void *start, 
size_t length) { }
+       .popsection
+       .subsection 1
+ 663:  \insn2
+-664:  .previous
+-      .org    . - (664b-663b) + (662b-661b)
++664:  .org    . - (664b-663b) + (662b-661b)
+       .org    . - (662b-661b) + (664b-663b)
++      .previous
+       .endif
+ .endm
+ 
+@@ -191,11 +191,11 @@ static inline void apply_alternatives_module(void 
*start, size_t length) { }
+  */
+ .macro alternative_endif
+ 664:
++      .org    . - (664b-663b) + (662b-661b)
++      .org    . - (662b-661b) + (664b-663b)
+       .if .Lasm_alt_mode==0
+       .previous
+       .endif
+-      .org    . - (664b-663b) + (662b-661b)
+-      .org    . - (662b-661b) + (664b-663b)
+ .endm
+ 
+ /*
+diff --git a/arch/arm64/include/asm/word-at-a-time.h 
b/arch/arm64/include/asm/word-at-a-time.h
+index 3333950b59093..ea487218db790 100644
+--- a/arch/arm64/include/asm/word-at-a-time.h
++++ b/arch/arm64/include/asm/word-at-a-time.h
+@@ -53,7 +53,7 @@ static inline unsigned long find_zero(unsigned long mask)
+  */
+ static inline unsigned long load_unaligned_zeropad(const void *addr)
+ {
+-      unsigned long ret, offset;
++      unsigned long ret, tmp;
+ 
+       /* Load word from unaligned pointer addr */
+       asm(
+@@ -61,9 +61,9 @@ static inline unsigned long load_unaligned_zeropad(const 
void *addr)
+       "2:\n"
+       "       .pushsection .fixup,\"ax\"\n"
+       "       .align 2\n"
+-      "3:     and     %1, %2, #0x7\n"
+-      "       bic     %2, %2, #0x7\n"
+-      "       ldr     %0, [%2]\n"
++      "3:     bic     %1, %2, #0x7\n"
++      "       ldr     %0, [%1]\n"
++      "       and     %1, %2, #0x7\n"
+       "       lsl     %1, %1, #0x3\n"
+ #ifndef __AARCH64EB__
+       "       lsr     %0, %0, %1\n"
+@@ -73,7 +73,7 @@ static inline unsigned long load_unaligned_zeropad(const 
void *addr)
+       "       b       2b\n"
+       "       .popsection\n"
+       _ASM_EXTABLE(1b, 3b)
+-      : "=&r" (ret), "=&r" (offset)
++      : "=&r" (ret), "=&r" (tmp)
+       : "r" (addr), "Q" (*(unsigned long *)addr));
+ 
+       return ret;
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
+index 6b23a0cb2b353..b21549a34447c 100644
+--- a/arch/riscv/Kconfig
++++ b/arch/riscv/Kconfig
+@@ -101,7 +101,7 @@ config ARCH_FLATMEM_ENABLE
+ config ARCH_SPARSEMEM_ENABLE
+       def_bool y
+       depends on MMU
+-      select SPARSEMEM_STATIC if 32BIT && SPARSMEM
++      select SPARSEMEM_STATIC if 32BIT && SPARSEMEM
+       select SPARSEMEM_VMEMMAP_ENABLE if 64BIT
+ 
+ config ARCH_SELECT_MEMORY_MODEL
+diff --git a/drivers/dma/dw/Kconfig b/drivers/dma/dw/Kconfig
+index e5162690de8f1..db25f9b7778c9 100644
+--- a/drivers/dma/dw/Kconfig
++++ b/drivers/dma/dw/Kconfig
+@@ -10,6 +10,7 @@ config DW_DMAC_CORE
+ 
+ config DW_DMAC
+       tristate "Synopsys DesignWare AHB DMA platform driver"
++      depends on HAS_IOMEM
+       select DW_DMAC_CORE
+       help
+         Support the Synopsys DesignWare AHB DMA controller. This
+@@ -18,6 +19,7 @@ config DW_DMAC
+ config DW_DMAC_PCI
+       tristate "Synopsys DesignWare AHB DMA PCI driver"
+       depends on PCI
++      depends on HAS_IOMEM
+       select DW_DMAC_CORE
+       help
+         Support the Synopsys DesignWare AHB DMA controller on the
+diff --git a/drivers/gpio/gpiolib-sysfs.c b/drivers/gpio/gpiolib-sysfs.c
+index fbf6b1a0a4fae..558cd900d3996 100644
+--- a/drivers/gpio/gpiolib-sysfs.c
++++ b/drivers/gpio/gpiolib-sysfs.c
+@@ -457,6 +457,8 @@ static ssize_t export_store(struct class *class,
+       long                    gpio;
+       struct gpio_desc        *desc;
+       int                     status;
++      struct gpio_chip        *gc;
++      int                     offset;
+ 
+       status = kstrtol(buf, 0, &gpio);
+       if (status < 0)
+@@ -468,6 +470,12 @@ static ssize_t export_store(struct class *class,
+               pr_warn("%s: invalid GPIO %ld\n", __func__, gpio);
+               return -EINVAL;
+       }
++      gc = desc->gdev->chip;
++      offset = gpio_chip_hwgpio(desc);
++      if (!gpiochip_line_is_valid(gc, offset)) {
++              pr_warn("%s: GPIO %ld masked\n", __func__, gpio);
++              return -EINVAL;
++      }
+ 
+       /* No extra locking here; FLAG_SYSFS just signifies that the
+        * request and export were done by on behalf of userspace, so
+diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+index f84049119f1c1..e3579e5ffa146 100644
+--- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c
+@@ -1131,8 +1131,8 @@ static int a5xx_pm_suspend(struct msm_gpu *gpu)
+ 
+ static int a5xx_get_timestamp(struct msm_gpu *gpu, uint64_t *value)
+ {
+-      *value = gpu_read64(gpu, REG_A5XX_RBBM_PERFCTR_CP_0_LO,
+-              REG_A5XX_RBBM_PERFCTR_CP_0_HI);
++      *value = gpu_read64(gpu, REG_A5XX_RBBM_ALWAYSON_COUNTER_LO,
++              REG_A5XX_RBBM_ALWAYSON_COUNTER_HI);
+ 
+       return 0;
+ }
+diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c 
b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+index ab75f0309d4b6..df2656e579917 100644
+--- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
++++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
+@@ -773,8 +773,8 @@ static int a6xx_get_timestamp(struct msm_gpu *gpu, 
uint64_t *value)
+       /* Force the GPU power on so we can read this register */
+       a6xx_gmu_set_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
+ 
+-      *value = gpu_read64(gpu, REG_A6XX_RBBM_PERFCTR_CP_0_LO,
+-              REG_A6XX_RBBM_PERFCTR_CP_0_HI);
++      *value = gpu_read64(gpu, REG_A6XX_CP_ALWAYS_ON_COUNTER_LO,
++              REG_A6XX_CP_ALWAYS_ON_COUNTER_HI);
+ 
+       a6xx_gmu_clear_oob(&a6xx_gpu->gmu, GMU_OOB_GPU_SET);
+       return 0;
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c
+index f1928c1ac139c..bf0621e446199 100644
+--- a/drivers/hid/wacom_wac.c
++++ b/drivers/hid/wacom_wac.c
+@@ -3574,8 +3574,6 @@ int wacom_setup_pen_input_capabilities(struct input_dev 
*input_dev,
+ {
+       struct wacom_features *features = &wacom_wac->features;
+ 
+-      input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+-
+       if (!(features->device_type & WACOM_DEVICETYPE_PEN))
+               return -ENODEV;
+ 
+@@ -3590,6 +3588,7 @@ int wacom_setup_pen_input_capabilities(struct input_dev 
*input_dev,
+               return 0;
+       }
+ 
++      input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       __set_bit(BTN_TOUCH, input_dev->keybit);
+       __set_bit(ABS_MISC, input_dev->absbit);
+ 
+@@ -3742,8 +3741,6 @@ int wacom_setup_touch_input_capabilities(struct 
input_dev *input_dev,
+ {
+       struct wacom_features *features = &wacom_wac->features;
+ 
+-      input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+-
+       if (!(features->device_type & WACOM_DEVICETYPE_TOUCH))
+               return -ENODEV;
+ 
+@@ -3756,6 +3753,7 @@ int wacom_setup_touch_input_capabilities(struct 
input_dev *input_dev,
+               /* setup has already been done */
+               return 0;
+ 
++      input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+       __set_bit(BTN_TOUCH, input_dev->keybit);
+ 
+       if (features->touch_max == 1) {
+diff --git a/drivers/input/keyboard/nspire-keypad.c 
b/drivers/input/keyboard/nspire-keypad.c
+index 63d5e488137dc..e9fa1423f1360 100644
+--- a/drivers/input/keyboard/nspire-keypad.c
++++ b/drivers/input/keyboard/nspire-keypad.c
+@@ -93,9 +93,15 @@ static irqreturn_t nspire_keypad_irq(int irq, void *dev_id)
+       return IRQ_HANDLED;
+ }
+ 
+-static int nspire_keypad_chip_init(struct nspire_keypad *keypad)
++static int nspire_keypad_open(struct input_dev *input)
+ {
++      struct nspire_keypad *keypad = input_get_drvdata(input);
+       unsigned long val = 0, cycles_per_us, delay_cycles, row_delay_cycles;
++      int error;
++
++      error = clk_prepare_enable(keypad->clk);
++      if (error)
++              return error;
+ 
+       cycles_per_us = (clk_get_rate(keypad->clk) / 1000000);
+       if (cycles_per_us == 0)
+@@ -121,30 +127,6 @@ static int nspire_keypad_chip_init(struct nspire_keypad 
*keypad)
+       keypad->int_mask = 1 << 1;
+       writel(keypad->int_mask, keypad->reg_base + KEYPAD_INTMSK);
+ 
+-      /* Disable GPIO interrupts to prevent hanging on touchpad */
+-      /* Possibly used to detect touchpad events */
+-      writel(0, keypad->reg_base + KEYPAD_UNKNOWN_INT);
+-      /* Acknowledge existing interrupts */
+-      writel(~0, keypad->reg_base + KEYPAD_UNKNOWN_INT_STS);
+-
+-      return 0;
+-}
+-
+-static int nspire_keypad_open(struct input_dev *input)
+-{
+-      struct nspire_keypad *keypad = input_get_drvdata(input);
+-      int error;
+-
+-      error = clk_prepare_enable(keypad->clk);
+-      if (error)
+-              return error;
+-
+-      error = nspire_keypad_chip_init(keypad);
+-      if (error) {
+-              clk_disable_unprepare(keypad->clk);
+-              return error;
+-      }
+-
+       return 0;
+ }
+ 
+@@ -152,6 +134,11 @@ static void nspire_keypad_close(struct input_dev *input)
+ {
+       struct nspire_keypad *keypad = input_get_drvdata(input);
+ 
++      /* Disable interrupts */
++      writel(0, keypad->reg_base + KEYPAD_INTMSK);
++      /* Acknowledge existing interrupts */
++      writel(~0, keypad->reg_base + KEYPAD_INT);
++
+       clk_disable_unprepare(keypad->clk);
+ }
+ 
+@@ -210,6 +197,25 @@ static int nspire_keypad_probe(struct platform_device 
*pdev)
+               return -ENOMEM;
+       }
+ 
++      error = clk_prepare_enable(keypad->clk);
++      if (error) {
++              dev_err(&pdev->dev, "failed to enable clock\n");
++              return error;
++      }
++
++      /* Disable interrupts */
++      writel(0, keypad->reg_base + KEYPAD_INTMSK);
++      /* Acknowledge existing interrupts */
++      writel(~0, keypad->reg_base + KEYPAD_INT);
++
++      /* Disable GPIO interrupts to prevent hanging on touchpad */
++      /* Possibly used to detect touchpad events */
++      writel(0, keypad->reg_base + KEYPAD_UNKNOWN_INT);
++      /* Acknowledge existing GPIO interrupts */
++      writel(~0, keypad->reg_base + KEYPAD_UNKNOWN_INT_STS);
++
++      clk_disable_unprepare(keypad->clk);
++
+       input_set_drvdata(input, keypad);
+ 
+       input->id.bustype = BUS_HOST;
+diff --git a/drivers/input/serio/i8042-x86ia64io.h 
b/drivers/input/serio/i8042-x86ia64io.h
+index e7346c5f4738a..23442a144b834 100644
+--- a/drivers/input/serio/i8042-x86ia64io.h
++++ b/drivers/input/serio/i8042-x86ia64io.h
+@@ -588,6 +588,7 @@ static const struct dmi_system_id 
i8042_dmi_noselftest_table[] = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "10"), /* Notebook */
+               },
++      }, {
+               .matches = {
+                       DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
+                       DMI_MATCH(DMI_CHASSIS_TYPE, "31"), /* Convertible 
Notebook */
+diff --git a/drivers/input/touchscreen/s6sy761.c 
b/drivers/input/touchscreen/s6sy761.c
+index b63d7fdf0cd20..85a1f465c097e 100644
+--- a/drivers/input/touchscreen/s6sy761.c
++++ b/drivers/input/touchscreen/s6sy761.c
+@@ -145,8 +145,8 @@ static void s6sy761_report_coordinates(struct s6sy761_data 
*sdata,
+       u8 major = event[4];
+       u8 minor = event[5];
+       u8 z = event[6] & S6SY761_MASK_Z;
+-      u16 x = (event[1] << 3) | ((event[3] & S6SY761_MASK_X) >> 4);
+-      u16 y = (event[2] << 3) | (event[3] & S6SY761_MASK_Y);
++      u16 x = (event[1] << 4) | ((event[3] & S6SY761_MASK_X) >> 4);
++      u16 y = (event[2] << 4) | (event[3] & S6SY761_MASK_Y);
+ 
+       input_mt_slot(sdata->input, tid);
+ 
+diff --git a/drivers/md/dm-verity-fec.c b/drivers/md/dm-verity-fec.c
+index 66f4c6398f670..cea2b37897367 100644
+--- a/drivers/md/dm-verity-fec.c
++++ b/drivers/md/dm-verity-fec.c
+@@ -65,7 +65,7 @@ static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int 
index,
+       u8 *res;
+ 
+       position = (index + rsb) * v->fec->roots;
+-      block = div64_u64_rem(position, v->fec->roots << SECTOR_SHIFT, &rem);
++      block = div64_u64_rem(position, v->fec->io_size, &rem);
+       *offset = (unsigned)rem;
+ 
+       res = dm_bufio_read(v->fec->bufio, block, buf);
+@@ -154,7 +154,7 @@ static int fec_decode_bufs(struct dm_verity *v, struct 
dm_verity_fec_io *fio,
+ 
+               /* read the next block when we run out of parity bytes */
+               offset += v->fec->roots;
+-              if (offset >= v->fec->roots << SECTOR_SHIFT) {
++              if (offset >= v->fec->io_size) {
+                       dm_bufio_release(buf);
+ 
+                       par = fec_read_parity(v, rsb, block_offset, &offset, 
&buf);
+@@ -742,8 +742,13 @@ int verity_fec_ctr(struct dm_verity *v)
+               return -E2BIG;
+       }
+ 
++      if ((f->roots << SECTOR_SHIFT) & ((1 << v->data_dev_block_bits) - 1))
++              f->io_size = 1 << v->data_dev_block_bits;
++      else
++              f->io_size = v->fec->roots << SECTOR_SHIFT;
++
+       f->bufio = dm_bufio_client_create(f->dev->bdev,
+-                                        f->roots << SECTOR_SHIFT,
++                                        f->io_size,
+                                         1, 0, NULL, NULL);
+       if (IS_ERR(f->bufio)) {
+               ti->error = "Cannot initialize FEC bufio client";
+diff --git a/drivers/md/dm-verity-fec.h b/drivers/md/dm-verity-fec.h
+index 42fbd3a7fc9f1..3c46c8d618833 100644
+--- a/drivers/md/dm-verity-fec.h
++++ b/drivers/md/dm-verity-fec.h
+@@ -36,6 +36,7 @@ struct dm_verity_fec {
+       struct dm_dev *dev;     /* parity data device */
+       struct dm_bufio_client *data_bufio;     /* for data dev access */
+       struct dm_bufio_client *bufio;          /* for parity data access */
++      size_t io_size;         /* IO size for roots */
+       sector_t start;         /* parity data start in blocks */
+       sector_t blocks;        /* number of blocks covered */
+       sector_t rounds;        /* number of interleaving rounds */
+diff --git a/drivers/net/dsa/mv88e6xxx/chip.c 
b/drivers/net/dsa/mv88e6xxx/chip.c
+index 1af09fd3fed1c..446eb06e50b49 100644
+--- a/drivers/net/dsa/mv88e6xxx/chip.c
++++ b/drivers/net/dsa/mv88e6xxx/chip.c
+@@ -2766,10 +2766,17 @@ unlock:
+       return err;
+ }
+ 
++/* prod_id for switch families which do not have a PHY model number */
++static const u16 family_prod_id_table[] = {
++      [MV88E6XXX_FAMILY_6341] = MV88E6XXX_PORT_SWITCH_ID_PROD_6341,
++      [MV88E6XXX_FAMILY_6390] = MV88E6XXX_PORT_SWITCH_ID_PROD_6390,
++};
++
+ static int mv88e6xxx_mdio_read(struct mii_bus *bus, int phy, int reg)
+ {
+       struct mv88e6xxx_mdio_bus *mdio_bus = bus->priv;
+       struct mv88e6xxx_chip *chip = mdio_bus->chip;
++      u16 prod_id;
+       u16 val;
+       int err;
+ 
+@@ -2780,23 +2787,12 @@ static int mv88e6xxx_mdio_read(struct mii_bus *bus, 
int phy, int reg)
+       err = chip->info->ops->phy_read(chip, bus, phy, reg, &val);
+       mv88e6xxx_reg_unlock(chip);
+ 
+-      if (reg == MII_PHYSID2) {
+-              /* Some internal PHYs don't have a model number. */
+-              if (chip->info->family != MV88E6XXX_FAMILY_6165)
+-                      /* Then there is the 6165 family. It gets is
+-                       * PHYs correct. But it can also have two
+-                       * SERDES interfaces in the PHY address
+-                       * space. And these don't have a model
+-                       * number. But they are not PHYs, so we don't
+-                       * want to give them something a PHY driver
+-                       * will recognise.
+-                       *
+-                       * Use the mv88e6390 family model number
+-                       * instead, for anything which really could be
+-                       * a PHY,
+-                       */
+-                      if (!(val & 0x3f0))
+-                              val |= MV88E6XXX_PORT_SWITCH_ID_PROD_6390 >> 4;
++      /* Some internal PHYs don't have a model number. */
++      if (reg == MII_PHYSID2 && !(val & 0x3f0) &&
++          chip->info->family < ARRAY_SIZE(family_prod_id_table)) {
++              prod_id = family_prod_id_table[chip->info->family];
++              if (prod_id)
++                      val |= prod_id >> 4;
+       }
+ 
+       return err ? err : val;
+diff --git a/drivers/net/ethernet/amd/pcnet32.c 
b/drivers/net/ethernet/amd/pcnet32.c
+index f5ad12c109344..da84660ceae1f 100644
+--- a/drivers/net/ethernet/amd/pcnet32.c
++++ b/drivers/net/ethernet/amd/pcnet32.c
+@@ -1548,8 +1548,7 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct 
pci_device_id *ent)
+       }
+       pci_set_master(pdev);
+ 
+-      ioaddr = pci_resource_start(pdev, 0);
+-      if (!ioaddr) {
++      if (!pci_resource_len(pdev, 0)) {
+               if (pcnet32_debug & NETIF_MSG_PROBE)
+                       pr_err("card has no PCI IO resources, aborting\n");
+               err = -ENODEV;
+@@ -1562,6 +1561,8 @@ pcnet32_probe_pci(struct pci_dev *pdev, const struct 
pci_device_id *ent)
+                       pr_err("architecture does not support 32bit PCI 
busmaster DMA\n");
+               goto err_disable_dev;
+       }
++
++      ioaddr = pci_resource_start(pdev, 0);
+       if (!request_region(ioaddr, PCNET32_TOTAL_SIZE, "pcnet32_probe_pci")) {
+               if (pcnet32_debug & NETIF_MSG_PROBE)
+                       pr_err("io address range already allocated\n");
+diff --git a/drivers/net/ethernet/cadence/macb_main.c 
b/drivers/net/ethernet/cadence/macb_main.c
+index bdef5b3dd848c..377668465535f 100644
+--- a/drivers/net/ethernet/cadence/macb_main.c
++++ b/drivers/net/ethernet/cadence/macb_main.c
+@@ -3590,6 +3590,7 @@ static int macb_init(struct platform_device *pdev)
+       reg = gem_readl(bp, DCFG8);
+       bp->max_tuples = min((GEM_BFEXT(SCR2CMP, reg) / 3),
+                       GEM_BFEXT(T2SCR, reg));
++      INIT_LIST_HEAD(&bp->rx_fs_list.list);
+       if (bp->max_tuples > 0) {
+               /* also needs one ethtype match to check IPv4 */
+               if (GEM_BFEXT(SCR2ETH, reg) > 0) {
+@@ -3600,7 +3601,6 @@ static int macb_init(struct platform_device *pdev)
+                       /* Filtering is supported in hw but don't enable it in 
kernel now */
+                       dev->hw_features |= NETIF_F_NTUPLE;
+                       /* init Rx flow definitions */
+-                      INIT_LIST_HEAD(&bp->rx_fs_list.list);
+                       bp->rx_fs_list.count = 0;
+                       spin_lock_init(&bp->rx_fs_lock);
+               } else
+diff --git a/drivers/net/ethernet/davicom/dm9000.c 
b/drivers/net/ethernet/davicom/dm9000.c
+index 4b958681d66e7..1d5d8984b49a3 100644
+--- a/drivers/net/ethernet/davicom/dm9000.c
++++ b/drivers/net/ethernet/davicom/dm9000.c
+@@ -1476,8 +1476,10 @@ dm9000_probe(struct platform_device *pdev)
+ 
+       /* Init network device */
+       ndev = alloc_etherdev(sizeof(struct board_info));
+-      if (!ndev)
+-              return -ENOMEM;
++      if (!ndev) {
++              ret = -ENOMEM;
++              goto out_regulator_disable;
++      }
+ 
+       SET_NETDEV_DEV(ndev, &pdev->dev);
+ 
+diff --git a/drivers/net/ethernet/ibm/ibmvnic.c 
b/drivers/net/ethernet/ibm/ibmvnic.c
+index 79b13750fa2d2..a2b7b982ee290 100644
+--- a/drivers/net/ethernet/ibm/ibmvnic.c
++++ b/drivers/net/ethernet/ibm/ibmvnic.c
+@@ -1081,19 +1081,13 @@ static int __ibmvnic_open(struct net_device *netdev)
+ 
+       rc = set_link_state(adapter, IBMVNIC_LOGICAL_LNK_UP);
+       if (rc) {
+-              for (i = 0; i < adapter->req_rx_queues; i++)
+-                      napi_disable(&adapter->napi[i]);
++              ibmvnic_napi_disable(adapter);
+               release_resources(adapter);
+               return rc;
+       }
+ 
+       netif_tx_start_all_queues(netdev);
+ 
+-      if (prev_state == VNIC_CLOSED) {
+-              for (i = 0; i < adapter->req_rx_queues; i++)
+-                      napi_schedule(&adapter->napi[i]);
+-      }
+-
+       adapter->state = VNIC_OPEN;
+       return rc;
+ }
+@@ -1850,7 +1844,7 @@ static int do_reset(struct ibmvnic_adapter *adapter,
+       u64 old_num_rx_queues, old_num_tx_queues;
+       u64 old_num_rx_slots, old_num_tx_slots;
+       struct net_device *netdev = adapter->netdev;
+-      int i, rc;
++      int rc;
+ 
+       netdev_dbg(adapter->netdev, "Re-setting driver (%d)\n",
+                  rwi->reset_reason);
+@@ -1995,10 +1989,6 @@ static int do_reset(struct ibmvnic_adapter *adapter,
+       /* refresh device's multicast list */
+       ibmvnic_set_multi(netdev);
+ 
+-      /* kick napi */
+-      for (i = 0; i < adapter->req_rx_queues; i++)
+-              napi_schedule(&adapter->napi[i]);
+-
+       if (adapter->reset_reason == VNIC_RESET_FAILOVER ||
+           adapter->reset_reason == VNIC_RESET_MOBILITY) {
+               call_netdevice_notifiers(NETDEV_NOTIFY_PEERS, netdev);
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c 
b/drivers/net/ethernet/intel/i40e/i40e_main.c
+index a69aace057925..a1b4e995f2b7e 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
+@@ -11872,6 +11872,7 @@ static int i40e_sw_init(struct i40e_pf *pf)
+ {
+       int err = 0;
+       int size;
++      u16 pow;
+ 
+       /* Set default capability flags */
+       pf->flags = I40E_FLAG_RX_CSUM_ENABLED |
+@@ -11890,6 +11891,11 @@ static int i40e_sw_init(struct i40e_pf *pf)
+       pf->rss_table_size = pf->hw.func_caps.rss_table_size;
+       pf->rss_size_max = min_t(int, pf->rss_size_max,
+                                pf->hw.func_caps.num_tx_qp);
++
++      /* find the next higher power-of-2 of num cpus */
++      pow = roundup_pow_of_two(num_online_cpus());
++      pf->rss_size_max = min_t(int, pf->rss_size_max, pow);
++
+       if (pf->hw.func_caps.rss) {
+               pf->flags |= I40E_FLAG_RSS_ENABLED;
+               pf->alloc_rss_size = min_t(int, pf->rss_size_max,
+diff --git a/drivers/net/ethernet/realtek/r8169_main.c 
b/drivers/net/ethernet/realtek/r8169_main.c
+index bd8decc54b871..8ff178fc2670c 100644
+--- a/drivers/net/ethernet/realtek/r8169_main.c
++++ b/drivers/net/ethernet/realtek/r8169_main.c
+@@ -742,12 +742,6 @@ static void rtl_unlock_config_regs(struct rtl8169_private 
*tp)
+       RTL_W8(tp, Cfg9346, Cfg9346_Unlock);
+ }
+ 
+-static void rtl_tx_performance_tweak(struct rtl8169_private *tp, u16 force)
+-{
+-      pcie_capability_clear_and_set_word(tp->pci_dev, PCI_EXP_DEVCTL,
+-                                         PCI_EXP_DEVCTL_READRQ, force);
+-}
+-
+ static bool rtl_is_8125(struct rtl8169_private *tp)
+ {
+       return tp->mac_version >= RTL_GIGA_MAC_VER_60;
+@@ -4057,14 +4051,12 @@ static void r8168c_hw_jumbo_enable(struct 
rtl8169_private *tp)
+ {
+       RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
+       RTL_W8(tp, Config4, RTL_R8(tp, Config4) | Jumbo_En1);
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_512B);
+ }
+ 
+ static void r8168c_hw_jumbo_disable(struct rtl8169_private *tp)
+ {
+       RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
+       RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~Jumbo_En1);
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+ }
+ 
+ static void r8168dp_hw_jumbo_enable(struct rtl8169_private *tp)
+@@ -4082,7 +4074,6 @@ static void r8168e_hw_jumbo_enable(struct 
rtl8169_private *tp)
+       RTL_W8(tp, MaxTxPacketSize, 0x24);
+       RTL_W8(tp, Config3, RTL_R8(tp, Config3) | Jumbo_En0);
+       RTL_W8(tp, Config4, RTL_R8(tp, Config4) | 0x01);
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_512B);
+ }
+ 
+ static void r8168e_hw_jumbo_disable(struct rtl8169_private *tp)
+@@ -4090,93 +4081,70 @@ static void r8168e_hw_jumbo_disable(struct 
rtl8169_private *tp)
+       RTL_W8(tp, MaxTxPacketSize, 0x3f);
+       RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Jumbo_En0);
+       RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~0x01);
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-}
+-
+-static void r8168b_0_hw_jumbo_enable(struct rtl8169_private *tp)
+-{
+-      rtl_tx_performance_tweak(tp,
+-              PCI_EXP_DEVCTL_READRQ_512B | PCI_EXP_DEVCTL_NOSNOOP_EN);
+-}
+-
+-static void r8168b_0_hw_jumbo_disable(struct rtl8169_private *tp)
+-{
+-      rtl_tx_performance_tweak(tp,
+-              PCI_EXP_DEVCTL_READRQ_4096B | PCI_EXP_DEVCTL_NOSNOOP_EN);
+ }
+ 
+ static void r8168b_1_hw_jumbo_enable(struct rtl8169_private *tp)
+ {
+-      r8168b_0_hw_jumbo_enable(tp);
+-
+       RTL_W8(tp, Config4, RTL_R8(tp, Config4) | (1 << 0));
+ }
+ 
+ static void r8168b_1_hw_jumbo_disable(struct rtl8169_private *tp)
+ {
+-      r8168b_0_hw_jumbo_disable(tp);
+-
+       RTL_W8(tp, Config4, RTL_R8(tp, Config4) & ~(1 << 0));
+ }
+ 
+-static void rtl_hw_jumbo_enable(struct rtl8169_private *tp)
++static void rtl_jumbo_config(struct rtl8169_private *tp)
+ {
+-      rtl_unlock_config_regs(tp);
+-      switch (tp->mac_version) {
+-      case RTL_GIGA_MAC_VER_11:
+-              r8168b_0_hw_jumbo_enable(tp);
+-              break;
+-      case RTL_GIGA_MAC_VER_12:
+-      case RTL_GIGA_MAC_VER_17:
+-              r8168b_1_hw_jumbo_enable(tp);
+-              break;
+-      case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26:
+-              r8168c_hw_jumbo_enable(tp);
+-              break;
+-      case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28:
+-              r8168dp_hw_jumbo_enable(tp);
+-              break;
+-      case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33:
+-              r8168e_hw_jumbo_enable(tp);
+-              break;
+-      default:
+-              break;
+-      }
+-      rtl_lock_config_regs(tp);
+-}
++      bool jumbo = tp->dev->mtu > ETH_DATA_LEN;
++      int readrq = 4096;
+ 
+-static void rtl_hw_jumbo_disable(struct rtl8169_private *tp)
+-{
+       rtl_unlock_config_regs(tp);
+       switch (tp->mac_version) {
+-      case RTL_GIGA_MAC_VER_11:
+-              r8168b_0_hw_jumbo_disable(tp);
+-              break;
+       case RTL_GIGA_MAC_VER_12:
+       case RTL_GIGA_MAC_VER_17:
+-              r8168b_1_hw_jumbo_disable(tp);
++              if (jumbo) {
++                      readrq = 512;
++                      r8168b_1_hw_jumbo_enable(tp);
++              } else {
++                      r8168b_1_hw_jumbo_disable(tp);
++              }
+               break;
+       case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26:
+-              r8168c_hw_jumbo_disable(tp);
++              if (jumbo) {
++                      readrq = 512;
++                      r8168c_hw_jumbo_enable(tp);
++              } else {
++                      r8168c_hw_jumbo_disable(tp);
++              }
+               break;
+       case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28:
+-              r8168dp_hw_jumbo_disable(tp);
++              if (jumbo)
++                      r8168dp_hw_jumbo_enable(tp);
++              else
++                      r8168dp_hw_jumbo_disable(tp);
+               break;
+       case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33:
+-              r8168e_hw_jumbo_disable(tp);
++              if (jumbo) {
++                      pcie_set_readrq(tp->pci_dev, 512);
++                      r8168e_hw_jumbo_enable(tp);
++              } else {
++                      r8168e_hw_jumbo_disable(tp);
++              }
+               break;
+       default:
+               break;
+       }
+       rtl_lock_config_regs(tp);
+-}
+ 
+-static void rtl_jumbo_config(struct rtl8169_private *tp, int mtu)
+-{
+-      if (mtu > ETH_DATA_LEN)
+-              rtl_hw_jumbo_enable(tp);
+-      else
+-              rtl_hw_jumbo_disable(tp);
++      if (pci_is_pcie(tp->pci_dev) && tp->supports_gmii)
++              pcie_set_readrq(tp->pci_dev, readrq);
++
++      /* Chip doesn't support pause in jumbo mode */
++      linkmode_mod_bit(ETHTOOL_LINK_MODE_Pause_BIT,
++                       tp->phydev->advertising, !jumbo);
++      linkmode_mod_bit(ETHTOOL_LINK_MODE_Asym_Pause_BIT,
++                       tp->phydev->advertising, !jumbo);
++      phy_start_aneg(tp->phydev);
+ }
+ 
+ DECLARE_RTL_COND(rtl_chipcmd_cond)
+@@ -4575,18 +4543,12 @@ static void rtl_hw_start_8168d(struct rtl8169_private 
*tp)
+       rtl_set_def_aspm_entry_latency(tp);
+ 
+       rtl_disable_clock_request(tp);
+-
+-      if (tp->dev->mtu <= ETH_DATA_LEN)
+-              rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+ }
+ 
+ static void rtl_hw_start_8168dp(struct rtl8169_private *tp)
+ {
+       rtl_set_def_aspm_entry_latency(tp);
+ 
+-      if (tp->dev->mtu <= ETH_DATA_LEN)
+-              rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       rtl_disable_clock_request(tp);
+ }
+ 
+@@ -4601,8 +4563,6 @@ static void rtl_hw_start_8168d_4(struct rtl8169_private 
*tp)
+ 
+       rtl_set_def_aspm_entry_latency(tp);
+ 
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       rtl_ephy_init(tp, e_info_8168d_4);
+ 
+       rtl_enable_clock_request(tp);
+@@ -4677,8 +4637,6 @@ static void rtl_hw_start_8168f(struct rtl8169_private 
*tp)
+ {
+       rtl_set_def_aspm_entry_latency(tp);
+ 
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
+       rtl_eri_write(tp, 0xb8, ERIAR_MASK_0011, 0x0000);
+       rtl_set_fifo_size(tp, 0x10, 0x10, 0x02, 0x06);
+@@ -4741,8 +4699,6 @@ static void rtl_hw_start_8168g(struct rtl8169_private 
*tp)
+ 
+       rtl_set_def_aspm_entry_latency(tp);
+ 
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       rtl_reset_packet_filter(tp);
+       rtl_eri_write(tp, 0x2f8, ERIAR_MASK_0011, 0x1d8f);
+ 
+@@ -4979,8 +4935,6 @@ static void rtl_hw_start_8168h_1(struct rtl8169_private 
*tp)
+ 
+       rtl_set_def_aspm_entry_latency(tp);
+ 
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       rtl_reset_packet_filter(tp);
+ 
+       rtl_eri_set_bits(tp, 0xdc, ERIAR_MASK_1111, BIT(4));
+@@ -5038,8 +4992,6 @@ static void rtl_hw_start_8168ep(struct rtl8169_private 
*tp)
+ 
+       rtl_set_def_aspm_entry_latency(tp);
+ 
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       rtl_reset_packet_filter(tp);
+ 
+       rtl_eri_set_bits(tp, 0xd4, ERIAR_MASK_1111, 0x1f80);
+@@ -5142,8 +5094,6 @@ static void rtl_hw_start_8102e_1(struct rtl8169_private 
*tp)
+ 
+       RTL_W8(tp, DBG_REG, FIX_NAK_1);
+ 
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       RTL_W8(tp, Config1,
+              LEDS1 | LEDS0 | Speed_down | MEMMAP | IOMAP | VPD | PMEnable);
+       RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
+@@ -5159,8 +5109,6 @@ static void rtl_hw_start_8102e_2(struct rtl8169_private 
*tp)
+ {
+       rtl_set_def_aspm_entry_latency(tp);
+ 
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       RTL_W8(tp, Config1, MEMMAP | IOMAP | VPD | PMEnable);
+       RTL_W8(tp, Config3, RTL_R8(tp, Config3) & ~Beacon_en);
+ }
+@@ -5221,8 +5169,6 @@ static void rtl_hw_start_8402(struct rtl8169_private *tp)
+ 
+       rtl_ephy_init(tp, e_info_8402);
+ 
+-      rtl_tx_performance_tweak(tp, PCI_EXP_DEVCTL_READRQ_4096B);
+-
+       rtl_set_fifo_size(tp, 0x00, 0x00, 0x02, 0x06);
+       rtl_reset_packet_filter(tp);
+       rtl_eri_write(tp, 0xc0, ERIAR_MASK_0011, 0x0000);
+@@ -5438,10 +5384,18 @@ static void rtl_hw_start_8125(struct rtl8169_private 
*tp)
+ 
+ static void rtl_hw_start_8168(struct rtl8169_private *tp)
+ {
+-      if (tp->mac_version == RTL_GIGA_MAC_VER_13 ||
+-          tp->mac_version == RTL_GIGA_MAC_VER_16)
++      switch (tp->mac_version) {
++      case RTL_GIGA_MAC_VER_11:
++      case RTL_GIGA_MAC_VER_12:
++      case RTL_GIGA_MAC_VER_13:
++      case RTL_GIGA_MAC_VER_16:
++      case RTL_GIGA_MAC_VER_17:
+               pcie_capability_set_word(tp->pci_dev, PCI_EXP_DEVCTL,
+                                        PCI_EXP_DEVCTL_NOSNOOP_EN);
++              break;
++      default:
++              break;
++      }
+ 
+       if (rtl_is_8168evl_up(tp))
+               RTL_W8(tp, MaxTxPacketSize, EarlySize);
+@@ -5498,7 +5452,7 @@ static void rtl_hw_start(struct  rtl8169_private *tp)
+       rtl_set_rx_tx_desc_registers(tp);
+       rtl_lock_config_regs(tp);
+ 
+-      rtl_jumbo_config(tp, tp->dev->mtu);
++      rtl_jumbo_config(tp);
+ 
+       /* Initially a 10 us delay. Turned it into a PCI commit. - FR */
+       RTL_R16(tp, CPlusCmd);
+@@ -5513,10 +5467,9 @@ static int rtl8169_change_mtu(struct net_device *dev, 
int new_mtu)
+ {
+       struct rtl8169_private *tp = netdev_priv(dev);
+ 
+-      rtl_jumbo_config(tp, new_mtu);
+-
+       dev->mtu = new_mtu;
+       netdev_update_features(dev);
++      rtl_jumbo_config(tp);
+ 
+       /* Reportedly at least Asus X453MA truncates packets otherwise */
+       if (tp->mac_version == RTL_GIGA_MAC_VER_37)
+@@ -6368,8 +6321,6 @@ static int r8169_phy_connect(struct rtl8169_private *tp)
+       if (!tp->supports_gmii)
+               phy_set_max_speed(phydev, SPEED_100);
+ 
+-      phy_support_asym_pause(phydev);
+-
+       phy_attached_info(phydev);
+ 
+       return 0;
+diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
+index 91cf1d1672637..9dbe625ad4477 100644
+--- a/drivers/net/phy/marvell.c
++++ b/drivers/net/phy/marvell.c
+@@ -2401,9 +2401,31 @@ static struct phy_driver marvell_drivers[] = {
+               .get_stats = marvell_get_stats,
+       },
+       {
+-              .phy_id = MARVELL_PHY_ID_88E6390,
++              .phy_id = MARVELL_PHY_ID_88E6341_FAMILY,
+               .phy_id_mask = MARVELL_PHY_ID_MASK,
+-              .name = "Marvell 88E6390",
++              .name = "Marvell 88E6341 Family",
++              /* PHY_GBIT_FEATURES */
++              .probe = m88e1510_probe,
++              .config_init = &marvell_config_init,
++              .config_aneg = &m88e6390_config_aneg,
++              .read_status = &marvell_read_status,
++              .ack_interrupt = &marvell_ack_interrupt,
++              .config_intr = &marvell_config_intr,
++              .did_interrupt = &m88e1121_did_interrupt,
++              .resume = &genphy_resume,
++              .suspend = &genphy_suspend,
++              .read_page = marvell_read_page,
++              .write_page = marvell_write_page,
++              .get_sset_count = marvell_get_sset_count,
++              .get_strings = marvell_get_strings,
++              .get_stats = marvell_get_stats,
++              .get_tunable = m88e1540_get_tunable,
++              .set_tunable = m88e1540_set_tunable,
++      },
++      {
++              .phy_id = MARVELL_PHY_ID_88E6390_FAMILY,
++              .phy_id_mask = MARVELL_PHY_ID_MASK,
++              .name = "Marvell 88E6390 Family",
+               /* PHY_GBIT_FEATURES */
+               .probe = m88e6390_probe,
+               .config_init = &marvell_config_init,
+@@ -2441,7 +2463,8 @@ static struct mdio_device_id __maybe_unused 
marvell_tbl[] = {
+       { MARVELL_PHY_ID_88E1540, MARVELL_PHY_ID_MASK },
+       { MARVELL_PHY_ID_88E1545, MARVELL_PHY_ID_MASK },
+       { MARVELL_PHY_ID_88E3016, MARVELL_PHY_ID_MASK },
+-      { MARVELL_PHY_ID_88E6390, MARVELL_PHY_ID_MASK },
++      { MARVELL_PHY_ID_88E6341_FAMILY, MARVELL_PHY_ID_MASK },
++      { MARVELL_PHY_ID_88E6390_FAMILY, MARVELL_PHY_ID_MASK },
+       { }
+ };
+ 
+diff --git a/drivers/net/wireless/virt_wifi.c 
b/drivers/net/wireless/virt_wifi.c
+index 01305ba2d3aac..9d04ca53229b5 100644
+--- a/drivers/net/wireless/virt_wifi.c
++++ b/drivers/net/wireless/virt_wifi.c
+@@ -12,6 +12,7 @@
+ #include <net/cfg80211.h>
+ #include <net/rtnetlink.h>
+ #include <linux/etherdevice.h>
++#include <linux/math64.h>
+ #include <linux/module.h>
+ 
+ static struct wiphy *common_wiphy;
+@@ -168,11 +169,11 @@ static void virt_wifi_scan_result(struct work_struct 
*work)
+                            scan_result.work);
+       struct wiphy *wiphy = priv_to_wiphy(priv);
+       struct cfg80211_scan_info scan_info = { .aborted = false };
++      u64 tsf = div_u64(ktime_get_boottime_ns(), 1000);
+ 
+       informed_bss = cfg80211_inform_bss(wiphy, &channel_5ghz,
+                                          CFG80211_BSS_FTYPE_PRESP,
+-                                         fake_router_bssid,
+-                                         ktime_get_boottime_ns(),
++                                         fake_router_bssid, tsf,
+                                          WLAN_CAPABILITY_ESS, 0,
+                                          (void *)&ssid, sizeof(ssid),
+                                          DBM_TO_MBM(-50), GFP_KERNEL);
+diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c
+index ef423ba1a7116..b8236a9e8750d 100644
+--- a/drivers/nvdimm/region_devs.c
++++ b/drivers/nvdimm/region_devs.c
+@@ -1142,6 +1142,11 @@ int nvdimm_has_flush(struct nd_region *nd_region)
+                       || !IS_ENABLED(CONFIG_ARCH_HAS_PMEM_API))
+               return -ENXIO;
+ 
++      /* Test if an explicit flush function is defined */
++      if (test_bit(ND_REGION_ASYNC, &nd_region->flags) && nd_region->flush)
++              return 1;
++
++      /* Test if any flush hints for the region are available */
+       for (i = 0; i < nd_region->ndr_mappings; i++) {
+               struct nd_mapping *nd_mapping = &nd_region->mapping[i];
+               struct nvdimm *nvdimm = nd_mapping->nvdimm;
+@@ -1152,8 +1157,8 @@ int nvdimm_has_flush(struct nd_region *nd_region)
+       }
+ 
+       /*
+-       * The platform defines dimm devices without hints, assume
+-       * platform persistence mechanism like ADR
++       * The platform defines dimm devices without hints nor explicit flush,
++       * assume platform persistence mechanism like ADR
+        */
+       return 0;
+ }
+diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
+index dd755a56cf521..5d28bb7f2ca40 100644
+--- a/drivers/scsi/libsas/sas_ata.c
++++ b/drivers/scsi/libsas/sas_ata.c
+@@ -200,18 +200,17 @@ static unsigned int sas_ata_qc_issue(struct 
ata_queued_cmd *qc)
+               memcpy(task->ata_task.atapi_packet, qc->cdb, qc->dev->cdb_len);
+               task->total_xfer_len = qc->nbytes;
+               task->num_scatter = qc->n_elem;
++              task->data_dir = qc->dma_dir;
++      } else if (qc->tf.protocol == ATA_PROT_NODATA) {
++              task->data_dir = DMA_NONE;
+       } else {
+               for_each_sg(qc->sg, sg, qc->n_elem, si)
+                       xfer += sg_dma_len(sg);
+ 
+               task->total_xfer_len = xfer;
+               task->num_scatter = si;
+-      }
+-
+-      if (qc->tf.protocol == ATA_PROT_NODATA)
+-              task->data_dir = DMA_NONE;
+-      else
+               task->data_dir = qc->dma_dir;
++      }
+       task->scatter = qc->sg;
+       task->ata_task.retry_count = 1;
+       task->task_state_flags = SAS_TASK_STATE_PENDING;
+diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c
+index 7bbff91f8883e..88a56e8480f71 100644
+--- a/drivers/scsi/qla2xxx/qla_dbg.c
++++ b/drivers/scsi/qla2xxx/qla_dbg.c
+@@ -18,7 +18,7 @@
+  * | Device Discovery             |       0x2134       | 0x210e-0x2116  |
+  * |                            |                    | 0x211a         |
+  * |                              |                    | 0x211c-0x2128  |
+- * |                              |                    | 0x212a-0x2130  |
++ * |                              |                    | 0x212a-0x2134  |
+  * | Queue Command and IO tracing |       0x3074       | 0x300b         |
+  * |                              |                    | 0x3027-0x3028  |
+  * |                              |                    | 0x303d-0x3041  |
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index c57b95a206888..7c22f8eea3ead 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2281,7 +2281,7 @@ typedef struct {
+       uint8_t fabric_port_name[WWN_SIZE];
+       uint16_t fp_speed;
+       uint8_t fc4_type;
+-      uint8_t fc4f_nvme;      /* nvme fc4 feature bits */
++      uint8_t fc4_features;
+ } sw_info_t;
+ 
+ /* FCP-4 types */
+@@ -2452,7 +2452,7 @@ typedef struct fc_port {
+       u32 supported_classes;
+ 
+       uint8_t fc4_type;
+-      uint8_t fc4f_nvme;
++      uint8_t fc4_features;
+       uint8_t scan_state;
+ 
+       unsigned long last_queue_full;
+@@ -2466,6 +2466,7 @@ typedef struct fc_port {
+       struct qla_tgt_sess *tgt_session;
+       struct ct_sns_desc ct_desc;
+       enum discovery_state disc_state;
++      atomic_t shadow_disc_state;
+       enum discovery_state next_disc_state;
+       enum login_state fw_login_state;
+       unsigned long dm_login_expire;
+@@ -2483,6 +2484,9 @@ typedef struct fc_port {
+       u16 n2n_chip_reset;
+ } fc_port_t;
+ 
++#define FC4_PRIORITY_NVME     0
++#define FC4_PRIORITY_FCP      1
++
+ #define QLA_FCPORT_SCAN               1
+ #define QLA_FCPORT_FOUND      2
+ 
+@@ -2507,6 +2511,19 @@ struct event_arg {
+ 
+ extern const char *const port_state_str[5];
+ 
++static const char * const port_dstate_str[] = {
++      "DELETED",
++      "GNN_ID",
++      "GNL",
++      "LOGIN_PEND",
++      "LOGIN_FAILED",
++      "GPDB",
++      "UPD_FCPORT",
++      "LOGIN_COMPLETE",
++      "ADISC",
++      "DELETE_PEND"
++};
++
+ /*
+  * FC port flags.
+  */
+@@ -4298,6 +4315,8 @@ struct qla_hw_data {
+       atomic_t        nvme_active_aen_cnt;
+       uint16_t        nvme_last_rptd_aen;             /* Last recorded aen 
count */
+ 
++      uint8_t fc4_type_priority;
++
+       atomic_t zio_threshold;
+       uint16_t last_zio_threshold;
+ 
+@@ -4823,6 +4842,23 @@ struct sff_8247_a0 {
+        ha->current_topology == ISP_CFG_N || \
+        !ha->current_topology)
+ 
++#define NVME_TYPE(fcport) \
++      (fcport->fc4_type & FS_FC4TYPE_NVME) \
++
++#define FCP_TYPE(fcport) \
++      (fcport->fc4_type & FS_FC4TYPE_FCP) \
++
++#define NVME_ONLY_TARGET(fcport) \
++      (NVME_TYPE(fcport) && !FCP_TYPE(fcport))  \
++
++#define NVME_FCP_TARGET(fcport) \
++      (FCP_TYPE(fcport) && NVME_TYPE(fcport)) \
++
++#define NVME_TARGET(ha, fcport) \
++      ((NVME_FCP_TARGET(fcport) && \
++      (ha->fc4_type_priority == FC4_PRIORITY_NVME)) || \
++      NVME_ONLY_TARGET(fcport)) \
++
+ #define PRLI_PHASE(_cls) \
+       ((_cls == DSC_LS_PRLI_PEND) || (_cls == DSC_LS_PRLI_COMP))
+ 
+diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h
+index dc2366a296654..9dc09c1174169 100644
+--- a/drivers/scsi/qla2xxx/qla_fw.h
++++ b/drivers/scsi/qla2xxx/qla_fw.h
+@@ -2105,4 +2105,6 @@ struct qla_fcp_prio_cfg {
+ #define FA_FLASH_LAYOUT_ADDR_83       (0x3F1000/4)
+ #define FA_FLASH_LAYOUT_ADDR_28       (0x11000/4)
+ 
++#define NVRAM_DUAL_FCP_NVME_FLAG_OFFSET       0x196
++
+ #endif
+diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h
+index d11416dcee4ef..7aa233771ec86 100644
+--- a/drivers/scsi/qla2xxx/qla_gbl.h
++++ b/drivers/scsi/qla2xxx/qla_gbl.h
+@@ -80,6 +80,7 @@ extern int qla24xx_async_gnl(struct scsi_qla_host *, 
fc_port_t *);
+ int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e);
+ extern void *qla2x00_alloc_iocbs_ready(struct qla_qpair *, srb_t *);
+ extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
++extern int qla24xx_async_abort_cmd(srb_t *, bool);
+ 
+ extern void qla2x00_set_fcport_state(fc_port_t *fcport, int state);
+ extern fc_port_t *
+@@ -255,6 +256,7 @@ extern char *qla2x00_get_fw_version_str(struct 
scsi_qla_host *, char *);
+ 
+ extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, 
int);
+ extern void qla2x00_mark_all_devices_lost(scsi_qla_host_t *, int);
++extern int qla24xx_async_abort_cmd(srb_t *, bool);
+ 
+ extern struct fw_blob *qla2x00_request_firmware(scsi_qla_host_t *);
+ 
+@@ -917,4 +919,5 @@ int qla2x00_set_data_rate(scsi_qla_host_t *vha, uint16_t 
mode);
+ 
+ /* nvme.c */
+ void qla_nvme_unregister_remote_port(struct fc_port *fcport);
++void qla_handle_els_plogi_done(scsi_qla_host_t *vha, struct event_arg *ea);
+ #endif /* _QLA_GBL_H */
+diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c
+index fc6e12fb7d77b..d9b5ea77fde99 100644
+--- a/drivers/scsi/qla2xxx/qla_gs.c
++++ b/drivers/scsi/qla2xxx/qla_gs.c
+@@ -248,7 +248,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
+                   WWN_SIZE);
+ 
+               fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ?
+-                  FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER;
++                  FS_FC4TYPE_FCP : FC4_TYPE_OTHER;
+ 
+               if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
+                   ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
+@@ -2887,7 +2887,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
+       struct ct_sns_req       *ct_req;
+       struct ct_sns_rsp       *ct_rsp;
+       struct qla_hw_data *ha = vha->hw;
+-      uint8_t fcp_scsi_features = 0;
++      uint8_t fcp_scsi_features = 0, nvme_features = 0;
+       struct ct_arg arg;
+ 
+       for (i = 0; i < ha->max_fibre_devices; i++) {
+@@ -2933,14 +2933,19 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
+                          ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
+                       fcp_scsi_features &= 0x0f;
+ 
+-                      if (fcp_scsi_features)
+-                              list[i].fc4_type = FC4_TYPE_FCP_SCSI;
+-                      else
+-                              list[i].fc4_type = FC4_TYPE_OTHER;
++                      if (fcp_scsi_features) {
++                              list[i].fc4_type = FS_FC4TYPE_FCP;
++                              list[i].fc4_features = fcp_scsi_features;
++                      }
+ 
+-                      list[i].fc4f_nvme =
++                      nvme_features =
+                           ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
+-                      list[i].fc4f_nvme &= 0xf;
++                      nvme_features &= 0xf;
++
++                      if (nvme_features) {
++                              list[i].fc4_type |= FS_FC4TYPE_NVME;
++                              list[i].fc4_features = nvme_features;
++                      }
+               }
+ 
+               /* Last device exit. */
+@@ -3435,6 +3440,8 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
+       fc_port_t *fcport = sp->fcport;
+       struct ct_sns_rsp *ct_rsp;
+       struct event_arg ea;
++      uint8_t fc4_scsi_feat;
++      uint8_t fc4_nvme_feat;
+ 
+       ql_dbg(ql_dbg_disc, vha, 0x2133,
+              "Async done-%s res %x ID %x. %8phC\n",
+@@ -3442,24 +3449,25 @@ void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
+ 
+       fcport->flags &= ~FCF_ASYNC_SENT;
+       ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
++      fc4_scsi_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
++      fc4_nvme_feat = ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
++
+       /*
+        * FC-GS-7, 5.2.3.12 FC-4 Features - format
+        * The format of the FC-4 Features object, as defined by the FC-4,
+        * Shall be an array of 4-bit values, one for each type code value
+        */
+       if (!res) {
+-              if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) 
{
++              if (fc4_scsi_feat & 0xf) {
+                       /* w1 b00:03 */
+-                      fcport->fc4_type =
+-                          
ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
+-                      fcport->fc4_type &= 0xf;
+-             }
++                      fcport->fc4_type = FS_FC4TYPE_FCP;
++                      fcport->fc4_features = fc4_scsi_feat & 0xf;
++              }
+ 
+-              if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
++              if (fc4_nvme_feat & 0xf) {
+                       /* w5 [00:03]/28h */
+-                      fcport->fc4f_nvme =
+-                          ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
+-                      fcport->fc4f_nvme &= 0xf;
++                      fcport->fc4_type |= FS_FC4TYPE_NVME;
++                      fcport->fc4_features = fc4_nvme_feat & 0xf;
+               }
+       }
+ 
+@@ -4282,7 +4290,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t 
*fcport)
+       if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
+               return rval;
+ 
+-      fcport->disc_state = DSC_GNN_ID;
++      qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID);
+       sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
+       if (!sp)
+               goto done;
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index b300e11095828..643b8ae36cbeb 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -50,16 +50,9 @@ qla2x00_sp_timeout(struct timer_list *t)
+ {
+       srb_t *sp = from_timer(sp, t, u.iocb_cmd.timer);
+       struct srb_iocb *iocb;
+-      struct req_que *req;
+-      unsigned long flags;
+-      struct qla_hw_data *ha = sp->vha->hw;
+ 
+-      WARN_ON_ONCE(irqs_disabled());
+-      spin_lock_irqsave(&ha->hardware_lock, flags);
+-      req = sp->qpair->req;
+-      req->outstanding_cmds[sp->handle] = NULL;
++      WARN_ON(irqs_disabled());
+       iocb = &sp->u.iocb_cmd;
+-      spin_unlock_irqrestore(&ha->hardware_lock, flags);
+       iocb->timeout(sp);
+ }
+ 
+@@ -153,7 +146,7 @@ static void qla24xx_abort_sp_done(srb_t *sp, int res)
+               sp->free(sp);
+ }
+ 
+-static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
++int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
+ {
+       scsi_qla_host_t *vha = cmd_sp->vha;
+       struct srb_iocb *abt_iocb;
+@@ -253,6 +246,7 @@ qla2x00_async_iocb_timeout(void *data)
+       case SRB_NACK_PRLI:
+       case SRB_NACK_LOGO:
+       case SRB_CTRL_VP:
++      default:
+               rc = qla24xx_async_abort_cmd(sp, false);
+               if (rc) {
+                       spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
+@@ -269,10 +263,6 @@ qla2x00_async_iocb_timeout(void *data)
+                       sp->done(sp, QLA_FUNCTION_TIMEOUT);
+               }
+               break;
+-      default:
+-              WARN_ON_ONCE(true);
+-              sp->done(sp, QLA_FUNCTION_TIMEOUT);
+-              break;
+       }
+ }
+ 
+@@ -337,10 +327,10 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t 
*fcport,
+       if (!sp)
+               goto done;
+ 
++      qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
+       fcport->flags |= FCF_ASYNC_SENT;
+       fcport->logout_completed = 0;
+ 
+-      fcport->disc_state = DSC_LOGIN_PEND;
+       sp->type = SRB_LOGIN_CMD;
+       sp->name = "login";
+       sp->gen1 = fcport->rscn_gen;
+@@ -356,7 +346,7 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t 
*fcport,
+       else
+               lio->u.logio.flags |= SRB_LOGIN_COND_PLOGI;
+ 
+-      if (fcport->fc4f_nvme)
++      if (NVME_TARGET(vha->hw, fcport))
+               lio->u.logio.flags |= SRB_LOGIN_SKIP_PRLI;
+ 
+       ql_dbg(ql_dbg_disc, vha, 0x2072,
+@@ -544,7 +534,7 @@ static int qla_post_els_plogi_work(struct scsi_qla_host 
*vha, fc_port_t *fcport)
+ 
+       e->u.fcport.fcport = fcport;
+       fcport->flags |= FCF_ASYNC_ACTIVE;
+-      fcport->disc_state = DSC_LOGIN_PEND;
++      qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
+       return qla2x00_post_work(vha, e);
+ }
+ 
+@@ -767,14 +757,12 @@ static void 
qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
+                       fcport->fc4_type &= ~FS_FC4TYPE_NVME;
+               }
+ 
+-
+               ql_dbg(ql_dbg_disc, vha, 0x20e2,
+-                  "%s found %8phC CLS [%x|%x] nvme %d 
ID[%02x%02x%02x|%02x%02x%02x] lid[%d|%d]\n",
++                  "%s found %8phC CLS [%x|%x] fc4_type %d ID[%06x|%06x] 
lid[%d|%d]\n",
+                   __func__, fcport->port_name,
+                   e->current_login_state, fcport->fw_login_state,
+-                  fcport->fc4f_nvme, id.b.domain, id.b.area, id.b.al_pa,
+-                  fcport->d_id.b.domain, fcport->d_id.b.area,
+-                  fcport->d_id.b.al_pa, loop_id, fcport->loop_id);
++                  fcport->fc4_type, id.b24, fcport->d_id.b24,
++                  loop_id, fcport->loop_id);
+ 
+               switch (fcport->disc_state) {
+               case DSC_DELETE_PEND:
+@@ -856,7 +844,8 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t 
*vha,
+                                * with GNL. Push disc_state back to DELETED
+                                * so GNL can go out again
+                                */
+-                              fcport->disc_state = DSC_DELETED;
++                              qla2x00_set_fcport_disc_state(fcport,
++                                  DSC_DELETED);
+                               break;
+                       case DSC_LS_PRLI_COMP:
+                               if ((e->prli_svc_param_word_3[0] & BIT_4) == 0)
+@@ -932,7 +921,7 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t 
*vha,
+                       qla24xx_fcport_handle_login(vha, fcport);
+                       break;
+               case ISP_CFG_N:
+-                      fcport->disc_state = DSC_DELETED;
++                      qla2x00_set_fcport_disc_state(fcport, DSC_DELETED);
+                       if (time_after_eq(jiffies, fcport->dm_login_expire)) {
+                               if (fcport->n2n_link_reset_cnt < 2) {
+                                       fcport->n2n_link_reset_cnt++;
+@@ -1102,7 +1091,7 @@ int qla24xx_async_gnl(struct scsi_qla_host *vha, 
fc_port_t *fcport)
+ 
+       spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
+       fcport->flags |= FCF_ASYNC_SENT;
+-      fcport->disc_state = DSC_GNL;
++      qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
+       fcport->last_rscn_gen = fcport->rscn_gen;
+       fcport->last_login_gen = fcport->login_gen;
+ 
+@@ -1277,13 +1266,13 @@ qla24xx_async_prli(struct scsi_qla_host *vha, 
fc_port_t *fcport)
+       sp->done = qla2x00_async_prli_sp_done;
+       lio->u.logio.flags = 0;
+ 
+-      if  (fcport->fc4f_nvme)
++      if (NVME_TARGET(vha->hw, fcport))
+               lio->u.logio.flags |= SRB_LOGIN_NVME_PRLI;
+ 
+       ql_dbg(ql_dbg_disc, vha, 0x211b,
+           "Async-prli - %8phC hdl=%x, loopid=%x portid=%06x retries=%d %s.\n",
+           fcport->port_name, sp->handle, fcport->loop_id, fcport->d_id.b24,
+-          fcport->login_retry, fcport->fc4f_nvme ? "nvme" : "fc");
++          fcport->login_retry, NVME_TARGET(vha->hw, fcport) ? "nvme" : "fc");
+ 
+       rval = qla2x00_start_sp(sp);
+       if (rval != QLA_SUCCESS) {
+@@ -1332,12 +1321,12 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, 
fc_port_t *fcport, u8 opt)
+               return rval;
+       }
+ 
+-      fcport->disc_state = DSC_GPDB;
+-
+       sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
+       if (!sp)
+               goto done;
+ 
++      qla2x00_set_fcport_disc_state(fcport, DSC_GPDB);
++
+       fcport->flags |= FCF_ASYNC_SENT;
+       sp->type = SRB_MB_IOCB;
+       sp->name = "gpdb";
+@@ -1416,7 +1405,7 @@ void __qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
+               ql_dbg(ql_dbg_disc, vha, 0x20d6,
+                   "%s %d %8phC session revalidate success\n",
+                   __func__, __LINE__, ea->fcport->port_name);
+-              ea->fcport->disc_state = DSC_LOGIN_COMPLETE;
++              qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_COMPLETE);
+       }
+       spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
+ }
+@@ -1434,14 +1423,14 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
+       fcport->flags &= ~FCF_ASYNC_SENT;
+ 
+       ql_dbg(ql_dbg_disc, vha, 0x20d2,
+-          "%s %8phC DS %d LS %d nvme %x rc %d\n", __func__, fcport->port_name,
+-          fcport->disc_state, pd->current_login_state, fcport->fc4f_nvme,
+-          ea->rc);
++          "%s %8phC DS %d LS %d fc4_type %x rc %d\n", __func__,
++          fcport->port_name, fcport->disc_state, pd->current_login_state,
++          fcport->fc4_type, ea->rc);
+ 
+       if (fcport->disc_state == DSC_DELETE_PEND)
+               return;
+ 
+-      if (fcport->fc4f_nvme)
++      if (NVME_TARGET(vha->hw, fcport))
+               ls = pd->current_login_state >> 4;
+       else
+               ls = pd->current_login_state & 0xf;
+@@ -1470,7 +1459,7 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, 
struct event_arg *ea)
+               /* Set discovery state back to GNL to Relogin attempt */
+               if (qla_dual_mode_enabled(vha) ||
+                   qla_ini_mode_enabled(vha)) {
+-                      fcport->disc_state = DSC_GNL;
++                      qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
+                       set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+               }
+               return;
+@@ -1630,7 +1619,8 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host 
*vha, fc_port_t *fcport)
+                               ql_dbg(ql_dbg_disc, vha, 0x2118,
+                                   "%s %d %8phC post %s PRLI\n",
+                                   __func__, __LINE__, fcport->port_name,
+-                                  fcport->fc4f_nvme ? "NVME" : "FC");
++                                  NVME_TARGET(vha->hw, fcport) ? "NVME" :
++                                  "FC");
+                               qla24xx_post_prli_work(vha, fcport);
+                       }
+                       break;
+@@ -1757,6 +1747,15 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
+       qla24xx_fcport_handle_login(vha, fcport);
+ }
+ 
++void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
++                                    struct event_arg *ea)
++{
++      ql_dbg(ql_dbg_disc, vha, 0x2118,
++          "%s %d %8phC post PRLI\n",
++          __func__, __LINE__, ea->fcport->port_name);
++      qla24xx_post_prli_work(vha, ea->fcport);
++}
++
+ /*
+  * RSCN(s) came in for this fcport, but the RSCN(s) was not able
+  * to be consumed by the fcport
+@@ -1785,9 +1784,23 @@ qla2x00_tmf_iocb_timeout(void *data)
+ {
+       srb_t *sp = data;
+       struct srb_iocb *tmf = &sp->u.iocb_cmd;
++      int rc, h;
++      unsigned long flags;
+ 
+-      tmf->u.tmf.comp_status = CS_TIMEOUT;
+-      complete(&tmf->u.tmf.comp);
++      rc = qla24xx_async_abort_cmd(sp, false);
++      if (rc) {
++              spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
++              for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
++                      if (sp->qpair->req->outstanding_cmds[h] == sp) {
++                              sp->qpair->req->outstanding_cmds[h] = NULL;
++                              break;
++                      }
++              }
++              spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
++              tmf->u.tmf.comp_status = CS_TIMEOUT;
++              tmf->u.tmf.data = QLA_FUNCTION_FAILED;
++              complete(&tmf->u.tmf.comp);
++      }
+ }
+ 
+ static void qla2x00_tmf_sp_done(srb_t *sp, int res)
+@@ -1916,12 +1929,20 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
+                       break;
+               }
+ 
+-              if (ea->fcport->fc4f_nvme) {
++              /*
++               * Retry PRLI with other FC-4 type if failure occurred on dual
++               * FCP/NVMe port
++               */
++              if (NVME_FCP_TARGET(ea->fcport)) {
+                       ql_dbg(ql_dbg_disc, vha, 0x2118,
+-                              "%s %d %8phC post fc4 prli\n",
+-                              __func__, __LINE__, ea->fcport->port_name);
+-                      ea->fcport->fc4f_nvme = 0;
+-                      return;
++                              "%s %d %8phC post %s prli\n",
++                              __func__, __LINE__, ea->fcport->port_name,
++                              (ea->fcport->fc4_type & FS_FC4TYPE_NVME) ?
++                              "NVMe" : "FCP");
++                      if (vha->hw->fc4_type_priority == FC4_PRIORITY_NVME)
++                              ea->fcport->fc4_type &= ~FS_FC4TYPE_NVME;
++                      else
++                              ea->fcport->fc4_type &= ~FS_FC4TYPE_FCP;
+               }
+ 
+               ea->fcport->flags &= ~FCF_ASYNC_SENT;
+@@ -1988,7 +2009,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
+                * force a relogin attempt via implicit LOGO, PLOGI, and PRLI
+                * requests.
+                */
+-              if (ea->fcport->fc4f_nvme) {
++              if (NVME_TARGET(vha->hw, ea->fcport)) {
+                       ql_dbg(ql_dbg_disc, vha, 0x2117,
+                               "%s %d %8phC post prli\n",
+                               __func__, __LINE__, ea->fcport->port_name);
+@@ -2015,7 +2036,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host 
*vha, struct event_arg *ea)
+                   __func__, __LINE__, ea->fcport->port_name, ea->data[1]);
+ 
+               ea->fcport->flags &= ~FCF_ASYNC_SENT;
+-              ea->fcport->disc_state = DSC_LOGIN_FAILED;
++              qla2x00_set_fcport_disc_state(ea->fcport, DSC_LOGIN_FAILED);
+               if (ea->data[1] & QLA_LOGIO_LOGIN_RETRIED)
+                       set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+               else
+@@ -5395,7 +5416,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t 
*fcport)
+       ql_dbg(ql_dbg_disc, vha, 0x20ef, "%s %8phC\n",
+           __func__, fcport->port_name);
+ 
+-      fcport->disc_state = DSC_UPD_FCPORT;
++      qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
+       fcport->login_retry = vha->hw->login_retry_count;
+       fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
+       fcport->deleted = 0;
+@@ -5413,9 +5434,9 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t 
*fcport)
+ 
+       qla2x00_iidma_fcport(vha, fcport);
+ 
+-      if (fcport->fc4f_nvme) {
++      if (NVME_TARGET(vha->hw, fcport)) {
+               qla_nvme_register_remote(vha, fcport);
+-              fcport->disc_state = DSC_LOGIN_COMPLETE;
++              qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
+               qla2x00_set_fcport_state(fcport, FCS_ONLINE);
+               return;
+       }
+@@ -5460,7 +5481,7 @@ qla2x00_update_fcport(scsi_qla_host_t *vha, fc_port_t 
*fcport)
+               }
+       }
+ 
+-      fcport->disc_state = DSC_LOGIN_COMPLETE;
++      qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
+ }
+ 
+ void qla_register_fcport_fn(struct work_struct *work)
+@@ -5741,11 +5762,8 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
+                               new_fcport->fc4_type = swl[swl_idx].fc4_type;
+ 
+                               new_fcport->nvme_flag = 0;
+-                              new_fcport->fc4f_nvme = 0;
+                               if (vha->flags.nvme_enabled &&
+-                                  swl[swl_idx].fc4f_nvme) {
+-                                      new_fcport->fc4f_nvme =
+-                                          swl[swl_idx].fc4f_nvme;
++                                  swl[swl_idx].fc4_type & FS_FC4TYPE_NVME) {
+                                       ql_log(ql_log_info, vha, 0x2131,
+                                           "FOUND: NVME port %8phC as FC Type 
28h\n",
+                                           new_fcport->port_name);
+@@ -5801,7 +5819,7 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
+ 
+               /* Bypass ports whose FCP-4 type is not FCP_SCSI */
+               if (ql2xgffidenable &&
+-                  (new_fcport->fc4_type != FC4_TYPE_FCP_SCSI &&
++                  (!(new_fcport->fc4_type & FS_FC4TYPE_FCP) &&
+                   new_fcport->fc4_type != FC4_TYPE_UNKNOWN))
+                       continue;
+ 
+@@ -5870,9 +5888,9 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *vha)
+                       break;
+               }
+ 
+-              if (fcport->fc4f_nvme) {
++              if (NVME_TARGET(vha->hw, fcport)) {
+                       if (fcport->disc_state == DSC_DELETE_PEND) {
+-                              fcport->disc_state = DSC_GNL;
++                              qla2x00_set_fcport_disc_state(fcport, DSC_GNL);
+                               vha->fcport_count--;
+                               fcport->login_succ = 0;
+                       }
+@@ -8545,6 +8563,11 @@ qla81xx_nvram_config(scsi_qla_host_t *vha)
+       /* N2N: driver will initiate Login instead of FW */
+       icb->firmware_options_3 |= BIT_8;
+ 
++      /* Determine NVMe/FCP priority for target ports */
++      ha->fc4_type_priority = qla2xxx_get_fc4_priority(vha);
++      ql_log(ql_log_info, vha, 0xffff, "FC4 priority set to %s\n",
++          ha->fc4_type_priority & BIT_0 ? "FCP" : "NVMe");
++
+       if (rval) {
+               ql_log(ql_log_warn, vha, 0x0076,
+                   "NVRAM configuration failed.\n");
+diff --git a/drivers/scsi/qla2xxx/qla_inline.h 
b/drivers/scsi/qla2xxx/qla_inline.h
+index 6dfde42d799b5..477b0b8a5f4bc 100644
+--- a/drivers/scsi/qla2xxx/qla_inline.h
++++ b/drivers/scsi/qla2xxx/qla_inline.h
+@@ -105,6 +105,30 @@ qla2x00_clean_dsd_pool(struct qla_hw_data *ha, struct 
crc_context *ctx)
+       INIT_LIST_HEAD(&ctx->dsd_list);
+ }
+ 
++static inline void
++qla2x00_set_fcport_disc_state(fc_port_t *fcport, int state)
++{
++      int old_val;
++      uint8_t shiftbits, mask;
++
++      /* This will have to change when the max no. of states > 16 */
++      shiftbits = 4;
++      mask = (1 << shiftbits) - 1;
++
++      fcport->disc_state = state;
++      while (1) {
++              old_val = atomic_read(&fcport->shadow_disc_state);
++              if (old_val == atomic_cmpxchg(&fcport->shadow_disc_state,
++                  old_val, (old_val << shiftbits) | state)) {
++                      ql_dbg(ql_dbg_disc, fcport->vha, 0x2134,
++                          "FCPort %8phC disc_state transition: %s to %s - 
portid=%06x.\n",
++                          fcport->port_name, port_dstate_str[old_val & mask],
++                          port_dstate_str[state], fcport->d_id.b24);
++                      return;
++              }
++      }
++}
++
+ static inline int
+ qla2x00_hba_err_chk_enabled(srb_t *sp)
+ {
+@@ -312,3 +336,15 @@ qla_83xx_start_iocbs(struct qla_qpair *qpair)
+ 
+       WRT_REG_DWORD(req->req_q_in, req->ring_index);
+ }
++
++static inline int
++qla2xxx_get_fc4_priority(struct scsi_qla_host *vha)
++{
++      uint32_t data;
++
++      data =
++          ((uint8_t *)vha->hw->nvram)[NVRAM_DUAL_FCP_NVME_FLAG_OFFSET];
++
++
++      return ((data >> 6) & BIT_0);
++}
+diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c
+index aed4ce66e6cf9..936103604d02d 100644
+--- a/drivers/scsi/qla2xxx/qla_iocb.c
++++ b/drivers/scsi/qla2xxx/qla_iocb.c
+@@ -2537,13 +2537,32 @@ qla2x00_els_dcmd_iocb_timeout(void *data)
+       fc_port_t *fcport = sp->fcport;
+       struct scsi_qla_host *vha = sp->vha;
+       struct srb_iocb *lio = &sp->u.iocb_cmd;
++      unsigned long flags = 0;
++      int res, h;
+ 
+       ql_dbg(ql_dbg_io, vha, 0x3069,
+           "%s Timeout, hdl=%x, portid=%02x%02x%02x\n",
+           sp->name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area,
+           fcport->d_id.b.al_pa);
+ 
+-      complete(&lio->u.els_logo.comp);
++      /* Abort the exchange */
++      res = qla24xx_async_abort_cmd(sp, false);
++      if (res) {
++              ql_dbg(ql_dbg_io, vha, 0x3070,
++                  "mbx abort_command failed.\n");
++              spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
++              for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
++                      if (sp->qpair->req->outstanding_cmds[h] == sp) {
++                              sp->qpair->req->outstanding_cmds[h] = NULL;
++                              break;
++                      }
++              }
++              spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
++              complete(&lio->u.els_logo.comp);
++      } else {
++              ql_dbg(ql_dbg_io, vha, 0x3071,
++                  "mbx abort_command success.\n");
++      }
+ }
+ 
+ static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res)
+@@ -2708,23 +2727,29 @@ qla2x00_els_dcmd2_iocb_timeout(void *data)
+       srb_t *sp = data;
+       fc_port_t *fcport = sp->fcport;
+       struct scsi_qla_host *vha = sp->vha;
+-      struct qla_hw_data *ha = vha->hw;
+       unsigned long flags = 0;
+-      int res;
++      int res, h;
+ 
+       ql_dbg(ql_dbg_io + ql_dbg_disc, vha, 0x3069,
+           "%s hdl=%x ELS Timeout, %8phC portid=%06x\n",
+           sp->name, sp->handle, fcport->port_name, fcport->d_id.b24);
+ 
+       /* Abort the exchange */
+-      spin_lock_irqsave(&ha->hardware_lock, flags);
+-      res = ha->isp_ops->abort_command(sp);
++      res = qla24xx_async_abort_cmd(sp, false);
+       ql_dbg(ql_dbg_io, vha, 0x3070,
+           "mbx abort_command %s\n",
+           (res == QLA_SUCCESS) ? "successful" : "failed");
+-      spin_unlock_irqrestore(&ha->hardware_lock, flags);
+-
+-      sp->done(sp, QLA_FUNCTION_TIMEOUT);
++      if (res) {
++              spin_lock_irqsave(sp->qpair->qp_lock_ptr, flags);
++              for (h = 1; h < sp->qpair->req->num_outstanding_cmds; h++) {
++                      if (sp->qpair->req->outstanding_cmds[h] == sp) {
++                              sp->qpair->req->outstanding_cmds[h] = NULL;
++                              break;
++                      }
++              }
++              spin_unlock_irqrestore(sp->qpair->qp_lock_ptr, flags);
++              sp->done(sp, QLA_FUNCTION_TIMEOUT);
++      }
+ }
+ 
+ void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi)
+@@ -2769,9 +2794,8 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
+               case CS_COMPLETE:
+                       memset(&ea, 0, sizeof(ea));
+                       ea.fcport = fcport;
+-                      ea.data[0] = MBS_COMMAND_COMPLETE;
+-                      ea.sp = sp;
+-                      qla24xx_handle_plogi_done_event(vha, &ea);
++                      ea.rc = res;
++                      qla_handle_els_plogi_done(vha, &ea);
+                       break;
+ 
+               case CS_IOCB_ERROR:
+@@ -2844,7 +2868,8 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
+                                   fw_status[0], fw_status[1], fw_status[2]);
+ 
+                               fcport->flags &= ~FCF_ASYNC_SENT;
+-                              fcport->disc_state = DSC_LOGIN_FAILED;
++                              qla2x00_set_fcport_disc_state(fcport,
++                                  DSC_LOGIN_FAILED);
+                               set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+                               break;
+                       }
+@@ -2857,7 +2882,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
+                           fw_status[0], fw_status[1], fw_status[2]);
+ 
+                       sp->fcport->flags &= ~FCF_ASYNC_SENT;
+-                      sp->fcport->disc_state = DSC_LOGIN_FAILED;
++                      qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_FAILED);
+                       set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
+                       break;
+               }
+@@ -2894,7 +2919,7 @@ qla24xx_els_dcmd2_iocb(scsi_qla_host_t *vha, int 
els_opcode,
+       }
+ 
+       fcport->flags |= FCF_ASYNC_SENT;
+-      fcport->disc_state = DSC_LOGIN_PEND;
++      qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_PEND);
+       elsio = &sp->u.iocb_cmd;
+       ql_dbg(ql_dbg_io, vha, 0x3073,
+           "Enter: PLOGI portid=%06x\n", fcport->d_id.b24);
+diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
+index c1631e42d35d1..098388a12febc 100644
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -1924,7 +1924,7 @@ qla2x00_get_port_database(scsi_qla_host_t *vha, 
fc_port_t *fcport, uint8_t opt)
+               pd24 = (struct port_database_24xx *) pd;
+ 
+               /* Check for logged in state. */
+-              if (fcport->fc4f_nvme) {
++              if (NVME_TARGET(ha, fcport)) {
+                       current_login_state = pd24->current_login_state >> 4;
+                       last_login_state = pd24->last_login_state >> 4;
+               } else {
+@@ -3891,8 +3891,9 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
+                               fcport->scan_state = QLA_FCPORT_FOUND;
+                               fcport->n2n_flag = 1;
+                               fcport->keep_nport_handle = 1;
++                              fcport->fc4_type = FS_FC4TYPE_FCP;
+                               if (vha->flags.nvme_enabled)
+-                                      fcport->fc4f_nvme = 1;
++                                      fcport->fc4_type |= FS_FC4TYPE_NVME;
+ 
+                               switch (fcport->disc_state) {
+                               case DSC_DELETED:
+@@ -6350,7 +6351,7 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, 
fc_port_t *fcport,
+       uint64_t zero = 0;
+       u8 current_login_state, last_login_state;
+ 
+-      if (fcport->fc4f_nvme) {
++      if (NVME_TARGET(vha->hw, fcport)) {
+               current_login_state = pd->current_login_state >> 4;
+               last_login_state = pd->last_login_state >> 4;
+       } else {
+@@ -6385,8 +6386,8 @@ int __qla24xx_parse_gpdb(struct scsi_qla_host *vha, 
fc_port_t *fcport,
+       fcport->d_id.b.al_pa = pd->port_id[2];
+       fcport->d_id.b.rsvd_1 = 0;
+ 
+-      if (fcport->fc4f_nvme) {
+-              fcport->port_type = 0;
++      if (NVME_TARGET(vha->hw, fcport)) {
++              fcport->port_type = FCT_NVME;
+               if ((pd->prli_svc_param_word_3[0] & BIT_5) == 0)
+                       fcport->port_type |= FCT_NVME_INITIATOR;
+               if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0)
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 67b1e74fcd1e6..af8306a9777fc 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -5014,7 +5014,7 @@ void qla24xx_sched_upd_fcport(fc_port_t *fcport)
+       fcport->jiffies_at_registration = jiffies;
+       fcport->sec_since_registration = 0;
+       fcport->next_disc_state = DSC_DELETED;
+-      fcport->disc_state = DSC_UPD_FCPORT;
++      qla2x00_set_fcport_disc_state(fcport, DSC_UPD_FCPORT);
+       spin_unlock_irqrestore(&fcport->vha->work_lock, flags);
+ 
+       queue_work(system_unbound_wq, &fcport->reg_work);
+@@ -5055,19 +5055,17 @@ void qla24xx_create_new_sess(struct scsi_qla_host 
*vha, struct qla_work_evt *e)
+                       fcport->d_id = e->u.new_sess.id;
+                       fcport->flags |= FCF_FABRIC_DEVICE;
+                       fcport->fw_login_state = DSC_LS_PLOGI_PEND;
+-                      if (e->u.new_sess.fc4_type == FS_FC4TYPE_FCP)
+-                              fcport->fc4_type = FC4_TYPE_FCP_SCSI;
+-
+-                      if (e->u.new_sess.fc4_type == FS_FC4TYPE_NVME) {
+-                              fcport->fc4_type = FC4_TYPE_OTHER;
+-                              fcport->fc4f_nvme = FC4_TYPE_NVME;
+-                      }
+ 
+                       memcpy(fcport->port_name, e->u.new_sess.port_name,
+                           WWN_SIZE);
+ 
+-                      if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N)
++                      fcport->fc4_type = e->u.new_sess.fc4_type;
++                      if (e->u.new_sess.fc4_type & FS_FCP_IS_N2N) {
++                              fcport->fc4_type = FS_FC4TYPE_FCP;
+                               fcport->n2n_flag = 1;
++                              if (vha->flags.nvme_enabled)
++                                      fcport->fc4_type |= FS_FC4TYPE_NVME;
++                      }
+ 
+               } else {
+                       ql_dbg(ql_dbg_disc, vha, 0xffff,
+@@ -5171,7 +5169,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, 
struct qla_work_evt *e)
+                               fcport->flags &= ~FCF_FABRIC_DEVICE;
+                               fcport->keep_nport_handle = 1;
+                               if (vha->flags.nvme_enabled) {
+-                                      fcport->fc4f_nvme = 1;
++                                      fcport->fc4_type =
++                                          (FS_FC4TYPE_NVME | FS_FC4TYPE_FCP);
+                                       fcport->n2n_flag = 1;
+                               }
+                               fcport->fw_login_state = 0;
+diff --git a/drivers/scsi/qla2xxx/qla_target.c 
b/drivers/scsi/qla2xxx/qla_target.c
+index 8fd0a568303b5..509539ec58e93 100644
+--- a/drivers/scsi/qla2xxx/qla_target.c
++++ b/drivers/scsi/qla2xxx/qla_target.c
+@@ -596,7 +596,8 @@ static void qla2x00_async_nack_sp_done(srb_t *sp, int res)
+                       spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
+               } else {
+                       sp->fcport->login_retry = 0;
+-                      sp->fcport->disc_state = DSC_LOGIN_COMPLETE;
++                      qla2x00_set_fcport_disc_state(sp->fcport,
++                          DSC_LOGIN_COMPLETE);
+                       sp->fcport->deleted = 0;
+                       sp->fcport->logout_on_delete = 1;
+               }
+@@ -1056,7 +1057,7 @@ void qlt_free_session_done(struct work_struct *work)
+                       tgt->sess_count--;
+       }
+ 
+-      sess->disc_state = DSC_DELETED;
++      qla2x00_set_fcport_disc_state(sess, DSC_DELETED);
+       sess->fw_login_state = DSC_LS_PORT_UNAVAIL;
+       sess->deleted = QLA_SESS_DELETED;
+ 
+@@ -1166,7 +1167,7 @@ void qlt_unreg_sess(struct fc_port *sess)
+               vha->hw->tgt.tgt_ops->clear_nacl_from_fcport_map(sess);
+ 
+       sess->deleted = QLA_SESS_DELETION_IN_PROGRESS;
+-      sess->disc_state = DSC_DELETE_PEND;
++      qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND);
+       sess->last_rscn_gen = sess->rscn_gen;
+       sess->last_login_gen = sess->login_gen;
+ 
+@@ -1268,7 +1269,7 @@ void qlt_schedule_sess_for_deletion(struct fc_port *sess)
+       spin_unlock_irqrestore(&sess->vha->work_lock, flags);
+ 
+       sess->prli_pend_timer = 0;
+-      sess->disc_state = DSC_DELETE_PEND;
++      qla2x00_set_fcport_disc_state(sess, DSC_DELETE_PEND);
+ 
+       qla24xx_chk_fcp_state(sess);
+ 
+@@ -6061,7 +6062,7 @@ static fc_port_t *qlt_get_port_database(struct 
scsi_qla_host *vha,
+               if (!IS_SW_RESV_ADDR(fcport->d_id))
+                  vha->fcport_count++;
+               fcport->login_gen++;
+-              fcport->disc_state = DSC_LOGIN_COMPLETE;
++              qla2x00_set_fcport_disc_state(fcport, DSC_LOGIN_COMPLETE);
+               fcport->login_succ = 1;
+               newfcport = 1;
+       }
+diff --git a/drivers/scsi/scsi_transport_srp.c 
b/drivers/scsi/scsi_transport_srp.c
+index 8cd0a87764dfd..9fee851c23a56 100644
+--- a/drivers/scsi/scsi_transport_srp.c
++++ b/drivers/scsi/scsi_transport_srp.c
+@@ -541,7 +541,7 @@ int srp_reconnect_rport(struct srp_rport *rport)
+       res = mutex_lock_interruptible(&rport->mutex);
+       if (res)
+               goto out;
+-      if (rport->state != SRP_RPORT_FAIL_FAST)
++      if (rport->state != SRP_RPORT_FAIL_FAST && rport->state != 
SRP_RPORT_LOST)
+               /*
+                * sdev state must be SDEV_TRANSPORT_OFFLINE, transition
+                * to SDEV_BLOCK is illegal. Calling scsi_target_unblock()
+diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
+index 2372e161cd5e8..a603f363835c4 100644
+--- a/drivers/vfio/pci/vfio_pci.c
++++ b/drivers/vfio/pci/vfio_pci.c
+@@ -1474,6 +1474,8 @@ static int vfio_pci_mmap(void *device_data, struct 
vm_area_struct *vma)
+ 
+       index = vma->vm_pgoff >> (VFIO_PCI_OFFSET_SHIFT - PAGE_SHIFT);
+ 
++      if (index >= VFIO_PCI_NUM_REGIONS + vdev->num_regions)
++              return -EINVAL;
+       if (vma->vm_end < vma->vm_start)
+               return -EINVAL;
+       if ((vma->vm_flags & VM_SHARED) == 0)
+@@ -1482,7 +1484,7 @@ static int vfio_pci_mmap(void *device_data, struct 
vm_area_struct *vma)
+               int regnum = index - VFIO_PCI_NUM_REGIONS;
+               struct vfio_pci_region *region = vdev->region + regnum;
+ 
+-              if (region && region->ops && region->ops->mmap &&
++              if (region->ops && region->ops->mmap &&
+                   (region->flags & VFIO_REGION_INFO_FLAG_MMAP))
+                       return region->ops->mmap(vdev, region, vma);
+               return -EINVAL;
+diff --git a/fs/readdir.c b/fs/readdir.c
+index de2eceffdee8b..07a3b5baa4047 100644
+--- a/fs/readdir.c
++++ b/fs/readdir.c
+@@ -150,6 +150,9 @@ static int fillonedir(struct dir_context *ctx, const char 
*name, int namlen,
+ 
+       if (buf->result)
+               return -EINVAL;
++      buf->result = verify_dirent_name(name, namlen);
++      if (buf->result < 0)
++              return buf->result;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
+               buf->result = -EOVERFLOW;
+@@ -417,6 +420,9 @@ static int compat_fillonedir(struct dir_context *ctx, 
const char *name,
+ 
+       if (buf->result)
+               return -EINVAL;
++      buf->result = verify_dirent_name(name, namlen);
++      if (buf->result < 0)
++              return buf->result;
+       d_ino = ino;
+       if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
+               buf->result = -EOVERFLOW;
+diff --git a/include/linux/marvell_phy.h b/include/linux/marvell_phy.h
+index af6b11d4d6737..1847a07842437 100644
+--- a/include/linux/marvell_phy.h
++++ b/include/linux/marvell_phy.h
+@@ -23,11 +23,12 @@
+ #define MARVELL_PHY_ID_88X3310                0x002b09a0
+ #define MARVELL_PHY_ID_88E2110                0x002b09b0
+ 
+-/* The MV88e6390 Ethernet switch contains embedded PHYs. These PHYs do
++/* These Ethernet switch families contain embedded PHYs, but they do
+  * not have a model ID. So the switch driver traps reads to the ID2
+  * register and returns the switch family ID
+  */
+-#define MARVELL_PHY_ID_88E6390                0x01410f90
++#define MARVELL_PHY_ID_88E6341_FAMILY 0x01410f41
++#define MARVELL_PHY_ID_88E6390_FAMILY 0x01410f90
+ 
+ #define MARVELL_PHY_FAMILY_ID(id)     ((id) >> 4)
+ 
+diff --git a/include/linux/netfilter_arp/arp_tables.h 
b/include/linux/netfilter_arp/arp_tables.h
+index e98028f00e479..6988cf9ffe3ae 100644
+--- a/include/linux/netfilter_arp/arp_tables.h
++++ b/include/linux/netfilter_arp/arp_tables.h
+@@ -52,8 +52,9 @@ extern void *arpt_alloc_initial_table(const struct xt_table 
*);
+ int arpt_register_table(struct net *net, const struct xt_table *table,
+                       const struct arpt_replace *repl,
+                       const struct nf_hook_ops *ops, struct xt_table **res);
+-void arpt_unregister_table(struct net *net, struct xt_table *table,
+-                         const struct nf_hook_ops *ops);
++void arpt_unregister_table(struct net *net, struct xt_table *table);
++void arpt_unregister_table_pre_exit(struct net *net, struct xt_table *table,
++                                  const struct nf_hook_ops *ops);
+ extern unsigned int arpt_do_table(struct sk_buff *skb,
+                                 const struct nf_hook_state *state,
+                                 struct xt_table *table);
+diff --git a/include/linux/netfilter_bridge/ebtables.h 
b/include/linux/netfilter_bridge/ebtables.h
+index 162f59d0d17a2..db472c9cd8e9d 100644
+--- a/include/linux/netfilter_bridge/ebtables.h
++++ b/include/linux/netfilter_bridge/ebtables.h
+@@ -110,8 +110,9 @@ extern int ebt_register_table(struct net *net,
+                             const struct ebt_table *table,
+                             const struct nf_hook_ops *ops,
+                             struct ebt_table **res);
+-extern void ebt_unregister_table(struct net *net, struct ebt_table *table,
+-                               const struct nf_hook_ops *);
++extern void ebt_unregister_table(struct net *net, struct ebt_table *table);
++void ebt_unregister_table_pre_exit(struct net *net, const char *tablename,
++                                 const struct nf_hook_ops *ops);
+ extern unsigned int ebt_do_table(struct sk_buff *skb,
+                                const struct nf_hook_state *state,
+                                struct ebt_table *table);
+diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
+index bca0f7f71cde4..7429f15717559 100644
+--- a/kernel/locking/lockdep.c
++++ b/kernel/locking/lockdep.c
+@@ -875,7 +875,8 @@ static bool assign_lock_key(struct lockdep_map *lock)
+               /* Debug-check: all keys must be persistent! */
+               debug_locks_off();
+               pr_err("INFO: trying to register non-static key.\n");
+-              pr_err("the code is fine but needs lockdep annotation.\n");
++              pr_err("The code is fine but needs lockdep annotation, or 
maybe\n");
++              pr_err("you didn't initialize this object before use?\n");
+               pr_err("turning off the locking correctness validator.\n");
+               dump_stack();
+               return false;
+diff --git a/net/bridge/netfilter/ebtable_broute.c 
b/net/bridge/netfilter/ebtable_broute.c
+index 66e7af1654943..32bc2821027f3 100644
+--- a/net/bridge/netfilter/ebtable_broute.c
++++ b/net/bridge/netfilter/ebtable_broute.c
+@@ -105,14 +105,20 @@ static int __net_init broute_net_init(struct net *net)
+                                 &net->xt.broute_table);
+ }
+ 
++static void __net_exit broute_net_pre_exit(struct net *net)
++{
++      ebt_unregister_table_pre_exit(net, "broute", &ebt_ops_broute);
++}
++
+ static void __net_exit broute_net_exit(struct net *net)
+ {
+-      ebt_unregister_table(net, net->xt.broute_table, &ebt_ops_broute);
++      ebt_unregister_table(net, net->xt.broute_table);
+ }
+ 
+ static struct pernet_operations broute_net_ops = {
+       .init = broute_net_init,
+       .exit = broute_net_exit,
++      .pre_exit = broute_net_pre_exit,
+ };
+ 
+ static int __init ebtable_broute_init(void)
+diff --git a/net/bridge/netfilter/ebtable_filter.c 
b/net/bridge/netfilter/ebtable_filter.c
+index 78cb9b21022d0..bcf982e12f16b 100644
+--- a/net/bridge/netfilter/ebtable_filter.c
++++ b/net/bridge/netfilter/ebtable_filter.c
+@@ -99,14 +99,20 @@ static int __net_init frame_filter_net_init(struct net 
*net)
+                                 &net->xt.frame_filter);
+ }
+ 
++static void __net_exit frame_filter_net_pre_exit(struct net *net)
++{
++      ebt_unregister_table_pre_exit(net, "filter", ebt_ops_filter);
++}
++
+ static void __net_exit frame_filter_net_exit(struct net *net)
+ {
+-      ebt_unregister_table(net, net->xt.frame_filter, ebt_ops_filter);
++      ebt_unregister_table(net, net->xt.frame_filter);
+ }
+ 
+ static struct pernet_operations frame_filter_net_ops = {
+       .init = frame_filter_net_init,
+       .exit = frame_filter_net_exit,
++      .pre_exit = frame_filter_net_pre_exit,
+ };
+ 
+ static int __init ebtable_filter_init(void)
+diff --git a/net/bridge/netfilter/ebtable_nat.c 
b/net/bridge/netfilter/ebtable_nat.c
+index 0888936ef8537..0d092773f8161 100644
+--- a/net/bridge/netfilter/ebtable_nat.c
++++ b/net/bridge/netfilter/ebtable_nat.c
+@@ -99,14 +99,20 @@ static int __net_init frame_nat_net_init(struct net *net)
+                                 &net->xt.frame_nat);
+ }
+ 
++static void __net_exit frame_nat_net_pre_exit(struct net *net)
++{
++      ebt_unregister_table_pre_exit(net, "nat", ebt_ops_nat);
++}
++
+ static void __net_exit frame_nat_net_exit(struct net *net)
+ {
+-      ebt_unregister_table(net, net->xt.frame_nat, ebt_ops_nat);
++      ebt_unregister_table(net, net->xt.frame_nat);
+ }
+ 
+ static struct pernet_operations frame_nat_net_ops = {
+       .init = frame_nat_net_init,
+       .exit = frame_nat_net_exit,
++      .pre_exit = frame_nat_net_pre_exit,
+ };
+ 
+ static int __init ebtable_nat_init(void)
+diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
+index e1256e03a9a86..d9375c52f50e6 100644
+--- a/net/bridge/netfilter/ebtables.c
++++ b/net/bridge/netfilter/ebtables.c
+@@ -1237,10 +1237,34 @@ out:
+       return ret;
+ }
+ 
+-void ebt_unregister_table(struct net *net, struct ebt_table *table,
+-                        const struct nf_hook_ops *ops)
++static struct ebt_table *__ebt_find_table(struct net *net, const char *name)
++{
++      struct ebt_table *t;
++
++      mutex_lock(&ebt_mutex);
++
++      list_for_each_entry(t, &net->xt.tables[NFPROTO_BRIDGE], list) {
++              if (strcmp(t->name, name) == 0) {
++                      mutex_unlock(&ebt_mutex);
++                      return t;
++              }
++      }
++
++      mutex_unlock(&ebt_mutex);
++      return NULL;
++}
++
++void ebt_unregister_table_pre_exit(struct net *net, const char *name, const 
struct nf_hook_ops *ops)
++{
++      struct ebt_table *table = __ebt_find_table(net, name);
++
++      if (table)
++              nf_unregister_net_hooks(net, ops, 
hweight32(table->valid_hooks));
++}
++EXPORT_SYMBOL(ebt_unregister_table_pre_exit);
++
++void ebt_unregister_table(struct net *net, struct ebt_table *table)
+ {
+-      nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks));
+       __ebt_unregister_table(net, table);
+ }
+ 
+diff --git a/net/core/dev.c b/net/core/dev.c
+index 2ec21380f86d9..91909e5d6807e 100644
+--- a/net/core/dev.c
++++ b/net/core/dev.c
+@@ -5406,7 +5406,8 @@ static void skb_gro_reset_offset(struct sk_buff *skb)
+ 
+       if (skb_mac_header(skb) == skb_tail_pointer(skb) &&
+           pinfo->nr_frags &&
+-          !PageHighMem(skb_frag_page(frag0))) {
++          !PageHighMem(skb_frag_page(frag0)) &&
++          (!NET_IP_ALIGN || !(skb_frag_off(frag0) & 3))) {
+               NAPI_GRO_CB(skb)->frag0 = skb_frag_address(frag0);
+               NAPI_GRO_CB(skb)->frag0_len = min_t(unsigned int,
+                                                   skb_frag_size(frag0),
+diff --git a/net/core/neighbour.c b/net/core/neighbour.c
+index 7080d708b7d08..6635b83113f8f 100644
+--- a/net/core/neighbour.c
++++ b/net/core/neighbour.c
+@@ -1379,7 +1379,7 @@ static int __neigh_update(struct neighbour *neigh, const 
u8 *lladdr,
+                        * we can reinject the packet there.
+                        */
+                       n2 = NULL;
+-                      if (dst) {
++                      if (dst && dst->obsolete != DST_OBSOLETE_DEAD) {
+                               n2 = dst_neigh_lookup_skb(dst, skb);
+                               if (n2)
+                                       n1 = n2;
+diff --git a/net/ieee802154/nl802154.c b/net/ieee802154/nl802154.c
+index f03958fcb5be1..328bb9f5342e5 100644
+--- a/net/ieee802154/nl802154.c
++++ b/net/ieee802154/nl802154.c
+@@ -1514,6 +1514,11 @@ nl802154_dump_llsec_key(struct sk_buff *skb, struct 
netlink_callback *cb)
+       if (err)
+               return err;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
++              err = skb->len;
++              goto out_err;
++      }
++
+       if (!wpan_dev->netdev) {
+               err = -EINVAL;
+               goto out_err;
+@@ -1568,6 +1573,9 @@ static int nl802154_add_llsec_key(struct sk_buff *skb, 
struct genl_info *info)
+       struct ieee802154_llsec_key_id id = { };
+       u32 commands[NL802154_CMD_FRAME_NR_IDS / 32] = { };
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
+           nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, 
info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
+               return -EINVAL;
+@@ -1617,6 +1625,9 @@ static int nl802154_del_llsec_key(struct sk_buff *skb, 
struct genl_info *info)
+       struct nlattr *attrs[NL802154_KEY_ATTR_MAX + 1];
+       struct ieee802154_llsec_key_id id;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (!info->attrs[NL802154_ATTR_SEC_KEY] ||
+           nla_parse_nested_deprecated(attrs, NL802154_KEY_ATTR_MAX, 
info->attrs[NL802154_ATTR_SEC_KEY], nl802154_key_policy, info->extack))
+               return -EINVAL;
+@@ -1682,6 +1693,11 @@ nl802154_dump_llsec_dev(struct sk_buff *skb, struct 
netlink_callback *cb)
+       if (err)
+               return err;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
++              err = skb->len;
++              goto out_err;
++      }
++
+       if (!wpan_dev->netdev) {
+               err = -EINVAL;
+               goto out_err;
+@@ -1768,6 +1784,9 @@ static int nl802154_add_llsec_dev(struct sk_buff *skb, 
struct genl_info *info)
+       struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+       struct ieee802154_llsec_device dev_desc;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (ieee802154_llsec_parse_device(info->attrs[NL802154_ATTR_SEC_DEVICE],
+                                         &dev_desc) < 0)
+               return -EINVAL;
+@@ -1783,6 +1802,9 @@ static int nl802154_del_llsec_dev(struct sk_buff *skb, 
struct genl_info *info)
+       struct nlattr *attrs[NL802154_DEV_ATTR_MAX + 1];
+       __le64 extended_addr;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (!info->attrs[NL802154_ATTR_SEC_DEVICE] ||
+           nla_parse_nested_deprecated(attrs, NL802154_DEV_ATTR_MAX, 
info->attrs[NL802154_ATTR_SEC_DEVICE], nl802154_dev_policy, info->extack))
+               return -EINVAL;
+@@ -1852,6 +1874,11 @@ nl802154_dump_llsec_devkey(struct sk_buff *skb, struct 
netlink_callback *cb)
+       if (err)
+               return err;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
++              err = skb->len;
++              goto out_err;
++      }
++
+       if (!wpan_dev->netdev) {
+               err = -EINVAL;
+               goto out_err;
+@@ -1909,6 +1936,9 @@ static int nl802154_add_llsec_devkey(struct sk_buff 
*skb, struct genl_info *info
+       struct ieee802154_llsec_device_key key;
+       __le64 extended_addr;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
+           nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, 
info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack) < 
0)
+               return -EINVAL;
+@@ -1940,6 +1970,9 @@ static int nl802154_del_llsec_devkey(struct sk_buff 
*skb, struct genl_info *info
+       struct ieee802154_llsec_device_key key;
+       __le64 extended_addr;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (!info->attrs[NL802154_ATTR_SEC_DEVKEY] ||
+           nla_parse_nested_deprecated(attrs, NL802154_DEVKEY_ATTR_MAX, 
info->attrs[NL802154_ATTR_SEC_DEVKEY], nl802154_devkey_policy, info->extack))
+               return -EINVAL;
+@@ -2014,6 +2047,11 @@ nl802154_dump_llsec_seclevel(struct sk_buff *skb, 
struct netlink_callback *cb)
+       if (err)
+               return err;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR) {
++              err = skb->len;
++              goto out_err;
++      }
++
+       if (!wpan_dev->netdev) {
+               err = -EINVAL;
+               goto out_err;
+@@ -2098,6 +2136,9 @@ static int nl802154_add_llsec_seclevel(struct sk_buff 
*skb,
+       struct wpan_dev *wpan_dev = dev->ieee802154_ptr;
+       struct ieee802154_llsec_seclevel sl;
+ 
++      if (wpan_dev->iftype == NL802154_IFTYPE_MONITOR)
++              return -EOPNOTSUPP;
++
+       if (llsec_parse_seclevel(info->attrs[NL802154_ATTR_SEC_LEVEL],
+                                &sl) < 0)
+               return -EINVAL;
+diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
+index dc7dac676415e..a6f2e5bf70456 100644
+--- a/net/ipv4/netfilter/arp_tables.c
++++ b/net/ipv4/netfilter/arp_tables.c
+@@ -1580,10 +1580,15 @@ out_free:
+       return ret;
+ }
+ 
+-void arpt_unregister_table(struct net *net, struct xt_table *table,
+-                         const struct nf_hook_ops *ops)
++void arpt_unregister_table_pre_exit(struct net *net, struct xt_table *table,
++                                  const struct nf_hook_ops *ops)
+ {
+       nf_unregister_net_hooks(net, ops, hweight32(table->valid_hooks));
++}
++EXPORT_SYMBOL(arpt_unregister_table_pre_exit);
++
++void arpt_unregister_table(struct net *net, struct xt_table *table)
++{
+       __arpt_unregister_table(net, table);
+ }
+ 
+diff --git a/net/ipv4/netfilter/arptable_filter.c 
b/net/ipv4/netfilter/arptable_filter.c
+index c216b9ad3bb24..6c300ba5634e2 100644
+--- a/net/ipv4/netfilter/arptable_filter.c
++++ b/net/ipv4/netfilter/arptable_filter.c
+@@ -56,16 +56,24 @@ static int __net_init arptable_filter_table_init(struct 
net *net)
+       return err;
+ }
+ 
++static void __net_exit arptable_filter_net_pre_exit(struct net *net)
++{
++      if (net->ipv4.arptable_filter)
++              arpt_unregister_table_pre_exit(net, net->ipv4.arptable_filter,
++                                             arpfilter_ops);
++}
++
+ static void __net_exit arptable_filter_net_exit(struct net *net)
+ {
+       if (!net->ipv4.arptable_filter)
+               return;
+-      arpt_unregister_table(net, net->ipv4.arptable_filter, arpfilter_ops);
++      arpt_unregister_table(net, net->ipv4.arptable_filter);
+       net->ipv4.arptable_filter = NULL;
+ }
+ 
+ static struct pernet_operations arptable_filter_net_ops = {
+       .exit = arptable_filter_net_exit,
++      .pre_exit = arptable_filter_net_pre_exit,
+ };
+ 
+ static int __init arptable_filter_init(void)
+diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
+index 8dcf7bacc99a6..69799b612ee80 100644
+--- a/net/ipv6/ip6_tunnel.c
++++ b/net/ipv6/ip6_tunnel.c
+@@ -2217,6 +2217,16 @@ static void __net_exit ip6_tnl_destroy_tunnels(struct 
net *net, struct list_head
+                       t = rtnl_dereference(t->next);
+               }
+       }
++
++      t = rtnl_dereference(ip6n->tnls_wc[0]);
++      while (t) {
++              /* If dev is in the same netns, it has already
++               * been added to the list by the previous loop.
++               */
++              if (!net_eq(dev_net(t->dev), net))
++                      unregister_netdevice_queue(t->dev, list);
++              t = rtnl_dereference(t->next);
++      }
+ }
+ 
+ static int __net_init ip6_tnl_init_net(struct net *net)
+diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
+index de4c871787e2f..2710f3bc856f8 100644
+--- a/net/ipv6/sit.c
++++ b/net/ipv6/sit.c
+@@ -1819,9 +1819,9 @@ static void __net_exit sit_destroy_tunnels(struct net 
*net,
+               if (dev->rtnl_link_ops == &sit_link_ops)
+                       unregister_netdevice_queue(dev, head);
+ 
+-      for (prio = 1; prio < 4; prio++) {
++      for (prio = 0; prio < 4; prio++) {
+               int h;
+-              for (h = 0; h < IP6_SIT_HASH_SIZE; h++) {
++              for (h = 0; h < (prio ? IP6_SIT_HASH_SIZE : 1); h++) {
+                       struct ip_tunnel *t;
+ 
+                       t = rtnl_dereference(sitn->tunnels[prio][h]);
+diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
+index 677928bf13d13..1b50bbf030ed8 100644
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1670,8 +1670,10 @@ static int ieee80211_change_station(struct wiphy *wiphy,
+               }
+ 
+               if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
+-                  sta->sdata->u.vlan.sta)
++                  sta->sdata->u.vlan.sta) {
++                      ieee80211_clear_fast_rx(sta);
+                       RCU_INIT_POINTER(sta->sdata->u.vlan.sta, NULL);
++              }
+ 
+               if (test_sta_flag(sta, WLAN_STA_AUTHORIZED))
+                       ieee80211_vif_dec_num_mcast(sta->sdata);
+diff --git a/net/netfilter/nf_conntrack_standalone.c 
b/net/netfilter/nf_conntrack_standalone.c
+index dc57f530df9db..1a69825401263 100644
+--- a/net/netfilter/nf_conntrack_standalone.c
++++ b/net/netfilter/nf_conntrack_standalone.c
+@@ -266,6 +266,7 @@ static const char* l4proto_name(u16 proto)
+       case IPPROTO_GRE: return "gre";
+       case IPPROTO_SCTP: return "sctp";
+       case IPPROTO_UDPLITE: return "udplite";
++      case IPPROTO_ICMPV6: return "icmpv6";
+       }
+ 
+       return "unknown";
+diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c
+index 35b67d7e36947..6e7b92e6f4246 100644
+--- a/net/netfilter/nft_limit.c
++++ b/net/netfilter/nft_limit.c
+@@ -76,13 +76,13 @@ static int nft_limit_init(struct nft_limit *limit,
+               return -EOVERFLOW;
+ 
+       if (pkts) {
+-              tokens = div_u64(limit->nsecs, limit->rate) * limit->burst;
++              tokens = div64_u64(limit->nsecs, limit->rate) * limit->burst;
+       } else {
+               /* The token bucket size limits the number of tokens can be
+                * accumulated. tokens_max specifies the bucket size.
+                * tokens_max = unit * (rate + burst) / rate.
+                */
+-              tokens = div_u64(limit->nsecs * (limit->rate + limit->burst),
++              tokens = div64_u64(limit->nsecs * (limit->rate + limit->burst),
+                                limit->rate);
+       }
+ 
+diff --git a/net/sctp/socket.c b/net/sctp/socket.c
+index 41abfff6a6a3d..783fd65b1f98d 100644
+--- a/net/sctp/socket.c
++++ b/net/sctp/socket.c
+@@ -1539,11 +1539,9 @@ static void sctp_close(struct sock *sk, long timeout)
+ 
+       /* Supposedly, no process has access to the socket, but
+        * the net layers still may.
+-       * Also, sctp_destroy_sock() needs to be called with addr_wq_lock
+-       * held and that should be grabbed before socket lock.
+        */
+-      spin_lock_bh(&net->sctp.addr_wq_lock);
+-      bh_lock_sock_nested(sk);
++      local_bh_disable();
++      bh_lock_sock(sk);
+ 
+       /* Hold the sock, since sk_common_release() will put sock_put()
+        * and we have just a little more cleanup.
+@@ -1552,7 +1550,7 @@ static void sctp_close(struct sock *sk, long timeout)
+       sk_common_release(sk);
+ 
+       bh_unlock_sock(sk);
+-      spin_unlock_bh(&net->sctp.addr_wq_lock);
++      local_bh_enable();
+ 
+       sock_put(sk);
+ 
+@@ -5115,9 +5113,6 @@ static int sctp_init_sock(struct sock *sk)
+       sk_sockets_allocated_inc(sk);
+       sock_prot_inuse_add(net, sk->sk_prot, 1);
+ 
+-      /* Nothing can fail after this block, otherwise
+-       * sctp_destroy_sock() will be called without addr_wq_lock held
+-       */
+       if (net->sctp.default_auto_asconf) {
+               spin_lock(&sock_net(sk)->sctp.addr_wq_lock);
+               list_add_tail(&sp->auto_asconf_list,
+@@ -5152,7 +5147,9 @@ static void sctp_destroy_sock(struct sock *sk)
+ 
+       if (sp->do_auto_asconf) {
+               sp->do_auto_asconf = 0;
++              spin_lock_bh(&sock_net(sk)->sctp.addr_wq_lock);
+               list_del(&sp->auto_asconf_list);
++              spin_unlock_bh(&sock_net(sk)->sctp.addr_wq_lock);
+       }
+       sctp_endpoint_free(sp->ep);
+       local_bh_disable();
+diff --git a/sound/soc/codecs/max98373.c b/sound/soc/codecs/max98373.c
+index 96718e3a1ad0e..16fbc9faed90b 100644
+--- a/sound/soc/codecs/max98373.c
++++ b/sound/soc/codecs/max98373.c
+@@ -410,11 +410,13 @@ static int max98373_dac_event(struct snd_soc_dapm_widget 
*w,
+               regmap_update_bits(max98373->regmap,
+                       MAX98373_R20FF_GLOBAL_SHDN,
+                       MAX98373_GLOBAL_EN_MASK, 1);
++              usleep_range(30000, 31000);
+               break;
+       case SND_SOC_DAPM_POST_PMD:
+               regmap_update_bits(max98373->regmap,
+                       MAX98373_R20FF_GLOBAL_SHDN,
+                       MAX98373_GLOBAL_EN_MASK, 0);
++              usleep_range(30000, 31000);
+               max98373->tdm_mode = false;
+               break;
+       default:
+diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
+index 84290be778f0e..33ade79fa032e 100644
+--- a/sound/soc/fsl/fsl_esai.c
++++ b/sound/soc/fsl/fsl_esai.c
+@@ -494,11 +494,13 @@ static int fsl_esai_startup(struct snd_pcm_substream 
*substream,
+                                  ESAI_SAICR_SYNC, esai_priv->synchronous ?
+                                  ESAI_SAICR_SYNC : 0);
+ 
+-              /* Set a default slot number -- 2 */
++              /* Set slots count */
+               regmap_update_bits(esai_priv->regmap, REG_ESAI_TCCR,
+-                                 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
++                                 ESAI_xCCR_xDC_MASK,
++                                 ESAI_xCCR_xDC(esai_priv->slots));
+               regmap_update_bits(esai_priv->regmap, REG_ESAI_RCCR,
+-                                 ESAI_xCCR_xDC_MASK, ESAI_xCCR_xDC(2));
++                                 ESAI_xCCR_xDC_MASK,
++                                 ESAI_xCCR_xDC(esai_priv->slots));
+       }
+ 
+       return 0;

Reply via email to