]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge branch 'rcu/urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/paulmck...
authorIngo Molnar <mingo@kernel.org>
Fri, 9 Jun 2017 06:17:10 +0000 (08:17 +0200)
committerIngo Molnar <mingo@kernel.org>
Fri, 9 Jun 2017 06:17:10 +0000 (08:17 +0200)
Pull RCU fix from Paul E. McKenney:

" This series enables srcu_read_lock() and srcu_read_unlock() to be used from
  interrupt handlers, which fixes a bug in KVM's use of SRCU in delivery
  of interrupts to guest OSes. "

Signed-off-by: Ingo Molnar <mingo@kernel.org>
146 files changed:
Documentation/devicetree/bindings/net/dsa/marvell.txt
Documentation/networking/dpaa.txt [new file with mode: 0644]
Documentation/networking/tcp.txt
MAINTAINERS
arch/arm/boot/compressed/efi-header.S
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/imx6ul-14x14-evk.dts
arch/arm/common/mcpm_entry.c
arch/arm/include/asm/pgtable-nommu.h
arch/sparc/Kconfig
arch/sparc/include/asm/mmu_64.h
arch/sparc/include/asm/mmu_context_64.h
arch/sparc/include/asm/pil.h
arch/sparc/include/asm/vio.h
arch/sparc/kernel/ds.c
arch/sparc/kernel/irq_64.c
arch/sparc/kernel/kernel.h
arch/sparc/kernel/smp_64.c
arch/sparc/kernel/tsb.S
arch/sparc/kernel/ttable_64.S
arch/sparc/kernel/vio.c
arch/sparc/lib/Makefile
arch/sparc/lib/multi3.S [new file with mode: 0644]
arch/sparc/mm/init_64.c
arch/sparc/mm/tsb.c
arch/sparc/mm/ultra.S
drivers/ata/ahci.c
drivers/ata/libahci_platform.c
drivers/ata/libata-core.c
drivers/ata/sata_mv.c
drivers/ata/sata_rcar.c
drivers/isdn/i4l/isdn_ppp.c
drivers/isdn/mISDN/stack.c
drivers/media/Kconfig
drivers/media/Makefile
drivers/media/cec/Kconfig
drivers/media/cec/Makefile
drivers/media/cec/cec-adap.c
drivers/media/cec/cec-core.c
drivers/media/i2c/Kconfig
drivers/media/platform/Kconfig
drivers/media/platform/vivid/Kconfig
drivers/media/rc/rc-ir-raw.c
drivers/media/usb/pulse8-cec/Kconfig
drivers/media/usb/rainshadow-cec/Kconfig
drivers/media/usb/rainshadow-cec/rainshadow-cec.c
drivers/net/dsa/mv88e6xxx/global2.h
drivers/net/ethernet/amd/xgbe/xgbe-desc.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/chelsio/cxgb4/t4fw_version.h
drivers/net/ethernet/ethoc.c
drivers/net/ethernet/freescale/fsl_pq_mdio.c
drivers/net/ethernet/ibm/ibmvnic.c
drivers/net/ethernet/intel/i40e/i40e_main.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.c
drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
drivers/net/ethernet/mellanox/mlx4/mcg.c
drivers/net/ethernet/mellanox/mlx4/qp.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/ethernet/mellanox/mlx5/core/main.c
drivers/net/ethernet/qlogic/qed/qed_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
drivers/net/ethernet/qualcomm/emac/emac-mac.c
drivers/net/ethernet/qualcomm/emac/emac-phy.c
drivers/net/ethernet/qualcomm/emac/emac.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/stmicro/stmmac/altr_tse_pcs.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/geneve.c
drivers/net/hamradio/hdlcdrv.c
drivers/net/phy/marvell.c
drivers/net/phy/mdio_bus.c
drivers/net/phy/micrel.c
drivers/net/phy/phy.c
drivers/net/virtio_net.c
drivers/net/vxlan.c
drivers/net/wireless/ath/wcn36xx/main.c
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
drivers/net/wireless/intel/iwlwifi/iwl-7000.c
drivers/net/wireless/intel/iwlwifi/iwl-8000.c
drivers/net/wireless/intel/iwlwifi/iwl-prph.h
drivers/net/wireless/intel/iwlwifi/mvm/fw-api-rs.h
drivers/net/wireless/intel/iwlwifi/mvm/fw-api-tx.h
drivers/net/wireless/intel/iwlwifi/mvm/fw-dbg.c
drivers/net/wireless/intel/iwlwifi/mvm/mac-ctxt.c
drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
drivers/net/wireless/intel/iwlwifi/mvm/ops.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.c
drivers/net/wireless/intel/iwlwifi/mvm/rs.h
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.h
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
drivers/net/wireless/intel/iwlwifi/mvm/tx.c
drivers/net/wireless/intel/iwlwifi/pcie/trans.c
drivers/net/wireless/intel/iwlwifi/pcie/tx-gen2.c
drivers/staging/media/atomisp/i2c/Makefile
drivers/staging/media/atomisp/i2c/imx/Makefile
drivers/staging/media/atomisp/i2c/ov5693/Makefile
drivers/staging/media/atomisp/pci/atomisp2/Makefile
include/linux/cgroup-defs.h
include/linux/cgroup.h
include/linux/compiler-clang.h
include/linux/mlx4/qp.h
include/media/cec-notifier.h
include/media/cec.h
include/net/ipv6.h
include/net/tcp.h
kernel/cgroup/cgroup.c
kernel/cgroup/cpuset.c
net/bridge/br_netlink.c
net/bridge/br_stp_if.c
net/core/devlink.c
net/core/skbuff.c
net/dsa/dsa.c
net/dsa/dsa2.c
net/dsa/legacy.c
net/ipv4/af_inet.c
net/ipv4/tcp.c
net/ipv4/tcp_cong.c
net/ipv6/calipso.c
net/ipv6/ip6_offload.c
net/ipv6/ip6_tunnel.c
net/ipv6/ping.c
net/ipv6/raw.c
net/ipv6/xfrm6_mode_ro.c
net/ipv6/xfrm6_mode_transport.c
net/mac80211/agg-tx.c
net/mac80211/ht.c
net/mac80211/ieee80211_i.h
net/mac80211/iface.c
net/mac80211/sta_info.c
net/mac80211/sta_info.h
net/mpls/af_mpls.c
net/netfilter/nf_conntrack_netlink.c
net/netfilter/nf_conntrack_proto_sctp.c
net/netfilter/nf_nat_core.c
net/netfilter/nft_set_rbtree.c
net/netlink/af_netlink.c

index 7ef9dbb08957a593528a4d873d1f3af29892f5c2..1d4d0f49c9d06eb66d9957fb0661cec35ddc7af9 100644 (file)
@@ -26,6 +26,10 @@ Optional properties:
 - interrupt-controller : Indicates the switch is itself an interrupt
                          controller. This is used for the PHY interrupts.
 #interrupt-cells = <2> : Controller uses two cells, number and flag
+- eeprom-length                : Set to the length of an EEPROM connected to the
+                         switch. Must be set if the switch can not detect
+                         the presence and/or size of a connected EEPROM,
+                         otherwise optional.
 - mdio                 : Container of PHY and devices on the switches MDIO
                          bus.
 - mdio?                : Container of PHYs and devices on the external MDIO
diff --git a/Documentation/networking/dpaa.txt b/Documentation/networking/dpaa.txt
new file mode 100644 (file)
index 0000000..76e016d
--- /dev/null
@@ -0,0 +1,194 @@
+The QorIQ DPAA Ethernet Driver
+==============================
+
+Authors:
+Madalin Bucur <madalin.bucur@nxp.com>
+Camelia Groza <camelia.groza@nxp.com>
+
+Contents
+========
+
+       - DPAA Ethernet Overview
+       - DPAA Ethernet Supported SoCs
+       - Configuring DPAA Ethernet in your kernel
+       - DPAA Ethernet Frame Processing
+       - DPAA Ethernet Features
+       - Debugging
+
+DPAA Ethernet Overview
+======================
+
+DPAA stands for Data Path Acceleration Architecture and it is a
+set of networking acceleration IPs that are available on several
+generations of SoCs, both on PowerPC and ARM64.
+
+The Freescale DPAA architecture consists of a series of hardware blocks
+that support Ethernet connectivity. The Ethernet driver depends upon the
+following drivers in the Linux kernel:
+
+ - Peripheral Access Memory Unit (PAMU) (* needed only for PPC platforms)
+    drivers/iommu/fsl_*
+ - Frame Manager (FMan)
+    drivers/net/ethernet/freescale/fman
+ - Queue Manager (QMan), Buffer Manager (BMan)
+    drivers/soc/fsl/qbman
+
+A simplified view of the dpaa_eth interfaces mapped to FMan MACs:
+
+  dpaa_eth       /eth0\     ...       /ethN\
+  driver        |      |             |      |
+  -------------   ----   -----------   ----   -------------
+       -Ports  / Tx  Rx \    ...    / Tx  Rx \
+  FMan        |          |         |          |
+       -MACs  |   MAC0   |         |   MACN   |
+             /   dtsec0   \  ...  /   dtsecN   \ (or tgec)
+            /              \     /              \(or memac)
+  ---------  --------------  ---  --------------  ---------
+      FMan, FMan Port, FMan SP, FMan MURAM drivers
+  ---------------------------------------------------------
+      FMan HW blocks: MURAM, MACs, Ports, SP
+  ---------------------------------------------------------
+
+The dpaa_eth relation to the QMan, BMan and FMan:
+              ________________________________
+  dpaa_eth   /            eth0                \
+  driver    /                                  \
+  ---------   -^-   -^-   -^-   ---    ---------
+  QMan driver / \   / \   / \  \   /  | BMan    |
+             |Rx | |Rx | |Tx | |Tx |  | driver  |
+  ---------  |Dfl| |Err| |Cnf| |FQs|  |         |
+  QMan HW    |FQ | |FQ | |FQs| |   |  |         |
+             /   \ /   \ /   \  \ /   |         |
+  ---------   ---   ---   ---   -v-    ---------
+            |        FMan QMI         |         |
+            | FMan HW       FMan BMI  | BMan HW |
+              -----------------------   --------
+
+where the acronyms used above (and in the code) are:
+DPAA = Data Path Acceleration Architecture
+FMan = DPAA Frame Manager
+QMan = DPAA Queue Manager
+BMan = DPAA Buffers Manager
+QMI = QMan interface in FMan
+BMI = BMan interface in FMan
+FMan SP = FMan Storage Profiles
+MURAM = Multi-user RAM in FMan
+FQ = QMan Frame Queue
+Rx Dfl FQ = default reception FQ
+Rx Err FQ = Rx error frames FQ
+Tx Cnf FQ = Tx confirmation FQs
+Tx FQs = transmission frame queues
+dtsec = datapath three speed Ethernet controller (10/100/1000 Mbps)
+tgec = ten gigabit Ethernet controller (10 Gbps)
+memac = multirate Ethernet MAC (10/100/1000/10000)
+
+DPAA Ethernet Supported SoCs
+============================
+
+The DPAA drivers enable the Ethernet controllers present on the following SoCs:
+
+# PPC
+P1023
+P2041
+P3041
+P4080
+P5020
+P5040
+T1023
+T1024
+T1040
+T1042
+T2080
+T4240
+B4860
+
+# ARM
+LS1043A
+LS1046A
+
+Configuring DPAA Ethernet in your kernel
+========================================
+
+To enable the DPAA Ethernet driver, the following Kconfig options are required:
+
+# common for arch/arm64 and arch/powerpc platforms
+CONFIG_FSL_DPAA=y
+CONFIG_FSL_FMAN=y
+CONFIG_FSL_DPAA_ETH=y
+CONFIG_FSL_XGMAC_MDIO=y
+
+# for arch/powerpc only
+CONFIG_FSL_PAMU=y
+
+# common options needed for the PHYs used on the RDBs
+CONFIG_VITESSE_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_AQUANTIA_PHY=y
+
+DPAA Ethernet Frame Processing
+==============================
+
+On Rx, buffers for the incoming frames are retrieved from one of the three
+existing buffers pools. The driver initializes and seeds these, each with
+buffers of different sizes: 1KB, 2KB and 4KB.
+
+On Tx, all transmitted frames are returned to the driver through Tx
+confirmation frame queues. The driver is then responsible for freeing the
+buffers. In order to do this properly, a backpointer is added to the buffer
+before transmission that points to the skb. When the buffer returns to the
+driver on a confirmation FQ, the skb can be correctly consumed.
+
+DPAA Ethernet Features
+======================
+
+Currently the DPAA Ethernet driver enables the basic features required for
+a Linux Ethernet driver. The support for advanced features will be added
+gradually.
+
+The driver has Rx and Tx checksum offloading for UDP and TCP. Currently the Rx
+checksum offload feature is enabled by default and cannot be controlled through
+ethtool.
+
+The driver has support for multiple prioritized Tx traffic classes. Priorities
+range from 0 (lowest) to 3 (highest). These are mapped to HW workqueues with
+strict priority levels. Each traffic class contains NR_CPU TX queues. By
+default, only one traffic class is enabled and the lowest priority Tx queues
+are used. Higher priority traffic classes can be enabled with the mqprio
+qdisc. For example, all four traffic classes are enabled on an interface with
+the following command. Furthermore, skb priority levels are mapped to traffic
+classes as follows:
+
+       * priorities 0 to 3 - traffic class 0 (low priority)
+       * priorities 4 to 7 - traffic class 1 (medium-low priority)
+       * priorities 8 to 11 - traffic class 2 (medium-high priority)
+       * priorities 12 to 15 - traffic class 3 (high priority)
+
+tc qdisc add dev <int> root handle 1: \
+        mqprio num_tc 4 map 0 0 0 0 1 1 1 1 2 2 2 2 3 3 3 3 hw 1
+
+Debugging
+=========
+
+The following statistics are exported for each interface through ethtool:
+
+       - interrupt count per CPU
+       - Rx packets count per CPU
+       - Tx packets count per CPU
+       - Tx confirmed packets count per CPU
+       - Tx S/G frames count per CPU
+       - Tx error count per CPU
+       - Rx error count per CPU
+       - Rx error count per type
+       - congestion related statistics:
+               - congestion status
+               - time spent in congestion
+               - number of time the device entered congestion
+               - dropped packets count per cause
+
+The driver also exports the following information in sysfs:
+
+       - the FQ IDs for each FQ type
+       /sys/devices/platform/dpaa-ethernet.0/net/<int>/fqids
+
+       - the IDs of the buffer pools in use
+       /sys/devices/platform/dpaa-ethernet.0/net/<int>/bpids
index bdc4c0db51e1078fb002907124fe7008ef4c0cd4..9c7139d57e5748508ce20400349cfdefd0284f74 100644 (file)
@@ -1,7 +1,7 @@
 TCP protocol
 ============
 
-Last updated: 9 February 2008
+Last updated: 3 June 2017
 
 Contents
 ========
@@ -29,18 +29,19 @@ As of 2.6.13, Linux supports pluggable congestion control algorithms.
 A congestion control mechanism can be registered through functions in
 tcp_cong.c. The functions used by the congestion control mechanism are
 registered via passing a tcp_congestion_ops struct to
-tcp_register_congestion_control. As a minimum name, ssthresh,
-cong_avoid must be valid.
+tcp_register_congestion_control. As a minimum, the congestion control
+mechanism must provide a valid name and must implement either ssthresh,
+cong_avoid and undo_cwnd hooks or the "omnipotent" cong_control hook.
 
 Private data for a congestion control mechanism is stored in tp->ca_priv.
 tcp_ca(tp) returns a pointer to this space.  This is preallocated space - it
 is important to check the size of your private data will fit this space, or
-alternatively space could be allocated elsewhere and a pointer to it could
+alternatively, space could be allocated elsewhere and a pointer to it could
 be stored here.
 
 There are three kinds of congestion control algorithms currently: The
 simplest ones are derived from TCP reno (highspeed, scalable) and just
-provide an alternative the congestion window calculation. More complex
+provide an alternative congestion window calculation. More complex
 ones like BIC try to look at other events to provide better
 heuristics.  There are also round trip time based algorithms like
 Vegas and Westwood+.
@@ -49,21 +50,15 @@ Good TCP congestion control is a complex problem because the algorithm
 needs to maintain fairness and performance. Please review current
 research and RFC's before developing new modules.
 
-The method that is used to determine which congestion control mechanism is
-determined by the setting of the sysctl net.ipv4.tcp_congestion_control.
-The default congestion control will be the last one registered (LIFO);
-so if you built everything as modules, the default will be reno. If you
-build with the defaults from Kconfig, then CUBIC will be builtin (not a
-module) and it will end up the default.
+The default congestion control mechanism is chosen based on the
+DEFAULT_TCP_CONG Kconfig parameter. If you really want a particular default
+value then you can set it using sysctl net.ipv4.tcp_congestion_control. The
+module will be autoloaded if needed and you will get the expected protocol. If
+you ask for an unknown congestion method, then the sysctl attempt will fail.
 
-If you really want a particular default value then you will need
-to set it with the sysctl.  If you use a sysctl, the module will be autoloaded
-if needed and you will get the expected protocol. If you ask for an
-unknown congestion method, then the sysctl attempt will fail.
-
-If you remove a tcp congestion control module, then you will get the next
+If you remove a TCP congestion control module, then you will get the next
 available one. Since reno cannot be built as a module, and cannot be
-deleted, it will always be available.
+removed, it will always be available.
 
 How the new TCP output machine [nyi] works.
 ===========================================
index 7a28acd7f525ce7c918015be587e1a7bcfab17b9..fb60bf6dfead7f324e759670fc434995fb5581c5 100644 (file)
@@ -8508,7 +8508,7 @@ S:        Odd Fixes
 F:     drivers/media/radio/radio-miropcm20*
 
 MELLANOX MLX4 core VPI driver
-M:     Yishai Hadas <yishaih@mellanox.com>
+M:     Tariq Toukan <tariqt@mellanox.com>
 L:     netdev@vger.kernel.org
 L:     linux-rdma@vger.kernel.org
 W:     http://www.mellanox.com
@@ -8516,7 +8516,6 @@ Q:        http://patchwork.ozlabs.org/project/netdev/list/
 S:     Supported
 F:     drivers/net/ethernet/mellanox/mlx4/
 F:     include/linux/mlx4/
-F:     include/uapi/rdma/mlx4-abi.h
 
 MELLANOX MLX4 IB driver
 M:     Yishai Hadas <yishaih@mellanox.com>
@@ -8526,6 +8525,7 @@ Q:        http://patchwork.kernel.org/project/linux-rdma/list/
 S:     Supported
 F:     drivers/infiniband/hw/mlx4/
 F:     include/linux/mlx4/
+F:     include/uapi/rdma/mlx4-abi.h
 
 MELLANOX MLX5 core VPI driver
 M:     Saeed Mahameed <saeedm@mellanox.com>
@@ -8538,7 +8538,6 @@ Q:        http://patchwork.ozlabs.org/project/netdev/list/
 S:     Supported
 F:     drivers/net/ethernet/mellanox/mlx5/core/
 F:     include/linux/mlx5/
-F:     include/uapi/rdma/mlx5-abi.h
 
 MELLANOX MLX5 IB driver
 M:     Matan Barak <matanb@mellanox.com>
@@ -8549,6 +8548,7 @@ Q:        http://patchwork.kernel.org/project/linux-rdma/list/
 S:     Supported
 F:     drivers/infiniband/hw/mlx5/
 F:     include/linux/mlx5/
+F:     include/uapi/rdma/mlx5-abi.h
 
 MELEXIS MLX90614 DRIVER
 M:     Crt Mori <cmo@melexis.com>
index 9d5dc4fda3c16710c0443b6a5043f212230f057d..3f7d1b74c5e02bd46730c58b0a66756c89b904ab 100644 (file)
                @ there.
                .inst   'M' | ('Z' << 8) | (0x1310 << 16)   @ tstne r0, #0x4d000
 #else
-               mov     r0, r0
+               W(mov)  r0, r0
 #endif
                .endm
 
                .macro  __EFI_HEADER
 #ifdef CONFIG_EFI_STUB
-               b       __efi_start
-
                .set    start_offset, __efi_start - start
                .org    start + 0x3c
                @
index 7c711ba614173d91d8c2fd6ff4ccb13980bb3109..8a756870c238435af684215c653f54a739f4f1a5 100644 (file)
@@ -130,19 +130,22 @@ start:
                .rept   7
                __nop
                .endr
-   ARM(                mov     r0, r0          )
-   ARM(                b       1f              )
- THUMB(                badr    r12, 1f         )
- THUMB(                bx      r12             )
+#ifndef CONFIG_THUMB2_KERNEL
+               mov     r0, r0
+#else
+ AR_CLASS(     sub     pc, pc, #3      )       @ A/R: switch to Thumb2 mode
+  M_CLASS(     nop.w                   )       @ M: already in Thumb2 mode
+               .thumb
+#endif
+               W(b)    1f
 
                .word   _magic_sig      @ Magic numbers to help the loader
                .word   _magic_start    @ absolute load/run zImage address
                .word   _magic_end      @ zImage end address
                .word   0x04030201      @ endianness flag
 
- THUMB(                .thumb                  )
-1:             __EFI_HEADER
-
+               __EFI_HEADER
+1:
  ARM_BE8(      setend  be              )       @ go BE8 if compiled for BE8
  AR_CLASS(     mrs     r9, cpsr        )
 #ifdef CONFIG_ARM_VIRT_EXT
index f18e1f1d0ce2c6aad83c08b7ad8ac4cfc41e715e..d2be8aa3370b7840e014964c147a4742d5ca87e8 100644 (file)
 
                ethphy0: ethernet-phy@2 {
                        reg = <2>;
+                       micrel,led-mode = <1>;
+                       clocks = <&clks IMX6UL_CLK_ENET_REF>;
+                       clock-names = "rmii-ref";
                };
 
                ethphy1: ethernet-phy@1 {
                        reg = <1>;
+                       micrel,led-mode = <1>;
+                       clocks = <&clks IMX6UL_CLK_ENET2_REF>;
+                       clock-names = "rmii-ref";
                };
        };
 };
index cf062472e07bcb4be470bf35ab029df3438dbc7e..2b913f17d50f5d91f50d3aa30e3a8a26c97847b9 100644 (file)
@@ -235,7 +235,7 @@ int mcpm_cpu_power_up(unsigned int cpu, unsigned int cluster)
        return ret;
 }
 
-typedef void (*phys_reset_t)(unsigned long);
+typedef typeof(cpu_reset) phys_reset_t;
 
 void mcpm_cpu_power_down(void)
 {
@@ -300,7 +300,7 @@ void mcpm_cpu_power_down(void)
         * on the CPU.
         */
        phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset);
-       phys_reset(__pa_symbol(mcpm_entry_point));
+       phys_reset(__pa_symbol(mcpm_entry_point), false);
 
        /* should never get here */
        BUG();
@@ -389,7 +389,7 @@ static int __init nocache_trampoline(unsigned long _arg)
        __mcpm_cpu_down(cpu, cluster);
 
        phys_reset = (phys_reset_t)(unsigned long)__pa_symbol(cpu_reset);
-       phys_reset(__pa_symbol(mcpm_entry_point));
+       phys_reset(__pa_symbol(mcpm_entry_point), false);
        BUG();
 }
 
index 302240c19a5aa688e7bdab1ece506dfbeaccea4e..a0d726a47c8a272b722b0d5623021058da50e113 100644 (file)
@@ -66,6 +66,7 @@ typedef pte_t *pte_addr_t;
 #define pgprot_noncached(prot) (prot)
 #define pgprot_writecombine(prot) (prot)
 #define pgprot_dmacoherent(prot) (prot)
+#define pgprot_device(prot)    (prot)
 
 
 /*
index 58243b0d21c006cfea9c47723221a33b7673fae9..b558c9e29de37f3ebeb18593c1a3d234c7d9d060 100644 (file)
@@ -192,9 +192,9 @@ config NR_CPUS
        int "Maximum number of CPUs"
        depends on SMP
        range 2 32 if SPARC32
-       range 2 1024 if SPARC64
+       range 2 4096 if SPARC64
        default 32 if SPARC32
-       default 64 if SPARC64
+       default 4096 if SPARC64
 
 source kernel/Kconfig.hz
 
@@ -295,9 +295,13 @@ config NUMA
        depends on SPARC64 && SMP
 
 config NODES_SHIFT
-       int
-       default "4"
+       int "Maximum NUMA Nodes (as a power of 2)"
+       range 4 5 if SPARC64
+       default "5"
        depends on NEED_MULTIPLE_NODES
+       help
+         Specify the maximum number of NUMA Nodes available on the target
+         system.  Increases memory reserved to accommodate various tables.
 
 # Some NUMA nodes have memory ranges that span
 # other nodes.  Even though a pfn is valid and
index f7de0dbc38af2dd36c9f34df53e6e951f6729825..83b36a5371ffc62e80fa694e077867f4f8b1f49f 100644 (file)
@@ -52,7 +52,7 @@
 #define CTX_NR_MASK            TAG_CONTEXT_BITS
 #define CTX_HW_MASK            (CTX_NR_MASK | CTX_PGSZ_MASK)
 
-#define CTX_FIRST_VERSION      ((_AC(1,UL) << CTX_VERSION_SHIFT) + _AC(1,UL))
+#define CTX_FIRST_VERSION      BIT(CTX_VERSION_SHIFT)
 #define CTX_VALID(__ctx)       \
         (!(((__ctx.sparc64_ctx_val) ^ tlb_context_cache) & CTX_VERSION_MASK))
 #define CTX_HWBITS(__ctx)      ((__ctx.sparc64_ctx_val) & CTX_HW_MASK)
index 22fede6eba116020cf7049e2f45a57545a6d55cb..2cddcda4f85f7555dced053b1fc82fd991e19943 100644 (file)
@@ -19,13 +19,8 @@ extern spinlock_t ctx_alloc_lock;
 extern unsigned long tlb_context_cache;
 extern unsigned long mmu_context_bmap[];
 
+DECLARE_PER_CPU(struct mm_struct *, per_cpu_secondary_mm);
 void get_new_mmu_context(struct mm_struct *mm);
-#ifdef CONFIG_SMP
-void smp_new_mmu_context_version(void);
-#else
-#define smp_new_mmu_context_version() do { } while (0)
-#endif
-
 int init_new_context(struct task_struct *tsk, struct mm_struct *mm);
 void destroy_context(struct mm_struct *mm);
 
@@ -76,8 +71,9 @@ void __flush_tlb_mm(unsigned long, unsigned long);
 static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, struct task_struct *tsk)
 {
        unsigned long ctx_valid, flags;
-       int cpu;
+       int cpu = smp_processor_id();
 
+       per_cpu(per_cpu_secondary_mm, cpu) = mm;
        if (unlikely(mm == &init_mm))
                return;
 
@@ -123,7 +119,6 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
         * for the first time, we must flush that context out of the
         * local TLB.
         */
-       cpu = smp_processor_id();
        if (!ctx_valid || !cpumask_test_cpu(cpu, mm_cpumask(mm))) {
                cpumask_set_cpu(cpu, mm_cpumask(mm));
                __flush_tlb_mm(CTX_HWBITS(mm->context),
@@ -133,26 +128,7 @@ static inline void switch_mm(struct mm_struct *old_mm, struct mm_struct *mm, str
 }
 
 #define deactivate_mm(tsk,mm)  do { } while (0)
-
-/* Activate a new MM instance for the current task. */
-static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm)
-{
-       unsigned long flags;
-       int cpu;
-
-       spin_lock_irqsave(&mm->context.lock, flags);
-       if (!CTX_VALID(mm->context))
-               get_new_mmu_context(mm);
-       cpu = smp_processor_id();
-       if (!cpumask_test_cpu(cpu, mm_cpumask(mm)))
-               cpumask_set_cpu(cpu, mm_cpumask(mm));
-
-       load_secondary_context(mm);
-       __flush_tlb_mm(CTX_HWBITS(mm->context), SECONDARY_CONTEXT);
-       tsb_context_switch(mm);
-       spin_unlock_irqrestore(&mm->context.lock, flags);
-}
-
+#define activate_mm(active_mm, mm) switch_mm(active_mm, mm, NULL)
 #endif /* !(__ASSEMBLY__) */
 
 #endif /* !(__SPARC64_MMU_CONTEXT_H) */
index 2669370305465d7a4d1c2f9c5a7c9eae2f66474d..522b43db2ed336a5d34dee17b4e8c3b593e6ee5d 100644 (file)
@@ -20,7 +20,6 @@
 #define PIL_SMP_CALL_FUNC      1
 #define PIL_SMP_RECEIVE_SIGNAL 2
 #define PIL_SMP_CAPTURE                3
-#define PIL_SMP_CTX_NEW_VERSION        4
 #define PIL_DEVICE_IRQ         5
 #define PIL_SMP_CALL_FUNC_SNGL 6
 #define PIL_DEFERRED_PCR_WORK  7
index 8174f6cdbbbbd87af5bdbcb923352ddadb4e237e..9dca7a892978a49d234a2b9325228b2c900d1276 100644 (file)
@@ -327,6 +327,7 @@ struct vio_dev {
        int                     compat_len;
 
        u64                     dev_no;
+       u64                     id;
 
        unsigned long           channel_id;
 
index b542cc7c8d94d8fc75319091f91ba5dc25251fd9..f87265afb1759e16b735e95067044f827dff27e7 100644 (file)
@@ -909,7 +909,7 @@ static int register_services(struct ds_info *dp)
                pbuf.req.handle = cp->handle;
                pbuf.req.major = 1;
                pbuf.req.minor = 0;
-               strcpy(pbuf.req.svc_id, cp->service_id);
+               strcpy(pbuf.id_buf, cp->service_id);
 
                err = __ds_send(lp, &pbuf, msg_len);
                if (err > 0)
index 4d0248aa0928695597161d93f325a49311b43e2c..99dd133a029f06528f78b2b811d81c97fc7cf9f4 100644 (file)
@@ -1034,17 +1034,26 @@ static void __init init_cpu_send_mondo_info(struct trap_per_cpu *tb)
 {
 #ifdef CONFIG_SMP
        unsigned long page;
+       void *mondo, *p;
 
-       BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > (PAGE_SIZE - 64));
+       BUILD_BUG_ON((NR_CPUS * sizeof(u16)) > PAGE_SIZE);
+
+       /* Make sure mondo block is 64byte aligned */
+       p = kzalloc(127, GFP_KERNEL);
+       if (!p) {
+               prom_printf("SUN4V: Error, cannot allocate mondo block.\n");
+               prom_halt();
+       }
+       mondo = (void *)(((unsigned long)p + 63) & ~0x3f);
+       tb->cpu_mondo_block_pa = __pa(mondo);
 
        page = get_zeroed_page(GFP_KERNEL);
        if (!page) {
-               prom_printf("SUN4V: Error, cannot allocate cpu mondo page.\n");
+               prom_printf("SUN4V: Error, cannot allocate cpu list page.\n");
                prom_halt();
        }
 
-       tb->cpu_mondo_block_pa = __pa(page);
-       tb->cpu_list_pa = __pa(page + 64);
+       tb->cpu_list_pa = __pa(page);
 #endif
 }
 
index c9804551262cc2832ea35b0d1285dc3051319fd4..6ae1e77be0bfde27696595a1f33e939935d83321 100644 (file)
@@ -37,7 +37,6 @@ void handle_stdfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr
 /* smp_64.c */
 void __irq_entry smp_call_function_client(int irq, struct pt_regs *regs);
 void __irq_entry smp_call_function_single_client(int irq, struct pt_regs *regs);
-void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs);
 void __irq_entry smp_penguin_jailcell(int irq, struct pt_regs *regs);
 void __irq_entry smp_receive_signal_client(int irq, struct pt_regs *regs);
 
index b3bc0ac757cc11c0c77e106a447817b89d821cae..fdf31040a7dc5cc460de6d60c9724a60933b38dc 100644 (file)
@@ -964,37 +964,6 @@ void flush_dcache_page_all(struct mm_struct *mm, struct page *page)
        preempt_enable();
 }
 
-void __irq_entry smp_new_mmu_context_version_client(int irq, struct pt_regs *regs)
-{
-       struct mm_struct *mm;
-       unsigned long flags;
-
-       clear_softint(1 << irq);
-
-       /* See if we need to allocate a new TLB context because
-        * the version of the one we are using is now out of date.
-        */
-       mm = current->active_mm;
-       if (unlikely(!mm || (mm == &init_mm)))
-               return;
-
-       spin_lock_irqsave(&mm->context.lock, flags);
-
-       if (unlikely(!CTX_VALID(mm->context)))
-               get_new_mmu_context(mm);
-
-       spin_unlock_irqrestore(&mm->context.lock, flags);
-
-       load_secondary_context(mm);
-       __flush_tlb_mm(CTX_HWBITS(mm->context),
-                      SECONDARY_CONTEXT);
-}
-
-void smp_new_mmu_context_version(void)
-{
-       smp_cross_call(&xcall_new_mmu_context_version, 0, 0, 0);
-}
-
 #ifdef CONFIG_KGDB
 void kgdb_roundup_cpus(unsigned long flags)
 {
index 10689cfd0ad40e6b12ae6b148f99ac2f5c7deb64..07c0df92496034efd1262dd2b40e56ffd5486c0c 100644 (file)
@@ -455,13 +455,16 @@ __tsb_context_switch:
        .type   copy_tsb,#function
 copy_tsb:              /* %o0=old_tsb_base, %o1=old_tsb_size
                         * %o2=new_tsb_base, %o3=new_tsb_size
+                        * %o4=page_size_shift
                         */
        sethi           %uhi(TSB_PASS_BITS), %g7
        srlx            %o3, 4, %o3
-       add             %o0, %o1, %g1   /* end of old tsb */
+       add             %o0, %o1, %o1   /* end of old tsb */
        sllx            %g7, 32, %g7
        sub             %o3, 1, %o3     /* %o3 == new tsb hash mask */
 
+       mov             %o4, %g1        /* page_size_shift */
+
 661:   prefetcha       [%o0] ASI_N, #one_read
        .section        .tsb_phys_patch, "ax"
        .word           661b
@@ -486,9 +489,9 @@ copy_tsb:           /* %o0=old_tsb_base, %o1=old_tsb_size
        /* This can definitely be computed faster... */
        srlx            %o0, 4, %o5     /* Build index */
        and             %o5, 511, %o5   /* Mask index */
-       sllx            %o5, PAGE_SHIFT, %o5 /* Put into vaddr position */
+       sllx            %o5, %g1, %o5   /* Put into vaddr position */
        or              %o4, %o5, %o4   /* Full VADDR. */
-       srlx            %o4, PAGE_SHIFT, %o4 /* Shift down to create index */
+       srlx            %o4, %g1, %o4   /* Shift down to create index */
        and             %o4, %o3, %o4   /* Mask with new_tsb_nents-1 */
        sllx            %o4, 4, %o4     /* Shift back up into tsb ent offset */
        TSB_STORE(%o2 + %o4, %g2)       /* Store TAG */
@@ -496,7 +499,7 @@ copy_tsb:           /* %o0=old_tsb_base, %o1=old_tsb_size
        TSB_STORE(%o2 + %o4, %g3)       /* Store TTE */
 
 80:    add             %o0, 16, %o0
-       cmp             %o0, %g1
+       cmp             %o0, %o1
        bne,pt          %xcc, 90b
         nop
 
index 7bd8f6556352d91cdc30e18d590e7421ffba6465..efe93ab4a9c0654143d52569c7157f9117e7ae37 100644 (file)
@@ -50,7 +50,7 @@ tl0_resv03e:  BTRAP(0x3e) BTRAP(0x3f) BTRAP(0x40)
 tl0_irq1:      TRAP_IRQ(smp_call_function_client, 1)
 tl0_irq2:      TRAP_IRQ(smp_receive_signal_client, 2)
 tl0_irq3:      TRAP_IRQ(smp_penguin_jailcell, 3)
-tl0_irq4:      TRAP_IRQ(smp_new_mmu_context_version_client, 4)
+tl0_irq4:       BTRAP(0x44)
 #else
 tl0_irq1:      BTRAP(0x41)
 tl0_irq2:      BTRAP(0x42)
index f6bb857254fcfa170155d4cd8dc8cb717c5bfb97..075d38980dee394fdb32f86e130d0b3ec37ebfeb 100644 (file)
@@ -302,13 +302,16 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        if (!id) {
                dev_set_name(&vdev->dev, "%s", bus_id_name);
                vdev->dev_no = ~(u64)0;
+               vdev->id = ~(u64)0;
        } else if (!cfg_handle) {
                dev_set_name(&vdev->dev, "%s-%llu", bus_id_name, *id);
                vdev->dev_no = *id;
+               vdev->id = ~(u64)0;
        } else {
                dev_set_name(&vdev->dev, "%s-%llu-%llu", bus_id_name,
                             *cfg_handle, *id);
                vdev->dev_no = *cfg_handle;
+               vdev->id = *id;
        }
 
        vdev->dev.parent = parent;
@@ -351,27 +354,84 @@ static void vio_add(struct mdesc_handle *hp, u64 node)
        (void) vio_create_one(hp, node, &root_vdev->dev);
 }
 
+struct vio_md_node_query {
+       const char *type;
+       u64 dev_no;
+       u64 id;
+};
+
 static int vio_md_node_match(struct device *dev, void *arg)
 {
+       struct vio_md_node_query *query = (struct vio_md_node_query *) arg;
        struct vio_dev *vdev = to_vio_dev(dev);
 
-       if (vdev->mp == (u64) arg)
-               return 1;
+       if (vdev->dev_no != query->dev_no)
+               return 0;
+       if (vdev->id != query->id)
+               return 0;
+       if (strcmp(vdev->type, query->type))
+               return 0;
 
-       return 0;
+       return 1;
 }
 
 static void vio_remove(struct mdesc_handle *hp, u64 node)
 {
+       const char *type;
+       const u64 *id, *cfg_handle;
+       u64 a;
+       struct vio_md_node_query query;
        struct device *dev;
 
-       dev = device_find_child(&root_vdev->dev, (void *) node,
+       type = mdesc_get_property(hp, node, "device-type", NULL);
+       if (!type) {
+               type = mdesc_get_property(hp, node, "name", NULL);
+               if (!type)
+                       type = mdesc_node_name(hp, node);
+       }
+
+       query.type = type;
+
+       id = mdesc_get_property(hp, node, "id", NULL);
+       cfg_handle = NULL;
+       mdesc_for_each_arc(a, hp, node, MDESC_ARC_TYPE_BACK) {
+               u64 target;
+
+               target = mdesc_arc_target(hp, a);
+               cfg_handle = mdesc_get_property(hp, target,
+                                               "cfg-handle", NULL);
+               if (cfg_handle)
+                       break;
+       }
+
+       if (!id) {
+               query.dev_no = ~(u64)0;
+               query.id = ~(u64)0;
+       } else if (!cfg_handle) {
+               query.dev_no = *id;
+               query.id = ~(u64)0;
+       } else {
+               query.dev_no = *cfg_handle;
+               query.id = *id;
+       }
+
+       dev = device_find_child(&root_vdev->dev, &query,
                                vio_md_node_match);
        if (dev) {
                printk(KERN_INFO "VIO: Removing device %s\n", dev_name(dev));
 
                device_unregister(dev);
                put_device(dev);
+       } else {
+               if (!id)
+                       printk(KERN_ERR "VIO: Removed unknown %s node.\n",
+                              type);
+               else if (!cfg_handle)
+                       printk(KERN_ERR "VIO: Removed unknown %s node %llu.\n",
+                              type, *id);
+               else
+                       printk(KERN_ERR "VIO: Removed unknown %s node %llu-%llu.\n",
+                              type, *cfg_handle, *id);
        }
 }
 
index 69912d2f8b54e903ef040b346371cc27204b9d15..07c03e72d81248cebe9c3d48bbc93e1e2de455b7 100644 (file)
@@ -15,6 +15,7 @@ lib-$(CONFIG_SPARC32) += copy_user.o locks.o
 lib-$(CONFIG_SPARC64) += atomic_64.o
 lib-$(CONFIG_SPARC32) += lshrdi3.o ashldi3.o
 lib-$(CONFIG_SPARC32) += muldi3.o bitext.o cmpdi2.o
+lib-$(CONFIG_SPARC64) += multi3.o
 
 lib-$(CONFIG_SPARC64) += copy_page.o clear_page.o bzero.o
 lib-$(CONFIG_SPARC64) += csum_copy.o csum_copy_from_user.o csum_copy_to_user.o
diff --git a/arch/sparc/lib/multi3.S b/arch/sparc/lib/multi3.S
new file mode 100644 (file)
index 0000000..d6b6c97
--- /dev/null
@@ -0,0 +1,35 @@
+#include <linux/linkage.h>
+#include <asm/export.h>
+
+       .text
+       .align  4
+ENTRY(__multi3) /* %o0 = u, %o1 = v */
+       mov     %o1, %g1
+       srl     %o3, 0, %g4
+       mulx    %g4, %g1, %o1
+       srlx    %g1, 0x20, %g3
+       mulx    %g3, %g4, %g5
+       sllx    %g5, 0x20, %o5
+       srl     %g1, 0, %g4
+       sub     %o1, %o5, %o5
+       srlx    %o5, 0x20, %o5
+       addcc   %g5, %o5, %g5
+       srlx    %o3, 0x20, %o5
+       mulx    %g4, %o5, %g4
+       mulx    %g3, %o5, %o5
+       sethi   %hi(0x80000000), %g3
+       addcc   %g5, %g4, %g5
+       srlx    %g5, 0x20, %g5
+       add     %g3, %g3, %g3
+       movcc   %xcc, %g0, %g3
+       addcc   %o5, %g5, %o5
+       sllx    %g4, 0x20, %g4
+       add     %o1, %g4, %o1
+       add     %o5, %g3, %g2
+       mulx    %g1, %o2, %g1
+       add     %g1, %g2, %g1
+       mulx    %o0, %o3, %o0
+       retl
+        add    %g1, %o0, %o0
+ENDPROC(__multi3)
+EXPORT_SYMBOL(__multi3)
index 0cda653ae007645fa01f05b4c40518332159a6ac..3c40ebd50f928cbbbfe69c65c35810a78b30c53d 100644 (file)
@@ -358,7 +358,8 @@ static int __init setup_hugepagesz(char *string)
        }
 
        if ((hv_pgsz_mask & cpu_pgsz_mask) == 0U) {
-               pr_warn("hugepagesz=%llu not supported by MMU.\n",
+               hugetlb_bad_size();
+               pr_err("hugepagesz=%llu not supported by MMU.\n",
                        hugepage_size);
                goto out;
        }
@@ -706,10 +707,58 @@ EXPORT_SYMBOL(__flush_dcache_range);
 
 /* get_new_mmu_context() uses "cache + 1".  */
 DEFINE_SPINLOCK(ctx_alloc_lock);
-unsigned long tlb_context_cache = CTX_FIRST_VERSION - 1;
+unsigned long tlb_context_cache = CTX_FIRST_VERSION;
 #define MAX_CTX_NR     (1UL << CTX_NR_BITS)
 #define CTX_BMAP_SLOTS BITS_TO_LONGS(MAX_CTX_NR)
 DECLARE_BITMAP(mmu_context_bmap, MAX_CTX_NR);
+DEFINE_PER_CPU(struct mm_struct *, per_cpu_secondary_mm) = {0};
+
+static void mmu_context_wrap(void)
+{
+       unsigned long old_ver = tlb_context_cache & CTX_VERSION_MASK;
+       unsigned long new_ver, new_ctx, old_ctx;
+       struct mm_struct *mm;
+       int cpu;
+
+       bitmap_zero(mmu_context_bmap, 1 << CTX_NR_BITS);
+
+       /* Reserve kernel context */
+       set_bit(0, mmu_context_bmap);
+
+       new_ver = (tlb_context_cache & CTX_VERSION_MASK) + CTX_FIRST_VERSION;
+       if (unlikely(new_ver == 0))
+               new_ver = CTX_FIRST_VERSION;
+       tlb_context_cache = new_ver;
+
+       /*
+        * Make sure that any new mm that are added into per_cpu_secondary_mm,
+        * are going to go through get_new_mmu_context() path.
+        */
+       mb();
+
+       /*
+        * Updated versions to current on those CPUs that had valid secondary
+        * contexts
+        */
+       for_each_online_cpu(cpu) {
+               /*
+                * If a new mm is stored after we took this mm from the array,
+                * it will go into get_new_mmu_context() path, because we
+                * already bumped the version in tlb_context_cache.
+                */
+               mm = per_cpu(per_cpu_secondary_mm, cpu);
+
+               if (unlikely(!mm || mm == &init_mm))
+                       continue;
+
+               old_ctx = mm->context.sparc64_ctx_val;
+               if (likely((old_ctx & CTX_VERSION_MASK) == old_ver)) {
+                       new_ctx = (old_ctx & ~CTX_VERSION_MASK) | new_ver;
+                       set_bit(new_ctx & CTX_NR_MASK, mmu_context_bmap);
+                       mm->context.sparc64_ctx_val = new_ctx;
+               }
+       }
+}
 
 /* Caller does TLB context flushing on local CPU if necessary.
  * The caller also ensures that CTX_VALID(mm->context) is false.
@@ -725,48 +774,30 @@ void get_new_mmu_context(struct mm_struct *mm)
 {
        unsigned long ctx, new_ctx;
        unsigned long orig_pgsz_bits;
-       int new_version;
 
        spin_lock(&ctx_alloc_lock);
+retry:
+       /* wrap might have happened, test again if our context became valid */
+       if (unlikely(CTX_VALID(mm->context)))
+               goto out;
        orig_pgsz_bits = (mm->context.sparc64_ctx_val & CTX_PGSZ_MASK);
        ctx = (tlb_context_cache + 1) & CTX_NR_MASK;
        new_ctx = find_next_zero_bit(mmu_context_bmap, 1 << CTX_NR_BITS, ctx);
-       new_version = 0;
        if (new_ctx >= (1 << CTX_NR_BITS)) {
                new_ctx = find_next_zero_bit(mmu_context_bmap, ctx, 1);
                if (new_ctx >= ctx) {
-                       int i;
-                       new_ctx = (tlb_context_cache & CTX_VERSION_MASK) +
-                               CTX_FIRST_VERSION;
-                       if (new_ctx == 1)
-                               new_ctx = CTX_FIRST_VERSION;
-
-                       /* Don't call memset, for 16 entries that's just
-                        * plain silly...
-                        */
-                       mmu_context_bmap[0] = 3;
-                       mmu_context_bmap[1] = 0;
-                       mmu_context_bmap[2] = 0;
-                       mmu_context_bmap[3] = 0;
-                       for (i = 4; i < CTX_BMAP_SLOTS; i += 4) {
-                               mmu_context_bmap[i + 0] = 0;
-                               mmu_context_bmap[i + 1] = 0;
-                               mmu_context_bmap[i + 2] = 0;
-                               mmu_context_bmap[i + 3] = 0;
-                       }
-                       new_version = 1;
-                       goto out;
+                       mmu_context_wrap();
+                       goto retry;
                }
        }
+       if (mm->context.sparc64_ctx_val)
+               cpumask_clear(mm_cpumask(mm));
        mmu_context_bmap[new_ctx>>6] |= (1UL << (new_ctx & 63));
        new_ctx |= (tlb_context_cache & CTX_VERSION_MASK);
-out:
        tlb_context_cache = new_ctx;
        mm->context.sparc64_ctx_val = new_ctx | orig_pgsz_bits;
+out:
        spin_unlock(&ctx_alloc_lock);
-
-       if (unlikely(new_version))
-               smp_new_mmu_context_version();
 }
 
 static int numa_enabled = 1;
index bedf08b22a4773c5a104b56f7de8b44c461630c1..0d4b998c7d7b74a9e930f12d735591f14769befd 100644 (file)
@@ -496,7 +496,8 @@ retry_tsb_alloc:
                extern void copy_tsb(unsigned long old_tsb_base,
                                     unsigned long old_tsb_size,
                                     unsigned long new_tsb_base,
-                                    unsigned long new_tsb_size);
+                                    unsigned long new_tsb_size,
+                                    unsigned long page_size_shift);
                unsigned long old_tsb_base = (unsigned long) old_tsb;
                unsigned long new_tsb_base = (unsigned long) new_tsb;
 
@@ -504,7 +505,9 @@ retry_tsb_alloc:
                        old_tsb_base = __pa(old_tsb_base);
                        new_tsb_base = __pa(new_tsb_base);
                }
-               copy_tsb(old_tsb_base, old_size, new_tsb_base, new_size);
+               copy_tsb(old_tsb_base, old_size, new_tsb_base, new_size,
+                       tsb_index == MM_TSB_BASE ?
+                       PAGE_SHIFT : REAL_HPAGE_SHIFT);
        }
 
        mm->context.tsb_block[tsb_index].tsb = new_tsb;
index 5d2fd6cd31896b87a3373a59cbfc3130808c6908..fcf4d27a38fb47af30d026079022d07bb803e323 100644 (file)
@@ -971,11 +971,6 @@ xcall_capture:
        wr              %g0, (1 << PIL_SMP_CAPTURE), %set_softint
        retry
 
-       .globl          xcall_new_mmu_context_version
-xcall_new_mmu_context_version:
-       wr              %g0, (1 << PIL_SMP_CTX_NEW_VERSION), %set_softint
-       retry
-
 #ifdef CONFIG_KGDB
        .globl          xcall_kgdb_capture
 xcall_kgdb_capture:
index 2fc52407306c15c27b9fb0b11c2db4ef4641aeba..c69954023c2e7d8c235aace4b66a1d32298f36eb 100644 (file)
@@ -1364,6 +1364,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host)
 {}
 #endif
 
+/*
+ * On the Acer Aspire Switch Alpha 12, sometimes all SATA ports are detected
+ * as DUMMY, or detected but eventually get a "link down" and never get up
+ * again. When this happens, CAP.NP may hold a value of 0x00 or 0x01, and the
+ * port_map may hold a value of 0x00.
+ *
+ * Overriding CAP.NP to 0x02 and the port_map to 0x7 will reveal all 3 ports
+ * and can significantly reduce the occurrence of the problem.
+ *
+ * https://bugzilla.kernel.org/show_bug.cgi?id=189471
+ */
+static void acer_sa5_271_workaround(struct ahci_host_priv *hpriv,
+                                   struct pci_dev *pdev)
+{
+       static const struct dmi_system_id sysids[] = {
+               {
+                       .ident = "Acer Switch Alpha 12",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "Switch SA5-271")
+                       },
+               },
+               { }
+       };
+
+       if (dmi_check_system(sysids)) {
+               dev_info(&pdev->dev, "enabling Acer Switch Alpha 12 workaround\n");
+               if ((hpriv->saved_cap & 0xC734FF00) == 0xC734FF00) {
+                       hpriv->port_map = 0x7;
+                       hpriv->cap = 0xC734FF02;
+               }
+       }
+}
+
 #ifdef CONFIG_ARM64
 /*
  * Due to ERRATA#22536, ThunderX needs to handle HOST_IRQ_STAT differently.
@@ -1636,6 +1670,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                         "online status unreliable, applying workaround\n");
        }
 
+
+       /* Acer SA5-271 workaround modifies private_data */
+       acer_sa5_271_workaround(hpriv, pdev);
+
        /* CAP.NP sometimes indicate the index of the last enabled
         * port, at other times, that of the last possible port, so
         * determining the maximum port number requires looking at
index aaa761b9081cc02a75792302c741f7b54ebd9823..cd2eab6aa92ea245e1a3dab839be7fe8aa938cdb 100644 (file)
@@ -514,8 +514,9 @@ int ahci_platform_init_host(struct platform_device *pdev,
 
        irq = platform_get_irq(pdev, 0);
        if (irq <= 0) {
-               dev_err(dev, "no irq\n");
-               return -EINVAL;
+               if (irq != -EPROBE_DEFER)
+                       dev_err(dev, "no irq\n");
+               return irq;
        }
 
        hpriv->irq = irq;
index 2d83b8c7596567a020300d8dd1aeefeb33a6a055..e157a0e4441916b77b53c402741b74e124012cc9 100644 (file)
@@ -6800,7 +6800,7 @@ static int __init ata_parse_force_one(char **cur,
        }
 
        force_ent->port = simple_strtoul(id, &endp, 10);
-       if (p == endp || *endp != '\0') {
+       if (id == endp || *endp != '\0') {
                *reason = "invalid port/link";
                return -EINVAL;
        }
index b66bcda88320fefa399ac9653eca64d3045a6a96..3b2246dded74fbeed89d53f913c725ab6e5c0082 100644 (file)
@@ -4067,7 +4067,6 @@ static int mv_platform_probe(struct platform_device *pdev)
        struct ata_host *host;
        struct mv_host_priv *hpriv;
        struct resource *res;
-       void __iomem *mmio;
        int n_ports = 0, irq = 0;
        int rc;
        int port;
@@ -4086,9 +4085,8 @@ static int mv_platform_probe(struct platform_device *pdev)
         * Get the register base first
         */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       mmio = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(mmio))
-               return PTR_ERR(mmio);
+       if (res == NULL)
+               return -EINVAL;
 
        /* allocate host */
        if (pdev->dev.of_node) {
@@ -4132,7 +4130,12 @@ static int mv_platform_probe(struct platform_device *pdev)
        hpriv->board_idx = chip_soc;
 
        host->iomap = NULL;
-       hpriv->base = mmio - SATAHC0_REG_BASE;
+       hpriv->base = devm_ioremap(&pdev->dev, res->start,
+                                  resource_size(res));
+       if (!hpriv->base)
+               return -ENOMEM;
+
+       hpriv->base -= SATAHC0_REG_BASE;
 
        hpriv->clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(hpriv->clk))
index 5d38245a7a73a7cc4fa0d49255a52c7daead7886..b7939a2c1fab53ff2a94799a261d401c1c440f2e 100644 (file)
@@ -890,7 +890,10 @@ static int sata_rcar_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "failed to get access to sata clock\n");
                return PTR_ERR(priv->clk);
        }
-       clk_prepare_enable(priv->clk);
+
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+               return ret;
 
        host = ata_host_alloc(&pdev->dev, 1);
        if (!host) {
@@ -970,8 +973,11 @@ static int sata_rcar_resume(struct device *dev)
        struct ata_host *host = dev_get_drvdata(dev);
        struct sata_rcar_priv *priv = host->private_data;
        void __iomem *base = priv->base;
+       int ret;
 
-       clk_prepare_enable(priv->clk);
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+               return ret;
 
        /* ack and mask */
        iowrite32(0, base + SATAINTSTAT_REG);
@@ -988,8 +994,11 @@ static int sata_rcar_restore(struct device *dev)
 {
        struct ata_host *host = dev_get_drvdata(dev);
        struct sata_rcar_priv *priv = host->private_data;
+       int ret;
 
-       clk_prepare_enable(priv->clk);
+       ret = clk_prepare_enable(priv->clk);
+       if (ret)
+               return ret;
 
        sata_rcar_setup_port(host);
 
index d07dd5196ffca59c11532051fb88e2ecdc7326c9..8aa158a091806fd7d3107ed56b8550198be7b9a0 100644 (file)
@@ -2364,7 +2364,7 @@ static struct ippp_ccp_reset_state *isdn_ppp_ccp_reset_alloc_state(struct ippp_s
                       id);
                return NULL;
        } else {
-               rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_KERNEL);
+               rs = kzalloc(sizeof(struct ippp_ccp_reset_state), GFP_ATOMIC);
                if (!rs)
                        return NULL;
                rs->state = CCPResetIdle;
index 8b7faea2ddf88b718c252dc049e5d1b8b5e8357b..422dced7c90ac26dcf0d366fedb32ab9edf44207 100644 (file)
@@ -75,7 +75,7 @@ send_socklist(struct mISDN_sock_list *sl, struct sk_buff *skb)
                if (sk->sk_state != MISDN_BOUND)
                        continue;
                if (!cskb)
-                       cskb = skb_copy(skb, GFP_KERNEL);
+                       cskb = skb_copy(skb, GFP_ATOMIC);
                if (!cskb) {
                        printk(KERN_WARNING "%s no skb\n", __func__);
                        break;
index b72edd27f880fbe99641cd36b44005c6ad9252c6..55d9c2b82b7eab11268d88f7d8e5cf586f910985 100644 (file)
@@ -2,6 +2,12 @@
 # Multimedia device configuration
 #
 
+config CEC_CORE
+       tristate
+
+config CEC_NOTIFIER
+       bool
+
 menuconfig MEDIA_SUPPORT
        tristate "Multimedia support"
        depends on HAS_IOMEM
index 523fea3648ad71749009fc9f7d0f543d36734128..044503aa8801744785da9c637bda4c020bfac766 100644 (file)
@@ -4,8 +4,6 @@
 
 media-objs     := media-device.o media-devnode.o media-entity.o
 
-obj-$(CONFIG_CEC_CORE) += cec/
-
 #
 # I2C drivers should come before other drivers, otherwise they'll fail
 # when compiled as builtin drivers
@@ -26,6 +24,8 @@ obj-$(CONFIG_DVB_CORE)  += dvb-core/
 # There are both core and drivers at RC subtree - merge before drivers
 obj-y += rc/
 
+obj-$(CONFIG_CEC_CORE) += cec/
+
 #
 # Finally, merge the drivers that require the core
 #
index f944d93e3167f4e338a1e9cb607af32311136b50..4e25a950ae6f5af73c7bc7bd305a51368ef7d52b 100644 (file)
@@ -1,19 +1,5 @@
-config CEC_CORE
-       tristate
-       depends on MEDIA_CEC_SUPPORT
-       default y
-
-config MEDIA_CEC_NOTIFIER
-       bool
-
 config MEDIA_CEC_RC
        bool "HDMI CEC RC integration"
        depends on CEC_CORE && RC_CORE
        ---help---
          Pass on CEC remote control messages to the RC framework.
-
-config MEDIA_CEC_DEBUG
-       bool "HDMI CEC debugfs interface"
-       depends on CEC_CORE && DEBUG_FS
-       ---help---
-         Turns on the DebugFS interface for CEC devices.
index 402a6c62a3e8b9bb4857ac553e1b9a14c6babc16..eaf408e646697adcb8cc95b95c8425574715bdee 100644 (file)
@@ -1,6 +1,6 @@
 cec-objs := cec-core.o cec-adap.o cec-api.o cec-edid.o
 
-ifeq ($(CONFIG_MEDIA_CEC_NOTIFIER),y)
+ifeq ($(CONFIG_CEC_NOTIFIER),y)
   cec-objs += cec-notifier.o
 endif
 
index f5fe01c9da8af17906805668b8448cd6aaf9da1e..9dfc79800c7191964557afe729603afa5cf2b5df 100644 (file)
@@ -1864,7 +1864,7 @@ void cec_monitor_all_cnt_dec(struct cec_adapter *adap)
                WARN_ON(call_op(adap, adap_monitor_all_enable, 0));
 }
 
-#ifdef CONFIG_MEDIA_CEC_DEBUG
+#ifdef CONFIG_DEBUG_FS
 /*
  * Log the current state of the CEC adapter.
  * Very useful for debugging.
index f9ebff90f8ebc08b77088c8f1901d8aa7077b99f..2f87748ba4fceea377284be6a1c35b6478ca4788 100644 (file)
@@ -187,7 +187,7 @@ static void cec_devnode_unregister(struct cec_devnode *devnode)
        put_device(&devnode->dev);
 }
 
-#ifdef CONFIG_MEDIA_CEC_NOTIFIER
+#ifdef CONFIG_CEC_NOTIFIER
 static void cec_cec_notify(struct cec_adapter *adap, u16 pa)
 {
        cec_s_phys_addr(adap, pa, false);
@@ -323,7 +323,7 @@ int cec_register_adapter(struct cec_adapter *adap,
        }
 
        dev_set_drvdata(&adap->devnode.dev, adap);
-#ifdef CONFIG_MEDIA_CEC_DEBUG
+#ifdef CONFIG_DEBUG_FS
        if (!top_cec_dir)
                return 0;
 
@@ -355,7 +355,7 @@ void cec_unregister_adapter(struct cec_adapter *adap)
        adap->rc = NULL;
 #endif
        debugfs_remove_recursive(adap->cec_dir);
-#ifdef CONFIG_MEDIA_CEC_NOTIFIER
+#ifdef CONFIG_CEC_NOTIFIER
        if (adap->notifier)
                cec_notifier_unregister(adap->notifier);
 #endif
@@ -395,7 +395,7 @@ static int __init cec_devnode_init(void)
                return ret;
        }
 
-#ifdef CONFIG_MEDIA_CEC_DEBUG
+#ifdef CONFIG_DEBUG_FS
        top_cec_dir = debugfs_create_dir("cec", NULL);
        if (IS_ERR_OR_NULL(top_cec_dir)) {
                pr_warn("cec: Failed to create debugfs cec dir\n");
index fd181c99ce117fc44c16ded99d50abe9a655b4f8..aaa9471c7d117eae0a00e4bbbf4ed20e3ca65b36 100644 (file)
@@ -220,7 +220,8 @@ config VIDEO_ADV7604
 
 config VIDEO_ADV7604_CEC
        bool "Enable Analog Devices ADV7604 CEC support"
-       depends on VIDEO_ADV7604 && CEC_CORE
+       depends on VIDEO_ADV7604
+       select CEC_CORE
        ---help---
          When selected the adv7604 will support the optional
          HDMI CEC feature.
@@ -240,7 +241,8 @@ config VIDEO_ADV7842
 
 config VIDEO_ADV7842_CEC
        bool "Enable Analog Devices ADV7842 CEC support"
-       depends on VIDEO_ADV7842 && CEC_CORE
+       depends on VIDEO_ADV7842
+       select CEC_CORE
        ---help---
          When selected the adv7842 will support the optional
          HDMI CEC feature.
@@ -478,7 +480,8 @@ config VIDEO_ADV7511
 
 config VIDEO_ADV7511_CEC
        bool "Enable Analog Devices ADV7511 CEC support"
-       depends on VIDEO_ADV7511 && CEC_CORE
+       depends on VIDEO_ADV7511
+       select CEC_CORE
        ---help---
          When selected the adv7511 will support the optional
          HDMI CEC feature.
index ac026ee1ca07484ffa6b0c51632d1c9958c0d3cd..041cb80a26b1ff22f049abaed44b0a62c9b91a9c 100644 (file)
@@ -501,8 +501,9 @@ if CEC_PLATFORM_DRIVERS
 
 config VIDEO_SAMSUNG_S5P_CEC
        tristate "Samsung S5P CEC driver"
-       depends on CEC_CORE && (PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST)
-       select MEDIA_CEC_NOTIFIER
+       depends on PLAT_S5P || ARCH_EXYNOS || COMPILE_TEST
+       select CEC_CORE
+       select CEC_NOTIFIER
        ---help---
          This is a driver for Samsung S5P HDMI CEC interface. It uses the
          generic CEC framework interface.
@@ -511,8 +512,9 @@ config VIDEO_SAMSUNG_S5P_CEC
 
 config VIDEO_STI_HDMI_CEC
        tristate "STMicroelectronics STiH4xx HDMI CEC driver"
-       depends on CEC_CORE && (ARCH_STI || COMPILE_TEST)
-       select MEDIA_CEC_NOTIFIER
+       depends on ARCH_STI || COMPILE_TEST
+       select CEC_CORE
+       select CEC_NOTIFIER
        ---help---
          This is a driver for STIH4xx HDMI CEC interface. It uses the
          generic CEC framework interface.
index b36ac19dc6e48d60afbc4053fb848d9439dfcd5d..154de92dd809e74ff3d7539787856fef631229fc 100644 (file)
@@ -26,7 +26,8 @@ config VIDEO_VIVID
 
 config VIDEO_VIVID_CEC
        bool "Enable CEC emulation support"
-       depends on VIDEO_VIVID && CEC_CORE
+       depends on VIDEO_VIVID
+       select CEC_CORE
        ---help---
          When selected the vivid module will emulate the optional
          HDMI CEC feature.
index 90f66dc7c0d74dbed7cf370f652546eadc563bf8..a2fc1a1d58b0e317539a1a679e32f96c12d3b00f 100644 (file)
@@ -211,7 +211,7 @@ EXPORT_SYMBOL_GPL(ir_raw_event_set_idle);
  */
 void ir_raw_event_handle(struct rc_dev *dev)
 {
-       if (!dev->raw)
+       if (!dev->raw || !dev->raw->thread)
                return;
 
        wake_up_process(dev->raw->thread);
@@ -490,6 +490,7 @@ int ir_raw_event_register(struct rc_dev *dev)
 {
        int rc;
        struct ir_raw_handler *handler;
+       struct task_struct *thread;
 
        if (!dev)
                return -EINVAL;
@@ -507,13 +508,15 @@ int ir_raw_event_register(struct rc_dev *dev)
         * because the event is coming from userspace
         */
        if (dev->driver_type != RC_DRIVER_IR_RAW_TX) {
-               dev->raw->thread = kthread_run(ir_raw_event_thread, dev->raw,
-                                              "rc%u", dev->minor);
+               thread = kthread_run(ir_raw_event_thread, dev->raw, "rc%u",
+                                    dev->minor);
 
-               if (IS_ERR(dev->raw->thread)) {
-                       rc = PTR_ERR(dev->raw->thread);
+               if (IS_ERR(thread)) {
+                       rc = PTR_ERR(thread);
                        goto out;
                }
+
+               dev->raw->thread = thread;
        }
 
        mutex_lock(&ir_raw_handler_lock);
index 8937f3986a01f1c89e3fcc5b6825cb6b754ddf20..18ead44824ba2bd02d27480e0f04ac69f39182fd 100644 (file)
@@ -1,6 +1,7 @@
 config USB_PULSE8_CEC
        tristate "Pulse Eight HDMI CEC"
-       depends on USB_ACM && CEC_CORE
+       depends on USB_ACM
+       select CEC_CORE
        select SERIO
        select SERIO_SERPORT
        ---help---
index 3eb86607efb8f627566af1ff374053d7f6b980ec..030ef01b1ff04137ede4a84ddf0357afe943343d 100644 (file)
@@ -1,6 +1,7 @@
 config USB_RAINSHADOW_CEC
        tristate "RainShadow Tech HDMI CEC"
-       depends on USB_ACM && CEC_CORE
+       depends on USB_ACM
+       select CEC_CORE
        select SERIO
        select SERIO_SERPORT
        ---help---
index 541ca543f71f4efe7e29e7c22bce114c2b18fc3d..71bd68548c9c87d3359a458efe9069c59a81e81a 100644 (file)
@@ -119,7 +119,7 @@ static void rain_irq_work_handler(struct work_struct *work)
 
        while (true) {
                unsigned long flags;
-               bool exit_loop;
+               bool exit_loop = false;
                char data;
 
                spin_lock_irqsave(&rain->buf_lock, flags);
index 96046bb12ca17333530f237fddb46438c3298dea..14c0be98e0a4d449aa4122c2db6e9ef6af007c84 100644 (file)
@@ -114,13 +114,13 @@ static inline int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
        return -EOPNOTSUPP;
 }
 
-int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
-                          int src_port, u16 data)
+static inline int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip,
+                                        int src_dev, int src_port, u16 data)
 {
        return -EOPNOTSUPP;
 }
 
-int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
+static inline int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
 {
        return -EOPNOTSUPP;
 }
index b3bc87fe3764e397e4a9ce19518866cb97530771..0a98c369df2045ccbb9fbf7a55af848530a5f464 100644 (file)
@@ -324,7 +324,7 @@ static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata,
                              struct xgbe_ring *ring,
                              struct xgbe_ring_data *rdata)
 {
-       int order, ret;
+       int ret;
 
        if (!ring->rx_hdr_pa.pages) {
                ret = xgbe_alloc_pages(pdata, &ring->rx_hdr_pa, GFP_ATOMIC, 0);
@@ -333,9 +333,8 @@ static int xgbe_map_rx_buffer(struct xgbe_prv_data *pdata,
        }
 
        if (!ring->rx_buf_pa.pages) {
-               order = max_t(int, PAGE_ALLOC_COSTLY_ORDER - 1, 0);
                ret = xgbe_alloc_pages(pdata, &ring->rx_buf_pa, GFP_ATOMIC,
-                                      order);
+                                      PAGE_ALLOC_COSTLY_ORDER);
                if (ret)
                        return ret;
        }
index 099b374c1b17bbd8e9cabe68cdc7cd991a258737..5274501428e4fb05850bada0d4ff3cd8a346f59f 100644 (file)
@@ -2026,9 +2026,12 @@ static int bcm_sysport_probe(struct platform_device *pdev)
        priv->num_rx_desc_words = params->num_rx_desc_words;
 
        priv->irq0 = platform_get_irq(pdev, 0);
-       if (!priv->is_lite)
+       if (!priv->is_lite) {
                priv->irq1 = platform_get_irq(pdev, 1);
-       priv->wol_irq = platform_get_irq(pdev, 2);
+               priv->wol_irq = platform_get_irq(pdev, 2);
+       } else {
+               priv->wol_irq = platform_get_irq(pdev, 1);
+       }
        if (priv->irq0 <= 0 || (priv->irq1 <= 0 && !priv->is_lite)) {
                dev_err(&pdev->dev, "invalid interrupts\n");
                ret = -EINVAL;
index eccb3d1b6abb748c14567d0efcdc28a405b64fb5..5f49334dcad5a8c8602cc3aa2e8795b2d489bb43 100644 (file)
@@ -1926,7 +1926,7 @@ u16 bnx2x_select_queue(struct net_device *dev, struct sk_buff *skb,
        }
 
        /* select a non-FCoE queue */
-       return fallback(dev, skb) % BNX2X_NUM_ETH_QUEUES(bp);
+       return fallback(dev, skb) % (BNX2X_NUM_ETH_QUEUES(bp) * bp->max_cos);
 }
 
 void bnx2x_set_num_queues(struct bnx2x *bp)
index 38a5c6764bb50f45124c212db37e11d2cc777076..77ed2f628f9ca23854ae8b062ff919ce6d2e3425 100644 (file)
@@ -2196,10 +2196,14 @@ static int cxgb_up(struct adapter *adap)
                if (err)
                        goto irq_err;
        }
+
+       mutex_lock(&uld_mutex);
        enable_rx(adap);
        t4_sge_start(adap);
        t4_intr_enable(adap);
        adap->flags |= FULL_INIT_DONE;
+       mutex_unlock(&uld_mutex);
+
        notify_ulds(adap, CXGB4_STATE_UP);
 #if IS_ENABLED(CONFIG_IPV6)
        update_clip(adap);
@@ -2771,6 +2775,9 @@ void t4_fatal_err(struct adapter *adap)
 {
        int port;
 
+       if (pci_channel_offline(adap->pdev))
+               return;
+
        /* Disable the SGE since ULDs are going to free resources that
         * could be exposed to the adapter.  RDMA MWs for example...
         */
@@ -3882,9 +3889,10 @@ static pci_ers_result_t eeh_err_detected(struct pci_dev *pdev,
        spin_lock(&adap->stats_lock);
        for_each_port(adap, i) {
                struct net_device *dev = adap->port[i];
-
-               netif_device_detach(dev);
-               netif_carrier_off(dev);
+               if (dev) {
+                       netif_device_detach(dev);
+                       netif_carrier_off(dev);
+               }
        }
        spin_unlock(&adap->stats_lock);
        disable_interrupts(adap);
@@ -3963,12 +3971,13 @@ static void eeh_resume(struct pci_dev *pdev)
        rtnl_lock();
        for_each_port(adap, i) {
                struct net_device *dev = adap->port[i];
-
-               if (netif_running(dev)) {
-                       link_start(dev);
-                       cxgb_set_rxmode(dev);
+               if (dev) {
+                       if (netif_running(dev)) {
+                               link_start(dev);
+                               cxgb_set_rxmode(dev);
+                       }
+                       netif_device_attach(dev);
                }
-               netif_device_attach(dev);
        }
        rtnl_unlock();
 }
index aded42b96f6d966ba7e814c0a89c738968a655b6..3a34aa629f7dd81a56e6b5c1c63bfdeb685c3f25 100644 (file)
@@ -4557,8 +4557,13 @@ void t4_intr_enable(struct adapter *adapter)
  */
 void t4_intr_disable(struct adapter *adapter)
 {
-       u32 whoami = t4_read_reg(adapter, PL_WHOAMI_A);
-       u32 pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
+       u32 whoami, pf;
+
+       if (pci_channel_offline(adapter->pdev))
+               return;
+
+       whoami = t4_read_reg(adapter, PL_WHOAMI_A);
+       pf = CHELSIO_CHIP_VERSION(adapter->params.chip) <= CHELSIO_T5 ?
                        SOURCEPF_G(whoami) : T6_SOURCEPF_G(whoami);
 
        t4_write_reg(adapter, MYPF_REG(PL_PF_INT_ENABLE_A), 0);
index 3549d387627888a2629b5f07dd1b001d2db1fc70..f2d623a7aee04e21f1e4e52645d66788a59341ab 100644 (file)
@@ -37,7 +37,7 @@
 
 #define T4FW_VERSION_MAJOR 0x01
 #define T4FW_VERSION_MINOR 0x10
-#define T4FW_VERSION_MICRO 0x2B
+#define T4FW_VERSION_MICRO 0x2D
 #define T4FW_VERSION_BUILD 0x00
 
 #define T4FW_MIN_VERSION_MAJOR 0x01
@@ -46,7 +46,7 @@
 
 #define T5FW_VERSION_MAJOR 0x01
 #define T5FW_VERSION_MINOR 0x10
-#define T5FW_VERSION_MICRO 0x2B
+#define T5FW_VERSION_MICRO 0x2D
 #define T5FW_VERSION_BUILD 0x00
 
 #define T5FW_MIN_VERSION_MAJOR 0x00
@@ -55,7 +55,7 @@
 
 #define T6FW_VERSION_MAJOR 0x01
 #define T6FW_VERSION_MINOR 0x10
-#define T6FW_VERSION_MICRO 0x2B
+#define T6FW_VERSION_MICRO 0x2D
 #define T6FW_VERSION_BUILD 0x00
 
 #define T6FW_MIN_VERSION_MAJOR 0x00
index e863ba74d005d7f255931b336825df2abadd2fc8..8bb0db990c8fcf8258201f1af5fcf3fa9976b5f9 100644 (file)
@@ -739,6 +739,8 @@ static int ethoc_open(struct net_device *dev)
        if (ret)
                return ret;
 
+       napi_enable(&priv->napi);
+
        ethoc_init_ring(priv, dev->mem_start);
        ethoc_reset(priv);
 
@@ -754,7 +756,6 @@ static int ethoc_open(struct net_device *dev)
        priv->old_duplex = -1;
 
        phy_start(dev->phydev);
-       napi_enable(&priv->napi);
 
        if (netif_msg_ifup(priv)) {
                dev_info(&dev->dev, "I/O: %08lx Memory: %08lx-%08lx\n",
index 446c7b374ff5c36712d5813cf94b4e9b4ca0b01e..a10de1e9c157d2590eb19122f27fd5dda1a4816b 100644 (file)
@@ -381,7 +381,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
 {
        const struct of_device_id *id =
                of_match_device(fsl_pq_mdio_match, &pdev->dev);
-       const struct fsl_pq_mdio_data *data = id->data;
+       const struct fsl_pq_mdio_data *data;
        struct device_node *np = pdev->dev.of_node;
        struct resource res;
        struct device_node *tbi;
@@ -389,6 +389,13 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
        struct mii_bus *new_bus;
        int err;
 
+       if (!id) {
+               dev_err(&pdev->dev, "Failed to match device\n");
+               return -ENODEV;
+       }
+
+       data = id->data;
+
        dev_dbg(&pdev->dev, "found %s compatible node\n", id->compatible);
 
        new_bus = mdiobus_alloc_size(sizeof(*priv));
index 4f2d329dba998308eeb2ddaed52733cb3059f605..a93757c255f77445e2245ee8b065d2c6ee31cf3f 100644 (file)
@@ -81,7 +81,7 @@
 static const char ibmvnic_driver_name[] = "ibmvnic";
 static const char ibmvnic_driver_string[] = "IBM System i/p Virtual NIC Driver";
 
-MODULE_AUTHOR("Santiago Leon <santi_leon@yahoo.com>");
+MODULE_AUTHOR("Santiago Leon");
 MODULE_DESCRIPTION("IBM System i/p Virtual NIC Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(IBMVNIC_DRIVER_VERSION);
index d5c9c9e06ff57e21c1e28d09b9eea18af6e22f1a..150caf6ca2b4bb1da5e0ea63f37fd086c058efad 100644 (file)
@@ -295,7 +295,7 @@ struct i40e_vsi *i40e_find_vsi_from_id(struct i40e_pf *pf, u16 id)
  **/
 void i40e_service_event_schedule(struct i40e_pf *pf)
 {
-       if (!test_bit(__I40E_VSI_DOWN, pf->state) &&
+       if (!test_bit(__I40E_DOWN, pf->state) &&
            !test_bit(__I40E_RESET_RECOVERY_PENDING, pf->state))
                queue_work(i40e_wq, &pf->service_task);
 }
@@ -3611,7 +3611,7 @@ static irqreturn_t i40e_intr(int irq, void *data)
                 * this is not a performance path and napi_schedule()
                 * can deal with rescheduling.
                 */
-               if (!test_bit(__I40E_VSI_DOWN, pf->state))
+               if (!test_bit(__I40E_DOWN, pf->state))
                        napi_schedule_irqoff(&q_vector->napi);
        }
 
@@ -3687,7 +3687,7 @@ static irqreturn_t i40e_intr(int irq, void *data)
 enable_intr:
        /* re-enable interrupt causes */
        wr32(hw, I40E_PFINT_ICR0_ENA, ena_mask);
-       if (!test_bit(__I40E_VSI_DOWN, pf->state)) {
+       if (!test_bit(__I40E_DOWN, pf->state)) {
                i40e_service_event_schedule(pf);
                i40e_irq_dynamic_enable_icr0(pf, false);
        }
@@ -6203,7 +6203,7 @@ static void i40e_fdir_reinit_subtask(struct i40e_pf *pf)
 {
 
        /* if interface is down do nothing */
-       if (test_bit(__I40E_VSI_DOWN, pf->state))
+       if (test_bit(__I40E_DOWN, pf->state))
                return;
 
        if (test_bit(__I40E_FD_FLUSH_REQUESTED, pf->state))
@@ -6344,7 +6344,7 @@ static void i40e_watchdog_subtask(struct i40e_pf *pf)
        int i;
 
        /* if interface is down do nothing */
-       if (test_bit(__I40E_VSI_DOWN, pf->state) ||
+       if (test_bit(__I40E_DOWN, pf->state) ||
            test_bit(__I40E_CONFIG_BUSY, pf->state))
                return;
 
@@ -6399,9 +6399,9 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
                reset_flags |= BIT(__I40E_GLOBAL_RESET_REQUESTED);
                clear_bit(__I40E_GLOBAL_RESET_REQUESTED, pf->state);
        }
-       if (test_bit(__I40E_VSI_DOWN_REQUESTED, pf->state)) {
-               reset_flags |= BIT(__I40E_VSI_DOWN_REQUESTED);
-               clear_bit(__I40E_VSI_DOWN_REQUESTED, pf->state);
+       if (test_bit(__I40E_DOWN_REQUESTED, pf->state)) {
+               reset_flags |= BIT(__I40E_DOWN_REQUESTED);
+               clear_bit(__I40E_DOWN_REQUESTED, pf->state);
        }
 
        /* If there's a recovery already waiting, it takes
@@ -6415,7 +6415,7 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
 
        /* If we're already down or resetting, just bail */
        if (reset_flags &&
-           !test_bit(__I40E_VSI_DOWN, pf->state) &&
+           !test_bit(__I40E_DOWN, pf->state) &&
            !test_bit(__I40E_CONFIG_BUSY, pf->state)) {
                rtnl_lock();
                i40e_do_reset(pf, reset_flags, true);
@@ -7002,7 +7002,7 @@ static void i40e_rebuild(struct i40e_pf *pf, bool reinit, bool lock_acquired)
        u32 val;
        int v;
 
-       if (test_bit(__I40E_VSI_DOWN, pf->state))
+       if (test_bit(__I40E_DOWN, pf->state))
                goto clear_recovery;
        dev_dbg(&pf->pdev->dev, "Rebuilding internal switch\n");
 
@@ -9767,7 +9767,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
                return -ENODEV;
        }
        if (vsi == pf->vsi[pf->lan_vsi] &&
-           !test_bit(__I40E_VSI_DOWN, pf->state)) {
+           !test_bit(__I40E_DOWN, pf->state)) {
                dev_info(&pf->pdev->dev, "Can't remove PF VSI\n");
                return -ENODEV;
        }
@@ -11003,7 +11003,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        }
        pf->next_vsi = 0;
        pf->pdev = pdev;
-       set_bit(__I40E_VSI_DOWN, pf->state);
+       set_bit(__I40E_DOWN, pf->state);
 
        hw = &pf->hw;
        hw->back = pf;
@@ -11293,7 +11293,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
         * before setting up the misc vector or we get a race and the vector
         * ends up disabled forever.
         */
-       clear_bit(__I40E_VSI_DOWN, pf->state);
+       clear_bit(__I40E_DOWN, pf->state);
 
        /* In case of MSIX we are going to setup the misc vector right here
         * to handle admin queue events etc. In case of legacy and MSI
@@ -11448,7 +11448,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* Unwind what we've done if something failed in the setup */
 err_vsis:
-       set_bit(__I40E_VSI_DOWN, pf->state);
+       set_bit(__I40E_DOWN, pf->state);
        i40e_clear_interrupt_scheme(pf);
        kfree(pf->vsi);
 err_switch_setup:
@@ -11500,7 +11500,7 @@ static void i40e_remove(struct pci_dev *pdev)
 
        /* no more scheduling of any task */
        set_bit(__I40E_SUSPENDED, pf->state);
-       set_bit(__I40E_VSI_DOWN, pf->state);
+       set_bit(__I40E_DOWN, pf->state);
        if (pf->service_timer.data)
                del_timer_sync(&pf->service_timer);
        if (pf->service_task.func)
@@ -11740,7 +11740,7 @@ static void i40e_shutdown(struct pci_dev *pdev)
        struct i40e_hw *hw = &pf->hw;
 
        set_bit(__I40E_SUSPENDED, pf->state);
-       set_bit(__I40E_VSI_DOWN, pf->state);
+       set_bit(__I40E_DOWN, pf->state);
        rtnl_lock();
        i40e_prep_for_reset(pf, true);
        rtnl_unlock();
@@ -11789,7 +11789,7 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state)
        int retval = 0;
 
        set_bit(__I40E_SUSPENDED, pf->state);
-       set_bit(__I40E_VSI_DOWN, pf->state);
+       set_bit(__I40E_DOWN, pf->state);
 
        if (pf->wol_en && (pf->flags & I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE))
                i40e_enable_mc_magic_wake(pf);
@@ -11841,7 +11841,7 @@ static int i40e_resume(struct pci_dev *pdev)
 
        /* handling the reset will rebuild the device state */
        if (test_and_clear_bit(__I40E_SUSPENDED, pf->state)) {
-               clear_bit(__I40E_VSI_DOWN, pf->state);
+               clear_bit(__I40E_DOWN, pf->state);
                rtnl_lock();
                i40e_reset_and_rebuild(pf, false, true);
                rtnl_unlock();
index 29321a6167a6675757e74ab4e3cd1a100cb423b0..cd894f4023b1b68cc4e202ff7064e63e2f8be031 100644 (file)
@@ -1854,7 +1854,8 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
 #if (PAGE_SIZE < 8192)
        unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2;
 #else
-       unsigned int truesize = SKB_DATA_ALIGN(size);
+       unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
+                               SKB_DATA_ALIGN(I40E_SKB_PAD + size);
 #endif
        struct sk_buff *skb;
 
index dfe241a12ad0756d10a77b954486d2194a31c5ca..12b02e5305038d55fcee5d2109b4ab534a09b1bb 100644 (file)
@@ -1190,7 +1190,8 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
 #if (PAGE_SIZE < 8192)
        unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2;
 #else
-       unsigned int truesize = SKB_DATA_ALIGN(size);
+       unsigned int truesize = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) +
+                               SKB_DATA_ALIGN(I40E_SKB_PAD + size);
 #endif
        struct sk_buff *skb;
 
index ae5fdc2df65412afce4e72b8384c9c4b3302c56e..ffbcb27c05e55f43630a812249bab21609886dd9 100644 (file)
@@ -1562,11 +1562,6 @@ static int mlx4_en_flow_replace(struct net_device *dev,
                qpn = priv->drop_qp.qpn;
        else if (cmd->fs.ring_cookie & EN_ETHTOOL_QP_ATTACH) {
                qpn = cmd->fs.ring_cookie & (EN_ETHTOOL_QP_ATTACH - 1);
-               if (qpn < priv->rss_map.base_qpn ||
-                   qpn >= priv->rss_map.base_qpn + priv->rx_ring_num) {
-                       en_warn(priv, "rxnfc: QP (0x%x) doesn't exist\n", qpn);
-                       return -EINVAL;
-               }
        } else {
                if (cmd->fs.ring_cookie >= priv->rx_ring_num) {
                        en_warn(priv, "rxnfc: RX ring (%llu) doesn't exist\n",
index 1a670b68155550fe9f61fb2bc2c7a3688391249c..0710b367746468f1d4faeb5b8a8f3266ca941674 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/etherdevice.h>
 
 #include <linux/mlx4/cmd.h>
+#include <linux/mlx4/qp.h>
 #include <linux/export.h>
 
 #include "mlx4.h"
@@ -985,16 +986,21 @@ int mlx4_flow_attach(struct mlx4_dev *dev,
        if (IS_ERR(mailbox))
                return PTR_ERR(mailbox);
 
+       if (!mlx4_qp_lookup(dev, rule->qpn)) {
+               mlx4_err_rule(dev, "QP doesn't exist\n", rule);
+               ret = -EINVAL;
+               goto out;
+       }
+
        trans_rule_ctrl_to_hw(rule, mailbox->buf);
 
        size += sizeof(struct mlx4_net_trans_rule_hw_ctrl);
 
        list_for_each_entry(cur, &rule->list, list) {
                ret = parse_trans_rule(dev, cur, mailbox->buf + size);
-               if (ret < 0) {
-                       mlx4_free_cmd_mailbox(dev, mailbox);
-                       return ret;
-               }
+               if (ret < 0)
+                       goto out;
+
                size += ret;
        }
 
@@ -1021,6 +1027,7 @@ int mlx4_flow_attach(struct mlx4_dev *dev,
                }
        }
 
+out:
        mlx4_free_cmd_mailbox(dev, mailbox);
 
        return ret;
index 2d6abd4662b143612769ef9b91783249bcd2ac8b..5a310d313e94d08d035c265e6b538c27dcf957c3 100644 (file)
@@ -384,6 +384,19 @@ static void mlx4_qp_free_icm(struct mlx4_dev *dev, int qpn)
                __mlx4_qp_free_icm(dev, qpn);
 }
 
+struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn)
+{
+       struct mlx4_qp_table *qp_table = &mlx4_priv(dev)->qp_table;
+       struct mlx4_qp *qp;
+
+       spin_lock(&qp_table->lock);
+
+       qp = __mlx4_qp_lookup(dev, qpn);
+
+       spin_unlock(&qp_table->lock);
+       return qp;
+}
+
 int mlx4_qp_alloc(struct mlx4_dev *dev, int qpn, struct mlx4_qp *qp, gfp_t gfp)
 {
        struct mlx4_priv *priv = mlx4_priv(dev);
@@ -471,6 +484,12 @@ int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
        }
 
        if (attr & MLX4_UPDATE_QP_QOS_VPORT) {
+               if (!(dev->caps.flags2 & MLX4_DEV_CAP_FLAG2_QOS_VPP)) {
+                       mlx4_warn(dev, "Granular QoS per VF is not enabled\n");
+                       err = -EOPNOTSUPP;
+                       goto out;
+               }
+
                qp_mask |= 1ULL << MLX4_UPD_QP_MASK_QOS_VPP;
                cmd->qp_context.qos_vport = params->qos_vport;
        }
index 07516545474f3ac76e750aaa4af2532b6ac81207..812783865205715e8e88ad66d4ccbfe7172ec6e5 100644 (file)
@@ -5255,6 +5255,13 @@ void mlx4_delete_all_resources_for_slave(struct mlx4_dev *dev, int slave)
        mutex_unlock(&priv->mfunc.master.res_tracker.slave_list[slave].mutex);
 }
 
+static void update_qos_vpp(struct mlx4_update_qp_context *ctx,
+                          struct mlx4_vf_immed_vlan_work *work)
+{
+       ctx->qp_mask |= cpu_to_be64(1ULL << MLX4_UPD_QP_MASK_QOS_VPP);
+       ctx->qp_context.qos_vport = work->qos_vport;
+}
+
 void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
 {
        struct mlx4_vf_immed_vlan_work *work =
@@ -5369,11 +5376,10 @@ void mlx4_vf_immed_vlan_work_handler(struct work_struct *_work)
                                        qp->sched_queue & 0xC7;
                                upd_context->qp_context.pri_path.sched_queue |=
                                        ((work->qos & 0x7) << 3);
-                               upd_context->qp_mask |=
-                                       cpu_to_be64(1ULL <<
-                                                   MLX4_UPD_QP_MASK_QOS_VPP);
-                               upd_context->qp_context.qos_vport =
-                                       work->qos_vport;
+
+                               if (dev->caps.flags2 &
+                                   MLX4_DEV_CAP_FLAG2_QOS_VPP)
+                                       update_qos_vpp(upd_context, work);
                        }
 
                        err = mlx4_cmd(dev, mailbox->dma,
index fe5546bb41537f0af0c4bcfe9054ccceaa42bbb2..af945edfee1905dbe676218cb53123535a37171f 100644 (file)
@@ -621,10 +621,9 @@ static int mlx5_irq_set_affinity_hint(struct mlx5_core_dev *mdev, int i)
        cpumask_set_cpu(cpumask_local_spread(i, priv->numa_node),
                        priv->irq_info[i].mask);
 
-#ifdef CONFIG_SMP
-       if (irq_set_affinity_hint(irq, priv->irq_info[i].mask))
+       if (IS_ENABLED(CONFIG_SMP) &&
+           irq_set_affinity_hint(irq, priv->irq_info[i].mask))
                mlx5_core_warn(mdev, "irq_set_affinity_hint failed, irq 0x%.4x", irq);
-#endif
 
        return 0;
 }
index 537d1236a4fec0a2973d52ed34cf7f73d8a4b052..715b3aaf83ac4d65cdea4eb15f6f2089e402c469 100644 (file)
@@ -1730,7 +1730,8 @@ void qed_get_protocol_stats(struct qed_dev *cdev,
                qed_get_protocol_stats_iscsi(cdev, &stats->iscsi_stats);
                break;
        default:
-               DP_ERR(cdev, "Invalid protocol type = %d\n", type);
+               DP_VERBOSE(cdev, QED_MSG_SP,
+                          "Invalid protocol type = %d\n", type);
                return;
        }
 }
index 7245b1072518fff31566c471b6eb32b512e41846..81312924df1407092fd1dd43cc0555d16976160b 100644 (file)
@@ -1824,22 +1824,44 @@ struct qlcnic_hardware_ops {
        u32 (*get_cap_size)(void *, int);
        void (*set_sys_info)(void *, int, u32);
        void (*store_cap_mask)(void *, u32);
+       bool (*encap_rx_offload) (struct qlcnic_adapter *adapter);
+       bool (*encap_tx_offload) (struct qlcnic_adapter *adapter);
 };
 
 extern struct qlcnic_nic_template qlcnic_vf_ops;
 
-static inline bool qlcnic_encap_tx_offload(struct qlcnic_adapter *adapter)
+static inline bool qlcnic_83xx_encap_tx_offload(struct qlcnic_adapter *adapter)
 {
        return adapter->ahw->extra_capability[0] &
               QLCNIC_83XX_FW_CAPAB_ENCAP_TX_OFFLOAD;
 }
 
-static inline bool qlcnic_encap_rx_offload(struct qlcnic_adapter *adapter)
+static inline bool qlcnic_83xx_encap_rx_offload(struct qlcnic_adapter *adapter)
 {
        return adapter->ahw->extra_capability[0] &
               QLCNIC_83XX_FW_CAPAB_ENCAP_RX_OFFLOAD;
 }
 
+static inline bool qlcnic_82xx_encap_tx_offload(struct qlcnic_adapter *adapter)
+{
+       return false;
+}
+
+static inline bool qlcnic_82xx_encap_rx_offload(struct qlcnic_adapter *adapter)
+{
+        return false;
+}
+
+static inline bool qlcnic_encap_rx_offload(struct qlcnic_adapter *adapter)
+{
+        return adapter->ahw->hw_ops->encap_rx_offload(adapter);
+}
+
+static inline bool qlcnic_encap_tx_offload(struct qlcnic_adapter *adapter)
+{
+        return adapter->ahw->hw_ops->encap_tx_offload(adapter);
+}
+
 static inline int qlcnic_start_firmware(struct qlcnic_adapter *adapter)
 {
        return adapter->nic_ops->start_firmware(adapter);
index 4fb68797630e9531e7ffc4e7bc7c015313a44063..f7080d0ab8746263c6955163640964eac2fd2cb0 100644 (file)
@@ -242,6 +242,8 @@ static struct qlcnic_hardware_ops qlcnic_83xx_hw_ops = {
        .get_cap_size                   = qlcnic_83xx_get_cap_size,
        .set_sys_info                   = qlcnic_83xx_set_sys_info,
        .store_cap_mask                 = qlcnic_83xx_store_cap_mask,
+       .encap_rx_offload               = qlcnic_83xx_encap_rx_offload,
+       .encap_tx_offload               = qlcnic_83xx_encap_tx_offload,
 };
 
 static struct qlcnic_nic_template qlcnic_83xx_ops = {
index 838cc0ceafd8d0824495206bf30cdaf53f98bc59..7848cf04b29a83f0a356b3eb5360d6a6e65871f0 100644 (file)
@@ -341,7 +341,7 @@ qlcnic_pcie_sem_lock(struct qlcnic_adapter *adapter, int sem, u32 id_reg)
                        }
                        return -EIO;
                }
-               usleep_range(1000, 1500);
+               udelay(1200);
        }
 
        if (id_reg)
index b6628aaa6e4a45a8eaecd9d5fc4ea8136d7a07af..1b5f7d57b6f8fed6a8b232adfdee76b2cbaff13f 100644 (file)
@@ -632,6 +632,8 @@ static struct qlcnic_hardware_ops qlcnic_hw_ops = {
        .get_cap_size                   = qlcnic_82xx_get_cap_size,
        .set_sys_info                   = qlcnic_82xx_set_sys_info,
        .store_cap_mask                 = qlcnic_82xx_store_cap_mask,
+       .encap_rx_offload               = qlcnic_82xx_encap_rx_offload,
+       .encap_tx_offload               = qlcnic_82xx_encap_tx_offload,
 };
 
 static int qlcnic_check_multi_tx_capability(struct qlcnic_adapter *adapter)
index 2f656f395f39699e4cec53f4ff25ea7e745d1041..c58180f408448e9a86a7ce40c6fb286063a6afb0 100644 (file)
@@ -77,6 +77,8 @@ static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {
        .free_mac_list                  = qlcnic_sriov_vf_free_mac_list,
        .enable_sds_intr                = qlcnic_83xx_enable_sds_intr,
        .disable_sds_intr               = qlcnic_83xx_disable_sds_intr,
+       .encap_rx_offload               = qlcnic_83xx_encap_rx_offload,
+       .encap_tx_offload               = qlcnic_83xx_encap_tx_offload,
 };
 
 static struct qlcnic_nic_template qlcnic_sriov_vf_ops = {
index cc065ffbe4b5584a6498237d1e4a929ff1d6ebd0..bcd4708b374574fb06faf28d9b0a6cc90bc9c56d 100644 (file)
@@ -931,7 +931,7 @@ int emac_mac_up(struct emac_adapter *adpt)
        emac_mac_config(adpt);
        emac_mac_rx_descs_refill(adpt, &adpt->rx_q);
 
-       adpt->phydev->irq = PHY_IGNORE_INTERRUPT;
+       adpt->phydev->irq = PHY_POLL;
        ret = phy_connect_direct(netdev, adpt->phydev, emac_adjust_link,
                                 PHY_INTERFACE_MODE_SGMII);
        if (ret) {
index 441c1936648993fa394e5c676b7bd9957e52efa3..18461fcb981501efd7015634999cb787041c01a7 100644 (file)
 /* Qualcomm Technologies, Inc. EMAC PHY Controller driver.
  */
 
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/of_net.h>
 #include <linux/of_mdio.h>
 #include <linux/phy.h>
 #include <linux/iopoll.h>
 #include <linux/acpi.h>
 #include "emac.h"
-#include "emac-mac.h"
 
 /* EMAC base register offsets */
 #define EMAC_MDIO_CTRL                                        0x001414
 
 #define MDIO_WAIT_TIMES                                           1000
 
-#define EMAC_LINK_SPEED_DEFAULT (\
-               EMAC_LINK_SPEED_10_HALF  |\
-               EMAC_LINK_SPEED_10_FULL  |\
-               EMAC_LINK_SPEED_100_HALF |\
-               EMAC_LINK_SPEED_100_FULL |\
-               EMAC_LINK_SPEED_1GB_FULL)
-
-/**
- * emac_phy_mdio_autopoll_disable() - disable mdio autopoll
- * @adpt: the emac adapter
- *
- * The autopoll feature takes over the MDIO bus.  In order for
- * the PHY driver to be able to talk to the PHY over the MDIO
- * bus, we need to temporarily disable the autopoll feature.
- */
-static int emac_phy_mdio_autopoll_disable(struct emac_adapter *adpt)
-{
-       u32 val;
-
-       /* disable autopoll */
-       emac_reg_update32(adpt->base + EMAC_MDIO_CTRL, MDIO_AP_EN, 0);
-
-       /* wait for any mdio polling to complete */
-       if (!readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, val,
-                               !(val & MDIO_BUSY), 100, MDIO_WAIT_TIMES * 100))
-               return 0;
-
-       /* failed to disable; ensure it is enabled before returning */
-       emac_reg_update32(adpt->base + EMAC_MDIO_CTRL, 0, MDIO_AP_EN);
-
-       return -EBUSY;
-}
-
-/**
- * emac_phy_mdio_autopoll_disable() - disable mdio autopoll
- * @adpt: the emac adapter
- *
- * The EMAC has the ability to poll the external PHY on the MDIO
- * bus for link state changes.  This eliminates the need for the
- * driver to poll the phy.  If if the link state does change,
- * the EMAC issues an interrupt on behalf of the PHY.
- */
-static void emac_phy_mdio_autopoll_enable(struct emac_adapter *adpt)
-{
-       emac_reg_update32(adpt->base + EMAC_MDIO_CTRL, 0, MDIO_AP_EN);
-}
-
 static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum)
 {
        struct emac_adapter *adpt = bus->priv;
        u32 reg;
-       int ret;
-
-       ret = emac_phy_mdio_autopoll_disable(adpt);
-       if (ret)
-               return ret;
 
        emac_reg_update32(adpt->base + EMAC_PHY_STS, PHY_ADDR_BMSK,
                          (addr << PHY_ADDR_SHFT));
@@ -122,24 +66,15 @@ static int emac_mdio_read(struct mii_bus *bus, int addr, int regnum)
        if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg,
                               !(reg & (MDIO_START | MDIO_BUSY)),
                               100, MDIO_WAIT_TIMES * 100))
-               ret = -EIO;
-       else
-               ret = (reg >> MDIO_DATA_SHFT) & MDIO_DATA_BMSK;
+               return -EIO;
 
-       emac_phy_mdio_autopoll_enable(adpt);
-
-       return ret;
+       return (reg >> MDIO_DATA_SHFT) & MDIO_DATA_BMSK;
 }
 
 static int emac_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
 {
        struct emac_adapter *adpt = bus->priv;
        u32 reg;
-       int ret;
-
-       ret = emac_phy_mdio_autopoll_disable(adpt);
-       if (ret)
-               return ret;
 
        emac_reg_update32(adpt->base + EMAC_PHY_STS, PHY_ADDR_BMSK,
                          (addr << PHY_ADDR_SHFT));
@@ -155,11 +90,9 @@ static int emac_mdio_write(struct mii_bus *bus, int addr, int regnum, u16 val)
        if (readl_poll_timeout(adpt->base + EMAC_MDIO_CTRL, reg,
                               !(reg & (MDIO_START | MDIO_BUSY)), 100,
                               MDIO_WAIT_TIMES * 100))
-               ret = -EIO;
+               return -EIO;
 
-       emac_phy_mdio_autopoll_enable(adpt);
-
-       return ret;
+       return 0;
 }
 
 /* Configure the MDIO bus and connect the external PHY */
index 28a8cdc364851e56a5757a8f2970853c0a462cc4..98a326faea294eec0c59f9b0ffe15d57046ce5eb 100644 (file)
 #define DMAR_DLY_CNT_DEF                                   15
 #define DMAW_DLY_CNT_DEF                                    4
 
-#define IMR_NORMAL_MASK         (\
-               ISR_ERROR       |\
-               ISR_GPHY_LINK   |\
-               ISR_TX_PKT      |\
-               GPHY_WAKEUP_INT)
-
-#define IMR_EXTENDED_MASK       (\
-               SW_MAN_INT      |\
-               ISR_OVER        |\
-               ISR_ERROR       |\
-               ISR_GPHY_LINK   |\
-               ISR_TX_PKT      |\
-               GPHY_WAKEUP_INT)
+#define IMR_NORMAL_MASK                (ISR_ERROR | ISR_OVER | ISR_TX_PKT)
 
 #define ISR_TX_PKT      (\
        TX_PKT_INT      |\
        TX_PKT_INT2     |\
        TX_PKT_INT3)
 
-#define ISR_GPHY_LINK        (\
-       GPHY_LINK_UP_INT     |\
-       GPHY_LINK_DOWN_INT)
-
 #define ISR_OVER        (\
        RFD0_UR_INT     |\
        RFD1_UR_INT     |\
@@ -187,10 +171,6 @@ irqreturn_t emac_isr(int _irq, void *data)
        if (status & ISR_OVER)
                net_warn_ratelimited("warning: TX/RX overflow\n");
 
-       /* link event */
-       if (status & ISR_GPHY_LINK)
-               phy_mac_interrupt(adpt->phydev, !!(status & GPHY_LINK_UP_INT));
-
 exit:
        /* enable the interrupt */
        writel(irq->mask, adpt->base + EMAC_INT_MASK);
index 3cd7989c007dfe46947e2ddb366a904f1af90198..784782da3a85b638e9e2a195fe66b15c72fe0fe5 100644 (file)
@@ -230,18 +230,6 @@ static void ravb_ring_free(struct net_device *ndev, int q)
        int ring_size;
        int i;
 
-       /* Free RX skb ringbuffer */
-       if (priv->rx_skb[q]) {
-               for (i = 0; i < priv->num_rx_ring[q]; i++)
-                       dev_kfree_skb(priv->rx_skb[q][i]);
-       }
-       kfree(priv->rx_skb[q]);
-       priv->rx_skb[q] = NULL;
-
-       /* Free aligned TX buffers */
-       kfree(priv->tx_align[q]);
-       priv->tx_align[q] = NULL;
-
        if (priv->rx_ring[q]) {
                for (i = 0; i < priv->num_rx_ring[q]; i++) {
                        struct ravb_ex_rx_desc *desc = &priv->rx_ring[q][i];
@@ -270,6 +258,18 @@ static void ravb_ring_free(struct net_device *ndev, int q)
                priv->tx_ring[q] = NULL;
        }
 
+       /* Free RX skb ringbuffer */
+       if (priv->rx_skb[q]) {
+               for (i = 0; i < priv->num_rx_ring[q]; i++)
+                       dev_kfree_skb(priv->rx_skb[q][i]);
+       }
+       kfree(priv->rx_skb[q]);
+       priv->rx_skb[q] = NULL;
+
+       /* Free aligned TX buffers */
+       kfree(priv->tx_align[q]);
+       priv->tx_align[q] = NULL;
+
        /* Free TX skb ringbuffer.
         * SKBs are freed by ravb_tx_free() call above.
         */
index 489ef146201e61c629c17010f672a621642e94b3..6a9c954492f225987d5dc63713034548e7aabdbb 100644 (file)
@@ -37,6 +37,7 @@
 #define TSE_PCS_CONTROL_AN_EN_MASK                     BIT(12)
 #define TSE_PCS_CONTROL_REG                            0x00
 #define TSE_PCS_CONTROL_RESTART_AN_MASK                        BIT(9)
+#define TSE_PCS_CTRL_AUTONEG_SGMII                     0x1140
 #define TSE_PCS_IF_MODE_REG                            0x28
 #define TSE_PCS_LINK_TIMER_0_REG                       0x24
 #define TSE_PCS_LINK_TIMER_1_REG                       0x26
@@ -65,6 +66,7 @@
 #define TSE_PCS_SW_RESET_TIMEOUT                       100
 #define TSE_PCS_USE_SGMII_AN_MASK                      BIT(1)
 #define TSE_PCS_USE_SGMII_ENA                          BIT(0)
+#define TSE_PCS_IF_USE_SGMII                           0x03
 
 #define SGMII_ADAPTER_CTRL_REG                         0x00
 #define SGMII_ADAPTER_DISABLE                          0x0001
@@ -101,7 +103,9 @@ int tse_pcs_init(void __iomem *base, struct tse_pcs *pcs)
 {
        int ret = 0;
 
-       writew(TSE_PCS_USE_SGMII_ENA, base + TSE_PCS_IF_MODE_REG);
+       writew(TSE_PCS_IF_USE_SGMII, base + TSE_PCS_IF_MODE_REG);
+
+       writew(TSE_PCS_CTRL_AUTONEG_SGMII, base + TSE_PCS_CONTROL_REG);
 
        writew(TSE_PCS_SGMII_LINK_TIMER_0, base + TSE_PCS_LINK_TIMER_0_REG);
        writew(TSE_PCS_SGMII_LINK_TIMER_1, base + TSE_PCS_LINK_TIMER_1_REG);
index a74c481401c46ee659b1244b0124966cabeafdbd..12236daf7bb6d5358fdafe50e37227e19b95bc33 100644 (file)
@@ -1208,7 +1208,7 @@ static int init_dma_rx_desc_rings(struct net_device *dev, gfp_t flags)
        u32 rx_count = priv->plat->rx_queues_to_use;
        unsigned int bfsize = 0;
        int ret = -ENOMEM;
-       u32 queue;
+       int queue;
        int i;
 
        if (priv->hw->mode->set_16kib_bfsize)
@@ -2724,7 +2724,7 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, unsigned int des,
 
                priv->hw->desc->prepare_tso_tx_desc(desc, 0, buff_size,
                        0, 1,
-                       (last_segment) && (buff_size < TSO_MAX_BUFF_SIZE),
+                       (last_segment) && (tmp_len <= TSO_MAX_BUFF_SIZE),
                        0, 0);
 
                tmp_len -= TSO_MAX_BUFF_SIZE;
@@ -2947,7 +2947,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        int i, csum_insertion = 0, is_jumbo = 0;
        u32 queue = skb_get_queue_mapping(skb);
        int nfrags = skb_shinfo(skb)->nr_frags;
-       unsigned int entry, first_entry;
+       int entry;
+       unsigned int first_entry;
        struct dma_desc *desc, *first;
        struct stmmac_tx_queue *tx_q;
        unsigned int enh_desc;
index 959fd12d2e670dfa52d7d9d11f835e990c82aa7c..6ebb0f559a427fdb4d27d9b668b46d7151650043 100644 (file)
@@ -1133,7 +1133,7 @@ static int geneve_configure(struct net *net, struct net_device *dev,
 
        /* make enough headroom for basic scenario */
        encap_len = GENEVE_BASE_HLEN + ETH_HLEN;
-       if (ip_tunnel_info_af(info) == AF_INET) {
+       if (!metadata && ip_tunnel_info_af(info) == AF_INET) {
                encap_len += sizeof(struct iphdr);
                dev->max_mtu -= sizeof(struct iphdr);
        } else {
index 8c3633c1d0789718fc528b9873e8295e6ab6b09e..97e3bc60c3e7d111184f4c60ce4afe50757d1398 100644 (file)
@@ -576,6 +576,8 @@ static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        case HDLCDRVCTL_CALIBRATE:
                if(!capable(CAP_SYS_RAWIO))
                        return -EPERM;
+               if (s->par.bitrate <= 0)
+                       return -EINVAL;
                if (bi.data.calibrate > INT_MAX / s->par.bitrate)
                        return -EINVAL;
                s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
index 9097e42bec2e42d8ee864edea4a6be5d8c0a92cc..57297ba239871c631baef1dcfc2c30a66fdf3bba 100644 (file)
@@ -1127,8 +1127,6 @@ static int marvell_read_status_page(struct phy_device *phydev, int page)
                if (adv < 0)
                        return adv;
 
-               lpa &= adv;
-
                if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
                        phydev->duplex = DUPLEX_FULL;
                else
index 8e73f5f36e7120a5aa28b6e0dfb992eca3330e3e..f99c21f78b639fc1e6b984a20383f62021b757eb 100644 (file)
@@ -658,6 +658,18 @@ static int mdio_bus_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
+static int mdio_uevent(struct device *dev, struct kobj_uevent_env *env)
+{
+       int rc;
+
+       /* Some devices have extra OF data and an OF-style MODALIAS */
+       rc = of_device_uevent_modalias(dev, env);
+       if (rc != -ENODEV)
+               return rc;
+
+       return 0;
+}
+
 #ifdef CONFIG_PM
 static int mdio_bus_suspend(struct device *dev)
 {
@@ -708,6 +720,7 @@ static const struct dev_pm_ops mdio_bus_pm_ops = {
 struct bus_type mdio_bus_type = {
        .name           = "mdio_bus",
        .match          = mdio_bus_match,
+       .uevent         = mdio_uevent,
        .pm             = MDIO_BUS_PM_OPS,
 };
 EXPORT_SYMBOL(mdio_bus_type);
index 6a5fd18f062c4ea400bc8036d787a94fe5108a34..b9252b8d81ffb720272ca5f0b25910c021eb28a3 100644 (file)
@@ -268,23 +268,12 @@ out:
        return ret;
 }
 
-static int kszphy_config_init(struct phy_device *phydev)
+/* Some config bits need to be set again on resume, handle them here. */
+static int kszphy_config_reset(struct phy_device *phydev)
 {
        struct kszphy_priv *priv = phydev->priv;
-       const struct kszphy_type *type;
        int ret;
 
-       if (!priv)
-               return 0;
-
-       type = priv->type;
-
-       if (type->has_broadcast_disable)
-               kszphy_broadcast_disable(phydev);
-
-       if (type->has_nand_tree_disable)
-               kszphy_nand_tree_disable(phydev);
-
        if (priv->rmii_ref_clk_sel) {
                ret = kszphy_rmii_clk_sel(phydev, priv->rmii_ref_clk_sel_val);
                if (ret) {
@@ -295,11 +284,30 @@ static int kszphy_config_init(struct phy_device *phydev)
        }
 
        if (priv->led_mode >= 0)
-               kszphy_setup_led(phydev, type->led_mode_reg, priv->led_mode);
+               kszphy_setup_led(phydev, priv->type->led_mode_reg, priv->led_mode);
 
        return 0;
 }
 
+static int kszphy_config_init(struct phy_device *phydev)
+{
+       struct kszphy_priv *priv = phydev->priv;
+       const struct kszphy_type *type;
+
+       if (!priv)
+               return 0;
+
+       type = priv->type;
+
+       if (type->has_broadcast_disable)
+               kszphy_broadcast_disable(phydev);
+
+       if (type->has_nand_tree_disable)
+               kszphy_nand_tree_disable(phydev);
+
+       return kszphy_config_reset(phydev);
+}
+
 static int ksz8041_config_init(struct phy_device *phydev)
 {
        struct device_node *of_node = phydev->mdio.dev.of_node;
@@ -700,8 +708,14 @@ static int kszphy_suspend(struct phy_device *phydev)
 
 static int kszphy_resume(struct phy_device *phydev)
 {
+       int ret;
+
        genphy_resume(phydev);
 
+       ret = kszphy_config_reset(phydev);
+       if (ret)
+               return ret;
+
        /* Enable PHY Interrupts */
        if (phy_interrupt_is_valid(phydev)) {
                phydev->interrupts = PHY_INTERRUPT_ENABLED;
index 82ab8fb82587553fefc1d05bbff06d4a76bc9679..7524caa0f29d9806e11826c7ecfd57842bff1822 100644 (file)
@@ -241,7 +241,7 @@ static const struct phy_setting settings[] = {
  * phy_lookup_setting - lookup a PHY setting
  * @speed: speed to match
  * @duplex: duplex to match
- * @feature: allowed link modes
+ * @features: allowed link modes
  * @exact: an exact match is required
  *
  * Search the settings array for a setting that matches the speed and
index 3e9246cc49c3784ebc045868a53318d35bf01075..a871f45ecc79a438b2b43465d3719f240ff25cb5 100644 (file)
@@ -869,7 +869,7 @@ static unsigned int get_mergeable_buf_len(struct receive_queue *rq,
        unsigned int len;
 
        len = hdr_len + clamp_t(unsigned int, ewma_pkt_len_read(avg_pkt_len),
-                               rq->min_buf_len - hdr_len, PAGE_SIZE - hdr_len);
+                               rq->min_buf_len, PAGE_SIZE - hdr_len);
        return ALIGN(len, L1_CACHE_BYTES);
 }
 
@@ -2144,7 +2144,8 @@ static unsigned int mergeable_min_buf_len(struct virtnet_info *vi, struct virtqu
        unsigned int buf_len = hdr_len + ETH_HLEN + VLAN_HLEN + packet_len;
        unsigned int min_buf_len = DIV_ROUND_UP(buf_len, rq_size);
 
-       return max(min_buf_len, hdr_len);
+       return max(max(min_buf_len, hdr_len) - hdr_len,
+                  (unsigned int)GOOD_PACKET_LEN);
 }
 
 static int virtnet_find_vqs(struct virtnet_info *vi)
index 328b4712683c334bf1de66a3a3789d0a04d734c3..a6b5052c1d36bb99260dd4232842fa9e8df2621c 100644 (file)
@@ -59,6 +59,8 @@ static const u8 all_zeros_mac[ETH_ALEN + 2];
 
 static int vxlan_sock_add(struct vxlan_dev *vxlan);
 
+static void vxlan_vs_del_dev(struct vxlan_dev *vxlan);
+
 /* per-network namespace private data for this module */
 struct vxlan_net {
        struct list_head  vxlan_list;
@@ -740,6 +742,22 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
        call_rcu(&f->rcu, vxlan_fdb_free);
 }
 
+static void vxlan_dst_free(struct rcu_head *head)
+{
+       struct vxlan_rdst *rd = container_of(head, struct vxlan_rdst, rcu);
+
+       dst_cache_destroy(&rd->dst_cache);
+       kfree(rd);
+}
+
+static void vxlan_fdb_dst_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f,
+                                 struct vxlan_rdst *rd)
+{
+       list_del_rcu(&rd->list);
+       vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
+       call_rcu(&rd->rcu, vxlan_dst_free);
+}
+
 static int vxlan_fdb_parse(struct nlattr *tb[], struct vxlan_dev *vxlan,
                           union vxlan_addr *ip, __be16 *port, __be32 *src_vni,
                           __be32 *vni, u32 *ifindex)
@@ -864,9 +882,7 @@ static int __vxlan_fdb_delete(struct vxlan_dev *vxlan,
         * otherwise destroy the fdb entry
         */
        if (rd && !list_is_singular(&f->remotes)) {
-               list_del_rcu(&rd->list);
-               vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
-               kfree_rcu(rd, rcu);
+               vxlan_fdb_dst_destroy(vxlan, f, rd);
                goto out;
        }
 
@@ -1067,6 +1083,8 @@ static void vxlan_sock_release(struct vxlan_dev *vxlan)
        rcu_assign_pointer(vxlan->vn4_sock, NULL);
        synchronize_net();
 
+       vxlan_vs_del_dev(vxlan);
+
        if (__vxlan_sock_release_prep(sock4)) {
                udp_tunnel_sock_release(sock4->sock);
                kfree(sock4);
@@ -2342,6 +2360,15 @@ static void vxlan_cleanup(unsigned long arg)
        mod_timer(&vxlan->age_timer, next_timer);
 }
 
+static void vxlan_vs_del_dev(struct vxlan_dev *vxlan)
+{
+       struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
+
+       spin_lock(&vn->sock_lock);
+       hlist_del_init_rcu(&vxlan->hlist);
+       spin_unlock(&vn->sock_lock);
+}
+
 static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
 {
        struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
@@ -3286,15 +3313,9 @@ static int vxlan_changelink(struct net_device *dev, struct nlattr *tb[],
 static void vxlan_dellink(struct net_device *dev, struct list_head *head)
 {
        struct vxlan_dev *vxlan = netdev_priv(dev);
-       struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
 
        vxlan_flush(vxlan, true);
 
-       spin_lock(&vn->sock_lock);
-       if (!hlist_unhashed(&vxlan->hlist))
-               hlist_del_rcu(&vxlan->hlist);
-       spin_unlock(&vn->sock_lock);
-
        gro_cells_destroy(&vxlan->gro_cells);
        list_del(&vxlan->next);
        unregister_netdevice_queue(dev, head);
index d5e993dc9b238c6fd306b801083346570eec8790..517a315e259b79f05f2d8d3e88c371a9f39ad9e9 100644 (file)
@@ -1271,6 +1271,8 @@ static int wcn36xx_remove(struct platform_device *pdev)
        qcom_smem_state_put(wcn->tx_enable_state);
        qcom_smem_state_put(wcn->tx_rings_empty_state);
 
+       rpmsg_destroy_ept(wcn->smd_channel);
+
        iounmap(wcn->dxe_base);
        iounmap(wcn->ccu_base);
 
index fc64b8913aa6a11c0111fec3b9d900174dc250c3..e03450059b06c0bfe510148f985c19668bcd3dff 100644 (file)
@@ -3422,7 +3422,7 @@ static int brcmf_sdio_bus_preinit(struct device *dev)
                /* otherwise, set txglomalign */
                value = sdiodev->settings->bus.sdio.sd_sgentry_align;
                /* SDIO ADMA requires at least 32 bit alignment */
-               value = max_t(u32, value, 4);
+               value = max_t(u32, value, ALIGNMENT);
                err = brcmf_iovar_data_set(dev, "bus:txglomalign", &value,
                                           sizeof(u32));
        }
index 3b3e076571d6d7089ae2df09d2dfbd2008cf81e4..45e2efc70d19e5f44c7a5e2a1cde2cf9a7448f91 100644 (file)
@@ -79,8 +79,8 @@
 /* Lowest firmware API version supported */
 #define IWL7260_UCODE_API_MIN  17
 #define IWL7265_UCODE_API_MIN  17
-#define IWL7265D_UCODE_API_MIN 17
-#define IWL3168_UCODE_API_MIN  20
+#define IWL7265D_UCODE_API_MIN 22
+#define IWL3168_UCODE_API_MIN  22
 
 /* NVM versions */
 #define IWL7260_NVM_VERSION            0x0a1d
index b9718c0cf17480dc4c1ab212fdbfabecb3125775..89137717c1fce778d63a55af99f16f970f3b34d6 100644 (file)
@@ -74,8 +74,8 @@
 #define IWL8265_UCODE_API_MAX  30
 
 /* Lowest firmware API version supported */
-#define IWL8000_UCODE_API_MIN  17
-#define IWL8265_UCODE_API_MIN  20
+#define IWL8000_UCODE_API_MIN  22
+#define IWL8265_UCODE_API_MIN  22
 
 /* NVM versions */
 #define IWL8000_NVM_VERSION            0x0a1d
index 306bc967742ee9a7b5629bab00f20cab77309fa1..77efbb78e867bfac47ae992c2703275e1b5062b2 100644 (file)
 #define MON_DMARB_RD_DATA_ADDR         (0xa03c5c)
 
 #define DBGC_IN_SAMPLE                 (0xa03c00)
+#define DBGC_OUT_CTRL                  (0xa03c0c)
 
 /* enable the ID buf for read */
 #define WFPM_PS_CTL_CLR                        0xA0300C
index 1b7d265ffb0acb476228b5b2a10040c09e41d61c..a10c6aae9ab98de7c752b05b9cc33059337b1410 100644 (file)
@@ -307,6 +307,11 @@ enum {
 /* Bit 1-3: LQ command color. Used to match responses to LQ commands */
 #define LQ_FLAG_COLOR_POS               1
 #define LQ_FLAG_COLOR_MSK               (7 << LQ_FLAG_COLOR_POS)
+#define LQ_FLAG_COLOR_GET(_f)          (((_f) & LQ_FLAG_COLOR_MSK) >>\
+                                        LQ_FLAG_COLOR_POS)
+#define LQ_FLAGS_COLOR_INC(_c)         ((((_c) + 1) << LQ_FLAG_COLOR_POS) &\
+                                        LQ_FLAG_COLOR_MSK)
+#define LQ_FLAG_COLOR_SET(_f, _c)      ((_c) | ((_f) & ~LQ_FLAG_COLOR_MSK))
 
 /* Bit 4-5: Tx RTS BW Signalling
  * (0) No RTS BW signalling
index 81b98915b1a42e21a318d293c459015688489c7f..1360ebfdc51bc6475c2c68301781b2296bb03369 100644 (file)
@@ -519,8 +519,11 @@ struct agg_tx_status {
  * bit-7 invalid rate indication
  */
 #define TX_RES_INIT_RATE_INDEX_MSK 0x0f
+#define TX_RES_RATE_TABLE_COLOR_POS 4
 #define TX_RES_RATE_TABLE_COLOR_MSK 0x70
 #define TX_RES_INV_RATE_INDEX_MSK 0x80
+#define TX_RES_RATE_TABLE_COL_GET(_f) (((_f) & TX_RES_RATE_TABLE_COLOR_MSK) >>\
+                                      TX_RES_RATE_TABLE_COLOR_POS)
 
 #define IWL_MVM_TX_RES_GET_TID(_ra_tid) ((_ra_tid) & 0x0f)
 #define IWL_MVM_TX_RES_GET_RA(_ra_tid) ((_ra_tid) >> 4)
index 7b86a4f1b574c6f507fbde87c1276241fd534a4a..c8712e6eea74187af9c0d8ef3a73622ab7d1d5fd 100644 (file)
@@ -1002,14 +1002,6 @@ int iwl_mvm_fw_dbg_collect_trig(struct iwl_mvm *mvm,
        return 0;
 }
 
-static inline void iwl_mvm_restart_early_start(struct iwl_mvm *mvm)
-{
-       if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000)
-               iwl_clear_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
-       else
-               iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 1);
-}
-
 int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
 {
        u8 *ptr;
@@ -1023,10 +1015,8 @@ int iwl_mvm_start_fw_dbg_conf(struct iwl_mvm *mvm, u8 conf_id)
        /* EARLY START - firmware's configuration is hard coded */
        if ((!mvm->fw->dbg_conf_tlv[conf_id] ||
             !mvm->fw->dbg_conf_tlv[conf_id]->num_of_hcmds) &&
-           conf_id == FW_DBG_START_FROM_ALIVE) {
-               iwl_mvm_restart_early_start(mvm);
+           conf_id == FW_DBG_START_FROM_ALIVE)
                return 0;
-       }
 
        if (!mvm->fw->dbg_conf_tlv[conf_id])
                return -EINVAL;
index 0f1831b419159b606967889ff8ea20c7ef86f0f2..fd2fc46e2fe51d8e8f1930af05e40ee9400c84a6 100644 (file)
@@ -1040,7 +1040,7 @@ static int iwl_mvm_mac_ctxt_send_beacon(struct iwl_mvm *mvm,
                struct iwl_mac_beacon_cmd_v6 beacon_cmd_v6;
                struct iwl_mac_beacon_cmd_v7 beacon_cmd;
        } u = {};
-       struct iwl_mac_beacon_cmd beacon_cmd;
+       struct iwl_mac_beacon_cmd beacon_cmd = {};
        struct ieee80211_tx_info *info;
        u32 beacon_skb_len;
        u32 rate, tx_flags;
index 4e74a6b90e70626d6e0e8bb8092796f078c7d55d..52f8d7a6a7dcec95d32089a11c7c9e37b53748a7 100644 (file)
@@ -1730,8 +1730,11 @@ int iwl_mvm_find_free_queue(struct iwl_mvm *mvm, u8 sta_id, u8 minq, u8 maxq);
  */
 static inline u32 iwl_mvm_flushable_queues(struct iwl_mvm *mvm)
 {
+       u32 cmd_queue = iwl_mvm_is_dqa_supported(mvm) ? IWL_MVM_DQA_CMD_QUEUE :
+               IWL_MVM_CMD_QUEUE;
+
        return ((BIT(mvm->cfg->base_params->num_of_queues) - 1) &
-               ~BIT(IWL_MVM_CMD_QUEUE));
+               ~BIT(cmd_queue));
 }
 
 static inline
@@ -1753,6 +1756,7 @@ static inline void iwl_mvm_stop_device(struct iwl_mvm *mvm)
        if (!iwl_mvm_has_new_tx_api(mvm))
                iwl_free_fw_paging(mvm);
        mvm->ucode_loaded = false;
+       mvm->fw_dbg_conf = FW_DBG_INVALID;
        iwl_trans_stop_device(mvm->trans);
 }
 
index 9ffff6ed813386418800cf38906b91989c5b6f52..3da5ec40aaead90731224bce3686071ae9dd9344 100644 (file)
@@ -1149,21 +1149,37 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
 
        mutex_lock(&mvm->mutex);
 
-       /* stop recording */
        if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_7000) {
+               /* stop recording */
                iwl_set_bits_prph(mvm->trans, MON_BUFF_SAMPLE_CTL, 0x100);
+
+               iwl_mvm_fw_error_dump(mvm);
+
+               /* start recording again if the firmware is not crashed */
+               if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
+                   mvm->fw->dbg_dest_tlv)
+                       iwl_clear_bits_prph(mvm->trans,
+                                           MON_BUFF_SAMPLE_CTL, 0x100);
        } else {
+               u32 in_sample = iwl_read_prph(mvm->trans, DBGC_IN_SAMPLE);
+               u32 out_ctrl = iwl_read_prph(mvm->trans, DBGC_OUT_CTRL);
+
+               /* stop recording */
                iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, 0);
-               /* wait before we collect the data till the DBGC stop */
                udelay(100);
-       }
+               iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, 0);
+               /* wait before we collect the data till the DBGC stop */
+               udelay(500);
 
-       iwl_mvm_fw_error_dump(mvm);
+               iwl_mvm_fw_error_dump(mvm);
 
-       /* start recording again if the firmware is not crashed */
-       WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
-                    mvm->fw->dbg_dest_tlv &&
-                    iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
+               /* start recording again if the firmware is not crashed */
+               if (!test_bit(STATUS_FW_ERROR, &mvm->trans->status) &&
+                   mvm->fw->dbg_dest_tlv) {
+                       iwl_write_prph(mvm->trans, DBGC_IN_SAMPLE, in_sample);
+                       iwl_write_prph(mvm->trans, DBGC_OUT_CTRL, out_ctrl);
+               }
+       }
 
        mutex_unlock(&mvm->mutex);
 
index 7788eefcd2bdd3066c0b40d5f5575e44f2102c0e..aa785cf3cf68399eb724b33d24d9168602f791a1 100644 (file)
@@ -2,7 +2,7 @@
  *
  * Copyright(c) 2005 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
- * Copyright(c) 2016 Intel Deutschland GmbH
+ * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -1083,34 +1083,6 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
                rs_get_lower_rate_in_column(lq_sta, rate);
 }
 
-/* Check if both rates are identical
- * allow_ant_mismatch enables matching a SISO rate on ANT_A or ANT_B
- * with a rate indicating STBC/BFER and ANT_AB.
- */
-static inline bool rs_rate_equal(struct rs_rate *a,
-                                struct rs_rate *b,
-                                bool allow_ant_mismatch)
-
-{
-       bool ant_match = (a->ant == b->ant) && (a->stbc == b->stbc) &&
-               (a->bfer == b->bfer);
-
-       if (allow_ant_mismatch) {
-               if (a->stbc || a->bfer) {
-                       WARN_ONCE(a->ant != ANT_AB, "stbc %d bfer %d ant %d",
-                                 a->stbc, a->bfer, a->ant);
-                       ant_match |= (b->ant == ANT_A || b->ant == ANT_B);
-               } else if (b->stbc || b->bfer) {
-                       WARN_ONCE(b->ant != ANT_AB, "stbc %d bfer %d ant %d",
-                                 b->stbc, b->bfer, b->ant);
-                       ant_match |= (a->ant == ANT_A || a->ant == ANT_B);
-               }
-       }
-
-       return (a->type == b->type) && (a->bw == b->bw) && (a->sgi == b->sgi) &&
-               (a->ldpc == b->ldpc) && (a->index == b->index) && ant_match;
-}
-
 /* Check if both rates share the same column */
 static inline bool rs_rate_column_match(struct rs_rate *a,
                                        struct rs_rate *b)
@@ -1182,12 +1154,12 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        u32 lq_hwrate;
        struct rs_rate lq_rate, tx_resp_rate;
        struct iwl_scale_tbl_info *curr_tbl, *other_tbl, *tmp_tbl;
-       u8 reduced_txp = (uintptr_t)info->status.status_driver_data[0];
+       u32 tlc_info = (uintptr_t)info->status.status_driver_data[0];
+       u8 reduced_txp = tlc_info & RS_DRV_DATA_TXP_MSK;
+       u8 lq_color = RS_DRV_DATA_LQ_COLOR_GET(tlc_info);
        u32 tx_resp_hwrate = (uintptr_t)info->status.status_driver_data[1];
        struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
        struct iwl_lq_sta *lq_sta = &mvmsta->lq_sta;
-       bool allow_ant_mismatch = fw_has_api(&mvm->fw->ucode_capa,
-                                            IWL_UCODE_TLV_API_LQ_SS_PARAMS);
 
        /* Treat uninitialized rate scaling data same as non-existing. */
        if (!lq_sta) {
@@ -1262,10 +1234,10 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
        rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
 
        /* Here we actually compare this rate to the latest LQ command */
-       if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) {
+       if (lq_color != LQ_FLAG_COLOR_GET(table->flags)) {
                IWL_DEBUG_RATE(mvm,
-                              "initial tx resp rate 0x%x does not match 0x%x\n",
-                              tx_resp_hwrate, lq_hwrate);
+                              "tx resp color 0x%x does not match 0x%x\n",
+                              lq_color, LQ_FLAG_COLOR_GET(table->flags));
 
                /*
                 * Since rates mis-match, the last LQ command may have failed.
@@ -3326,6 +3298,7 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
        u8 valid_tx_ant = 0;
        struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
        bool toggle_ant = false;
+       u32 color;
 
        memcpy(&rate, initial_rate, sizeof(rate));
 
@@ -3380,6 +3353,9 @@ static void rs_build_rates_table(struct iwl_mvm *mvm,
                                 num_rates, num_retries, valid_tx_ant,
                                 toggle_ant);
 
+       /* update the color of the LQ command (as a counter at bits 1-3) */
+       color = LQ_FLAGS_COLOR_INC(LQ_FLAG_COLOR_GET(lq_cmd->flags));
+       lq_cmd->flags = LQ_FLAG_COLOR_SET(lq_cmd->flags, color);
 }
 
 struct rs_bfer_active_iter_data {
index ee207f2c0a90c797e84659473f0bd1a455b00923..3abde1cb03034f9068230420072961371a187262 100644 (file)
@@ -2,6 +2,7 @@
  *
  * Copyright(c) 2003 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2015 Intel Mobile Communications GmbH
+ * Copyright(c) 2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License as
@@ -357,6 +358,20 @@ struct iwl_lq_sta {
        } pers;
 };
 
+/* ieee80211_tx_info's status_driver_data[0] is packed with lq color and txp
+ * Note, it's iwlmvm <-> mac80211 interface.
+ * bits 0-7: reduced tx power
+ * bits 8-10: LQ command's color
+ */
+#define RS_DRV_DATA_TXP_MSK 0xff
+#define RS_DRV_DATA_LQ_COLOR_POS 8
+#define RS_DRV_DATA_LQ_COLOR_MSK (7 << RS_DRV_DATA_LQ_COLOR_POS)
+#define RS_DRV_DATA_LQ_COLOR_GET(_f) (((_f) & RS_DRV_DATA_LQ_COLOR_MSK) >>\
+                                     RS_DRV_DATA_LQ_COLOR_POS)
+#define RS_DRV_DATA_PACK(_c, _p) ((void *)(uintptr_t)\
+                                 (((uintptr_t)_p) |\
+                                  ((_c) << RS_DRV_DATA_LQ_COLOR_POS)))
+
 /* Initialize station's rate scaling information after adding station */
 void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
                          enum nl80211_band band, bool init);
index f5c786ddc52631087b56067807bb4d48e0869664..614d67810d051c539bd093b9452c64dc4e9c8a2f 100644 (file)
@@ -2120,7 +2120,8 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
        if (!iwl_mvm_is_dqa_supported(mvm))
                return 0;
 
-       if (WARN_ON(vif->type != NL80211_IFTYPE_AP))
+       if (WARN_ON(vif->type != NL80211_IFTYPE_AP &&
+                   vif->type != NL80211_IFTYPE_ADHOC))
                return -ENOTSUPP;
 
        /*
@@ -2155,6 +2156,16 @@ int iwl_mvm_add_mcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
                mvmvif->cab_queue = queue;
        } else if (!fw_has_api(&mvm->fw->ucode_capa,
                               IWL_UCODE_TLV_API_STA_TYPE)) {
+               /*
+                * In IBSS, ieee80211_check_queues() sets the cab_queue to be
+                * invalid, so make sure we use the queue we want.
+                * Note that this is done here as we want to avoid making DQA
+                * changes in mac80211 layer.
+                */
+               if (vif->type == NL80211_IFTYPE_ADHOC) {
+                       vif->cab_queue = IWL_MVM_DQA_GCAST_QUEUE;
+                       mvmvif->cab_queue = vif->cab_queue;
+               }
                iwl_mvm_enable_txq(mvm, vif->cab_queue, vif->cab_queue, 0,
                                   &cfg, timeout);
        }
@@ -3321,18 +3332,15 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
 
        /* Get the station from the mvm local station table */
        mvm_sta = iwl_mvm_get_key_sta(mvm, vif, sta);
-       if (!mvm_sta) {
-               IWL_ERR(mvm, "Failed to find station\n");
-               return -EINVAL;
-       }
-       sta_id = mvm_sta->sta_id;
+       if (mvm_sta)
+               sta_id = mvm_sta->sta_id;
 
        IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
                      keyconf->keyidx, sta_id);
 
-       if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
-           keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
-           keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)
+       if (mvm_sta && (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
+                       keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
+                       keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256))
                return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
 
        if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {
index 2716cb5483bf5ab9851e7dbf1e5af04b887296e7..ad62b67dceb2836cefe354fd69af60aedc856f8e 100644 (file)
@@ -313,6 +313,7 @@ enum iwl_mvm_agg_state {
  *     This is basically (last acked packet++).
  * @rate_n_flags: Rate at which Tx was attempted. Holds the data between the
  *     Tx response (TX_CMD), and the block ack notification (COMPRESSED_BA).
+ * @lq_color: the color of the LQ command as it appears in tx response.
  * @amsdu_in_ampdu_allowed: true if A-MSDU in A-MPDU is allowed.
  * @state: state of the BA agreement establishment / tear down.
  * @txq_id: Tx queue used by the BA session / DQA
@@ -331,6 +332,7 @@ struct iwl_mvm_tid_data {
        u16 next_reclaimed;
        /* The rest is Tx AGG related */
        u32 rate_n_flags;
+       u8 lq_color;
        bool amsdu_in_ampdu_allowed;
        enum iwl_mvm_agg_state state;
        u16 txq_id;
index f9cbd197246f7ba6ba9e5e0af816cbec54eb9790..506d58104e1cc007ba9d767a16dd77f9df8f0481 100644 (file)
@@ -790,11 +790,13 @@ static int iwl_mvm_tcool_set_cur_state(struct thermal_cooling_device *cdev,
        struct iwl_mvm *mvm = (struct iwl_mvm *)(cdev->devdata);
        int ret;
 
-       if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR))
-               return -EIO;
-
        mutex_lock(&mvm->mutex);
 
+       if (!mvm->ucode_loaded || !(mvm->cur_ucode == IWL_UCODE_REGULAR)) {
+               ret = -EIO;
+               goto unlock;
+       }
+
        if (new_state >= ARRAY_SIZE(iwl_mvm_cdev_budgets)) {
                ret = -EINVAL;
                goto unlock;
index bcaceb64a6e8c230c5127ee5cc4b790b1f4f1d57..f21901cd4a4fdf75dac1b55d7b9525e84f9e65dd 100644 (file)
@@ -1323,6 +1323,7 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
        struct iwl_mvm_sta *mvmsta;
        struct sk_buff_head skbs;
        u8 skb_freed = 0;
+       u8 lq_color;
        u16 next_reclaimed, seq_ctl;
        bool is_ndp = false;
 
@@ -1405,8 +1406,9 @@ static void iwl_mvm_rx_tx_cmd_single(struct iwl_mvm *mvm,
                info->status.tx_time =
                        le16_to_cpu(tx_resp->wireless_media_time);
                BUILD_BUG_ON(ARRAY_SIZE(info->status.status_driver_data) < 1);
+               lq_color = TX_RES_RATE_TABLE_COL_GET(tx_resp->tlc_info);
                info->status.status_driver_data[0] =
-                               (void *)(uintptr_t)tx_resp->reduced_tpc;
+                       RS_DRV_DATA_PACK(lq_color, tx_resp->reduced_tpc);
 
                ieee80211_tx_status(mvm->hw, skb);
        }
@@ -1638,6 +1640,9 @@ static void iwl_mvm_rx_tx_cmd_agg(struct iwl_mvm *mvm,
                        le32_to_cpu(tx_resp->initial_rate);
                mvmsta->tid_data[tid].tx_time =
                        le16_to_cpu(tx_resp->wireless_media_time);
+               mvmsta->tid_data[tid].lq_color =
+                       (tx_resp->tlc_info & TX_RES_RATE_TABLE_COLOR_MSK) >>
+                       TX_RES_RATE_TABLE_COLOR_POS;
        }
 
        rcu_read_unlock();
@@ -1707,6 +1712,11 @@ static void iwl_mvm_tx_reclaim(struct iwl_mvm *mvm, int sta_id, int tid,
        iwl_mvm_check_ratid_empty(mvm, sta, tid);
 
        freed = 0;
+
+       /* pack lq color from tid_data along the reduced txp */
+       ba_info->status.status_driver_data[0] =
+               RS_DRV_DATA_PACK(tid_data->lq_color,
+                                ba_info->status.status_driver_data[0]);
        ba_info->status.status_driver_data[1] = (void *)(uintptr_t)rate;
 
        skb_queue_walk(&reclaimed_skbs, skb) {
index 70acf850a9f19f9750296ae2019d8f4a8c277b67..93cbc7a69bcd55d3560529c88b6a127451606cd7 100644 (file)
@@ -2803,7 +2803,8 @@ static struct iwl_trans_dump_data
 #ifdef CONFIG_PM_SLEEP
 static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
 {
-       if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3)
+       if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 &&
+           (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3))
                return iwl_pci_fw_enter_d0i3(trans);
 
        return 0;
@@ -2811,7 +2812,8 @@ static int iwl_trans_pcie_suspend(struct iwl_trans *trans)
 
 static void iwl_trans_pcie_resume(struct iwl_trans *trans)
 {
-       if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3)
+       if (trans->runtime_pm_mode == IWL_PLAT_PM_MODE_D0I3 &&
+           (trans->system_pm_mode == IWL_PLAT_PM_MODE_D0I3))
                iwl_pci_fw_exit_d0i3(trans);
 }
 #endif /* CONFIG_PM_SLEEP */
index 9fb46a6f47cf416e55d4416b228be50cdd460e4e..9c9bfbbabdf11ee597dfa7a3614e59d2e49236fe 100644 (file)
@@ -906,7 +906,7 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
 
        if (WARN_ON(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp))) {
                ret = -EINVAL;
-               goto error;
+               goto error_free_resp;
        }
 
        rsp = (void *)hcmd.resp_pkt->data;
@@ -915,13 +915,13 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
        if (qid > ARRAY_SIZE(trans_pcie->txq)) {
                WARN_ONCE(1, "queue index %d unsupported", qid);
                ret = -EIO;
-               goto error;
+               goto error_free_resp;
        }
 
        if (test_and_set_bit(qid, trans_pcie->queue_used)) {
                WARN_ONCE(1, "queue %d already used", qid);
                ret = -EIO;
-               goto error;
+               goto error_free_resp;
        }
 
        txq->id = qid;
@@ -934,8 +934,11 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
                           (txq->write_ptr) | (qid << 16));
        IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);
 
+       iwl_free_resp(&hcmd);
        return qid;
 
+error_free_resp:
+       iwl_free_resp(&hcmd);
 error:
        iwl_pcie_gen2_txq_free_memory(trans, txq);
        return ret;
index 8ea01904c0eae72b9273919c0214510072e89813..466517c7c8e618112dcdea3716631be9f277d400 100644 (file)
@@ -19,5 +19,3 @@ obj-$(CONFIG_VIDEO_AP1302)     += ap1302.o
 
 obj-$(CONFIG_VIDEO_LM3554) += lm3554.o
 
-ccflags-y += -Werror
-
index 1d7f7ab94cac3b7ebf454b16a890dab9dc255314..6b13a3a66e49e3ee064887fa324685ddf05d1a0c 100644 (file)
@@ -4,5 +4,3 @@ imx1x5-objs := imx.o drv201.o ad5816g.o dw9714.o dw9719.o dw9718.o vcm.o otp.o o
 
 ov8858_driver-objs := ../ov8858.o dw9718.o vcm.o
 obj-$(CONFIG_VIDEO_OV8858)     += ov8858_driver.o
-
-ccflags-y += -Werror
index fceb9e9b881bac608e81ae76ed50dad139e2432e..c9c0e1245858470147768987c12de5727e68ad22 100644 (file)
@@ -1,3 +1 @@
 obj-$(CONFIG_VIDEO_OV5693) += ov5693.o
-
-ccflags-y += -Werror
index 3fa7c1c1479f330367b7ab01bf41d8c502a69349..f126a89a08e93ff6511b603960285bfbe3a3c4f7 100644 (file)
@@ -351,5 +351,5 @@ DEFINES := -DHRT_HW -DHRT_ISP_CSS_CUSTOM_HOST -DHRT_USE_VIR_ADDRS -D__HOST__
 DEFINES += -DATOMISP_POSTFIX=\"css2400b0_v21\" -DISP2400B0
 DEFINES += -DSYSTEM_hive_isp_css_2400_system -DISP2400
 
-ccflags-y += $(INCLUDES) $(DEFINES) -fno-common -Werror
+ccflags-y += $(INCLUDES) $(DEFINES) -fno-common
 
index 21745946cae154f53cd87311e9350465388f70a5..ec47101cb1bf80f0867dbcff1d6aa10878df7418 100644 (file)
@@ -48,6 +48,7 @@ enum {
        CSS_ONLINE      = (1 << 1), /* between ->css_online() and ->css_offline() */
        CSS_RELEASED    = (1 << 2), /* refcnt reached zero, released */
        CSS_VISIBLE     = (1 << 3), /* css is visible to userland */
+       CSS_DYING       = (1 << 4), /* css is dying */
 };
 
 /* bits in struct cgroup flags field */
index ed2573e149faf070714e04f8160f7056b2fb1d3e..710a005c6b7a652bb9c32b5457dbd64196f6f4a0 100644 (file)
@@ -343,6 +343,26 @@ static inline bool css_tryget_online(struct cgroup_subsys_state *css)
        return true;
 }
 
+/**
+ * css_is_dying - test whether the specified css is dying
+ * @css: target css
+ *
+ * Test whether @css is in the process of offlining or already offline.  In
+ * most cases, ->css_online() and ->css_offline() callbacks should be
+ * enough; however, the actual offline operations are RCU delayed and this
+ * test returns %true also when @css is scheduled to be offlined.
+ *
+ * This is useful, for example, when the use case requires synchronous
+ * behavior with respect to cgroup removal.  cgroup removal schedules css
+ * offlining but the css can seem alive while the operation is being
+ * delayed.  If the delay affects user visible semantics, this test can be
+ * used to resolve the situation.
+ */
+static inline bool css_is_dying(struct cgroup_subsys_state *css)
+{
+       return !(css->flags & CSS_NO_REF) && percpu_ref_is_dying(&css->refcnt);
+}
+
 /**
  * css_put - put a css reference
  * @css: target css
index de179993e039d41d7e9034b5744be40954f81c09..ea9126006a69f94c7b8ea1705bf43bdf7b48e16c 100644 (file)
  * with any version that can compile the kernel
  */
 #define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
+
+/*
+ * GCC does not warn about unused static inline functions for
+ * -Wunused-function.  This turns out to avoid the need for complex #ifdef
+ * directives.  Suppress the warning in clang as well.
+ */
+#define inline inline __attribute__((unused))
index b4ee8f62ce8da82720cb79e7a9ea3ec97703b849..8e2828d48d7fcf6a7ba683bf51c8c91a1ad28ec0 100644 (file)
@@ -470,6 +470,7 @@ struct mlx4_update_qp_params {
        u16     rate_val;
 };
 
+struct mlx4_qp *mlx4_qp_lookup(struct mlx4_dev *dev, u32 qpn);
 int mlx4_update_qp(struct mlx4_dev *dev, u32 qpn,
                   enum mlx4_update_qp_attr attr,
                   struct mlx4_update_qp_params *params);
index eb50ce54b759154b99cf333e177adf8ca229c69b..413335c8cb529a8506a2f934577c3413512d8c97 100644 (file)
@@ -29,7 +29,7 @@ struct edid;
 struct cec_adapter;
 struct cec_notifier;
 
-#ifdef CONFIG_MEDIA_CEC_NOTIFIER
+#if IS_REACHABLE(CONFIG_CEC_CORE) && IS_ENABLED(CONFIG_CEC_NOTIFIER)
 
 /**
  * cec_notifier_get - find or create a new cec_notifier for the given device.
index b8eb895731d561a5f0ff4ec218055581ad6e21ee..bfa88d4d67e1d6663da4952a6a097e32f5e573a8 100644 (file)
@@ -173,7 +173,7 @@ struct cec_adapter {
        bool passthrough;
        struct cec_log_addrs log_addrs;
 
-#ifdef CONFIG_MEDIA_CEC_NOTIFIER
+#ifdef CONFIG_CEC_NOTIFIER
        struct cec_notifier *notifier;
 #endif
 
@@ -300,7 +300,7 @@ u16 cec_phys_addr_for_input(u16 phys_addr, u8 input);
  */
 int cec_phys_addr_validate(u16 phys_addr, u16 *parent, u16 *port);
 
-#ifdef CONFIG_MEDIA_CEC_NOTIFIER
+#ifdef CONFIG_CEC_NOTIFIER
 void cec_register_cec_notifier(struct cec_adapter *adap,
                               struct cec_notifier *notifier);
 #endif
index dbf0abba33b8da21be05abf6e719f69542da80fc..3e505bbff8ca4a41f8d39fefcd59aa01b85424f4 100644 (file)
@@ -1007,6 +1007,7 @@ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
  */
 extern const struct proto_ops inet6_stream_ops;
 extern const struct proto_ops inet6_dgram_ops;
+extern const struct proto_ops inet6_sockraw_ops;
 
 struct group_source_req;
 struct group_filter;
index 38a7427ae902e35973a8b7fa0e95ff602ede0e87..be6223c586fa05b3ef1dbcb96e73cf7b5dae292d 100644 (file)
@@ -924,7 +924,7 @@ struct tcp_congestion_ops {
        void (*cwnd_event)(struct sock *sk, enum tcp_ca_event ev);
        /* call when ack arrives (optional) */
        void (*in_ack_event)(struct sock *sk, u32 flags);
-       /* new value of cwnd after loss (optional) */
+       /* new value of cwnd after loss (required) */
        u32  (*undo_cwnd)(struct sock *sk);
        /* hook for packet ack accounting (optional) */
        void (*pkts_acked)(struct sock *sk, const struct ack_sample *sample);
index c3c9a0e1b3c9a474bd80b8cb10ea1049284474b0..8d4e85eae42c08481899e415075ee42c6d12f90f 100644 (file)
@@ -4265,6 +4265,11 @@ static void kill_css(struct cgroup_subsys_state *css)
 {
        lockdep_assert_held(&cgroup_mutex);
 
+       if (css->flags & CSS_DYING)
+               return;
+
+       css->flags |= CSS_DYING;
+
        /*
         * This must happen before css is disassociated with its cgroup.
         * See seq_css() for details.
index f6501f4f6040b5a9c21e84aeb57e20906ef1c614..ae643412948added94f05d7efb120631f7798b44 100644 (file)
@@ -176,9 +176,9 @@ typedef enum {
 } cpuset_flagbits_t;
 
 /* convenient tests for these bits */
-static inline bool is_cpuset_online(const struct cpuset *cs)
+static inline bool is_cpuset_online(struct cpuset *cs)
 {
-       return test_bit(CS_ONLINE, &cs->flags);
+       return test_bit(CS_ONLINE, &cs->flags) && !css_is_dying(&cs->css);
 }
 
 static inline int is_cpu_exclusive(const struct cpuset *cs)
index 574f78824d8a2ae53751bbe1849e53502bc575be..32bd3ead9ba14a0b42bda3fc959f9134a8c9cc36 100644 (file)
@@ -595,7 +595,7 @@ static int br_afspec(struct net_bridge *br,
                err = 0;
                switch (nla_type(attr)) {
                case IFLA_BRIDGE_VLAN_TUNNEL_INFO:
-                       if (!(p->flags & BR_VLAN_TUNNEL))
+                       if (!p || !(p->flags & BR_VLAN_TUNNEL))
                                return -EINVAL;
                        err = br_parse_vlan_tunnel_info(attr, &tinfo_curr);
                        if (err)
index 0db8102995a506d64ece0de48b7266ccf3839ba8..6f12a5271219f071ed2d0bacb263561cb9e0f605 100644 (file)
@@ -179,7 +179,8 @@ static void br_stp_start(struct net_bridge *br)
                br_debug(br, "using kernel STP\n");
 
                /* To start timers on any ports left in blocking */
-               mod_timer(&br->hello_timer, jiffies + br->hello_time);
+               if (br->dev->flags & IFF_UP)
+                       mod_timer(&br->hello_timer, jiffies + br->hello_time);
                br_port_state_selection(br);
        }
 
index b0b87a292e7ccac2221a2425510b3c28e1df97f7..a0adfc31a3fe854cd52600f6b2924255aee521c2 100644 (file)
@@ -1680,8 +1680,10 @@ start_again:
 
        hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
                          &devlink_nl_family, NLM_F_MULTI, cmd);
-       if (!hdr)
+       if (!hdr) {
+               nlmsg_free(skb);
                return -EMSGSIZE;
+       }
 
        if (devlink_nl_put_handle(skb, devlink))
                goto nla_put_failure;
@@ -2098,8 +2100,10 @@ start_again:
 
        hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
                          &devlink_nl_family, NLM_F_MULTI, cmd);
-       if (!hdr)
+       if (!hdr) {
+               nlmsg_free(skb);
                return -EMSGSIZE;
+       }
 
        if (devlink_nl_put_handle(skb, devlink))
                goto nla_put_failure;
index 346d3e85dfbc2eca1ded0442ecb78d31e1768523..b1be7c01efe269d2bc97be7dcd1cc5485d29fa7b 100644 (file)
@@ -3754,8 +3754,11 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk)
 
        spin_lock_irqsave(&q->lock, flags);
        skb = __skb_dequeue(q);
-       if (skb && (skb_next = skb_peek(q)))
+       if (skb && (skb_next = skb_peek(q))) {
                icmp_next = is_icmp_err_skb(skb_next);
+               if (icmp_next)
+                       sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_origin;
+       }
        spin_unlock_irqrestore(&q->lock, flags);
 
        if (is_icmp_err_skb(skb) && !icmp_next)
index 26130ae438da53f3f99a4e9fa712a572f40ca779..90038d45a54764df55017b46258dc772b0af1c96 100644 (file)
@@ -223,6 +223,53 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev,
        return 0;
 }
 
+#ifdef CONFIG_PM_SLEEP
+int dsa_switch_suspend(struct dsa_switch *ds)
+{
+       int i, ret = 0;
+
+       /* Suspend slave network devices */
+       for (i = 0; i < ds->num_ports; i++) {
+               if (!dsa_is_port_initialized(ds, i))
+                       continue;
+
+               ret = dsa_slave_suspend(ds->ports[i].netdev);
+               if (ret)
+                       return ret;
+       }
+
+       if (ds->ops->suspend)
+               ret = ds->ops->suspend(ds);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(dsa_switch_suspend);
+
+int dsa_switch_resume(struct dsa_switch *ds)
+{
+       int i, ret = 0;
+
+       if (ds->ops->resume)
+               ret = ds->ops->resume(ds);
+
+       if (ret)
+               return ret;
+
+       /* Resume slave network devices */
+       for (i = 0; i < ds->num_ports; i++) {
+               if (!dsa_is_port_initialized(ds, i))
+                       continue;
+
+               ret = dsa_slave_resume(ds->ports[i].netdev);
+               if (ret)
+                       return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(dsa_switch_resume);
+#endif
+
 static struct packet_type dsa_pack_type __read_mostly = {
        .type   = cpu_to_be16(ETH_P_XDSA),
        .func   = dsa_switch_rcv,
index 033b3bfb63dc1887b15b3e08f00a00f70b706ec4..7796580e99ee2c57cdd5503130c8ec2e121d879a 100644 (file)
@@ -484,8 +484,10 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst)
                dsa_ds_unapply(dst, ds);
        }
 
-       if (dst->cpu_switch)
+       if (dst->cpu_switch) {
                dsa_cpu_port_ethtool_restore(dst->cpu_switch);
+               dst->cpu_switch = NULL;
+       }
 
        pr_info("DSA: tree %d unapplied\n", dst->tree);
        dst->applied = false;
index ad345c8b0b0693cc214b212ccbb402859d910134..7281098df04ecd597b7824a9c0d2ec1d7f60e2b9 100644 (file)
@@ -289,53 +289,6 @@ static void dsa_switch_destroy(struct dsa_switch *ds)
        dsa_switch_unregister_notifier(ds);
 }
 
-#ifdef CONFIG_PM_SLEEP
-int dsa_switch_suspend(struct dsa_switch *ds)
-{
-       int i, ret = 0;
-
-       /* Suspend slave network devices */
-       for (i = 0; i < ds->num_ports; i++) {
-               if (!dsa_is_port_initialized(ds, i))
-                       continue;
-
-               ret = dsa_slave_suspend(ds->ports[i].netdev);
-               if (ret)
-                       return ret;
-       }
-
-       if (ds->ops->suspend)
-               ret = ds->ops->suspend(ds);
-
-       return ret;
-}
-EXPORT_SYMBOL_GPL(dsa_switch_suspend);
-
-int dsa_switch_resume(struct dsa_switch *ds)
-{
-       int i, ret = 0;
-
-       if (ds->ops->resume)
-               ret = ds->ops->resume(ds);
-
-       if (ret)
-               return ret;
-
-       /* Resume slave network devices */
-       for (i = 0; i < ds->num_ports; i++) {
-               if (!dsa_is_port_initialized(ds, i))
-                       continue;
-
-               ret = dsa_slave_resume(ds->ports[i].netdev);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(dsa_switch_resume);
-#endif
-
 /* platform driver init and cleanup *****************************************/
 static int dev_is_class(struct device *dev, void *class)
 {
index f3dad16613437c0c7ac3e9c7518a0929cddb3ca7..58925b6597de83e7d643fb9b1c7e992c9748ae1c 100644 (file)
@@ -1043,7 +1043,7 @@ static struct inet_protosw inetsw_array[] =
                .type =       SOCK_DGRAM,
                .protocol =   IPPROTO_ICMP,
                .prot =       &ping_prot,
-               .ops =        &inet_dgram_ops,
+               .ops =        &inet_sockraw_ops,
                .flags =      INET_PROTOSW_REUSE,
        },
 
index 59792d283ff8c19048904cb790dbeebef14da73d..b5ea036ca78144b86622cb0944d0b840f7225ec5 100644 (file)
@@ -2381,9 +2381,10 @@ static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int l
        return 0;
 }
 
-static int tcp_repair_options_est(struct tcp_sock *tp,
+static int tcp_repair_options_est(struct sock *sk,
                struct tcp_repair_opt __user *optbuf, unsigned int len)
 {
+       struct tcp_sock *tp = tcp_sk(sk);
        struct tcp_repair_opt opt;
 
        while (len >= sizeof(opt)) {
@@ -2396,6 +2397,7 @@ static int tcp_repair_options_est(struct tcp_sock *tp,
                switch (opt.opt_code) {
                case TCPOPT_MSS:
                        tp->rx_opt.mss_clamp = opt.opt_val;
+                       tcp_mtup_init(sk);
                        break;
                case TCPOPT_WINDOW:
                        {
@@ -2555,7 +2557,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level,
                if (!tp->repair)
                        err = -EINVAL;
                else if (sk->sk_state == TCP_ESTABLISHED)
-                       err = tcp_repair_options_est(tp,
+                       err = tcp_repair_options_est(sk,
                                        (struct tcp_repair_opt __user *)optval,
                                        optlen);
                else
index 6e3c512054a60715e8e2d16ffedd12cba6a3d2d9..324c9bcc5456b499b59cef40838b4e9829119e13 100644 (file)
@@ -180,6 +180,7 @@ void tcp_init_congestion_control(struct sock *sk)
 {
        const struct inet_connection_sock *icsk = inet_csk(sk);
 
+       tcp_sk(sk)->prior_ssthresh = 0;
        if (icsk->icsk_ca_ops->init)
                icsk->icsk_ca_ops->init(sk);
        if (tcp_ca_needs_ecn(sk))
index 37ac9de713c69af30ae50d03e53ee472a7520b98..8d772fea1ddecd427a66c18f34d50f969186f02a 100644 (file)
@@ -1319,7 +1319,7 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
        struct ipv6hdr *ip6_hdr;
        struct ipv6_opt_hdr *hop;
        unsigned char buf[CALIPSO_MAX_BUFFER];
-       int len_delta, new_end, pad;
+       int len_delta, new_end, pad, payload;
        unsigned int start, end;
 
        ip6_hdr = ipv6_hdr(skb);
@@ -1346,6 +1346,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
        if (ret_val < 0)
                return ret_val;
 
+       ip6_hdr = ipv6_hdr(skb); /* Reset as skb_cow() may have moved it */
+
        if (len_delta) {
                if (len_delta > 0)
                        skb_push(skb, len_delta);
@@ -1355,6 +1357,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb,
                        sizeof(*ip6_hdr) + start);
                skb_reset_network_header(skb);
                ip6_hdr = ipv6_hdr(skb);
+               payload = ntohs(ip6_hdr->payload_len);
+               ip6_hdr->payload_len = htons(payload + len_delta);
        }
 
        hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1);
index 280268f1dd7b0972d7fadbcc9e28b043ceae423d..cdb3728faca7746d91e2430f6024f060a82b24fd 100644 (file)
@@ -116,8 +116,10 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb,
 
                if (udpfrag) {
                        int err = ip6_find_1stfragopt(skb, &prevhdr);
-                       if (err < 0)
+                       if (err < 0) {
+                               kfree_skb_list(segs);
                                return ERR_PTR(err);
+                       }
                        fptr = (struct frag_hdr *)((u8 *)ipv6h + err);
                        fptr->frag_off = htons(offset);
                        if (skb->next)
index 7ae6c503f1ca2b089388598bfceb43e4aa2d2fea..9b37f9747fc6a6fbabb0740188bc98b5c95c41c4 100644 (file)
@@ -1095,6 +1095,9 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
 
        if (!dst) {
 route_lookup:
+               /* add dsfield to flowlabel for route lookup */
+               fl6->flowlabel = ip6_make_flowinfo(dsfield, fl6->flowlabel);
+
                dst = ip6_route_output(net, NULL, fl6);
 
                if (dst->error)
index 9b522fa90e6d8f4a87ebed7cf574a36ceea89c61..ac826dd338ff0825eaf0d2d74cee92d008e018bb 100644 (file)
@@ -192,7 +192,7 @@ static struct inet_protosw pingv6_protosw = {
        .type =      SOCK_DGRAM,
        .protocol =  IPPROTO_ICMPV6,
        .prot =      &pingv6_prot,
-       .ops =       &inet6_dgram_ops,
+       .ops =       &inet6_sockraw_ops,
        .flags =     INET_PROTOSW_REUSE,
 };
 
index 1f992d9e261d8b75226659a4cead95f8dc04dc4f..60be012fe7085cc7a199e84333cef5ee95ed1f04 100644 (file)
@@ -1338,7 +1338,7 @@ void raw6_proc_exit(void)
 #endif /* CONFIG_PROC_FS */
 
 /* Same as inet6_dgram_ops, sans udp_poll.  */
-static const struct proto_ops inet6_sockraw_ops = {
+const struct proto_ops inet6_sockraw_ops = {
        .family            = PF_INET6,
        .owner             = THIS_MODULE,
        .release           = inet6_release,
index 0e015906f9ca91e11d3e9e124c532c6a7cb04c5d..07d36573f50b9451e4c2bfee331ac2c023791a7a 100644 (file)
@@ -47,6 +47,8 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
        iph = ipv6_hdr(skb);
 
        hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
+       if (hdr_len < 0)
+               return hdr_len;
        skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
        skb_set_network_header(skb, -x->props.header_len);
        skb->transport_header = skb->network_header + hdr_len;
index 7a92c0f3191250118ce3572ca91ee9116460bce8..9ad07a91708ef7a1008d469766ab39b9b882883f 100644 (file)
@@ -30,6 +30,8 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb)
        skb_set_inner_transport_header(skb, skb_transport_offset(skb));
 
        hdr_len = x->type->hdr_offset(x, skb, &prevhdr);
+       if (hdr_len < 0)
+               return hdr_len;
        skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data);
        skb_set_network_header(skb, -x->props.header_len);
        skb->transport_header = skb->network_header + hdr_len;
index 60e2a62f7bef2fbb014f3a40403cf498a75d429c..cf2392b2ac717972e4354346fd086ec802370de3 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
- * Copyright(c) 2015 Intel Deutschland GmbH
+ * Copyright(c) 2015-2017 Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -741,46 +741,43 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local,
        ieee80211_agg_start_txq(sta, tid, true);
 }
 
-void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid)
+void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid,
+                             struct tid_ampdu_tx *tid_tx)
 {
-       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       struct ieee80211_sub_if_data *sdata = sta->sdata;
        struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-       struct tid_ampdu_tx *tid_tx;
 
-       trace_api_start_tx_ba_cb(sdata, ra, tid);
+       if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)))
+               return;
+
+       if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state))
+               ieee80211_agg_tx_operational(local, sta, tid);
+}
+
+static struct tid_ampdu_tx *
+ieee80211_lookup_tid_tx(struct ieee80211_sub_if_data *sdata,
+                       const u8 *ra, u16 tid, struct sta_info **sta)
+{
+       struct tid_ampdu_tx *tid_tx;
 
        if (tid >= IEEE80211_NUM_TIDS) {
                ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n",
                       tid, IEEE80211_NUM_TIDS);
-               return;
+               return NULL;
        }
 
-       mutex_lock(&local->sta_mtx);
-       sta = sta_info_get_bss(sdata, ra);
-       if (!sta) {
-               mutex_unlock(&local->sta_mtx);
+       *sta = sta_info_get_bss(sdata, ra);
+       if (!*sta) {
                ht_dbg(sdata, "Could not find station: %pM\n", ra);
-               return;
+               return NULL;
        }
 
-       mutex_lock(&sta->ampdu_mlme.mtx);
-       tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
+       tid_tx = rcu_dereference((*sta)->ampdu_mlme.tid_tx[tid]);
 
-       if (WARN_ON(!tid_tx)) {
+       if (WARN_ON(!tid_tx))
                ht_dbg(sdata, "addBA was not requested!\n");
-               goto unlock;
-       }
 
-       if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state)))
-               goto unlock;
-
-       if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state))
-               ieee80211_agg_tx_operational(local, sta, tid);
-
- unlock:
-       mutex_unlock(&sta->ampdu_mlme.mtx);
-       mutex_unlock(&local->sta_mtx);
+       return tid_tx;
 }
 
 void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
@@ -788,19 +785,20 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
 {
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
        struct ieee80211_local *local = sdata->local;
-       struct ieee80211_ra_tid *ra_tid;
-       struct sk_buff *skb = dev_alloc_skb(0);
+       struct sta_info *sta;
+       struct tid_ampdu_tx *tid_tx;
 
-       if (unlikely(!skb))
-               return;
+       trace_api_start_tx_ba_cb(sdata, ra, tid);
 
-       ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
-       memcpy(&ra_tid->ra, ra, ETH_ALEN);
-       ra_tid->tid = tid;
+       rcu_read_lock();
+       tid_tx = ieee80211_lookup_tid_tx(sdata, ra, tid, &sta);
+       if (!tid_tx)
+               goto out;
 
-       skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_START;
-       skb_queue_tail(&sdata->skb_queue, skb);
-       ieee80211_queue_work(&local->hw, &sdata->work);
+       set_bit(HT_AGG_STATE_START_CB, &tid_tx->state);
+       ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
+ out:
+       rcu_read_unlock();
 }
 EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe);
 
@@ -860,37 +858,18 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
 }
 EXPORT_SYMBOL(ieee80211_stop_tx_ba_session);
 
-void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
+void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
+                            struct tid_ampdu_tx *tid_tx)
 {
-       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
-       struct ieee80211_local *local = sdata->local;
-       struct sta_info *sta;
-       struct tid_ampdu_tx *tid_tx;
+       struct ieee80211_sub_if_data *sdata = sta->sdata;
        bool send_delba = false;
 
-       trace_api_stop_tx_ba_cb(sdata, ra, tid);
-
-       if (tid >= IEEE80211_NUM_TIDS) {
-               ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n",
-                      tid, IEEE80211_NUM_TIDS);
-               return;
-       }
-
-       ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", ra, tid);
-
-       mutex_lock(&local->sta_mtx);
-
-       sta = sta_info_get_bss(sdata, ra);
-       if (!sta) {
-               ht_dbg(sdata, "Could not find station: %pM\n", ra);
-               goto unlock;
-       }
+       ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n",
+              sta->sta.addr, tid);
 
-       mutex_lock(&sta->ampdu_mlme.mtx);
        spin_lock_bh(&sta->lock);
-       tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
 
-       if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
+       if (!test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
                ht_dbg(sdata,
                       "unexpected callback to A-MPDU stop for %pM tid %d\n",
                       sta->sta.addr, tid);
@@ -906,12 +885,8 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid)
        spin_unlock_bh(&sta->lock);
 
        if (send_delba)
-               ieee80211_send_delba(sdata, ra, tid,
+               ieee80211_send_delba(sdata, sta->sta.addr, tid,
                        WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE);
-
-       mutex_unlock(&sta->ampdu_mlme.mtx);
- unlock:
-       mutex_unlock(&local->sta_mtx);
 }
 
 void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
@@ -919,19 +894,20 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
 {
        struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
        struct ieee80211_local *local = sdata->local;
-       struct ieee80211_ra_tid *ra_tid;
-       struct sk_buff *skb = dev_alloc_skb(0);
+       struct sta_info *sta;
+       struct tid_ampdu_tx *tid_tx;
 
-       if (unlikely(!skb))
-               return;
+       trace_api_stop_tx_ba_cb(sdata, ra, tid);
 
-       ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
-       memcpy(&ra_tid->ra, ra, ETH_ALEN);
-       ra_tid->tid = tid;
+       rcu_read_lock();
+       tid_tx = ieee80211_lookup_tid_tx(sdata, ra, tid, &sta);
+       if (!tid_tx)
+               goto out;
 
-       skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_STOP;
-       skb_queue_tail(&sdata->skb_queue, skb);
-       ieee80211_queue_work(&local->hw, &sdata->work);
+       set_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state);
+       ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work);
+ out:
+       rcu_read_unlock();
 }
 EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe);
 
index f4a52877356349abed96d0a77d6ae75f301181e4..6ca5442b1e03b18aa81764089bf74c002d337690 100644 (file)
@@ -7,6 +7,7 @@
  * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>
  * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
  * Copyright 2007-2010, Intel Corporation
+ * Copyright 2017      Intel Deutschland GmbH
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -289,8 +290,6 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
 {
        int i;
 
-       cancel_work_sync(&sta->ampdu_mlme.work);
-
        for (i = 0; i <  IEEE80211_NUM_TIDS; i++) {
                __ieee80211_stop_tx_ba_session(sta, i, reason);
                __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT,
@@ -298,6 +297,9 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta,
                                               reason != AGG_STOP_DESTROY_STA &&
                                               reason != AGG_STOP_PEER_REQUEST);
        }
+
+       /* stopping might queue the work again - so cancel only afterwards */
+       cancel_work_sync(&sta->ampdu_mlme.work);
 }
 
 void ieee80211_ba_session_work(struct work_struct *work)
@@ -352,10 +354,16 @@ void ieee80211_ba_session_work(struct work_struct *work)
                spin_unlock_bh(&sta->lock);
 
                tid_tx = rcu_dereference_protected_tid_tx(sta, tid);
-               if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP,
-                                                &tid_tx->state))
+               if (!tid_tx)
+                       continue;
+
+               if (test_and_clear_bit(HT_AGG_STATE_START_CB, &tid_tx->state))
+                       ieee80211_start_tx_ba_cb(sta, tid, tid_tx);
+               if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state))
                        ___ieee80211_stop_tx_ba_session(sta, tid,
                                                        AGG_STOP_LOCAL_REQUEST);
+               if (test_and_clear_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state))
+                       ieee80211_stop_tx_ba_cb(sta, tid, tid_tx);
        }
        mutex_unlock(&sta->ampdu_mlme.mtx);
 }
index f8f6c148f5545feeb78c16ca6f33ebf5e02d0ab5..665501ac358f8d83630f2727fe6249dcfeeb9689 100644 (file)
@@ -1036,8 +1036,6 @@ struct ieee80211_rx_agg {
 
 enum sdata_queue_type {
        IEEE80211_SDATA_QUEUE_TYPE_FRAME        = 0,
-       IEEE80211_SDATA_QUEUE_AGG_START         = 1,
-       IEEE80211_SDATA_QUEUE_AGG_STOP          = 2,
        IEEE80211_SDATA_QUEUE_RX_AGG_START      = 3,
        IEEE80211_SDATA_QUEUE_RX_AGG_STOP       = 4,
 };
@@ -1427,12 +1425,6 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata)
        return local->hw.wiphy->bands[band];
 }
 
-/* this struct represents 802.11n's RA/TID combination */
-struct ieee80211_ra_tid {
-       u8 ra[ETH_ALEN];
-       u16 tid;
-};
-
 /* this struct holds the value parsing from channel switch IE  */
 struct ieee80211_csa_ie {
        struct cfg80211_chan_def chandef;
@@ -1794,8 +1786,10 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                                   enum ieee80211_agg_stop_reason reason);
 int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                                    enum ieee80211_agg_stop_reason reason);
-void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid);
-void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid);
+void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid,
+                             struct tid_ampdu_tx *tid_tx);
+void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid,
+                            struct tid_ampdu_tx *tid_tx);
 void ieee80211_ba_session_work(struct work_struct *work);
 void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid);
 void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid);
index 3bd5b81f5d81ec7d73686043c2683630e24ecde4..8fae1a72e6a7c7ea4f71ec3a3beb215b987a715f 100644 (file)
@@ -1237,7 +1237,6 @@ static void ieee80211_iface_work(struct work_struct *work)
        struct ieee80211_local *local = sdata->local;
        struct sk_buff *skb;
        struct sta_info *sta;
-       struct ieee80211_ra_tid *ra_tid;
        struct ieee80211_rx_agg *rx_agg;
 
        if (!ieee80211_sdata_running(sdata))
@@ -1253,15 +1252,7 @@ static void ieee80211_iface_work(struct work_struct *work)
        while ((skb = skb_dequeue(&sdata->skb_queue))) {
                struct ieee80211_mgmt *mgmt = (void *)skb->data;
 
-               if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) {
-                       ra_tid = (void *)&skb->cb;
-                       ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra,
-                                                ra_tid->tid);
-               } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) {
-                       ra_tid = (void *)&skb->cb;
-                       ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra,
-                                               ra_tid->tid);
-               } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
+               if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) {
                        rx_agg = (void *)&skb->cb;
                        mutex_lock(&local->sta_mtx);
                        sta = sta_info_get_bss(sdata, rx_agg->addr);
index 7cdf7a835bb01e8fade3b9d9bb6efaa19158f72b..403e3cc58b573dc511c8ba399ddefdc7e8e24ba0 100644 (file)
@@ -2155,7 +2155,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
                        struct ieee80211_sta_rx_stats *cpurxs;
 
                        cpurxs = per_cpu_ptr(sta->pcpu_rx_stats, cpu);
-                       sinfo->rx_packets += cpurxs->dropped;
+                       sinfo->rx_dropped_misc += cpurxs->dropped;
                }
        }
 
index 5609cacb20d5f31e02ba877f88a6f0290e18ce8b..ea0747d6a6da194fec9116dc14b58a543f1accf2 100644 (file)
@@ -116,6 +116,8 @@ enum ieee80211_sta_info_flags {
 #define HT_AGG_STATE_STOPPING          3
 #define HT_AGG_STATE_WANT_START                4
 #define HT_AGG_STATE_WANT_STOP         5
+#define HT_AGG_STATE_START_CB          6
+#define HT_AGG_STATE_STOP_CB           7
 
 enum ieee80211_agg_stop_reason {
        AGG_STOP_DECLINED,
index 257ec66009da2dd7010d063c0ad29dbb9a32564e..7b05fd1497ceddea47c2c7917f5ee58f6ff2d560 100644 (file)
@@ -1418,7 +1418,7 @@ static void mpls_ifup(struct net_device *dev, unsigned int flags)
                                continue;
                        alive++;
                        nh_flags &= ~flags;
-                       WRITE_ONCE(nh->nh_flags, flags);
+                       WRITE_ONCE(nh->nh_flags, nh_flags);
                } endfor_nexthops(rt);
 
                WRITE_ONCE(rt->rt_nhn_alive, alive);
index 9799a50bc604cc630494514cc80aa49edc2def0e..a8be9b72e6cd2ca34166bba49a532f4f92e86e9e 100644 (file)
@@ -890,8 +890,13 @@ restart:
        }
 out:
        local_bh_enable();
-       if (last)
+       if (last) {
+               /* nf ct hash resize happened, now clear the leftover. */
+               if ((struct nf_conn *)cb->args[1] == last)
+                       cb->args[1] = 0;
+
                nf_ct_put(last);
+       }
 
        while (i) {
                i--;
index 13875d599a85713bbfeb2fee7b8978fa498a10ed..1c5b14a6cab369591bd13e22b284a0737ad75c2e 100644 (file)
@@ -512,16 +512,19 @@ static int sctp_error(struct net *net, struct nf_conn *tpl, struct sk_buff *skb,
                      u8 pf, unsigned int hooknum)
 {
        const struct sctphdr *sh;
-       struct sctphdr _sctph;
        const char *logmsg;
 
-       sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph);
-       if (!sh) {
+       if (skb->len < dataoff + sizeof(struct sctphdr)) {
                logmsg = "nf_ct_sctp: short packet ";
                goto out_invalid;
        }
        if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING &&
            skb->ip_summed == CHECKSUM_NONE) {
+               if (!skb_make_writable(skb, dataoff + sizeof(struct sctphdr))) {
+                       logmsg = "nf_ct_sctp: failed to read header ";
+                       goto out_invalid;
+               }
+               sh = (const struct sctphdr *)(skb->data + dataoff);
                if (sh->checksum != sctp_compute_cksum(skb, dataoff)) {
                        logmsg = "nf_ct_sctp: bad CRC ";
                        goto out_invalid;
index ef0be325a0c6368bfe29ecda39db37dcb178a6d2..6c72922d20caee83f498cb02cdce0c46899a1c22 100644 (file)
@@ -566,7 +566,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data)
         * Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack()
         * will delete entry from already-freed table.
         */
-       ct->status &= ~IPS_NAT_DONE_MASK;
+       clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status);
        rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource,
                        nf_nat_bysource_params);
 
index e97e2fb53f0a107b0361322be10f16b4ab4b5d32..fbdbaa00dd5fd751f6ab8f428de987017b5bdf79 100644 (file)
@@ -116,17 +116,17 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,
                else if (d > 0)
                        p = &parent->rb_right;
                else {
-                       if (nft_set_elem_active(&rbe->ext, genmask)) {
-                               if (nft_rbtree_interval_end(rbe) &&
-                                   !nft_rbtree_interval_end(new))
-                                       p = &parent->rb_left;
-                               else if (!nft_rbtree_interval_end(rbe) &&
-                                        nft_rbtree_interval_end(new))
-                                       p = &parent->rb_right;
-                               else {
-                                       *ext = &rbe->ext;
-                                       return -EEXIST;
-                               }
+                       if (nft_rbtree_interval_end(rbe) &&
+                           !nft_rbtree_interval_end(new)) {
+                               p = &parent->rb_left;
+                       } else if (!nft_rbtree_interval_end(rbe) &&
+                                  nft_rbtree_interval_end(new)) {
+                               p = &parent->rb_right;
+                       } else if (nft_set_elem_active(&rbe->ext, genmask)) {
+                               *ext = &rbe->ext;
+                               return -EEXIST;
+                       } else {
+                               p = &parent->rb_left;
                        }
                }
        }
index ee841f00a6ec715914fb14bb31dc8405f8dd4c4e..7586d446d7dcafc5c44b43190398840b68107d1f 100644 (file)
@@ -62,6 +62,7 @@
 #include <asm/cacheflush.h>
 #include <linux/hash.h>
 #include <linux/genetlink.h>
+#include <linux/net_namespace.h>
 
 #include <net/net_namespace.h>
 #include <net/sock.h>
@@ -1415,7 +1416,8 @@ static void do_one_broadcast(struct sock *sk,
                goto out;
        }
        NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net);
-       NETLINK_CB(p->skb2).nsid_is_set = true;
+       if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED)
+               NETLINK_CB(p->skb2).nsid_is_set = true;
        val = netlink_broadcast_deliver(sk, p->skb2);
        if (val < 0) {
                netlink_overrun(sk);