Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Sep 2014 23:49:56 +0000 (16:49 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 11 Sep 2014 23:49:56 +0000 (16:49 -0700)
Pull powerpc fixes from Michael Ellerman:
 "Ben's travelling so this is my first attempt at a pull request.

  There's nothing too exciting.  The CONFIG_FHANDLE one is annoying, I
  know you love defconfig changes.  But we've had a couple of developers
  waste time debugging boxes that wouldn't boot, only to realise it's
  just that systemd needs CONFIG_FHANDLE and our defconfigs don't have
  it.

  The new syscalls seem to be working, I've run the selftests that
  exist, and also let trinity bash on them for a while"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mpe/linux:
  powerpc: Wire up sys_seccomp(), sys_getrandom() and sys_memfd_create()
  powerpc: Make CONFIG_FHANDLE=y for all 64 bit powerpc defconfigs
  powerpc: use machine_subsys_initcall() for opal_hmi_handler_init()
  powerpc/perf: Fix ABIv2 kernel backtraces
  powerpc/pseries: Fix endian issues in memory hotplug

186 files changed:
Documentation/devicetree/bindings/dma/rcar-audmapp.txt
Documentation/devicetree/bindings/net/stmmac.txt
MAINTAINERS
arch/microblaze/Kconfig
arch/microblaze/include/asm/entry.h
arch/microblaze/include/asm/uaccess.h
arch/microblaze/include/asm/unistd.h
arch/s390/include/asm/ipl.h
arch/s390/kernel/ipl.c
arch/s390/kernel/vdso32/clock_gettime.S
arch/s390/kernel/vdso64/clock_gettime.S
arch/sh/mm/gup.c
drivers/acpi/acpi_cmos_rtc.c
drivers/acpi/acpi_lpss.c
drivers/acpi/battery.c
drivers/ata/ahci.c
drivers/ata/ahci_tegra.c
drivers/ata/ahci_xgene.c
drivers/ata/ata_piix.c
drivers/ata/pata_jmicron.c
drivers/bcma/host_pci.c
drivers/cpufreq/cpufreq_opp.c
drivers/dma/dma-jz4740.c
drivers/infiniband/hw/mlx4/main.c
drivers/infiniband/hw/mlx4/qp.c
drivers/input/keyboard/cap1106.c
drivers/input/keyboard/matrix_keypad.c
drivers/input/mouse/alps.c
drivers/input/mouse/elantech.c
drivers/input/mouse/psmouse-base.c
drivers/input/mouse/synaptics.c
drivers/input/mouse/synaptics.h
drivers/input/mouse/synaptics_usb.c
drivers/input/mouse/trackpoint.c
drivers/input/serio/serport.c
drivers/input/touchscreen/atmel_mxt_ts.c
drivers/input/touchscreen/wm9712.c
drivers/input/touchscreen/wm9713.c
drivers/net/ethernet/3com/3c59x.c
drivers/net/ethernet/aeroflex/greth.c
drivers/net/ethernet/aeroflex/greth.h
drivers/net/ethernet/amd/xgbe/xgbe-debugfs.c
drivers/net/ethernet/amd/xgbe/xgbe-dev.c
drivers/net/ethernet/amd/xgbe/xgbe-drv.c
drivers/net/ethernet/amd/xgbe/xgbe-ethtool.c
drivers/net/ethernet/amd/xgbe/xgbe-main.c
drivers/net/ethernet/amd/xgbe/xgbe.h
drivers/net/ethernet/apm/xgene/Kconfig
drivers/net/ethernet/broadcom/Kconfig
drivers/net/ethernet/broadcom/bnx2x/bnx2x_hsi.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.h
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/cnic.c
drivers/net/ethernet/broadcom/tg3.c
drivers/net/ethernet/broadcom/tg3.h
drivers/net/ethernet/brocade/bna/bnad.c
drivers/net/ethernet/calxeda/Kconfig
drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
drivers/net/ethernet/ibm/ehea/ehea_main.c
drivers/net/ethernet/intel/e1000/e1000_main.c
drivers/net/ethernet/intel/e1000e/netdev.c
drivers/net/ethernet/intel/i40e/i40e_txrx.c
drivers/net/ethernet/intel/i40evf/i40e_txrx.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/mcg.c
drivers/net/ethernet/moxa/moxart_ether.c
drivers/net/ethernet/nxp/lpc_eth.c
drivers/net/ethernet/qlogic/qlge/qlge_main.c
drivers/net/ethernet/renesas/Kconfig
drivers/net/ethernet/stmicro/stmmac/chain_mode.c
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
drivers/net/ethernet/stmicro/stmmac/mmc.h
drivers/net/ethernet/stmicro/stmmac/mmc_core.c
drivers/net/ethernet/stmicro/stmmac/ring_mode.c
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.h
drivers/net/fddi/skfp/h/skfbi.h
drivers/net/phy/phy.c
drivers/net/vmxnet3/vmxnet3_drv.c
drivers/net/vmxnet3/vmxnet3_int.h
drivers/net/vxlan.c
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/ath/ath9k/spectral.c
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/dvm/rxon.c
drivers/net/wireless/iwlwifi/iwl-7000.c
drivers/net/wireless/iwlwifi/iwl-8000.c
drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
drivers/net/xen-netback/interface.c
drivers/pinctrl/pinctrl-baytrail.c
drivers/s390/block/dasd_devmap.c
drivers/s390/net/qeth_core.h
drivers/s390/net/qeth_core_main.c
drivers/s390/net/qeth_l2_sys.c
drivers/ssb/b43_pci_bridge.c
fs/cifs/Kconfig
fs/cifs/cifsglob.h
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/readdir.c
fs/cifs/sess.c
fs/cifs/smb2file.c
fs/cifs/smb2inode.c
fs/cifs/smb2ops.c
fs/cifs/smb2pdu.c
fs/eventpoll.c
fs/ext4/namei.c
fs/ext4/resize.c
fs/lockd/svc.c
fs/nfsd/nfs4xdr.c
fs/notify/fdinfo.c
fs/udf/ialloc.c
fs/udf/inode.c
fs/udf/namei.c
fs/udf/super.c
fs/udf/udfdecl.h
include/linux/mlx4/device.h
include/linux/netdevice.h
include/linux/netfilter.h
include/net/bluetooth/hci_core.h
include/net/netns/ieee802154_6lowpan.h
include/net/regulatory.h
include/net/sctp/sctp.h
include/net/sock.h
include/net/wimax.h
include/trace/events/irq.h
include/uapi/linux/Kbuild
include/uapi/linux/input.h
kernel/cgroup.c
kernel/kcmp.c
kernel/printk/printk.c
mm/memblock.c
mm/mmap.c
mm/nobootmem.c
mm/percpu-vm.c
mm/percpu.c
net/bluetooth/hci_conn.c
net/bluetooth/hci_core.c
net/bluetooth/hci_event.c
net/core/datagram.c
net/core/dev.c
net/core/gen_estimator.c
net/core/gen_stats.c
net/core/skbuff.c
net/core/sock.c
net/ieee802154/6lowpan_rtnl.c
net/ieee802154/reassembly.c
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Makefile
net/ipv6/addrconf.c
net/ipv6/anycast.c
net/ipv6/mcast.c
net/ipv6/netfilter/Kconfig
net/ipv6/netfilter/Makefile
net/l2tp/l2tp_ppp.c
net/mac80211/chan.c
net/mac80211/debugfs_sta.c
net/mac80211/iface.c
net/mac80211/mesh_plink.c
net/mac80211/mlme.c
net/mac80211/sta_info.c
net/mac802154/wpan.c
net/netfilter/Kconfig
net/netfilter/Makefile
net/netfilter/core.c
net/netfilter/ipvs/ip_vs_core.c
net/netfilter/ipvs/ip_vs_xmit.c
net/netfilter/xt_cgroup.c
net/openvswitch/datapath.c
net/rfkill/rfkill-gpio.c
net/sctp/socket.c
net/socket.c
scripts/checkpatch.pl

index 9f1d750..61bca50 100644 (file)
@@ -16,9 +16,9 @@ Example:
 * DMA client
 
 Required properties:
-- dmas:                a list of <[DMA multiplexer phandle] [SRS/DRS value]> pairs,
-               where SRS/DRS values are fixed handles, specified in the SoC
-               manual as the value that would be written into the PDMACHCR.
+- dmas:                a list of <[DMA multiplexer phandle] [SRS << 8 | DRS]> pairs.
+               where SRS/DRS are specified in the SoC manual.
+               It will be written into PDMACHCR as high 16-bit parts.
 - dma-names:   a list of DMA channel names, one per "dmas" entry
 
 Example:
index 9b03c57..e45ac3f 100644 (file)
@@ -39,6 +39,10 @@ Optional properties:
   further clocks may be specified in derived bindings.
 - clock-names: One name for each entry in the clocks property, the
   first one should be "stmmaceth".
+- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is
+  available this clock is used for programming the Timestamp Addend Register.
+  If not passed then the system clock will be used and this is fine on some
+  platforms.
 
 Examples:
 
index 5e7866a..34091d7 100644 (file)
@@ -7053,7 +7053,7 @@ S:        Maintained
 F:     drivers/pinctrl/sh-pfc/
 
 PIN CONTROLLER - SAMSUNG
-M:     Tomasz Figa <t.figa@samsung.com>
+M:     Tomasz Figa <tomasz.figa@gmail.com>
 M:     Thomas Abraham <thomas.abraham@linaro.org>
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
@@ -7899,7 +7899,8 @@ S:        Supported
 F:     drivers/media/i2c/s5k5baf.c
 
 SAMSUNG SOC CLOCK DRIVERS
-M:     Tomasz Figa <t.figa@samsung.com>
+M:     Sylwester Nawrocki <s.nawrocki@samsung.com>
+M:     Tomasz Figa <tomasz.figa@gmail.com>
 S:     Supported
 L:     linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
 F:     drivers/clk/samsung/
index 40e1c1d..6feded3 100644 (file)
@@ -127,7 +127,7 @@ config SECCOMP
 
 endmenu
 
-menu "Advanced setup"
+menu "Kernel features"
 
 config ADVANCED_OPTIONS
        bool "Prompt for advanced kernel configuration options"
@@ -248,10 +248,10 @@ config MICROBLAZE_64K_PAGES
 
 endchoice
 
-endmenu
-
 source "mm/Kconfig"
 
+endmenu
+
 menu "Executable file formats"
 
 source "fs/Kconfig.binfmt"
index b4a4cb1..596e485 100644 (file)
@@ -15,6 +15,7 @@
 
 #include <asm/percpu.h>
 #include <asm/ptrace.h>
+#include <linux/linkage.h>
 
 /*
  * These are per-cpu variables required in entry.S, among other
index 0aa0057..59a89a6 100644 (file)
@@ -98,13 +98,13 @@ static inline int access_ok(int type, const void __user *addr,
 
        if ((get_fs().seg < ((unsigned long)addr)) ||
                        (get_fs().seg < ((unsigned long)addr + size - 1))) {
-               pr_debug("ACCESS fail: %s at 0x%08x (size 0x%x), seg 0x%08x\n",
+               pr_devel("ACCESS fail: %s at 0x%08x (size 0x%x), seg 0x%08x\n",
                        type ? "WRITE" : "READ ", (__force u32)addr, (u32)size,
                        (u32)get_fs().seg);
                return 0;
        }
 ok:
-       pr_debug("ACCESS OK: %s at 0x%08x (size 0x%x), seg 0x%08x\n",
+       pr_devel("ACCESS OK: %s at 0x%08x (size 0x%x), seg 0x%08x\n",
                        type ? "WRITE" : "READ ", (__force u32)addr, (u32)size,
                        (u32)get_fs().seg);
        return 1;
index fd56a8f..ea4b233 100644 (file)
@@ -38,6 +38,6 @@
 
 #endif /* __ASSEMBLY__ */
 
-#define __NR_syscalls         381
+#define __NR_syscalls         387
 
 #endif /* _ASM_MICROBLAZE_UNISTD_H */
index 2fcccc0..c81661e 100644 (file)
 #define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \
                              sizeof(struct ipl_block_fcp))
 
-#define IPL_PARM_BLK0_FCP_LEN (sizeof(struct ipl_block_fcp) + 8)
+#define IPL_PARM_BLK0_FCP_LEN (sizeof(struct ipl_block_fcp) + 16)
 
 #define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \
                              sizeof(struct ipl_block_ccw))
 
-#define IPL_PARM_BLK0_CCW_LEN (sizeof(struct ipl_block_ccw) + 8)
+#define IPL_PARM_BLK0_CCW_LEN (sizeof(struct ipl_block_ccw) + 16)
 
 #define IPL_MAX_SUPPORTED_VERSION (0)
 
@@ -38,10 +38,11 @@ struct ipl_list_hdr {
        u8  pbt;
        u8  flags;
        u16 reserved2;
+       u8  loadparm[8];
 } __attribute__((packed));
 
 struct ipl_block_fcp {
-       u8  reserved1[313-1];
+       u8  reserved1[305-1];
        u8  opt;
        u8  reserved2[3];
        u16 reserved3;
@@ -62,7 +63,6 @@ struct ipl_block_fcp {
                                 offsetof(struct ipl_block_fcp, scp_data)))
 
 struct ipl_block_ccw {
-       u8  load_parm[8];
        u8  reserved1[84];
        u8  reserved2[2];
        u16 devno;
index 22aac58..39badb9 100644 (file)
@@ -455,22 +455,6 @@ DEFINE_IPL_ATTR_RO(ipl_fcp, bootprog, "%lld\n", (unsigned long long)
 DEFINE_IPL_ATTR_RO(ipl_fcp, br_lba, "%lld\n", (unsigned long long)
                   IPL_PARMBLOCK_START->ipl_info.fcp.br_lba);
 
-static struct attribute *ipl_fcp_attrs[] = {
-       &sys_ipl_type_attr.attr,
-       &sys_ipl_device_attr.attr,
-       &sys_ipl_fcp_wwpn_attr.attr,
-       &sys_ipl_fcp_lun_attr.attr,
-       &sys_ipl_fcp_bootprog_attr.attr,
-       &sys_ipl_fcp_br_lba_attr.attr,
-       NULL,
-};
-
-static struct attribute_group ipl_fcp_attr_group = {
-       .attrs = ipl_fcp_attrs,
-};
-
-/* CCW ipl device attributes */
-
 static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
                                     struct kobj_attribute *attr, char *page)
 {
@@ -487,6 +471,23 @@ static ssize_t ipl_ccw_loadparm_show(struct kobject *kobj,
 static struct kobj_attribute sys_ipl_ccw_loadparm_attr =
        __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
 
+static struct attribute *ipl_fcp_attrs[] = {
+       &sys_ipl_type_attr.attr,
+       &sys_ipl_device_attr.attr,
+       &sys_ipl_fcp_wwpn_attr.attr,
+       &sys_ipl_fcp_lun_attr.attr,
+       &sys_ipl_fcp_bootprog_attr.attr,
+       &sys_ipl_fcp_br_lba_attr.attr,
+       &sys_ipl_ccw_loadparm_attr.attr,
+       NULL,
+};
+
+static struct attribute_group ipl_fcp_attr_group = {
+       .attrs = ipl_fcp_attrs,
+};
+
+/* CCW ipl device attributes */
+
 static struct attribute *ipl_ccw_attrs_vm[] = {
        &sys_ipl_type_attr.attr,
        &sys_ipl_device_attr.attr,
@@ -765,28 +766,10 @@ DEFINE_IPL_ATTR_RW(reipl_fcp, br_lba, "%lld\n", "%lld\n",
 DEFINE_IPL_ATTR_RW(reipl_fcp, device, "0.0.%04llx\n", "0.0.%llx\n",
                   reipl_block_fcp->ipl_info.fcp.devno);
 
-static struct attribute *reipl_fcp_attrs[] = {
-       &sys_reipl_fcp_device_attr.attr,
-       &sys_reipl_fcp_wwpn_attr.attr,
-       &sys_reipl_fcp_lun_attr.attr,
-       &sys_reipl_fcp_bootprog_attr.attr,
-       &sys_reipl_fcp_br_lba_attr.attr,
-       NULL,
-};
-
-static struct attribute_group reipl_fcp_attr_group = {
-       .attrs = reipl_fcp_attrs,
-};
-
-/* CCW reipl device attributes */
-
-DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
-       reipl_block_ccw->ipl_info.ccw.devno);
-
 static void reipl_get_ascii_loadparm(char *loadparm,
                                     struct ipl_parameter_block *ibp)
 {
-       memcpy(loadparm, ibp->ipl_info.ccw.load_parm, LOADPARM_LEN);
+       memcpy(loadparm, ibp->hdr.loadparm, LOADPARM_LEN);
        EBCASC(loadparm, LOADPARM_LEN);
        loadparm[LOADPARM_LEN] = 0;
        strim(loadparm);
@@ -821,13 +804,50 @@ static ssize_t reipl_generic_loadparm_store(struct ipl_parameter_block *ipb,
                return -EINVAL;
        }
        /* initialize loadparm with blanks */
-       memset(ipb->ipl_info.ccw.load_parm, ' ', LOADPARM_LEN);
+       memset(ipb->hdr.loadparm, ' ', LOADPARM_LEN);
        /* copy and convert to ebcdic */
-       memcpy(ipb->ipl_info.ccw.load_parm, buf, lp_len);
-       ASCEBC(ipb->ipl_info.ccw.load_parm, LOADPARM_LEN);
+       memcpy(ipb->hdr.loadparm, buf, lp_len);
+       ASCEBC(ipb->hdr.loadparm, LOADPARM_LEN);
        return len;
 }
 
+/* FCP wrapper */
+static ssize_t reipl_fcp_loadparm_show(struct kobject *kobj,
+                                      struct kobj_attribute *attr, char *page)
+{
+       return reipl_generic_loadparm_show(reipl_block_fcp, page);
+}
+
+static ssize_t reipl_fcp_loadparm_store(struct kobject *kobj,
+                                       struct kobj_attribute *attr,
+                                       const char *buf, size_t len)
+{
+       return reipl_generic_loadparm_store(reipl_block_fcp, buf, len);
+}
+
+static struct kobj_attribute sys_reipl_fcp_loadparm_attr =
+       __ATTR(loadparm, S_IRUGO | S_IWUSR, reipl_fcp_loadparm_show,
+                                           reipl_fcp_loadparm_store);
+
+static struct attribute *reipl_fcp_attrs[] = {
+       &sys_reipl_fcp_device_attr.attr,
+       &sys_reipl_fcp_wwpn_attr.attr,
+       &sys_reipl_fcp_lun_attr.attr,
+       &sys_reipl_fcp_bootprog_attr.attr,
+       &sys_reipl_fcp_br_lba_attr.attr,
+       &sys_reipl_fcp_loadparm_attr.attr,
+       NULL,
+};
+
+static struct attribute_group reipl_fcp_attr_group = {
+       .attrs = reipl_fcp_attrs,
+};
+
+/* CCW reipl device attributes */
+
+DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
+       reipl_block_ccw->ipl_info.ccw.devno);
+
 /* NSS wrapper */
 static ssize_t reipl_nss_loadparm_show(struct kobject *kobj,
                                       struct kobj_attribute *attr, char *page)
@@ -1125,11 +1145,10 @@ static void reipl_block_ccw_fill_parms(struct ipl_parameter_block *ipb)
        /* LOADPARM */
        /* check if read scp info worked and set loadparm */
        if (sclp_ipl_info.is_valid)
-               memcpy(ipb->ipl_info.ccw.load_parm,
-                               &sclp_ipl_info.loadparm, LOADPARM_LEN);
+               memcpy(ipb->hdr.loadparm, &sclp_ipl_info.loadparm, LOADPARM_LEN);
        else
                /* read scp info failed: set empty loadparm (EBCDIC blanks) */
-               memset(ipb->ipl_info.ccw.load_parm, 0x40, LOADPARM_LEN);
+               memset(ipb->hdr.loadparm, 0x40, LOADPARM_LEN);
        ipb->hdr.flags = DIAG308_FLAGS_LP_VALID;
 
        /* VM PARM */
@@ -1251,9 +1270,16 @@ static int __init reipl_fcp_init(void)
                return rc;
        }
 
-       if (ipl_info.type == IPL_TYPE_FCP)
+       if (ipl_info.type == IPL_TYPE_FCP) {
                memcpy(reipl_block_fcp, IPL_PARMBLOCK_START, PAGE_SIZE);
-       else {
+               /*
+                * Fix loadparm: There are systems where the (SCSI) LOADPARM
+                * is invalid in the SCSI IPL parameter block, so take it
+                * always from sclp_ipl_info.
+                */
+               memcpy(reipl_block_fcp->hdr.loadparm, sclp_ipl_info.loadparm,
+                      LOADPARM_LEN);
+       } else {
                reipl_block_fcp->hdr.len = IPL_PARM_BLK_FCP_LEN;
                reipl_block_fcp->hdr.version = IPL_PARM_BLOCK_VERSION;
                reipl_block_fcp->hdr.blk0_len = IPL_PARM_BLK0_FCP_LEN;
@@ -1864,7 +1890,23 @@ static void __init shutdown_actions_init(void)
 
 static int __init s390_ipl_init(void)
 {
+       char str[8] = {0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40};
+
        sclp_get_ipl_info(&sclp_ipl_info);
+       /*
+        * Fix loadparm: There are systems where the (SCSI) LOADPARM
+        * returned by read SCP info is invalid (contains EBCDIC blanks)
+        * when the system has been booted via diag308. In that case we use
+        * the value from diag308, if available.
+        *
+        * There are also systems where diag308 store does not work in
+        * case the system is booted from HMC. Fortunately in this case
+        * READ SCP info provides the correct value.
+        */
+       if (memcmp(sclp_ipl_info.loadparm, str, sizeof(str)) == 0 &&
+           diag308_set_works)
+               memcpy(sclp_ipl_info.loadparm, ipl_block.hdr.loadparm,
+                      LOADPARM_LEN);
        shutdown_actions_init();
        shutdown_triggers_init();
        return 0;
index 65fc397..7cf18f8 100644 (file)
@@ -22,13 +22,11 @@ __kernel_clock_gettime:
        basr    %r5,0
 0:     al      %r5,21f-0b(%r5)                 /* get &_vdso_data */
        chi     %r2,__CLOCK_REALTIME
-       je      10f
+       je      11f
        chi     %r2,__CLOCK_MONOTONIC
        jne     19f
 
        /* CLOCK_MONOTONIC */
-       ltr     %r3,%r3
-       jz      9f                              /* tp == NULL */
 1:     l       %r4,__VDSO_UPD_COUNT+4(%r5)     /* load update counter */
        tml     %r4,0x0001                      /* pending update ? loop */
        jnz     1b
@@ -67,12 +65,10 @@ __kernel_clock_gettime:
        j       6b
 8:     st      %r2,0(%r3)                      /* store tp->tv_sec */
        st      %r1,4(%r3)                      /* store tp->tv_nsec */
-9:     lhi     %r2,0
+       lhi     %r2,0
        br      %r14
 
        /* CLOCK_REALTIME */
-10:    ltr     %r3,%r3                         /* tp == NULL */
-       jz      18f
 11:    l       %r4,__VDSO_UPD_COUNT+4(%r5)     /* load update counter */
        tml     %r4,0x0001                      /* pending update ? loop */
        jnz     11b
@@ -111,7 +107,7 @@ __kernel_clock_gettime:
        j       15b
 17:    st      %r2,0(%r3)                      /* store tp->tv_sec */
        st      %r1,4(%r3)                      /* store tp->tv_nsec */
-18:    lhi     %r2,0
+       lhi     %r2,0
        br      %r14
 
        /* Fallback to system call */
index 91940ed..3f34e09 100644 (file)
@@ -21,7 +21,7 @@ __kernel_clock_gettime:
        .cfi_startproc
        larl    %r5,_vdso_data
        cghi    %r2,__CLOCK_REALTIME
-       je      4f
+       je      5f
        cghi    %r2,__CLOCK_THREAD_CPUTIME_ID
        je      9f
        cghi    %r2,-2          /* Per-thread CPUCLOCK with PID=0, VIRT=1 */
@@ -30,8 +30,6 @@ __kernel_clock_gettime:
        jne     12f
 
        /* CLOCK_MONOTONIC */
-       ltgr    %r3,%r3
-       jz      3f                              /* tp == NULL */
 0:     lg      %r4,__VDSO_UPD_COUNT(%r5)       /* load update counter */
        tmll    %r4,0x0001                      /* pending update ? loop */
        jnz     0b
@@ -53,12 +51,10 @@ __kernel_clock_gettime:
        j       1b
 2:     stg     %r0,0(%r3)                      /* store tp->tv_sec */
        stg     %r1,8(%r3)                      /* store tp->tv_nsec */
-3:     lghi    %r2,0
+       lghi    %r2,0
        br      %r14
 
        /* CLOCK_REALTIME */
-4:     ltr     %r3,%r3                         /* tp == NULL */
-       jz      8f
 5:     lg      %r4,__VDSO_UPD_COUNT(%r5)       /* load update counter */
        tmll    %r4,0x0001                      /* pending update ? loop */
        jnz     5b
@@ -80,7 +76,7 @@ __kernel_clock_gettime:
        j       6b
 7:     stg     %r0,0(%r3)                      /* store tp->tv_sec */
        stg     %r1,8(%r3)                      /* store tp->tv_nsec */
-8:     lghi    %r2,0
+       lghi    %r2,0
        br      %r14
 
        /* CLOCK_THREAD_CPUTIME_ID for this thread */
index bf8daf9..37458f3 100644 (file)
@@ -105,6 +105,8 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
                VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
                page = pte_page(pte);
                get_page(page);
+               __flush_anon_page(page, addr);
+               flush_dcache_page(page);
                pages[*nr] = page;
                (*nr)++;
 
index 2da8660..81dc750 100644 (file)
@@ -33,7 +33,7 @@ acpi_cmos_rtc_space_handler(u32 function, acpi_physical_address address,
                      void *handler_context, void *region_context)
 {
        int i;
-       u8 *value = (u8 *)&value64;
+       u8 *value = (u8 *)value64;
 
        if (address > 0xff || !value64)
                return AE_BAD_PARAMETER;
index 9dfec48..fddc1e8 100644 (file)
@@ -610,7 +610,7 @@ static int acpi_lpss_suspend_late(struct device *dev)
        return acpi_dev_suspend_late(dev);
 }
 
-static int acpi_lpss_restore_early(struct device *dev)
+static int acpi_lpss_resume_early(struct device *dev)
 {
        int ret = acpi_dev_resume_early(dev);
 
@@ -650,15 +650,15 @@ static int acpi_lpss_runtime_resume(struct device *dev)
 static struct dev_pm_domain acpi_lpss_pm_domain = {
        .ops = {
 #ifdef CONFIG_PM_SLEEP
-               .suspend_late = acpi_lpss_suspend_late,
-               .restore_early = acpi_lpss_restore_early,
                .prepare = acpi_subsys_prepare,
                .complete = acpi_subsys_complete,
                .suspend = acpi_subsys_suspend,
-               .resume_early = acpi_subsys_resume_early,
+               .suspend_late = acpi_lpss_suspend_late,
+               .resume_early = acpi_lpss_resume_early,
                .freeze = acpi_subsys_freeze,
                .poweroff = acpi_subsys_suspend,
-               .poweroff_late = acpi_subsys_suspend_late,
+               .poweroff_late = acpi_lpss_suspend_late,
+               .restore_early = acpi_lpss_resume_early,
 #endif
 #ifdef CONFIG_PM_RUNTIME
                .runtime_suspend = acpi_lpss_runtime_suspend,
index 1c162e7..5fdfe65 100644 (file)
@@ -534,20 +534,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)
                        " invalid.\n");
        }
 
-       /*
-        * When fully charged, some batteries wrongly report
-        * capacity_now = design_capacity instead of = full_charge_capacity
-        */
-       if (battery->capacity_now > battery->full_charge_capacity
-           && battery->full_charge_capacity != ACPI_BATTERY_VALUE_UNKNOWN) {
-               if (battery->capacity_now != battery->design_capacity)
-                       printk_once(KERN_WARNING FW_BUG
-                               "battery: reported current charge level (%d) "
-                               "is higher than reported maximum charge level (%d).\n",
-                               battery->capacity_now, battery->full_charge_capacity);
-               battery->capacity_now = battery->full_charge_capacity;
-       }
-
        if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)
            && battery->capacity_now >= 0 && battery->capacity_now <= 100)
                battery->capacity_now = (battery->capacity_now *
index a29f801..a0cc0ed 100644 (file)
@@ -305,6 +305,14 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_VDEVICE(INTEL, 0x9c85), board_ahci }, /* Wildcat Point-LP RAID */
        { PCI_VDEVICE(INTEL, 0x9c87), board_ahci }, /* Wildcat Point-LP RAID */
        { PCI_VDEVICE(INTEL, 0x9c8f), board_ahci }, /* Wildcat Point-LP RAID */
+       { PCI_VDEVICE(INTEL, 0x8c82), board_ahci }, /* 9 Series AHCI */
+       { PCI_VDEVICE(INTEL, 0x8c83), board_ahci }, /* 9 Series AHCI */
+       { PCI_VDEVICE(INTEL, 0x8c84), board_ahci }, /* 9 Series RAID */
+       { PCI_VDEVICE(INTEL, 0x8c85), board_ahci }, /* 9 Series RAID */
+       { PCI_VDEVICE(INTEL, 0x8c86), board_ahci }, /* 9 Series RAID */
+       { PCI_VDEVICE(INTEL, 0x8c87), board_ahci }, /* 9 Series RAID */
+       { PCI_VDEVICE(INTEL, 0x8c8e), board_ahci }, /* 9 Series RAID */
+       { PCI_VDEVICE(INTEL, 0x8c8f), board_ahci }, /* 9 Series RAID */
 
        /* JMicron 360/1/3/5/6, match class to avoid IDE function */
        { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
@@ -442,6 +450,8 @@ static const struct pci_device_id ahci_pci_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x917a),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9172),
+         .driver_data = board_ahci_yes_fbs },                  /* 88se9182 */
+       { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9182),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 */
        { PCI_DEVICE(PCI_VENDOR_ID_MARVELL_EXT, 0x9192),
          .driver_data = board_ahci_yes_fbs },                  /* 88se9172 on some Gigabyte */
@@ -1329,6 +1339,18 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        else if (pdev->vendor == 0x1c44 && pdev->device == 0x8000)
                ahci_pci_bar = AHCI_PCI_BAR_ENMOTUS;
 
+       /*
+        * The JMicron chip 361/363 contains one SATA controller and one
+        * PATA controller,for powering on these both controllers, we must
+        * follow the sequence one by one, otherwise one of them can not be
+        * powered on successfully, so here we disable the async suspend
+        * method for these chips.
+        */
+       if (pdev->vendor == PCI_VENDOR_ID_JMICRON &&
+               (pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 ||
+               pdev->device == PCI_DEVICE_ID_JMICRON_JMB361))
+               device_disable_async_suspend(&pdev->dev);
+
        /* acquire resources */
        rc = pcim_enable_device(pdev);
        if (rc)
index f1fef74..0329044 100644 (file)
  */
 
 #include <linux/ahci_platform.h>
-#include <linux/reset.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/consumer.h>
+#include <linux/reset.h>
+
+#include <soc/tegra/fuse.h>
 #include <soc/tegra/pmc.h>
+
 #include "ahci.h"
 
 #define SATA_CONFIGURATION_0                           0x180
@@ -180,9 +183,12 @@ static int tegra_ahci_controller_init(struct ahci_host_priv *hpriv)
 
        /* Pad calibration */
 
-       /* FIXME Always use calibration 0. Change this to read the calibration
-        * fuse once the fuse driver has landed. */
-       val = 0;
+       ret = tegra_fuse_readl(FUSE_SATA_CALIB, &val);
+       if (ret) {
+               dev_err(&tegra->pdev->dev,
+                       "failed to read calibration fuse: %d\n", ret);
+               return ret;
+       }
 
        calib = tegra124_pad_calibration[val & FUSE_SATA_CALIB_MASK];
 
index c696230..f03aab1 100644 (file)
@@ -78,6 +78,9 @@
 #define CFG_MEM_RAM_SHUTDOWN           0x00000070
 #define BLOCK_MEM_RDY                  0x00000074
 
+/* Max retry for link down */
+#define MAX_LINK_DOWN_RETRY 3
+
 struct xgene_ahci_context {
        struct ahci_host_priv *hpriv;
        struct device *dev;
@@ -145,6 +148,14 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc)
        return rc;
 }
 
+static bool xgene_ahci_is_memram_inited(struct xgene_ahci_context *ctx)
+{
+       void __iomem *diagcsr = ctx->csr_diag;
+
+       return (readl(diagcsr + CFG_MEM_RAM_SHUTDOWN) == 0 &&
+               readl(diagcsr + BLOCK_MEM_RDY) == 0xFFFFFFFF);
+}
+
 /**
  * xgene_ahci_read_id - Read ID data from the specified device
  * @dev: device
@@ -229,8 +240,11 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel)
  * and Gen1 (1.5Gbps). Otherwise during long IO stress test, the PHY will
  * report disparity error and etc. In addition, during COMRESET, there can
  * be error reported in the register PORT_SCR_ERR. For SERR_DISPARITY and
- * SERR_10B_8B_ERR, the PHY receiver line must be reseted. The following
- * algorithm is followed to proper configure the hardware PHY during COMRESET:
+ * SERR_10B_8B_ERR, the PHY receiver line must be reseted. Also during long
+ * reboot cycle regression, sometimes the PHY reports link down even if the
+ * device is present because of speed negotiation failure. so need to retry
+ * the COMRESET to get the link up. The following algorithm is followed to
+ * proper configure the hardware PHY during COMRESET:
  *
  * Alg Part 1:
  * 1. Start the PHY at Gen3 speed (default setting)
@@ -246,9 +260,15 @@ static void xgene_ahci_set_phy_cfg(struct xgene_ahci_context *ctx, int channel)
  * Alg Part 2:
  * 1. On link up, if there are any SERR_DISPARITY and SERR_10B_8B_ERR error
  *    reported in the register PORT_SCR_ERR, then reset the PHY receiver line
- * 2. Go to Alg Part 3
+ * 2. Go to Alg Part 4
  *
  * Alg Part 3:
+ * 1. Check the PORT_SCR_STAT to see whether device presence detected but PHY
+ *    communication establishment failed and maximum link down attempts are
+ *    less than Max attempts 3 then goto Alg Part 1.
+ * 2. Go to Alg Part 4.
+ *
+ * Alg Part 4:
  * 1. Clear any pending from register PORT_SCR_ERR.
  *
  * NOTE: For the initial version, we will NOT support Gen1/Gen2. In addition
@@ -267,19 +287,27 @@ static int xgene_ahci_do_hardreset(struct ata_link *link,
        u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
        void __iomem *port_mmio = ahci_port_base(ap);
        struct ata_taskfile tf;
+       int link_down_retry = 0;
        int rc;
-       u32 val;
-
-       /* clear D2H reception area to properly wait for D2H FIS */
-       ata_tf_init(link->device, &tf);
-       tf.command = ATA_BUSY;
-       ata_tf_to_fis(&tf, 0, 0, d2h_fis);
-       rc = sata_link_hardreset(link, timing, deadline, online,
+       u32 val, sstatus;
+
+       do {
+               /* clear D2H reception area to properly wait for D2H FIS */
+               ata_tf_init(link->device, &tf);
+               tf.command = ATA_BUSY;
+               ata_tf_to_fis(&tf, 0, 0, d2h_fis);
+               rc = sata_link_hardreset(link, timing, deadline, online,
                                 ahci_check_ready);
+               if (*online) {
+                       val = readl(port_mmio + PORT_SCR_ERR);
+                       if (val & (SERR_DISPARITY | SERR_10B_8B_ERR))
+                               dev_warn(ctx->dev, "link has error\n");
+                       break;
+               }
 
-       val = readl(port_mmio + PORT_SCR_ERR);
-       if (val & (SERR_DISPARITY | SERR_10B_8B_ERR))
-               dev_warn(ctx->dev, "link has error\n");
+               sata_scr_read(link, SCR_STATUS, &sstatus);
+       } while (link_down_retry++ < MAX_LINK_DOWN_RETRY &&
+                (sstatus & 0xff) == 0x1);
 
        /* clear all errors if any pending */
        val = readl(port_mmio + PORT_SCR_ERR);
@@ -467,6 +495,11 @@ static int xgene_ahci_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       if (xgene_ahci_is_memram_inited(ctx)) {
+               dev_info(dev, "skip clock and PHY initialization\n");
+               goto skip_clk_phy;
+       }
+
        /* Due to errata, HW requires full toggle transition */
        rc = ahci_platform_enable_clks(hpriv);
        if (rc)
@@ -479,7 +512,7 @@ static int xgene_ahci_probe(struct platform_device *pdev)
 
        /* Configure the host controller */
        xgene_ahci_hw_init(hpriv);
-
+skip_clk_phy:
        hpriv->flags = AHCI_HFLAG_NO_PMP | AHCI_HFLAG_NO_NCQ;
 
        rc = ahci_platform_init_host(pdev, hpriv, &xgene_ahci_port_info);
index 893e30e..ffbe625 100644 (file)
@@ -340,6 +340,14 @@ static const struct pci_device_id piix_pci_tbl[] = {
        { 0x8086, 0x0F21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_byt },
        /* SATA Controller IDE (Coleto Creek) */
        { 0x8086, 0x23a6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
+       /* SATA Controller IDE (9 Series) */
+       { 0x8086, 0x8c88, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
+       /* SATA Controller IDE (9 Series) */
+       { 0x8086, 0x8c89, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata_snb },
+       /* SATA Controller IDE (9 Series) */
+       { 0x8086, 0x8c80, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
+       /* SATA Controller IDE (9 Series) */
+       { 0x8086, 0x8c81, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_snb },
 
        { }     /* terminate list */
 };
index 4d1a5d2..47e418b 100644 (file)
@@ -143,6 +143,18 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
        };
        const struct ata_port_info *ppi[] = { &info, NULL };
 
+       /*
+        * The JMicron chip 361/363 contains one SATA controller and one
+        * PATA controller,for powering on these both controllers, we must
+        * follow the sequence one by one, otherwise one of them can not be
+        * powered on successfully, so here we disable the async suspend
+        * method for these chips.
+        */
+       if (pdev->vendor == PCI_VENDOR_ID_JMICRON &&
+               (pdev->device == PCI_DEVICE_ID_JMICRON_JMB363 ||
+               pdev->device == PCI_DEVICE_ID_JMICRON_JMB361))
+               device_disable_async_suspend(&pdev->dev);
+
        return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL, 0);
 }
 
index 294a7dd..f032ed6 100644 (file)
@@ -282,6 +282,7 @@ static const struct pci_device_id bcma_pci_bridge_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) },  /* 0xA8DB */
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, bcma_pci_bridge_tbl);
index f7a32d2..773bcde 100644 (file)
@@ -60,7 +60,7 @@ int dev_pm_opp_init_cpufreq_table(struct device *dev,
                goto out;
        }
 
-       freq_table = kcalloc(sizeof(*freq_table), (max_opps + 1), GFP_ATOMIC);
+       freq_table = kcalloc((max_opps + 1), sizeof(*freq_table), GFP_ATOMIC);
        if (!freq_table) {
                ret = -ENOMEM;
                goto out;
index 6a9d89c..ae2ab14 100644 (file)
@@ -362,8 +362,9 @@ static void jz4740_dma_chan_irq(struct jz4740_dmaengine_chan *chan)
                        vchan_cyclic_callback(&chan->desc->vdesc);
                } else {
                        if (chan->next_sg == chan->desc->num_sgs) {
-                               chan->desc = NULL;
+                               list_del(&chan->desc->vdesc.node);
                                vchan_cookie_complete(&chan->desc->vdesc);
+                               chan->desc = NULL;
                        }
                }
        }
index e1e558a..af82563 100644 (file)
@@ -1089,6 +1089,30 @@ static int __mlx4_ib_destroy_flow(struct mlx4_dev *dev, u64 reg_id)
        return err;
 }
 
+static int mlx4_ib_tunnel_steer_add(struct ib_qp *qp, struct ib_flow_attr *flow_attr,
+                                   u64 *reg_id)
+{
+       void *ib_flow;
+       union ib_flow_spec *ib_spec;
+       struct mlx4_dev *dev = to_mdev(qp->device)->dev;
+       int err = 0;
+
+       if (dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
+               return 0; /* do nothing */
+
+       ib_flow = flow_attr + 1;
+       ib_spec = (union ib_flow_spec *)ib_flow;
+
+       if (ib_spec->type !=  IB_FLOW_SPEC_ETH || flow_attr->num_of_specs != 1)
+               return 0; /* do nothing */
+
+       err = mlx4_tunnel_steer_add(to_mdev(qp->device)->dev, ib_spec->eth.val.dst_mac,
+                                   flow_attr->port, qp->qp_num,
+                                   MLX4_DOMAIN_UVERBS | (flow_attr->priority & 0xff),
+                                   reg_id);
+       return err;
+}
+
 static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp,
                                    struct ib_flow_attr *flow_attr,
                                    int domain)
@@ -1136,6 +1160,12 @@ static struct ib_flow *mlx4_ib_create_flow(struct ib_qp *qp,
                i++;
        }
 
+       if (i < ARRAY_SIZE(type) && flow_attr->type == IB_FLOW_ATTR_NORMAL) {
+               err = mlx4_ib_tunnel_steer_add(qp, flow_attr, &mflow->reg_id[i]);
+               if (err)
+                       goto err_free;
+       }
+
        return &mflow->ibflow;
 
 err_free:
index 6778045..efb9eff 100644 (file)
@@ -1677,9 +1677,15 @@ static int __mlx4_ib_modify_qp(struct ib_qp *ibqp,
                }
        }
 
-       if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET)
+       if (qp->ibqp.qp_type == IB_QPT_RAW_PACKET) {
                context->pri_path.ackto = (context->pri_path.ackto & 0xf8) |
                                        MLX4_IB_LINK_TYPE_ETH;
+               if (dev->dev->caps.tunnel_offload_mode ==  MLX4_TUNNEL_OFFLOAD_MODE_VXLAN) {
+                       /* set QP to receive both tunneled & non-tunneled packets */
+                       if (!(context->flags & (1 << MLX4_RSS_QPC_FLAG_OFFSET)))
+                               context->srqn = cpu_to_be32(7 << 28);
+               }
+       }
 
        if (ibqp->qp_type == IB_QPT_UD && (new_state == IB_QPS_RTR)) {
                int is_eth = rdma_port_get_link_layer(
index 180b184..d70b65a 100644 (file)
@@ -33,8 +33,8 @@
 #define CAP1106_REG_SENSOR_CONFIG      0x22
 #define CAP1106_REG_SENSOR_CONFIG2     0x23
 #define CAP1106_REG_SAMPLING_CONFIG    0x24
-#define CAP1106_REG_CALIBRATION                0x25
-#define CAP1106_REG_INT_ENABLE         0x26
+#define CAP1106_REG_CALIBRATION                0x26
+#define CAP1106_REG_INT_ENABLE         0x27
 #define CAP1106_REG_REPEAT_RATE                0x28
 #define CAP1106_REG_MT_CONFIG          0x2a
 #define CAP1106_REG_MT_PATTERN_CONFIG  0x2b
index 8d2e19e..e651fa6 100644 (file)
@@ -332,23 +332,24 @@ static int matrix_keypad_init_gpio(struct platform_device *pdev,
        }
 
        if (pdata->clustered_irq > 0) {
-               err = request_irq(pdata->clustered_irq,
+               err = request_any_context_irq(pdata->clustered_irq,
                                matrix_keypad_interrupt,
                                pdata->clustered_irq_flags,
                                "matrix-keypad", keypad);
-               if (err) {
+               if (err < 0) {
                        dev_err(&pdev->dev,
                                "Unable to acquire clustered interrupt\n");
                        goto err_free_rows;
                }
        } else {
                for (i = 0; i < pdata->num_row_gpios; i++) {
-                       err = request_irq(gpio_to_irq(pdata->row_gpios[i]),
+                       err = request_any_context_irq(
+                                       gpio_to_irq(pdata->row_gpios[i]),
                                        matrix_keypad_interrupt,
                                        IRQF_TRIGGER_RISING |
                                        IRQF_TRIGGER_FALLING,
                                        "matrix-keypad", keypad);
-                       if (err) {
+                       if (err < 0) {
                                dev_err(&pdev->dev,
                                        "Unable to acquire interrupt for GPIO line %i\n",
                                        pdata->row_gpios[i]);
index a956b98..35a49bf 100644 (file)
@@ -2373,6 +2373,10 @@ int alps_init(struct psmouse *psmouse)
        dev2->keybit[BIT_WORD(BTN_LEFT)] =
                BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) | BIT_MASK(BTN_RIGHT);
 
+       __set_bit(INPUT_PROP_POINTER, dev2->propbit);
+       if (priv->flags & ALPS_DUALPOINT)
+               __set_bit(INPUT_PROP_POINTING_STICK, dev2->propbit);
+
        if (input_register_device(priv->dev2))
                goto init_fail;
 
index da51738..06fc6e7 100644 (file)
@@ -1331,6 +1331,13 @@ static bool elantech_is_signature_valid(const unsigned char *param)
        if (param[1] == 0)
                return true;
 
+       /*
+        * Some models have a revision higher then 20. Meaning param[2] may
+        * be 10 or 20, skip the rates check for these.
+        */
+       if (param[0] == 0x46 && (param[1] & 0xef) == 0x0f && param[2] < 40)
+               return true;
+
        for (i = 0; i < ARRAY_SIZE(rates); i++)
                if (param[2] == rates[i])
                        return false;
@@ -1607,6 +1614,10 @@ int elantech_init(struct psmouse *psmouse)
                tp_dev->keybit[BIT_WORD(BTN_LEFT)] =
                        BIT_MASK(BTN_LEFT) | BIT_MASK(BTN_MIDDLE) |
                        BIT_MASK(BTN_RIGHT);
+
+               __set_bit(INPUT_PROP_POINTER, tp_dev->propbit);
+               __set_bit(INPUT_PROP_POINTING_STICK, tp_dev->propbit);
+
                error = input_register_device(etd->tp_dev);
                if (error < 0)
                        goto init_fail_tp_reg;
index cff065f..b4e1f01 100644 (file)
@@ -670,6 +670,8 @@ static void psmouse_apply_defaults(struct psmouse *psmouse)
        __set_bit(REL_X, input_dev->relbit);
        __set_bit(REL_Y, input_dev->relbit);
 
+       __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+
        psmouse->set_rate = psmouse_set_rate;
        psmouse->set_resolution = psmouse_set_resolution;
        psmouse->poll = psmouse_poll;
index e8573c6..fd23181 100644 (file)
@@ -629,10 +629,61 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
                         ((buf[0] & 0x04) >> 1) |
                         ((buf[3] & 0x04) >> 2));
 
+               if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
+                       SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) &&
+                   hw->w == 2) {
+                       synaptics_parse_agm(buf, priv, hw);
+                       return 1;
+               }
+
+               hw->x = (((buf[3] & 0x10) << 8) |
+                        ((buf[1] & 0x0f) << 8) |
+                        buf[4]);
+               hw->y = (((buf[3] & 0x20) << 7) |
+                        ((buf[1] & 0xf0) << 4) |
+                        buf[5]);
+               hw->z = buf[2];
+
                hw->left  = (buf[0] & 0x01) ? 1 : 0;
                hw->right = (buf[0] & 0x02) ? 1 : 0;
 
-               if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
+               if (SYN_CAP_FORCEPAD(priv->ext_cap_0c)) {
+                       /*
+                        * ForcePads, like Clickpads, use middle button
+                        * bits to report primary button clicks.
+                        * Unfortunately they report primary button not
+                        * only when user presses on the pad above certain
+                        * threshold, but also when there are more than one
+                        * finger on the touchpad, which interferes with
+                        * out multi-finger gestures.
+                        */
+                       if (hw->z == 0) {
+                               /* No contacts */
+                               priv->press = priv->report_press = false;
+                       } else if (hw->w >= 4 && ((buf[0] ^ buf[3]) & 0x01)) {
+                               /*
+                                * Single-finger touch with pressure above
+                                * the threshold. If pressure stays long
+                                * enough, we'll start reporting primary
+                                * button. We rely on the device continuing
+                                * sending data even if finger does not
+                                * move.
+                                */
+                               if  (!priv->press) {
+                                       priv->press_start = jiffies;
+                                       priv->press = true;
+                               } else if (time_after(jiffies,
+                                               priv->press_start +
+                                                       msecs_to_jiffies(50))) {
+                                       priv->report_press = true;
+                               }
+                       } else {
+                               priv->press = false;
+                       }
+
+                       hw->left = priv->report_press;
+
+               } else if (SYN_CAP_CLICKPAD(priv->ext_cap_0c)) {
                        /*
                         * Clickpad's button is transmitted as middle button,
                         * however, since it is primary button, we will report
@@ -651,21 +702,6 @@ static int synaptics_parse_hw_state(const unsigned char buf[],
                        hw->down = ((buf[0] ^ buf[3]) & 0x02) ? 1 : 0;
                }
 
-               if ((SYN_CAP_ADV_GESTURE(priv->ext_cap_0c) ||
-                       SYN_CAP_IMAGE_SENSOR(priv->ext_cap_0c)) &&
-                   hw->w == 2) {
-                       synaptics_parse_agm(buf, priv, hw);
-                       return 1;
-               }
-
-               hw->x = (((buf[3] & 0x10) << 8) |
-                        ((buf[1] & 0x0f) << 8) |
-                        buf[4]);
-               hw->y = (((buf[3] & 0x20) << 7) |
-                        ((buf[1] & 0xf0) << 4) |
-                        buf[5]);
-               hw->z = buf[2];
-
                if (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) &&
                    ((buf[0] ^ buf[3]) & 0x02)) {
                        switch (SYN_CAP_MULTI_BUTTON_NO(priv->ext_cap) & ~0x01) {
index e594af0..fb2e076 100644 (file)
  * 2   0x08    image sensor            image sensor tracks 5 fingers, but only
  *                                     reports 2.
  * 2   0x20    report min              query 0x0f gives min coord reported
+ * 2   0x80    forcepad                forcepad is a variant of clickpad that
+ *                                     does not have physical buttons but rather
+ *                                     uses pressure above certain threshold to
+ *                                     report primary clicks. Forcepads also have
+ *                                     clickpad bit set.
  */
 #define SYN_CAP_CLICKPAD(ex0c)         ((ex0c) & 0x100000) /* 1-button ClickPad */
 #define SYN_CAP_CLICKPAD2BTN(ex0c)     ((ex0c) & 0x000100) /* 2-button ClickPad */
@@ -86,6 +91,7 @@
 #define SYN_CAP_ADV_GESTURE(ex0c)      ((ex0c) & 0x080000)
 #define SYN_CAP_REDUCED_FILTERING(ex0c)        ((ex0c) & 0x000400)
 #define SYN_CAP_IMAGE_SENSOR(ex0c)     ((ex0c) & 0x000800)
+#define SYN_CAP_FORCEPAD(ex0c)         ((ex0c) & 0x008000)
 
 /* synaptics modes query bits */
 #define SYN_MODE_ABSOLUTE(m)           ((m) & (1 << 7))
@@ -177,6 +183,11 @@ struct synaptics_data {
         */
        struct synaptics_hw_state agm;
        bool agm_pending;                       /* new AGM packet received */
+
+       /* ForcePad handling */
+       unsigned long                           press_start;
+       bool                                    press;
+       bool                                    report_press;
 };
 
 void synaptics_module_init(void);
index e122bda..6bcc018 100644 (file)
@@ -387,6 +387,7 @@ static int synusb_probe(struct usb_interface *intf,
                __set_bit(EV_REL, input_dev->evbit);
                __set_bit(REL_X, input_dev->relbit);
                __set_bit(REL_Y, input_dev->relbit);
+               __set_bit(INPUT_PROP_POINTING_STICK, input_dev->propbit);
                input_set_abs_params(input_dev, ABS_PRESSURE, 0, 127, 0, 0);
        } else {
                input_set_abs_params(input_dev, ABS_X,
@@ -401,6 +402,11 @@ static int synusb_probe(struct usb_interface *intf,
                __set_bit(BTN_TOOL_TRIPLETAP, input_dev->keybit);
        }
 
+       if (synusb->flags & SYNUSB_TOUCHSCREEN)
+               __set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+       else
+               __set_bit(INPUT_PROP_POINTER, input_dev->propbit);
+
        __set_bit(BTN_LEFT, input_dev->keybit);
        __set_bit(BTN_RIGHT, input_dev->keybit);
        __set_bit(BTN_MIDDLE, input_dev->keybit);
index ca843b6..30c8b69 100644 (file)
@@ -393,6 +393,9 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
        if ((button_info & 0x0f) >= 3)
                __set_bit(BTN_MIDDLE, psmouse->dev->keybit);
 
+       __set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit);
+       __set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit);
+
        trackpoint_defaults(psmouse->private);
 
        error = trackpoint_power_on_reset(&psmouse->ps2dev);
index 0cb7ef5..69175b8 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/init.h>
 #include <linux/serio.h>
 #include <linux/tty.h>
+#include <linux/compat.h>
 
 MODULE_AUTHOR("Vojtech Pavlik <vojtech@ucw.cz>");
 MODULE_DESCRIPTION("Input device TTY line discipline");
@@ -198,28 +199,55 @@ static ssize_t serport_ldisc_read(struct tty_struct * tty, struct file * file, u
        return 0;
 }
 
+static void serport_set_type(struct tty_struct *tty, unsigned long type)
+{
+       struct serport *serport = tty->disc_data;
+
+       serport->id.proto = type & 0x000000ff;
+       serport->id.id    = (type & 0x0000ff00) >> 8;
+       serport->id.extra = (type & 0x00ff0000) >> 16;
+}
+
 /*
  * serport_ldisc_ioctl() allows to set the port protocol, and device ID
  */
 
-static int serport_ldisc_ioctl(struct tty_struct * tty, struct file * file, unsigned int cmd, unsigned long arg)
+static int serport_ldisc_ioctl(struct tty_struct *tty, struct file *file,
+                              unsigned int cmd, unsigned long arg)
 {
-       struct serport *serport = (struct serport*) tty->disc_data;
-       unsigned long type;
-
        if (cmd == SPIOCSTYPE) {
+               unsigned long type;
+
                if (get_user(type, (unsigned long __user *) arg))
                        return -EFAULT;
 
-               serport->id.proto = type & 0x000000ff;
-               serport->id.id    = (type & 0x0000ff00) >> 8;
-               serport->id.extra = (type & 0x00ff0000) >> 16;
+               serport_set_type(tty, type);
+               return 0;
+       }
+
+       return -EINVAL;
+}
+
+#ifdef CONFIG_COMPAT
+#define COMPAT_SPIOCSTYPE      _IOW('q', 0x01, compat_ulong_t)
+static long serport_ldisc_compat_ioctl(struct tty_struct *tty,
+                                      struct file *file,
+                                      unsigned int cmd, unsigned long arg)
+{
+       if (cmd == COMPAT_SPIOCSTYPE) {
+               void __user *uarg = compat_ptr(arg);
+               compat_ulong_t compat_type;
+
+               if (get_user(compat_type, (compat_ulong_t __user *)uarg))
+                       return -EFAULT;
 
+               serport_set_type(tty, compat_type);
                return 0;
        }
 
        return -EINVAL;
 }
+#endif
 
 static void serport_ldisc_write_wakeup(struct tty_struct * tty)
 {
@@ -243,6 +271,9 @@ static struct tty_ldisc_ops serport_ldisc = {
        .close =        serport_ldisc_close,
        .read =         serport_ldisc_read,
        .ioctl =        serport_ldisc_ioctl,
+#ifdef CONFIG_COMPAT
+       .compat_ioctl = serport_ldisc_compat_ioctl,
+#endif
        .receive_buf =  serport_ldisc_receive,
        .write_wakeup = serport_ldisc_write_wakeup
 };
index db178ed..aaacf8b 100644 (file)
@@ -837,7 +837,12 @@ static irqreturn_t mxt_process_messages_t44(struct mxt_data *data)
        count = data->msg_buf[0];
 
        if (count == 0) {
-               dev_warn(dev, "Interrupt triggered but zero messages\n");
+               /*
+                * This condition is caused by the CHG line being configured
+                * in Mode 0. It results in unnecessary I2C operations but it
+                * is benign.
+                */
+               dev_dbg(dev, "Interrupt triggered but zero messages\n");
                return IRQ_NONE;
        } else if (count > data->max_reportid) {
                dev_err(dev, "T44 count %d exceeded max report id\n", count);
@@ -1374,11 +1379,16 @@ static int mxt_get_info(struct mxt_data *data)
        return 0;
 }
 
-static void mxt_free_object_table(struct mxt_data *data)
+static void mxt_free_input_device(struct mxt_data *data)
 {
-       input_unregister_device(data->input_dev);
-       data->input_dev = NULL;
+       if (data->input_dev) {
+               input_unregister_device(data->input_dev);
+               data->input_dev = NULL;
+       }
+}
 
+static void mxt_free_object_table(struct mxt_data *data)
+{
        kfree(data->object_table);
        data->object_table = NULL;
        kfree(data->msg_buf);
@@ -1957,11 +1967,13 @@ static int mxt_load_fw(struct device *dev, const char *fn)
                ret = mxt_lookup_bootloader_address(data, 0);
                if (ret)
                        goto release_firmware;
+
+               mxt_free_input_device(data);
+               mxt_free_object_table(data);
        } else {
                enable_irq(data->irq);
        }
 
-       mxt_free_object_table(data);
        reinit_completion(&data->bl_completion);
 
        ret = mxt_check_bootloader(data, MXT_WAITING_BOOTLOAD_CMD, false);
@@ -2210,6 +2222,7 @@ static int mxt_probe(struct i2c_client *client, const struct i2c_device_id *id)
        return 0;
 
 err_free_object:
+       mxt_free_input_device(data);
        mxt_free_object_table(data);
 err_free_irq:
        free_irq(client->irq, data);
@@ -2224,7 +2237,7 @@ static int mxt_remove(struct i2c_client *client)
 
        sysfs_remove_group(&client->dev.kobj, &mxt_attr_group);
        free_irq(data->irq, data);
-       input_unregister_device(data->input_dev);
+       mxt_free_input_device(data);
        mxt_free_object_table(data);
        kfree(data);
 
index 16b5211..705ffa1 100644 (file)
@@ -41,7 +41,7 @@
  */
 static int rpu = 8;
 module_param(rpu, int, 0);
-MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
+MODULE_PARM_DESC(rpu, "Set internal pull up resistor for pen detect.");
 
 /*
  * Set current used for pressure measurement.
index 7405353..572a5a6 100644 (file)
@@ -41,7 +41,7 @@
  */
 static int rpu = 8;
 module_param(rpu, int, 0);
-MODULE_PARM_DESC(rpu, "Set internal pull up resitor for pen detect.");
+MODULE_PARM_DESC(rpu, "Set internal pull up resistor for pen detect.");
 
 /*
  * Set current used for pressure measurement.
index 059c741..3fe45c7 100644 (file)
@@ -2177,10 +2177,10 @@ boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
 
                        vp->tx_ring[entry].frag[i+1].addr =
-                                       cpu_to_le32(pci_map_single(
-                                               VORTEX_PCI(vp),
-                                               (void *)skb_frag_address(frag),
-                                               skb_frag_size(frag), PCI_DMA_TODEVICE));
+                                       cpu_to_le32(skb_frag_dma_map(
+                                               &VORTEX_PCI(vp)->dev,
+                                               frag,
+                                               frag->page_offset, frag->size, DMA_TO_DEVICE));
 
                        if (i == skb_shinfo(skb)->nr_frags-1)
                                        vp->tx_ring[entry].frag[i+1].length = cpu_to_le32(skb_frag_size(frag)|LAST_FRAG);
index 23578df..3005155 100644 (file)
@@ -123,6 +123,12 @@ static inline void greth_enable_tx(struct greth_private *greth)
        GRETH_REGORIN(greth->regs->control, GRETH_TXEN);
 }
 
+static inline void greth_enable_tx_and_irq(struct greth_private *greth)
+{
+       wmb(); /* BDs must been written to memory before enabling TX */
+       GRETH_REGORIN(greth->regs->control, GRETH_TXEN | GRETH_TXI);
+}
+
 static inline void greth_disable_tx(struct greth_private *greth)
 {
        GRETH_REGANDIN(greth->regs->control, ~GRETH_TXEN);
@@ -447,29 +453,30 @@ out:
        return err;
 }
 
+static inline u16 greth_num_free_bds(u16 tx_last, u16 tx_next)
+{
+       if (tx_next < tx_last)
+               return (tx_last - tx_next) - 1;
+       else
+               return GRETH_TXBD_NUM - (tx_next - tx_last) - 1;
+}
 
 static netdev_tx_t
 greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
 {
        struct greth_private *greth = netdev_priv(dev);
        struct greth_bd *bdp;
-       u32 status = 0, dma_addr, ctrl;
+       u32 status, dma_addr;
        int curr_tx, nr_frags, i, err = NETDEV_TX_OK;
        unsigned long flags;
+       u16 tx_last;
 
        nr_frags = skb_shinfo(skb)->nr_frags;
+       tx_last = greth->tx_last;
+       rmb(); /* tx_last is updated by the poll task */
 
-       /* Clean TX Ring */
-       greth_clean_tx_gbit(dev);
-
-       if (greth->tx_free < nr_frags + 1) {
-               spin_lock_irqsave(&greth->devlock, flags);/*save from poll/irq*/
-               ctrl = GRETH_REGLOAD(greth->regs->control);
-               /* Enable TX IRQ only if not already in poll() routine */
-               if (ctrl & GRETH_RXI)
-                       GRETH_REGSAVE(greth->regs->control, ctrl | GRETH_TXI);
+       if (greth_num_free_bds(tx_last, greth->tx_next) < nr_frags + 1) {
                netif_stop_queue(dev);
-               spin_unlock_irqrestore(&greth->devlock, flags);
                err = NETDEV_TX_BUSY;
                goto out;
        }
@@ -488,6 +495,8 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
        /* Linear buf */
        if (nr_frags != 0)
                status = GRETH_TXBD_MORE;
+       else
+               status = GRETH_BD_IE;
 
        if (skb->ip_summed == CHECKSUM_PARTIAL)
                status |= GRETH_TXBD_CSALL;
@@ -545,14 +554,12 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev)
 
        /* Enable the descriptor chain by enabling the first descriptor */
        bdp = greth->tx_bd_base + greth->tx_next;
-       greth_write_bd(&bdp->stat, greth_read_bd(&bdp->stat) | GRETH_BD_EN);
-       greth->tx_next = curr_tx;
-       greth->tx_free -= nr_frags + 1;
-
-       wmb();
+       greth_write_bd(&bdp->stat,
+                      greth_read_bd(&bdp->stat) | GRETH_BD_EN);
 
        spin_lock_irqsave(&greth->devlock, flags); /*save from poll/irq*/
-       greth_enable_tx(greth);
+       greth->tx_next = curr_tx;
+       greth_enable_tx_and_irq(greth);
        spin_unlock_irqrestore(&greth->devlock, flags);
 
        return NETDEV_TX_OK;
@@ -648,7 +655,6 @@ static void greth_clean_tx(struct net_device *dev)
        if (greth->tx_free > 0) {
                netif_wake_queue(dev);
        }
-
 }
 
 static inline void greth_update_tx_stats(struct net_device *dev, u32 stat)
@@ -670,20 +676,22 @@ static void greth_clean_tx_gbit(struct net_device *dev)
 {
        struct greth_private *greth;
        struct greth_bd *bdp, *bdp_last_frag;
-       struct sk_buff *skb;
+       struct sk_buff *skb = NULL;
        u32 stat;
        int nr_frags, i;
+       u16 tx_last;
 
        greth = netdev_priv(dev);
+       tx_last = greth->tx_last;
 
-       while (greth->tx_free < GRETH_TXBD_NUM) {
+       while (tx_last != greth->tx_next) {
 
-               skb = greth->tx_skbuff[greth->tx_last];
+               skb = greth->tx_skbuff[tx_last];
 
                nr_frags = skb_shinfo(skb)->nr_frags;
 
                /* We only clean fully completed SKBs */
-               bdp_last_frag = greth->tx_bd_base + SKIP_TX(greth->tx_last, nr_frags);
+               bdp_last_frag = greth->tx_bd_base + SKIP_TX(tx_last, nr_frags);
 
                GRETH_REGSAVE(greth->regs->status, GRETH_INT_TE | GRETH_INT_TX);
                mb();
@@ -692,14 +700,14 @@ static void greth_clean_tx_gbit(struct net_device *dev)
                if (stat & GRETH_BD_EN)
                        break;
 
-               greth->tx_skbuff[greth->tx_last] = NULL;
+               greth->tx_skbuff[tx_last] = NULL;
 
                greth_update_tx_stats(dev, stat);
                dev->stats.tx_bytes += skb->len;
 
-               bdp = greth->tx_bd_base + greth->tx_last;
+               bdp = greth->tx_bd_base + tx_last;
 
-               greth->tx_last = NEXT_TX(greth->tx_last);
+               tx_last = NEXT_TX(tx_last);
 
                dma_unmap_single(greth->dev,
                                 greth_read_bd(&bdp->addr),
@@ -708,21 +716,26 @@ static void greth_clean_tx_gbit(struct net_device *dev)
 
                for (i = 0; i < nr_frags; i++) {
                        skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
-                       bdp = greth->tx_bd_base + greth->tx_last;
+                       bdp = greth->tx_bd_base + tx_last;
 
                        dma_unmap_page(greth->dev,
                                       greth_read_bd(&bdp->addr),
                                       skb_frag_size(frag),
                                       DMA_TO_DEVICE);
 
-                       greth->tx_last = NEXT_TX(greth->tx_last);
+                       tx_last = NEXT_TX(tx_last);
                }
-               greth->tx_free += nr_frags+1;
                dev_kfree_skb(skb);
        }
+       if (skb) { /* skb is set only if the above while loop was entered */
+               wmb();
+               greth->tx_last = tx_last;
 
-       if (netif_queue_stopped(dev) && (greth->tx_free > (MAX_SKB_FRAGS+1)))
-               netif_wake_queue(dev);
+               if (netif_queue_stopped(dev) &&
+                   (greth_num_free_bds(tx_last, greth->tx_next) >
+                   (MAX_SKB_FRAGS+1)))
+                       netif_wake_queue(dev);
+       }
 }
 
 static int greth_rx(struct net_device *dev, int limit)
@@ -965,16 +978,12 @@ static int greth_poll(struct napi_struct *napi, int budget)
        greth = container_of(napi, struct greth_private, napi);
 
 restart_txrx_poll:
-       if (netif_queue_stopped(greth->netdev)) {
-               if (greth->gbit_mac)
-                       greth_clean_tx_gbit(greth->netdev);
-               else
-                       greth_clean_tx(greth->netdev);
-       }
-
        if (greth->gbit_mac) {
+               greth_clean_tx_gbit(greth->netdev);
                work_done += greth_rx_gbit(greth->netdev, budget - work_done);
        } else {
+               if (netif_queue_stopped(greth->netdev))
+                       greth_clean_tx(greth->netdev);
                work_done += greth_rx(greth->netdev, budget - work_done);
        }
 
@@ -983,7 +992,8 @@ restart_txrx_poll:
                spin_lock_irqsave(&greth->devlock, flags);
 
                ctrl = GRETH_REGLOAD(greth->regs->control);
-               if (netif_queue_stopped(greth->netdev)) {
+               if ((greth->gbit_mac && (greth->tx_last != greth->tx_next)) ||
+                   (!greth->gbit_mac && netif_queue_stopped(greth->netdev))) {
                        GRETH_REGSAVE(greth->regs->control,
                                        ctrl | GRETH_TXI | GRETH_RXI);
                        mask = GRETH_INT_RX | GRETH_INT_RE |
index 232a622..ae16ac9 100644 (file)
@@ -107,7 +107,7 @@ struct greth_private {
 
        u16 tx_next;
        u16 tx_last;
-       u16 tx_free;
+       u16 tx_free; /* only used on 10/100Mbit */
        u16 rx_cur;
 
        struct greth_regs *regs;        /* Address of controller registers. */
index 346592d..a3c1135 100644 (file)
@@ -272,8 +272,8 @@ static ssize_t xpcs_reg_value_read(struct file *filp, char __user *buffer,
        struct xgbe_prv_data *pdata = filp->private_data;
        unsigned int value;
 
-       value = pdata->hw_if.read_mmd_regs(pdata, pdata->debugfs_xpcs_mmd,
-                                          pdata->debugfs_xpcs_reg);
+       value = XMDIO_READ(pdata, pdata->debugfs_xpcs_mmd,
+                          pdata->debugfs_xpcs_reg);
 
        return xgbe_common_read(buffer, count, ppos, value);
 }
@@ -290,8 +290,8 @@ static ssize_t xpcs_reg_value_write(struct file *filp,
        if (len < 0)
                return len;
 
-       pdata->hw_if.write_mmd_regs(pdata, pdata->debugfs_xpcs_mmd,
-                                   pdata->debugfs_xpcs_reg, value);
+       XMDIO_WRITE(pdata, pdata->debugfs_xpcs_mmd, pdata->debugfs_xpcs_reg,
+                   value);
 
        return len;
 }
index edaca44..ea27383 100644 (file)
@@ -348,7 +348,7 @@ static int xgbe_disable_tx_flow_control(struct xgbe_prv_data *pdata)
 
        /* Clear MAC flow control */
        max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-       q_count = min_t(unsigned int, pdata->rx_q_count, max_q_count);
+       q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
        reg = MAC_Q0TFCR;
        for (i = 0; i < q_count; i++) {
                reg_val = XGMAC_IOREAD(pdata, reg);
@@ -373,7 +373,7 @@ static int xgbe_enable_tx_flow_control(struct xgbe_prv_data *pdata)
 
        /* Set MAC flow control */
        max_q_count = XGMAC_MAX_FLOW_CONTROL_QUEUES;
-       q_count = min_t(unsigned int, pdata->rx_q_count, max_q_count);
+       q_count = min_t(unsigned int, pdata->tx_q_count, max_q_count);
        reg = MAC_Q0TFCR;
        for (i = 0; i < q_count; i++) {
                reg_val = XGMAC_IOREAD(pdata, reg);
@@ -509,8 +509,8 @@ static void xgbe_enable_mac_interrupts(struct xgbe_prv_data *pdata)
        XGMAC_IOWRITE(pdata, MAC_IER, mac_ier);
 
        /* Enable all counter interrupts */
-       XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xff);
-       XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xff);
+       XGMAC_IOWRITE_BITS(pdata, MMC_RIER, ALL_INTERRUPTS, 0xffffffff);
+       XGMAC_IOWRITE_BITS(pdata, MMC_TIER, ALL_INTERRUPTS, 0xffffffff);
 }
 
 static int xgbe_set_gmii_speed(struct xgbe_prv_data *pdata)
@@ -1633,6 +1633,9 @@ static int xgbe_flush_tx_queues(struct xgbe_prv_data *pdata)
 {
        unsigned int i, count;
 
+       if (XGMAC_GET_BITS(pdata->hw_feat.version, MAC_VR, SNPSVER) < 0x21)
+               return 0;
+
        for (i = 0; i < pdata->tx_q_count; i++)
                XGMAC_MTL_IOWRITE_BITS(pdata, i, MTL_Q_TQOMR, FTQ, 1);
 
@@ -1703,8 +1706,8 @@ static void xgbe_config_mtl_mode(struct xgbe_prv_data *pdata)
        XGMAC_IOWRITE_BITS(pdata, MTL_OMR, RAA, MTL_RAA_SP);
 }
 
-static unsigned int xgbe_calculate_per_queue_fifo(unsigned long fifo_size,
-                                                 unsigned char queue_count)
+static unsigned int xgbe_calculate_per_queue_fifo(unsigned int fifo_size,
+                                                 unsigned int queue_count)
 {
        unsigned int q_fifo_size = 0;
        enum xgbe_mtl_fifo_size p_fifo = XGMAC_MTL_FIFO_SIZE_256;
@@ -1748,6 +1751,10 @@ static unsigned int xgbe_calculate_per_queue_fifo(unsigned long fifo_size,
                q_fifo_size = XGBE_FIFO_SIZE_KB(256);
                break;
        }
+
+       /* The configured value is not the actual amount of fifo RAM */
+       q_fifo_size = min_t(unsigned int, XGBE_FIFO_MAX, q_fifo_size);
+
        q_fifo_size = q_fifo_size / queue_count;
 
        /* Set the queue fifo size programmable value */
@@ -1947,6 +1954,32 @@ static void xgbe_config_vlan_support(struct xgbe_prv_data *pdata)
                xgbe_disable_rx_vlan_stripping(pdata);
 }
 
+static u64 xgbe_mmc_read(struct xgbe_prv_data *pdata, unsigned int reg_lo)
+{
+       bool read_hi;
+       u64 val;
+
+       switch (reg_lo) {
+       /* These registers are always 64 bit */
+       case MMC_TXOCTETCOUNT_GB_LO:
+       case MMC_TXOCTETCOUNT_G_LO:
+       case MMC_RXOCTETCOUNT_GB_LO:
+       case MMC_RXOCTETCOUNT_G_LO:
+               read_hi = true;
+               break;
+
+       default:
+               read_hi = false;
+       };
+
+       val = XGMAC_IOREAD(pdata, reg_lo);
+
+       if (read_hi)
+               val |= ((u64)XGMAC_IOREAD(pdata, reg_lo + 4) << 32);
+
+       return val;
+}
+
 static void xgbe_tx_mmc_int(struct xgbe_prv_data *pdata)
 {
        struct xgbe_mmc_stats *stats = &pdata->mmc_stats;
@@ -1954,75 +1987,75 @@ static void xgbe_tx_mmc_int(struct xgbe_prv_data *pdata)
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_GB))
                stats->txoctetcount_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_GB))
                stats->txframecount_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_G))
                stats->txbroadcastframes_g +=
-                       XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO);
+                       xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_G_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_G))
                stats->txmulticastframes_g +=
-                       XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO);
+                       xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_G_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX64OCTETS_GB))
                stats->tx64octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TX64OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX65TO127OCTETS_GB))
                stats->tx65to127octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TX65TO127OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX128TO255OCTETS_GB))
                stats->tx128to255octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TX128TO255OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX256TO511OCTETS_GB))
                stats->tx256to511octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TX256TO511OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX512TO1023OCTETS_GB))
                stats->tx512to1023octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TX512TO1023OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TX1024TOMAXOCTETS_GB))
                stats->tx1024tomaxoctets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNICASTFRAMES_GB))
                stats->txunicastframes_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TXUNICASTFRAMES_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXMULTICASTFRAMES_GB))
                stats->txmulticastframes_gb +=
-                       XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXBROADCASTFRAMES_GB))
                stats->txbroadcastframes_g +=
-                       XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXUNDERFLOWERROR))
                stats->txunderflowerror +=
-                       XGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO);
+                       xgbe_mmc_read(pdata, MMC_TXUNDERFLOWERROR_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXOCTETCOUNT_G))
                stats->txoctetcount_g +=
-                       XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO);
+                       xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_G_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXFRAMECOUNT_G))
                stats->txframecount_g +=
-                       XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO);
+                       xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_G_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXPAUSEFRAMES))
                stats->txpauseframes +=
-                       XGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO);
+                       xgbe_mmc_read(pdata, MMC_TXPAUSEFRAMES_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_TISR, TXVLANFRAMES_G))
                stats->txvlanframes_g +=
-                       XGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO);
+                       xgbe_mmc_read(pdata, MMC_TXVLANFRAMES_G_LO);
 }
 
 static void xgbe_rx_mmc_int(struct xgbe_prv_data *pdata)
@@ -2032,95 +2065,95 @@ static void xgbe_rx_mmc_int(struct xgbe_prv_data *pdata)
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFRAMECOUNT_GB))
                stats->rxframecount_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RXFRAMECOUNT_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_GB))
                stats->rxoctetcount_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOCTETCOUNT_G))
                stats->rxoctetcount_g +=
-                       XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO);
+                       xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_G_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXBROADCASTFRAMES_G))
                stats->rxbroadcastframes_g +=
-                       XGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO);
+                       xgbe_mmc_read(pdata, MMC_RXBROADCASTFRAMES_G_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXMULTICASTFRAMES_G))
                stats->rxmulticastframes_g +=
-                       XGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO);
+                       xgbe_mmc_read(pdata, MMC_RXMULTICASTFRAMES_G_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXCRCERROR))
                stats->rxcrcerror +=
-                       XGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO);
+                       xgbe_mmc_read(pdata, MMC_RXCRCERROR_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXRUNTERROR))
                stats->rxrunterror +=
-                       XGMAC_IOREAD(pdata, MMC_RXRUNTERROR);
+                       xgbe_mmc_read(pdata, MMC_RXRUNTERROR);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXJABBERERROR))
                stats->rxjabbererror +=
-                       XGMAC_IOREAD(pdata, MMC_RXJABBERERROR);
+                       xgbe_mmc_read(pdata, MMC_RXJABBERERROR);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNDERSIZE_G))
                stats->rxundersize_g +=
-                       XGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G);
+                       xgbe_mmc_read(pdata, MMC_RXUNDERSIZE_G);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOVERSIZE_G))
                stats->rxoversize_g +=
-                       XGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G);
+                       xgbe_mmc_read(pdata, MMC_RXOVERSIZE_G);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX64OCTETS_GB))
                stats->rx64octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RX64OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX65TO127OCTETS_GB))
                stats->rx65to127octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RX65TO127OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX128TO255OCTETS_GB))
                stats->rx128to255octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RX128TO255OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX256TO511OCTETS_GB))
                stats->rx256to511octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RX256TO511OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX512TO1023OCTETS_GB))
                stats->rx512to1023octets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RX512TO1023OCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RX1024TOMAXOCTETS_GB))
                stats->rx1024tomaxoctets_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXUNICASTFRAMES_G))
                stats->rxunicastframes_g +=
-                       XGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO);
+                       xgbe_mmc_read(pdata, MMC_RXUNICASTFRAMES_G_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXLENGTHERROR))
                stats->rxlengtherror +=
-                       XGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO);
+                       xgbe_mmc_read(pdata, MMC_RXLENGTHERROR_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXOUTOFRANGETYPE))
                stats->rxoutofrangetype +=
-                       XGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO);
+                       xgbe_mmc_read(pdata, MMC_RXOUTOFRANGETYPE_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXPAUSEFRAMES))
                stats->rxpauseframes +=
-                       XGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO);
+                       xgbe_mmc_read(pdata, MMC_RXPAUSEFRAMES_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXFIFOOVERFLOW))
                stats->rxfifooverflow +=
-                       XGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO);
+                       xgbe_mmc_read(pdata, MMC_RXFIFOOVERFLOW_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXVLANFRAMES_GB))
                stats->rxvlanframes_gb +=
-                       XGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO);
+                       xgbe_mmc_read(pdata, MMC_RXVLANFRAMES_GB_LO);
 
        if (XGMAC_GET_BITS(mmc_isr, MMC_RISR, RXWATCHDOGERROR))
                stats->rxwatchdogerror +=
-                       XGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR);
+                       xgbe_mmc_read(pdata, MMC_RXWATCHDOGERROR);
 }
 
 static void xgbe_read_mmc_stats(struct xgbe_prv_data *pdata)
@@ -2131,127 +2164,127 @@ static void xgbe_read_mmc_stats(struct xgbe_prv_data *pdata)
        XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 1);
 
        stats->txoctetcount_gb +=
-               XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_GB_LO);
 
        stats->txframecount_gb +=
-               XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_GB_LO);
 
        stats->txbroadcastframes_g +=
-               XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_G_LO);
+               xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_G_LO);
 
        stats->txmulticastframes_g +=
-               XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_G_LO);
+               xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_G_LO);
 
        stats->tx64octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_TX64OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TX64OCTETS_GB_LO);
 
        stats->tx65to127octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_TX65TO127OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TX65TO127OCTETS_GB_LO);
 
        stats->tx128to255octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_TX128TO255OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TX128TO255OCTETS_GB_LO);
 
        stats->tx256to511octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_TX256TO511OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TX256TO511OCTETS_GB_LO);
 
        stats->tx512to1023octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_TX512TO1023OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TX512TO1023OCTETS_GB_LO);
 
        stats->tx1024tomaxoctets_gb +=
-               XGMAC_IOREAD(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TX1024TOMAXOCTETS_GB_LO);
 
        stats->txunicastframes_gb +=
-               XGMAC_IOREAD(pdata, MMC_TXUNICASTFRAMES_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TXUNICASTFRAMES_GB_LO);
 
        stats->txmulticastframes_gb +=
-               XGMAC_IOREAD(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TXMULTICASTFRAMES_GB_LO);
 
        stats->txbroadcastframes_g +=
-               XGMAC_IOREAD(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
+               xgbe_mmc_read(pdata, MMC_TXBROADCASTFRAMES_GB_LO);
 
        stats->txunderflowerror +=
-               XGMAC_IOREAD(pdata, MMC_TXUNDERFLOWERROR_LO);
+               xgbe_mmc_read(pdata, MMC_TXUNDERFLOWERROR_LO);
 
        stats->txoctetcount_g +=
-               XGMAC_IOREAD(pdata, MMC_TXOCTETCOUNT_G_LO);
+               xgbe_mmc_read(pdata, MMC_TXOCTETCOUNT_G_LO);
 
        stats->txframecount_g +=
-               XGMAC_IOREAD(pdata, MMC_TXFRAMECOUNT_G_LO);
+               xgbe_mmc_read(pdata, MMC_TXFRAMECOUNT_G_LO);
 
        stats->txpauseframes +=
-               XGMAC_IOREAD(pdata, MMC_TXPAUSEFRAMES_LO);
+               xgbe_mmc_read(pdata, MMC_TXPAUSEFRAMES_LO);
 
        stats->txvlanframes_g +=
-               XGMAC_IOREAD(pdata, MMC_TXVLANFRAMES_G_LO);
+               xgbe_mmc_read(pdata, MMC_TXVLANFRAMES_G_LO);
 
        stats->rxframecount_gb +=
-               XGMAC_IOREAD(pdata, MMC_RXFRAMECOUNT_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RXFRAMECOUNT_GB_LO);
 
        stats->rxoctetcount_gb +=
-               XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_GB_LO);
 
        stats->rxoctetcount_g +=
-               XGMAC_IOREAD(pdata, MMC_RXOCTETCOUNT_G_LO);
+               xgbe_mmc_read(pdata, MMC_RXOCTETCOUNT_G_LO);
 
        stats->rxbroadcastframes_g +=
-               XGMAC_IOREAD(pdata, MMC_RXBROADCASTFRAMES_G_LO);
+               xgbe_mmc_read(pdata, MMC_RXBROADCASTFRAMES_G_LO);
 
        stats->rxmulticastframes_g +=
-               XGMAC_IOREAD(pdata, MMC_RXMULTICASTFRAMES_G_LO);
+               xgbe_mmc_read(pdata, MMC_RXMULTICASTFRAMES_G_LO);
 
        stats->rxcrcerror +=
-               XGMAC_IOREAD(pdata, MMC_RXCRCERROR_LO);
+               xgbe_mmc_read(pdata, MMC_RXCRCERROR_LO);
 
        stats->rxrunterror +=
-               XGMAC_IOREAD(pdata, MMC_RXRUNTERROR);
+               xgbe_mmc_read(pdata, MMC_RXRUNTERROR);
 
        stats->rxjabbererror +=
-               XGMAC_IOREAD(pdata, MMC_RXJABBERERROR);
+               xgbe_mmc_read(pdata, MMC_RXJABBERERROR);
 
        stats->rxundersize_g +=
-               XGMAC_IOREAD(pdata, MMC_RXUNDERSIZE_G);
+               xgbe_mmc_read(pdata, MMC_RXUNDERSIZE_G);
 
        stats->rxoversize_g +=
-               XGMAC_IOREAD(pdata, MMC_RXOVERSIZE_G);
+               xgbe_mmc_read(pdata, MMC_RXOVERSIZE_G);
 
        stats->rx64octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_RX64OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RX64OCTETS_GB_LO);
 
        stats->rx65to127octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_RX65TO127OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RX65TO127OCTETS_GB_LO);
 
        stats->rx128to255octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_RX128TO255OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RX128TO255OCTETS_GB_LO);
 
        stats->rx256to511octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_RX256TO511OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RX256TO511OCTETS_GB_LO);
 
        stats->rx512to1023octets_gb +=
-               XGMAC_IOREAD(pdata, MMC_RX512TO1023OCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RX512TO1023OCTETS_GB_LO);
 
        stats->rx1024tomaxoctets_gb +=
-               XGMAC_IOREAD(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RX1024TOMAXOCTETS_GB_LO);
 
        stats->rxunicastframes_g +=
-               XGMAC_IOREAD(pdata, MMC_RXUNICASTFRAMES_G_LO);
+               xgbe_mmc_read(pdata, MMC_RXUNICASTFRAMES_G_LO);
 
        stats->rxlengtherror +=
-               XGMAC_IOREAD(pdata, MMC_RXLENGTHERROR_LO);
+               xgbe_mmc_read(pdata, MMC_RXLENGTHERROR_LO);
 
        stats->rxoutofrangetype +=
-               XGMAC_IOREAD(pdata, MMC_RXOUTOFRANGETYPE_LO);
+               xgbe_mmc_read(pdata, MMC_RXOUTOFRANGETYPE_LO);
 
        stats->rxpauseframes +=
-               XGMAC_IOREAD(pdata, MMC_RXPAUSEFRAMES_LO);
+               xgbe_mmc_read(pdata, MMC_RXPAUSEFRAMES_LO);
 
        stats->rxfifooverflow +=
-               XGMAC_IOREAD(pdata, MMC_RXFIFOOVERFLOW_LO);
+               xgbe_mmc_read(pdata, MMC_RXFIFOOVERFLOW_LO);
 
        stats->rxvlanframes_gb +=
-               XGMAC_IOREAD(pdata, MMC_RXVLANFRAMES_GB_LO);
+               xgbe_mmc_read(pdata, MMC_RXVLANFRAMES_GB_LO);
 
        stats->rxwatchdogerror +=
-               XGMAC_IOREAD(pdata, MMC_RXWATCHDOGERROR);
+               xgbe_mmc_read(pdata, MMC_RXWATCHDOGERROR);
 
        /* Un-freeze counters */
        XGMAC_IOWRITE_BITS(pdata, MMC_CR, MCF, 0);
index dc84f71..b26d758 100644 (file)
@@ -361,6 +361,8 @@ void xgbe_get_all_hw_features(struct xgbe_prv_data *pdata)
 
        memset(hw_feat, 0, sizeof(*hw_feat));
 
+       hw_feat->version = XGMAC_IOREAD(pdata, MAC_VR);
+
        /* Hardware feature register 0 */
        hw_feat->gmii        = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, GMIISEL);
        hw_feat->vlhash      = XGMAC_GET_BITS(mac_hfr0, MAC_HWF0R, VLHASH);
index a076aca..46f6130 100644 (file)
@@ -361,15 +361,16 @@ static void xgbe_get_drvinfo(struct net_device *netdev,
                             struct ethtool_drvinfo *drvinfo)
 {
        struct xgbe_prv_data *pdata = netdev_priv(netdev);
+       struct xgbe_hw_features *hw_feat = &pdata->hw_feat;
 
        strlcpy(drvinfo->driver, XGBE_DRV_NAME, sizeof(drvinfo->driver));
        strlcpy(drvinfo->version, XGBE_DRV_VERSION, sizeof(drvinfo->version));
        strlcpy(drvinfo->bus_info, dev_name(pdata->dev),
                sizeof(drvinfo->bus_info));
        snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version), "%d.%d.%d",
-                XGMAC_IOREAD_BITS(pdata, MAC_VR, USERVER),
-                XGMAC_IOREAD_BITS(pdata, MAC_VR, DEVID),
-                XGMAC_IOREAD_BITS(pdata, MAC_VR, SNPSVER));
+                XGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER),
+                XGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID),
+                XGMAC_GET_BITS(hw_feat->version, MAC_VR, SNPSVER));
        drvinfo->n_stats = XGBE_STATS_COUNT;
 }
 
index 8aa6a93..bdf9cfa 100644 (file)
@@ -172,7 +172,7 @@ static struct xgbe_channel *xgbe_alloc_rings(struct xgbe_prv_data *pdata)
                }
 
                if (i < pdata->rx_ring_count) {
-                       spin_lock_init(&tx_ring->lock);
+                       spin_lock_init(&rx_ring->lock);
                        channel->rx_ring = rx_ring++;
                }
 
index 07bf70a..e9fe6e6 100644 (file)
 #define XGMAC_DRIVER_CONTEXT   1
 #define XGMAC_IOCTL_CONTEXT    2
 
+#define XGBE_FIFO_MAX          81920
 #define XGBE_FIFO_SIZE_B(x)    (x)
 #define XGBE_FIFO_SIZE_KB(x)   (x * 1024)
 
@@ -526,6 +527,9 @@ struct xgbe_desc_if {
  * or configurations are present in the device.
  */
 struct xgbe_hw_features {
+       /* HW Version */
+       unsigned int version;
+
        /* HW Feature Register0 */
        unsigned int gmii;              /* 1000 Mbps support */
        unsigned int vlhash;            /* VLAN Hash Filter */
index 616dff6..f4054d2 100644 (file)
@@ -1,5 +1,6 @@
 config NET_XGENE
        tristate "APM X-Gene SoC Ethernet Driver"
+       depends on HAS_DMA
        select PHYLIB
        help
          This is the Ethernet driver for the on-chip ethernet interface on the
index 7dcfb19..d8d07a8 100644 (file)
@@ -84,7 +84,7 @@ config BNX2
 
 config CNIC
        tristate "QLogic CNIC support"
-       depends on PCI
+       depends on PCI && (IPV6 || IPV6=n)
        select BNX2
        select UIO
        ---help---
index 5ba8af5..c4daa06 100644 (file)
@@ -2233,7 +2233,12 @@ struct shmem2_region {
        u32 reserved3;                          /* Offset 0x14C */
        u32 reserved4;                          /* Offset 0x150 */
        u32 link_attr_sync[PORT_MAX];           /* Offset 0x154 */
-       #define LINK_ATTR_SYNC_KR2_ENABLE       (1<<0)
+       #define LINK_ATTR_SYNC_KR2_ENABLE       0x00000001
+       #define LINK_SFP_EEPROM_COMP_CODE_MASK  0x0000ff00
+       #define LINK_SFP_EEPROM_COMP_CODE_SHIFT          8
+       #define LINK_SFP_EEPROM_COMP_CODE_SR    0x00001000
+       #define LINK_SFP_EEPROM_COMP_CODE_LR    0x00002000
+       #define LINK_SFP_EEPROM_COMP_CODE_LRM   0x00004000
 
        u32 reserved5[2];
        u32 reserved6[PORT_MAX];
index 53fb4fa..549549e 100644 (file)
@@ -154,15 +154,22 @@ typedef int (*read_sfp_module_eeprom_func_p)(struct bnx2x_phy *phy,
                         LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
 
 #define SFP_EEPROM_CON_TYPE_ADDR               0x2
+       #define SFP_EEPROM_CON_TYPE_VAL_UNKNOWN 0x0
        #define SFP_EEPROM_CON_TYPE_VAL_LC      0x7
        #define SFP_EEPROM_CON_TYPE_VAL_COPPER  0x21
        #define SFP_EEPROM_CON_TYPE_VAL_RJ45    0x22
 
 
-#define SFP_EEPROM_COMP_CODE_ADDR              0x3
-       #define SFP_EEPROM_COMP_CODE_SR_MASK    (1<<4)
-       #define SFP_EEPROM_COMP_CODE_LR_MASK    (1<<5)
-       #define SFP_EEPROM_COMP_CODE_LRM_MASK   (1<<6)
+#define SFP_EEPROM_10G_COMP_CODE_ADDR          0x3
+       #define SFP_EEPROM_10G_COMP_CODE_SR_MASK        (1<<4)
+       #define SFP_EEPROM_10G_COMP_CODE_LR_MASK        (1<<5)
+       #define SFP_EEPROM_10G_COMP_CODE_LRM_MASK       (1<<6)
+
+#define SFP_EEPROM_1G_COMP_CODE_ADDR           0x6
+       #define SFP_EEPROM_1G_COMP_CODE_SX      (1<<0)
+       #define SFP_EEPROM_1G_COMP_CODE_LX      (1<<1)
+       #define SFP_EEPROM_1G_COMP_CODE_CX      (1<<2)
+       #define SFP_EEPROM_1G_COMP_CODE_BASE_T  (1<<3)
 
 #define SFP_EEPROM_FC_TX_TECH_ADDR             0x8
        #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
@@ -3633,8 +3640,8 @@ static void bnx2x_warpcore_enable_AN_KR2(struct bnx2x_phy *phy,
                                 reg_set[i].val);
 
        /* Start KR2 work-around timer which handles BCM8073 link-parner */
-       vars->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE;
-       bnx2x_update_link_attr(params, vars->link_attr_sync);
+       params->link_attr_sync |= LINK_ATTR_SYNC_KR2_ENABLE;
+       bnx2x_update_link_attr(params, params->link_attr_sync);
 }
 
 static void bnx2x_disable_kr2(struct link_params *params,
@@ -3666,8 +3673,8 @@ static void bnx2x_disable_kr2(struct link_params *params,
        for (i = 0; i < ARRAY_SIZE(reg_set); i++)
                bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
                                 reg_set[i].val);
-       vars->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
-       bnx2x_update_link_attr(params, vars->link_attr_sync);
+       params->link_attr_sync &= ~LINK_ATTR_SYNC_KR2_ENABLE;
+       bnx2x_update_link_attr(params, params->link_attr_sync);
 
        vars->check_kr2_recovery_cnt = CHECK_KR2_RECOVERY_CNT;
 }
@@ -4810,7 +4817,7 @@ void bnx2x_link_status_update(struct link_params *params,
                                        ~FEATURE_CONFIG_PFC_ENABLED;
 
        if (SHMEM2_HAS(bp, link_attr_sync))
-               vars->link_attr_sync = SHMEM2_RD(bp,
+               params->link_attr_sync = SHMEM2_RD(bp,
                                                 link_attr_sync[params->port]);
 
        DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
@@ -8057,21 +8064,24 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
 {
        struct bnx2x *bp = params->bp;
        u32 sync_offset = 0, phy_idx, media_types;
-       u8 gport, val[2], check_limiting_mode = 0;
+       u8 val[SFP_EEPROM_FC_TX_TECH_ADDR + 1], check_limiting_mode = 0;
        *edc_mode = EDC_MODE_LIMITING;
        phy->media_type = ETH_PHY_UNSPECIFIED;
        /* First check for copper cable */
        if (bnx2x_read_sfp_module_eeprom(phy,
                                         params,
                                         I2C_DEV_ADDR_A0,
-                                        SFP_EEPROM_CON_TYPE_ADDR,
-                                        2,
+                                        0,
+                                        SFP_EEPROM_FC_TX_TECH_ADDR + 1,
                                         (u8 *)val) != 0) {
                DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
                return -EINVAL;
        }
-
-       switch (val[0]) {
+       params->link_attr_sync &= ~LINK_SFP_EEPROM_COMP_CODE_MASK;
+       params->link_attr_sync |= val[SFP_EEPROM_10G_COMP_CODE_ADDR] <<
+               LINK_SFP_EEPROM_COMP_CODE_SHIFT;
+       bnx2x_update_link_attr(params, params->link_attr_sync);
+       switch (val[SFP_EEPROM_CON_TYPE_ADDR]) {
        case SFP_EEPROM_CON_TYPE_VAL_COPPER:
        {
                u8 copper_module_type;
@@ -8079,17 +8089,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
                /* Check if its active cable (includes SFP+ module)
                 * of passive cable
                 */
-               if (bnx2x_read_sfp_module_eeprom(phy,
-                                              params,
-                                              I2C_DEV_ADDR_A0,
-                                              SFP_EEPROM_FC_TX_TECH_ADDR,
-                                              1,
-                                              &copper_module_type) != 0) {
-                       DP(NETIF_MSG_LINK,
-                               "Failed to read copper-cable-type"
-                               " from SFP+ EEPROM\n");
-                       return -EINVAL;
-               }
+               copper_module_type = val[SFP_EEPROM_FC_TX_TECH_ADDR];
 
                if (copper_module_type &
                    SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
@@ -8115,16 +8115,18 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
                }
                break;
        }
+       case SFP_EEPROM_CON_TYPE_VAL_UNKNOWN:
        case SFP_EEPROM_CON_TYPE_VAL_LC:
        case SFP_EEPROM_CON_TYPE_VAL_RJ45:
                check_limiting_mode = 1;
-               if ((val[1] & (SFP_EEPROM_COMP_CODE_SR_MASK |
-                              SFP_EEPROM_COMP_CODE_LR_MASK |
-                              SFP_EEPROM_COMP_CODE_LRM_MASK)) == 0) {
+               if ((val[SFP_EEPROM_10G_COMP_CODE_ADDR] &
+                    (SFP_EEPROM_10G_COMP_CODE_SR_MASK |
+                     SFP_EEPROM_10G_COMP_CODE_LR_MASK |
+                     SFP_EEPROM_10G_COMP_CODE_LRM_MASK)) == 0) {
                        DP(NETIF_MSG_LINK, "1G SFP module detected\n");
-                       gport = params->port;
                        phy->media_type = ETH_PHY_SFP_1G_FIBER;
                        if (phy->req_line_speed != SPEED_1000) {
+                               u8 gport = params->port;
                                phy->req_line_speed = SPEED_1000;
                                if (!CHIP_IS_E1x(bp)) {
                                        gport = BP_PATH(bp) +
@@ -8134,6 +8136,12 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
                                           "Warning: Link speed was forced to 1000Mbps. Current SFP module in port %d is not compliant with 10G Ethernet\n",
                                           gport);
                        }
+                       if (val[SFP_EEPROM_1G_COMP_CODE_ADDR] &
+                           SFP_EEPROM_1G_COMP_CODE_BASE_T) {
+                               bnx2x_sfp_set_transmitter(params, phy, 0);
+                               msleep(40);
+                               bnx2x_sfp_set_transmitter(params, phy, 1);
+                       }
                } else {
                        int idx, cfg_idx = 0;
                        DP(NETIF_MSG_LINK, "10G Optic module detected\n");
@@ -8149,7 +8157,7 @@ static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
                break;
        default:
                DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
-                        val[0]);
+                        val[SFP_EEPROM_CON_TYPE_ADDR]);
                return -EINVAL;
        }
        sync_offset = params->shmem_base +
@@ -13507,7 +13515,7 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
 
        sigdet = bnx2x_warpcore_get_sigdet(phy, params);
        if (!sigdet) {
-               if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
+               if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
                        bnx2x_kr2_recovery(params, vars, phy);
                        DP(NETIF_MSG_LINK, "No sigdet\n");
                }
@@ -13525,7 +13533,7 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
 
        /* CL73 has not begun yet */
        if (base_page == 0) {
-               if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
+               if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
                        bnx2x_kr2_recovery(params, vars, phy);
                        DP(NETIF_MSG_LINK, "No BP\n");
                }
@@ -13541,7 +13549,7 @@ static void bnx2x_check_kr2_wa(struct link_params *params,
                            ((next_page & 0xe0) == 0x20))));
 
        /* In case KR2 is already disabled, check if we need to re-enable it */
-       if (!(vars->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
+       if (!(params->link_attr_sync & LINK_ATTR_SYNC_KR2_ENABLE)) {
                if (!not_kr2_device) {
                        DP(NETIF_MSG_LINK, "BP=0x%x, NP=0x%x\n", base_page,
                           next_page);
index 389f5f8..d9cce4c 100644 (file)
@@ -323,6 +323,9 @@ struct link_params {
 #define LINK_FLAGS_INT_DISABLED                (1<<0)
 #define PHY_INITIALIZED                (1<<1)
        u32 lfa_base;
+
+       /* The same definitions as the shmem2 parameter */
+       u32 link_attr_sync;
 };
 
 /* Output parameters */
@@ -364,8 +367,6 @@ struct link_vars {
        u8 rx_tx_asic_rst;
        u8 turn_to_run_wc_rt;
        u16 rsrv2;
-       /* The same definitions as the shmem2 parameter */
-       u32 link_attr_sync;
 };
 
 /***********************************************************/
index 900cab4..d1c093d 100644 (file)
@@ -6849,6 +6849,37 @@ static void bnx2x__common_init_phy(struct bnx2x *bp)
        bnx2x_release_phy_lock(bp);
 }
 
+static void bnx2x_config_endianity(struct bnx2x *bp, u32 val)
+{
+       REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, val);
+       REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, val);
+       REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, val);
+       REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, val);
+       REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, val);
+
+       /* make sure this value is 0 */
+       REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0);
+
+       REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, val);
+       REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, val);
+       REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, val);
+       REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, val);
+}
+
+static void bnx2x_set_endianity(struct bnx2x *bp)
+{
+#ifdef __BIG_ENDIAN
+       bnx2x_config_endianity(bp, 1);
+#else
+       bnx2x_config_endianity(bp, 0);
+#endif
+}
+
+static void bnx2x_reset_endianity(struct bnx2x *bp)
+{
+       bnx2x_config_endianity(bp, 0);
+}
+
 /**
  * bnx2x_init_hw_common - initialize the HW at the COMMON phase.
  *
@@ -6915,23 +6946,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp)
 
        bnx2x_init_block(bp, BLOCK_PXP2, PHASE_COMMON);
        bnx2x_init_pxp(bp);
-
-#ifdef __BIG_ENDIAN
-       REG_WR(bp, PXP2_REG_RQ_QM_ENDIAN_M, 1);
-       REG_WR(bp, PXP2_REG_RQ_TM_ENDIAN_M, 1);
-       REG_WR(bp, PXP2_REG_RQ_SRC_ENDIAN_M, 1);
-       REG_WR(bp, PXP2_REG_RQ_CDU_ENDIAN_M, 1);
-       REG_WR(bp, PXP2_REG_RQ_DBG_ENDIAN_M, 1);
-       /* make sure this value is 0 */
-       REG_WR(bp, PXP2_REG_RQ_HC_ENDIAN_M, 0);
-
-/*     REG_WR(bp, PXP2_REG_RD_PBF_SWAP_MODE, 1); */
-       REG_WR(bp, PXP2_REG_RD_QM_SWAP_MODE, 1);
-       REG_WR(bp, PXP2_REG_RD_TM_SWAP_MODE, 1);
-       REG_WR(bp, PXP2_REG_RD_SRC_SWAP_MODE, 1);
-       REG_WR(bp, PXP2_REG_RD_CDURD_SWAP_MODE, 1);
-#endif
-
+       bnx2x_set_endianity(bp);
        bnx2x_ilt_init_page_size(bp, INITOP_SET);
 
        if (CHIP_REV_IS_FPGA(bp) && CHIP_IS_E1H(bp))
@@ -13169,9 +13184,15 @@ static void __bnx2x_remove(struct pci_dev *pdev,
        bnx2x_iov_remove_one(bp);
 
        /* Power on: we can't let PCI layer write to us while we are in D3 */
-       if (IS_PF(bp))
+       if (IS_PF(bp)) {
                bnx2x_set_power_state(bp, PCI_D0);
 
+               /* Set endianity registers to reset values in case next driver
+                * boots in different endianty environment.
+                */
+               bnx2x_reset_endianity(bp);
+       }
+
        /* Disable MSI/MSI-X */
        bnx2x_disable_msi(bp);
 
index 27861a6..a6a9f28 100644 (file)
@@ -31,7 +31,7 @@
 #include <linux/if_vlan.h>
 #include <linux/prefetch.h>
 #include <linux/random.h>
-#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
+#if IS_ENABLED(CONFIG_VLAN_8021Q)
 #define BCM_VLAN 1
 #endif
 #include <net/ip.h>
@@ -3685,7 +3685,7 @@ static int cnic_get_v4_route(struct sockaddr_in *dst_addr,
 static int cnic_get_v6_route(struct sockaddr_in6 *dst_addr,
                             struct dst_entry **dst)
 {
-#if defined(CONFIG_IPV6) || (defined(CONFIG_IPV6_MODULE) && defined(MODULE))
+#if IS_ENABLED(CONFIG_IPV6)
        struct flowi6 fl6;
 
        memset(&fl6, 0, sizeof(fl6));
index 3ac5d23..cb77ae9 100644 (file)
@@ -11617,6 +11617,12 @@ static int tg3_open(struct net_device *dev)
        struct tg3 *tp = netdev_priv(dev);
        int err;
 
+       if (tp->pcierr_recovery) {
+               netdev_err(dev, "Failed to open device. PCI error recovery "
+                          "in progress\n");
+               return -EAGAIN;
+       }
+
        if (tp->fw_needed) {
                err = tg3_request_firmware(tp);
                if (tg3_asic_rev(tp) == ASIC_REV_57766) {
@@ -11674,6 +11680,12 @@ static int tg3_close(struct net_device *dev)
 {
        struct tg3 *tp = netdev_priv(dev);
 
+       if (tp->pcierr_recovery) {
+               netdev_err(dev, "Failed to close device. PCI error recovery "
+                          "in progress\n");
+               return -EAGAIN;
+       }
+
        tg3_ptp_fini(tp);
 
        tg3_stop(tp);
@@ -17561,6 +17573,7 @@ static int tg3_init_one(struct pci_dev *pdev,
        tp->rx_mode = TG3_DEF_RX_MODE;
        tp->tx_mode = TG3_DEF_TX_MODE;
        tp->irq_sync = 1;
+       tp->pcierr_recovery = false;
 
        if (tg3_debug > 0)
                tp->msg_enable = tg3_debug;
@@ -18071,6 +18084,8 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
 
        rtnl_lock();
 
+       tp->pcierr_recovery = true;
+
        /* We probably don't have netdev yet */
        if (!netdev || !netif_running(netdev))
                goto done;
@@ -18195,6 +18210,7 @@ static void tg3_io_resume(struct pci_dev *pdev)
        tg3_phy_start(tp);
 
 done:
+       tp->pcierr_recovery = false;
        rtnl_unlock();
 }
 
index 461acca..31c9f82 100644 (file)
@@ -3407,6 +3407,7 @@ struct tg3 {
 
        struct device                   *hwmon_dev;
        bool                            link_up;
+       bool                            pcierr_recovery;
 };
 
 /* Accessor macros for chip and asic attributes
index ff8cae5..ffc92a4 100644 (file)
@@ -2506,7 +2506,7 @@ bnad_tso_prepare(struct bnad *bnad, struct sk_buff *skb)
         * For TSO, the TCP checksum field is seeded with pseudo-header sum
         * excluding the length field.
         */
-       if (skb->protocol == htons(ETH_P_IP)) {
+       if (vlan_get_protocol(skb) == htons(ETH_P_IP)) {
                struct iphdr *iph = ip_hdr(skb);
 
                /* Do we really need these? */
@@ -2870,12 +2870,13 @@ bnad_txq_wi_prepare(struct bnad *bnad, struct bna_tcb *tcb,
                }
 
                if (skb->ip_summed == CHECKSUM_PARTIAL) {
+                       __be16 net_proto = vlan_get_protocol(skb);
                        u8 proto = 0;
 
-                       if (skb->protocol == htons(ETH_P_IP))
+                       if (net_proto == htons(ETH_P_IP))
                                proto = ip_hdr(skb)->protocol;
 #ifdef NETIF_F_IPV6_CSUM
-                       else if (skb->protocol == htons(ETH_P_IPV6)) {
+                       else if (net_proto == htons(ETH_P_IPV6)) {
                                /* nexthdr may not be TCP immediately. */
                                proto = ipv6_hdr(skb)->nexthdr;
                        }
index 184a063..07d2201 100644 (file)
@@ -1,6 +1,7 @@
 config NET_CALXEDA_XGMAC
        tristate "Calxeda 1G/10G XGMAC Ethernet driver"
        depends on HAS_IOMEM && HAS_DMA
+       depends on ARCH_HIGHBANK || COMPILE_TEST
        select CRC32
        help
          This is the driver for the XGMAC Ethernet IP block found on Calxeda
index 18fb9c6..8c34811 100644 (file)
@@ -1253,7 +1253,9 @@ freeout:  t4_free_sge_resources(adap);
                        goto freeout;
        }
 
-       t4_write_reg(adap, MPS_TRC_RSS_CONTROL,
+       t4_write_reg(adap, is_t4(adap->params.chip) ?
+                               MPS_TRC_RSS_CONTROL :
+                               MPS_T5_TRC_RSS_CONTROL,
                     RSSCONTROL(netdev2pinfo(adap->port[0])->tx_chan) |
                     QUEUENUMBER(s->ethrxq[0].rspq.abs_id));
        return 0;
@@ -1761,7 +1763,8 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
                0xd004, 0xd03c,
                0xdfc0, 0xdfe0,
                0xe000, 0xea7c,
-               0xf000, 0x11190,
+               0xf000, 0x11110,
+               0x11118, 0x11190,
                0x19040, 0x1906c,
                0x19078, 0x19080,
                0x1908c, 0x19124,
@@ -1968,7 +1971,8 @@ static void get_regs(struct net_device *dev, struct ethtool_regs *regs,
                0xd004, 0xd03c,
                0xdfc0, 0xdfe0,
                0xe000, 0x11088,
-               0x1109c, 0x1117c,
+               0x1109c, 0x11110,
+               0x11118, 0x1117c,
                0x11190, 0x11204,
                0x19040, 0x1906c,
                0x19078, 0x19080,
@@ -5955,7 +5959,8 @@ static int adap_init0(struct adapter *adap)
                params[3] = FW_PARAM_PFVF(CQ_END);
                params[4] = FW_PARAM_PFVF(OCQ_START);
                params[5] = FW_PARAM_PFVF(OCQ_END);
-               ret = t4_query_params(adap, 0, 0, 0, 6, params, val);
+               ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 6, params,
+                                     val);
                if (ret < 0)
                        goto bye;
                adap->vres.qp.start = val[0];
@@ -5967,7 +5972,8 @@ static int adap_init0(struct adapter *adap)
 
                params[0] = FW_PARAM_DEV(MAXORDIRD_QP);
                params[1] = FW_PARAM_DEV(MAXIRD_ADAPTER);
-               ret = t4_query_params(adap, 0, 0, 0, 2, params, val);
+               ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, params,
+                                     val);
                if (ret < 0) {
                        adap->params.max_ordird_qp = 8;
                        adap->params.max_ird_adapter = 32 * adap->tids.ntids;
index a853133..41d0446 100644 (file)
@@ -167,6 +167,34 @@ void t4_hw_pci_read_cfg4(struct adapter *adap, int reg, u32 *val)
        t4_write_reg(adap, PCIE_CFG_SPACE_REQ, 0);
 }
 
+/*
+ * t4_report_fw_error - report firmware error
+ * @adap: the adapter
+ *
+ * The adapter firmware can indicate error conditions to the host.
+ * If the firmware has indicated an error, print out the reason for
+ * the firmware error.
+ */
+static void t4_report_fw_error(struct adapter *adap)
+{
+       static const char *const reason[] = {
+               "Crash",                        /* PCIE_FW_EVAL_CRASH */
+               "During Device Preparation",    /* PCIE_FW_EVAL_PREP */
+               "During Device Configuration",  /* PCIE_FW_EVAL_CONF */
+               "During Device Initialization", /* PCIE_FW_EVAL_INIT */
+               "Unexpected Event",             /* PCIE_FW_EVAL_UNEXPECTEDEVENT */
+               "Insufficient Airflow",         /* PCIE_FW_EVAL_OVERHEAT */
+               "Device Shutdown",              /* PCIE_FW_EVAL_DEVICESHUTDOWN */
+               "Reserved",                     /* reserved */
+       };
+       u32 pcie_fw;
+
+       pcie_fw = t4_read_reg(adap, MA_PCIE_FW);
+       if (pcie_fw & FW_PCIE_FW_ERR)
+               dev_err(adap->pdev_dev, "Firmware reports adapter error: %s\n",
+                       reason[FW_PCIE_FW_EVAL_GET(pcie_fw)]);
+}
+
 /*
  * Get the reply to a mailbox command and store it in @rpl in big-endian order.
  */
@@ -300,6 +328,7 @@ int t4_wr_mbox_meat(struct adapter *adap, int mbox, const void *cmd, int size,
        dump_mbox(adap, mbox, data_reg);
        dev_err(adap->pdev_dev, "command %#x in mailbox %d timed out\n",
                *(const u8 *)cmd, mbox);
+       t4_report_fw_error(adap);
        return -ETIMEDOUT;
 }
 
@@ -566,6 +595,7 @@ int t4_memory_rw(struct adapter *adap, int win, int mtype, u32 addr,
 #define VPD_BASE           0x400
 #define VPD_BASE_OLD       0
 #define VPD_LEN            1024
+#define CHELSIO_VPD_UNIQUE_ID 0x82
 
 /**
  *     t4_seeprom_wp - enable/disable EEPROM write protection
@@ -603,7 +633,14 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
        ret = pci_read_vpd(adapter->pdev, VPD_BASE, sizeof(u32), vpd);
        if (ret < 0)
                goto out;
-       addr = *vpd == 0x82 ? VPD_BASE : VPD_BASE_OLD;
+
+       /* The VPD shall have a unique identifier specified by the PCI SIG.
+        * For chelsio adapters, the identifier is 0x82. The first byte of a VPD
+        * shall be CHELSIO_VPD_UNIQUE_ID (0x82). The VPD programming software
+        * is expected to automatically put this entry at the
+        * beginning of the VPD.
+        */
+       addr = *vpd == CHELSIO_VPD_UNIQUE_ID ? VPD_BASE : VPD_BASE_OLD;
 
        ret = pci_read_vpd(adapter->pdev, addr, VPD_LEN, vpd);
        if (ret < 0)
@@ -667,6 +704,7 @@ int get_vpd_params(struct adapter *adapter, struct vpd_params *p)
        i = pci_vpd_info_field_size(vpd + sn - PCI_VPD_INFO_FLD_HDR_SIZE);
        memcpy(p->sn, vpd + sn, min(i, SERNUM_LEN));
        strim(p->sn);
+       i = pci_vpd_info_field_size(vpd + pn - PCI_VPD_INFO_FLD_HDR_SIZE);
        memcpy(p->pn, vpd + pn, min(i, PN_LEN));
        strim(p->pn);
 
@@ -1394,15 +1432,18 @@ static void pcie_intr_handler(struct adapter *adapter)
 
        int fat;
 
-       fat = t4_handle_intr_status(adapter,
-                                   PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
-                                   sysbus_intr_info) +
-             t4_handle_intr_status(adapter,
-                                   PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
-                                   pcie_port_intr_info) +
-             t4_handle_intr_status(adapter, PCIE_INT_CAUSE,
-                                   is_t4(adapter->params.chip) ?
-                                   pcie_intr_info : t5_pcie_intr_info);
+       if (is_t4(adapter->params.chip))
+               fat = t4_handle_intr_status(adapter,
+                                           PCIE_CORE_UTL_SYSTEM_BUS_AGENT_STATUS,
+                                           sysbus_intr_info) +
+                       t4_handle_intr_status(adapter,
+                                             PCIE_CORE_UTL_PCI_EXPRESS_PORT_STATUS,
+                                             pcie_port_intr_info) +
+                       t4_handle_intr_status(adapter, PCIE_INT_CAUSE,
+                                             pcie_intr_info);
+       else
+               fat = t4_handle_intr_status(adapter, PCIE_INT_CAUSE,
+                                           t5_pcie_intr_info);
 
        if (fat)
                t4_fatal_err(adapter);
@@ -1521,6 +1562,9 @@ static void cim_intr_handler(struct adapter *adapter)
 
        int fat;
 
+       if (t4_read_reg(adapter, MA_PCIE_FW) & FW_PCIE_FW_ERR)
+               t4_report_fw_error(adapter);
+
        fat = t4_handle_intr_status(adapter, CIM_HOST_INT_CAUSE,
                                    cim_intr_info) +
              t4_handle_intr_status(adapter, CIM_HOST_UPACC_INT_CAUSE,
@@ -1768,10 +1812,16 @@ static void ma_intr_handler(struct adapter *adap)
 {
        u32 v, status = t4_read_reg(adap, MA_INT_CAUSE);
 
-       if (status & MEM_PERR_INT_CAUSE)
+       if (status & MEM_PERR_INT_CAUSE) {
                dev_alert(adap->pdev_dev,
                          "MA parity error, parity status %#x\n",
                          t4_read_reg(adap, MA_PARITY_ERROR_STATUS));
+               if (is_t5(adap->params.chip))
+                       dev_alert(adap->pdev_dev,
+                                 "MA parity error, parity status %#x\n",
+                                 t4_read_reg(adap,
+                                             MA_PARITY_ERROR_STATUS2));
+       }
        if (status & MEM_WRAP_INT_CAUSE) {
                v = t4_read_reg(adap, MA_INT_WRAP_STATUS);
                dev_alert(adap->pdev_dev, "MA address wrap-around error by "
@@ -2733,12 +2783,16 @@ retry:
        /*
         * Issue the HELLO command to the firmware.  If it's not successful
         * but indicates that we got a "busy" or "timeout" condition, retry
-        * the HELLO until we exhaust our retry limit.
+        * the HELLO until we exhaust our retry limit.  If we do exceed our
+        * retry limit, check to see if the firmware left us any error
+        * information and report that if so.
         */
        ret = t4_wr_mbox(adap, mbox, &c, sizeof(c), &c);
        if (ret < 0) {
                if ((ret == -EBUSY || ret == -ETIMEDOUT) && retries-- > 0)
                        goto retry;
+               if (t4_read_reg(adap, MA_PCIE_FW) & FW_PCIE_FW_ERR)
+                       t4_report_fw_error(adap);
                return ret;
        }
 
@@ -3742,6 +3796,7 @@ int t4_handle_fw_rpl(struct adapter *adap, const __be64 *rpl)
                        lc->link_ok = link_ok;
                        lc->speed = speed;
                        lc->fc = fc;
+                       lc->supported = be16_to_cpu(p->u.info.pcap);
                        t4_os_link_changed(adap, port, link_ok);
                }
                if (mod != pi->mod_type) {
index e3146e8..39fb325 100644 (file)
 #define  MEM_WRAP_CLIENT_NUM_GET(x) (((x) & MEM_WRAP_CLIENT_NUM_MASK) >> MEM_WRAP_CLIENT_NUM_SHIFT)
 #define MA_PCIE_FW 0x30b8
 #define MA_PARITY_ERROR_STATUS 0x77f4
+#define MA_PARITY_ERROR_STATUS2 0x7804
 
 #define MA_EXT_MEMORY1_BAR 0x7808
 #define EDC_0_BASE_ADDR 0x7900
 #define  TRCMULTIFILTER     0x00000001U
 
 #define MPS_TRC_RSS_CONTROL 0x9808
+#define MPS_T5_TRC_RSS_CONTROL 0xa00c
 #define  RSSCONTROL_MASK    0x00ff0000U
 #define  RSSCONTROL_SHIFT   16
 #define  RSSCONTROL(x)      ((x) << RSSCONTROL_SHIFT)
index 5f2729e..3409756 100644 (file)
@@ -2228,6 +2228,10 @@ struct fw_debug_cmd {
 #define FW_PCIE_FW_MASTER(x)     ((x) << FW_PCIE_FW_MASTER_SHIFT)
 #define FW_PCIE_FW_MASTER_GET(x) (((x) >> FW_PCIE_FW_MASTER_SHIFT) & \
                                 FW_PCIE_FW_MASTER_MASK)
+#define FW_PCIE_FW_EVAL_MASK   0x7
+#define FW_PCIE_FW_EVAL_SHIFT  24
+#define FW_PCIE_FW_EVAL_GET(x) (((x) >> FW_PCIE_FW_EVAL_SHIFT) & \
+                                FW_PCIE_FW_EVAL_MASK)
 
 struct fw_hdr {
        u8 ver;
index a0b418e..566b17d 100644 (file)
@@ -1994,7 +1994,7 @@ static void xmit_common(struct sk_buff *skb, struct ehea_swqe *swqe)
 {
        swqe->tx_control |= EHEA_SWQE_IMM_DATA_PRESENT | EHEA_SWQE_CRC;
 
-       if (skb->protocol != htons(ETH_P_IP))
+       if (vlan_get_protocol(skb) != htons(ETH_P_IP))
                return;
 
        if (skb->ip_summed == CHECKSUM_PARTIAL)
index cbc330b..ad3d5d1 100644 (file)
@@ -2674,7 +2674,8 @@ set_itr_now:
 #define E1000_TX_FLAGS_VLAN_SHIFT      16
 
 static int e1000_tso(struct e1000_adapter *adapter,
-                    struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
+                    struct e1000_tx_ring *tx_ring, struct sk_buff *skb,
+                    __be16 protocol)
 {
        struct e1000_context_desc *context_desc;
        struct e1000_buffer *buffer_info;
@@ -2692,7 +2693,7 @@ static int e1000_tso(struct e1000_adapter *adapter,
 
                hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
                mss = skb_shinfo(skb)->gso_size;
-               if (skb->protocol == htons(ETH_P_IP)) {
+               if (protocol == htons(ETH_P_IP)) {
                        struct iphdr *iph = ip_hdr(skb);
                        iph->tot_len = 0;
                        iph->check = 0;
@@ -2702,7 +2703,7 @@ static int e1000_tso(struct e1000_adapter *adapter,
                                                                 0);
                        cmd_length = E1000_TXD_CMD_IP;
                        ipcse = skb_transport_offset(skb) - 1;
-               } else if (skb->protocol == htons(ETH_P_IPV6)) {
+               } else if (skb_is_gso_v6(skb)) {
                        ipv6_hdr(skb)->payload_len = 0;
                        tcp_hdr(skb)->check =
                                ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
@@ -2745,7 +2746,8 @@ static int e1000_tso(struct e1000_adapter *adapter,
 }
 
 static bool e1000_tx_csum(struct e1000_adapter *adapter,
-                         struct e1000_tx_ring *tx_ring, struct sk_buff *skb)
+                         struct e1000_tx_ring *tx_ring, struct sk_buff *skb,
+                         __be16 protocol)
 {
        struct e1000_context_desc *context_desc;
        struct e1000_buffer *buffer_info;
@@ -2756,7 +2758,7 @@ static bool e1000_tx_csum(struct e1000_adapter *adapter,
        if (skb->ip_summed != CHECKSUM_PARTIAL)
                return false;
 
-       switch (skb->protocol) {
+       switch (protocol) {
        case cpu_to_be16(ETH_P_IP):
                if (ip_hdr(skb)->protocol == IPPROTO_TCP)
                        cmd_len |= E1000_TXD_CMD_TCP;
@@ -3097,6 +3099,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
        int count = 0;
        int tso;
        unsigned int f;
+       __be16 protocol = vlan_get_protocol(skb);
 
        /* This goes back to the question of how to logically map a Tx queue
         * to a flow.  Right now, performance is impacted slightly negatively
@@ -3210,7 +3213,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 
        first = tx_ring->next_to_use;
 
-       tso = e1000_tso(adapter, tx_ring, skb);
+       tso = e1000_tso(adapter, tx_ring, skb, protocol);
        if (tso < 0) {
                dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
@@ -3220,10 +3223,10 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
                if (likely(hw->mac_type != e1000_82544))
                        tx_ring->last_tx_tso = true;
                tx_flags |= E1000_TX_FLAGS_TSO;
-       } else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
+       } else if (likely(e1000_tx_csum(adapter, tx_ring, skb, protocol)))
                tx_flags |= E1000_TX_FLAGS_CSUM;
 
-       if (likely(skb->protocol == htons(ETH_P_IP)))
+       if (protocol == htons(ETH_P_IP))
                tx_flags |= E1000_TX_FLAGS_IPV4;
 
        if (unlikely(skb->no_fcs))
index 65c3aef..247335d 100644 (file)
@@ -5164,7 +5164,8 @@ link_up:
 #define E1000_TX_FLAGS_VLAN_MASK       0xffff0000
 #define E1000_TX_FLAGS_VLAN_SHIFT      16
 
-static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
+static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb,
+                    __be16 protocol)
 {
        struct e1000_context_desc *context_desc;
        struct e1000_buffer *buffer_info;
@@ -5183,7 +5184,7 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
 
        hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
        mss = skb_shinfo(skb)->gso_size;
-       if (skb->protocol == htons(ETH_P_IP)) {
+       if (protocol == htons(ETH_P_IP)) {
                struct iphdr *iph = ip_hdr(skb);
                iph->tot_len = 0;
                iph->check = 0;
@@ -5231,7 +5232,8 @@ static int e1000_tso(struct e1000_ring *tx_ring, struct sk_buff *skb)
        return 1;
 }
 
-static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
+static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb,
+                         __be16 protocol)
 {
        struct e1000_adapter *adapter = tx_ring->adapter;
        struct e1000_context_desc *context_desc;
@@ -5239,16 +5241,10 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
        unsigned int i;
        u8 css;
        u32 cmd_len = E1000_TXD_CMD_DEXT;
-       __be16 protocol;
 
        if (skb->ip_summed != CHECKSUM_PARTIAL)
                return false;
 
-       if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
-               protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
-       else
-               protocol = skb->protocol;
-
        switch (protocol) {
        case cpu_to_be16(ETH_P_IP):
                if (ip_hdr(skb)->protocol == IPPROTO_TCP)
@@ -5546,6 +5542,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
        int count = 0;
        int tso;
        unsigned int f;
+       __be16 protocol = vlan_get_protocol(skb);
 
        if (test_bit(__E1000_DOWN, &adapter->state)) {
                dev_kfree_skb_any(skb);
@@ -5620,7 +5617,7 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 
        first = tx_ring->next_to_use;
 
-       tso = e1000_tso(tx_ring, skb);
+       tso = e1000_tso(tx_ring, skb, protocol);
        if (tso < 0) {
                dev_kfree_skb_any(skb);
                return NETDEV_TX_OK;
@@ -5628,14 +5625,14 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
 
        if (tso)
                tx_flags |= E1000_TX_FLAGS_TSO;
-       else if (e1000_tx_csum(tx_ring, skb))
+       else if (e1000_tx_csum(tx_ring, skb, protocol))
                tx_flags |= E1000_TX_FLAGS_CSUM;
 
        /* Old method was to assume IPv4 packet by default if TSO was enabled.
         * 82571 hardware supports TSO capabilities for IPv6 as well...
         * no longer assume, we must.
         */
-       if (skb->protocol == htons(ETH_P_IP))
+       if (protocol == htons(ETH_P_IP))
                tx_flags |= E1000_TX_FLAGS_IPV4;
 
        if (unlikely(skb->no_fcs))
index a51aa37..369848e 100644 (file)
@@ -2295,7 +2295,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
                goto out_drop;
 
        /* obtain protocol of skb */
-       protocol = skb->protocol;
+       protocol = vlan_get_protocol(skb);
 
        /* record the location of the first descriptor for this packet */
        first = &tx_ring->tx_bi[tx_ring->next_to_use];
index 79bf96c..95a3ec2 100644 (file)
@@ -1597,7 +1597,7 @@ static netdev_tx_t i40e_xmit_frame_ring(struct sk_buff *skb,
                goto out_drop;
 
        /* obtain protocol of skb */
-       protocol = skb->protocol;
+       protocol = vlan_get_protocol(skb);
 
        /* record the location of the first descriptor for this packet */
        first = &tx_ring->tx_bi[tx_ring->next_to_use];
index c9f1d1b..ade067d 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mbus.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
+#include <linux/if_vlan.h>
 #include <net/ip.h>
 #include <net/ipv6.h>
 #include <linux/io.h>
@@ -1371,15 +1372,16 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb)
 {
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
                int ip_hdr_len = 0;
+               __be16 l3_proto = vlan_get_protocol(skb);
                u8 l4_proto;
 
-               if (skb->protocol == htons(ETH_P_IP)) {
+               if (l3_proto == htons(ETH_P_IP)) {
                        struct iphdr *ip4h = ip_hdr(skb);
 
                        /* Calculate IPv4 checksum and L4 checksum */
                        ip_hdr_len = ip4h->ihl;
                        l4_proto = ip4h->protocol;
-               } else if (skb->protocol == htons(ETH_P_IPV6)) {
+               } else if (l3_proto == htons(ETH_P_IPV6)) {
                        struct ipv6hdr *ip6h = ipv6_hdr(skb);
 
                        /* Read l4_protocol from one of IPv6 extra headers */
@@ -1390,7 +1392,7 @@ static u32 mvneta_skb_tx_csum(struct mvneta_port *pp, struct sk_buff *skb)
                        return MVNETA_TX_L4_CSUM_NOT;
 
                return mvneta_txq_desc_csum(skb_network_offset(skb),
-                               skb->protocol, ip_hdr_len, l4_proto);
+                                           l3_proto, ip_hdr_len, l4_proto);
        }
 
        return MVNETA_TX_L4_CSUM_NOT;
index bb536aa..abddcf8 100644 (file)
@@ -474,39 +474,12 @@ static int mlx4_en_tunnel_steer_add(struct mlx4_en_priv *priv, unsigned char *ad
                                    int qpn, u64 *reg_id)
 {
        int err;
-       struct mlx4_spec_list spec_eth_outer = { {NULL} };
-       struct mlx4_spec_list spec_vxlan     = { {NULL} };
-       struct mlx4_spec_list spec_eth_inner = { {NULL} };
-
-       struct mlx4_net_trans_rule rule = {
-               .queue_mode = MLX4_NET_TRANS_Q_FIFO,
-               .exclusive = 0,
-               .allow_loopback = 1,
-               .promisc_mode = MLX4_FS_REGULAR,
-               .priority = MLX4_DOMAIN_NIC,
-       };
-
-       __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16);
 
        if (priv->mdev->dev->caps.tunnel_offload_mode != MLX4_TUNNEL_OFFLOAD_MODE_VXLAN)
                return 0; /* do nothing */
 
-       rule.port = priv->port;
-       rule.qpn = qpn;
-       INIT_LIST_HEAD(&rule.list);
-
-       spec_eth_outer.id = MLX4_NET_TRANS_RULE_ID_ETH;
-       memcpy(spec_eth_outer.eth.dst_mac, addr, ETH_ALEN);
-       memcpy(spec_eth_outer.eth.dst_mac_msk, &mac_mask, ETH_ALEN);
-
-       spec_vxlan.id = MLX4_NET_TRANS_RULE_ID_VXLAN;    /* any vxlan header */
-       spec_eth_inner.id = MLX4_NET_TRANS_RULE_ID_ETH;  /* any inner eth header */
-
-       list_add_tail(&spec_eth_outer.list, &rule.list);
-       list_add_tail(&spec_vxlan.list,     &rule.list);
-       list_add_tail(&spec_eth_inner.list, &rule.list);
-
-       err = mlx4_flow_attach(priv->mdev->dev, &rule, reg_id);
+       err = mlx4_tunnel_steer_add(priv->mdev->dev, addr, priv->port, qpn,
+                                   MLX4_DOMAIN_NIC, reg_id);
        if (err) {
                en_err(priv, "failed to add vxlan steering rule, err %d\n", err);
                return err;
index d80e7a6..ca0f98c 100644 (file)
@@ -1020,6 +1020,44 @@ int mlx4_flow_detach(struct mlx4_dev *dev, u64 reg_id)
 }
 EXPORT_SYMBOL_GPL(mlx4_flow_detach);
 
+int mlx4_tunnel_steer_add(struct mlx4_dev *dev, unsigned char *addr,
+                         int port, int qpn, u16 prio, u64 *reg_id)
+{
+       int err;
+       struct mlx4_spec_list spec_eth_outer = { {NULL} };
+       struct mlx4_spec_list spec_vxlan     = { {NULL} };
+       struct mlx4_spec_list spec_eth_inner = { {NULL} };
+
+       struct mlx4_net_trans_rule rule = {
+               .queue_mode = MLX4_NET_TRANS_Q_FIFO,
+               .exclusive = 0,
+               .allow_loopback = 1,
+               .promisc_mode = MLX4_FS_REGULAR,
+       };
+
+       __be64 mac_mask = cpu_to_be64(MLX4_MAC_MASK << 16);
+
+       rule.port = port;
+       rule.qpn = qpn;
+       rule.priority = prio;
+       INIT_LIST_HEAD(&rule.list);
+
+       spec_eth_outer.id = MLX4_NET_TRANS_RULE_ID_ETH;
+       memcpy(spec_eth_outer.eth.dst_mac, addr, ETH_ALEN);
+       memcpy(spec_eth_outer.eth.dst_mac_msk, &mac_mask, ETH_ALEN);
+
+       spec_vxlan.id = MLX4_NET_TRANS_RULE_ID_VXLAN;    /* any vxlan header */
+       spec_eth_inner.id = MLX4_NET_TRANS_RULE_ID_ETH;  /* any inner eth header */
+
+       list_add_tail(&spec_eth_outer.list, &rule.list);
+       list_add_tail(&spec_vxlan.list,     &rule.list);
+       list_add_tail(&spec_eth_inner.list, &rule.list);
+
+       err = mlx4_flow_attach(dev, &rule, reg_id);
+       return err;
+}
+EXPORT_SYMBOL(mlx4_tunnel_steer_add);
+
 int mlx4_FLOW_STEERING_IB_UC_QP_RANGE(struct mlx4_dev *dev, u32 min_range_qpn,
                                      u32 max_range_qpn)
 {
index 5020fd4..2f12c88 100644 (file)
@@ -206,7 +206,7 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
        int rx_head = priv->rx_head;
        int rx = 0;
 
-       while (1) {
+       while (rx < budget) {
                desc = priv->rx_desc_base + (RX_REG_DESC_SIZE * rx_head);
                desc0 = readl(desc + RX_REG_OFFSET_DESC0);
 
@@ -218,7 +218,7 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
                        net_dbg_ratelimited("packet error\n");
                        priv->stats.rx_dropped++;
                        priv->stats.rx_errors++;
-                       continue;
+                       goto rx_next;
                }
 
                len = desc0 & RX_DESC0_FRAME_LEN_MASK;
@@ -226,13 +226,19 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
                if (len > RX_BUF_SIZE)
                        len = RX_BUF_SIZE;
 
-               skb = build_skb(priv->rx_buf[rx_head], priv->rx_buf_size);
+               dma_sync_single_for_cpu(&ndev->dev,
+                                       priv->rx_mapping[rx_head],
+                                       priv->rx_buf_size, DMA_FROM_DEVICE);
+               skb = netdev_alloc_skb_ip_align(ndev, len);
+
                if (unlikely(!skb)) {
-                       net_dbg_ratelimited("build_skb failed\n");
+                       net_dbg_ratelimited("netdev_alloc_skb_ip_align failed\n");
                        priv->stats.rx_dropped++;
                        priv->stats.rx_errors++;
+                       goto rx_next;
                }
 
+               memcpy(skb->data, priv->rx_buf[rx_head], len);
                skb_put(skb, len);
                skb->protocol = eth_type_trans(skb, ndev);
                napi_gro_receive(&priv->napi, skb);
@@ -244,18 +250,15 @@ static int moxart_rx_poll(struct napi_struct *napi, int budget)
                if (desc0 & RX_DESC0_MULTICAST)
                        priv->stats.multicast++;
 
+rx_next:
                writel(RX_DESC0_DMA_OWN, desc + RX_REG_OFFSET_DESC0);
 
                rx_head = RX_NEXT(rx_head);
                priv->rx_head = rx_head;
-
-               if (rx >= budget)
-                       break;
        }
 
        if (rx < budget) {
-               napi_gro_flush(napi, false);
-               __napi_complete(napi);
+               napi_complete(napi);
        }
 
        priv->reg_imr |= RPKT_FINISH_M;
@@ -346,10 +349,12 @@ static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
                len = ETH_ZLEN;
        }
 
-       txdes1 = readl(desc + TX_REG_OFFSET_DESC1);
-       txdes1 |= TX_DESC1_LTS | TX_DESC1_FTS;
-       txdes1 &= ~(TX_DESC1_FIFO_COMPLETE | TX_DESC1_INTR_COMPLETE);
-       txdes1 |= (len & TX_DESC1_BUF_SIZE_MASK);
+       dma_sync_single_for_device(&ndev->dev, priv->tx_mapping[tx_head],
+                                  priv->tx_buf_size, DMA_TO_DEVICE);
+
+       txdes1 = TX_DESC1_LTS | TX_DESC1_FTS | (len & TX_DESC1_BUF_SIZE_MASK);
+       if (tx_head == TX_DESC_NUM_MASK)
+               txdes1 |= TX_DESC1_END;
        writel(txdes1, desc + TX_REG_OFFSET_DESC1);
        writel(TX_DESC0_DMA_OWN, desc + TX_REG_OFFSET_DESC0);
 
@@ -465,8 +470,7 @@ static int moxart_mac_probe(struct platform_device *pdev)
        spin_lock_init(&priv->txlock);
 
        priv->tx_buf_size = TX_BUF_SIZE;
-       priv->rx_buf_size = RX_BUF_SIZE +
-                           SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
+       priv->rx_buf_size = RX_BUF_SIZE;
 
        priv->tx_desc_base = dma_alloc_coherent(NULL, TX_REG_DESC_SIZE *
                                                TX_DESC_NUM, &priv->tx_base,
index 8706c0d..a44a03c 100644 (file)
@@ -1220,6 +1220,9 @@ static int lpc_eth_open(struct net_device *ndev)
 
        __lpc_eth_clock_enable(pldat, true);
 
+       /* Suspended PHY makes LPC ethernet core block, so resume now */
+       phy_resume(pldat->phy_dev);
+
        /* Reset and initialize */
        __lpc_eth_reset(pldat);
        __lpc_eth_init(pldat);
index 188626e..3e96f26 100644 (file)
@@ -2556,6 +2556,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
 
        if (skb_is_gso(skb)) {
                int err;
+               __be16 l3_proto = vlan_get_protocol(skb);
 
                err = skb_cow_head(skb, 0);
                if (err < 0)
@@ -2572,7 +2573,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
                                << OB_MAC_TRANSPORT_HDR_SHIFT);
                mac_iocb_ptr->mss = cpu_to_le16(skb_shinfo(skb)->gso_size);
                mac_iocb_ptr->flags2 |= OB_MAC_TSO_IOCB_LSO;
-               if (likely(skb->protocol == htons(ETH_P_IP))) {
+               if (likely(l3_proto == htons(ETH_P_IP))) {
                        struct iphdr *iph = ip_hdr(skb);
                        iph->check = 0;
                        mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP4;
@@ -2580,7 +2581,7 @@ static int ql_tso(struct sk_buff *skb, struct ob_mac_tso_iocb_req *mac_iocb_ptr)
                                                                 iph->daddr, 0,
                                                                 IPPROTO_TCP,
                                                                 0);
-               } else if (skb->protocol == htons(ETH_P_IPV6)) {
+               } else if (l3_proto == htons(ETH_P_IPV6)) {
                        mac_iocb_ptr->flags1 |= OB_MAC_TSO_IOCB_IP6;
                        tcp_hdr(skb)->check =
                            ~csum_ipv6_magic(&ipv6_hdr(skb)->saddr,
index 9e757c7..196e98a 100644 (file)
@@ -5,6 +5,7 @@
 config SH_ETH
        tristate "Renesas SuperH Ethernet support"
        depends on HAS_DMA
+       depends on ARCH_SHMOBILE || SUPERH || COMPILE_TEST
        select CRC32
        select MII
        select MDIO_BITBANG
index c553f6b..cf28dab 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "stmmac.h"
 
-static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
+static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 {
        struct stmmac_priv *priv = (struct stmmac_priv *)p;
        unsigned int txsize = priv->dma_tx_size;
@@ -47,7 +47,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 
        desc->des2 = dma_map_single(priv->device, skb->data,
                                    bmax, DMA_TO_DEVICE);
-       priv->tx_skbuff_dma[entry] = desc->des2;
+       if (dma_mapping_error(priv->device, desc->des2))
+               return -1;
+       priv->tx_skbuff_dma[entry].buf = desc->des2;
        priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum, STMMAC_CHAIN_MODE);
 
        while (len != 0) {
@@ -59,7 +61,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
                        desc->des2 = dma_map_single(priv->device,
                                                    (skb->data + bmax * i),
                                                    bmax, DMA_TO_DEVICE);
-                       priv->tx_skbuff_dma[entry] = desc->des2;
+                       if (dma_mapping_error(priv->device, desc->des2))
+                               return -1;
+                       priv->tx_skbuff_dma[entry].buf = desc->des2;
                        priv->hw->desc->prepare_tx_desc(desc, 0, bmax, csum,
                                                        STMMAC_CHAIN_MODE);
                        priv->hw->desc->set_tx_owner(desc);
@@ -69,7 +73,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
                        desc->des2 = dma_map_single(priv->device,
                                                    (skb->data + bmax * i), len,
                                                    DMA_TO_DEVICE);
-                       priv->tx_skbuff_dma[entry] = desc->des2;
+                       if (dma_mapping_error(priv->device, desc->des2))
+                               return -1;
+                       priv->tx_skbuff_dma[entry].buf = desc->des2;
                        priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
                                                        STMMAC_CHAIN_MODE);
                        priv->hw->desc->set_tx_owner(desc);
index de507c3..593e6c4 100644 (file)
@@ -220,10 +220,10 @@ enum dma_irq_status {
        handle_tx = 0x8,
 };
 
-#define        CORE_IRQ_TX_PATH_IN_LPI_MODE    (1 << 1)
-#define        CORE_IRQ_TX_PATH_EXIT_LPI_MODE  (1 << 2)
-#define        CORE_IRQ_RX_PATH_IN_LPI_MODE    (1 << 3)
-#define        CORE_IRQ_RX_PATH_EXIT_LPI_MODE  (1 << 4)
+#define        CORE_IRQ_TX_PATH_IN_LPI_MODE    (1 << 0)
+#define        CORE_IRQ_TX_PATH_EXIT_LPI_MODE  (1 << 1)
+#define        CORE_IRQ_RX_PATH_IN_LPI_MODE    (1 << 2)
+#define        CORE_IRQ_RX_PATH_EXIT_LPI_MODE  (1 << 3)
 
 #define        CORE_PCS_ANE_COMPLETE           (1 << 5)
 #define        CORE_PCS_LINK_STATUS            (1 << 6)
@@ -287,7 +287,7 @@ struct dma_features {
 
 /* Default LPI timers */
 #define STMMAC_DEFAULT_LIT_LS  0x3E8
-#define STMMAC_DEFAULT_TWT_LS  0x0
+#define STMMAC_DEFAULT_TWT_LS  0x1E
 
 #define STMMAC_CHAIN_MODE      0x1
 #define STMMAC_RING_MODE       0x2
@@ -425,7 +425,7 @@ struct stmmac_mode_ops {
        void (*init) (void *des, dma_addr_t phy_addr, unsigned int size,
                      unsigned int extend_desc);
        unsigned int (*is_jumbo_frm) (int len, int ehn_desc);
-       unsigned int (*jumbo_frm) (void *priv, struct sk_buff *skb, int csum);
+       int (*jumbo_frm)(void *priv, struct sk_buff *skb, int csum);
        int (*set_16kib_bfsize)(int mtu);
        void (*init_desc3)(struct dma_desc *p);
        void (*refill_desc3) (void *priv, struct dma_desc *p);
@@ -445,6 +445,7 @@ struct mac_device_info {
        int multicast_filter_bins;
        int unicast_filter_entries;
        int mcast_bits_log2;
+       unsigned int rx_csum;
 };
 
 struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
index 71b5419..64d8f56 100644 (file)
@@ -153,7 +153,7 @@ enum inter_frame_gap {
 #define GMAC_CONTROL_RE                0x00000004      /* Receiver Enable */
 
 #define GMAC_CORE_INIT (GMAC_CONTROL_JD | GMAC_CONTROL_PS | GMAC_CONTROL_ACS | \
-                       GMAC_CONTROL_BE)
+                       GMAC_CONTROL_BE | GMAC_CONTROL_DCRS)
 
 /* GMAC Frame Filter defines */
 #define GMAC_FRAME_FILTER_PR   0x00000001      /* Promiscuous Mode */
index d8ef187..5efe60e 100644 (file)
@@ -58,7 +58,11 @@ static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
        void __iomem *ioaddr = hw->pcsr;
        u32 value = readl(ioaddr + GMAC_CONTROL);
 
-       value |= GMAC_CONTROL_IPC;
+       if (hw->rx_csum)
+               value |= GMAC_CONTROL_IPC;
+       else
+               value &= ~GMAC_CONTROL_IPC;
+
        writel(value, ioaddr + GMAC_CONTROL);
 
        value = readl(ioaddr + GMAC_CONTROL);
index 8607488..192c249 100644 (file)
@@ -68,7 +68,7 @@ struct stmmac_counters {
        unsigned int mmc_rx_octetcount_g;
        unsigned int mmc_rx_broadcastframe_g;
        unsigned int mmc_rx_multicastframe_g;
-       unsigned int mmc_rx_crc_errror;
+       unsigned int mmc_rx_crc_error;
        unsigned int mmc_rx_align_error;
        unsigned int mmc_rx_run_error;
        unsigned int mmc_rx_jabber_error;
index 50617c5..08c483b 100644 (file)
@@ -196,7 +196,7 @@ void dwmac_mmc_read(void __iomem *ioaddr, struct stmmac_counters *mmc)
        mmc->mmc_rx_octetcount_g += readl(ioaddr + MMC_RX_OCTETCOUNT_G);
        mmc->mmc_rx_broadcastframe_g += readl(ioaddr + MMC_RX_BROADCASTFRAME_G);
        mmc->mmc_rx_multicastframe_g += readl(ioaddr + MMC_RX_MULTICASTFRAME_G);
-       mmc->mmc_rx_crc_errror += readl(ioaddr + MMC_RX_CRC_ERRROR);
+       mmc->mmc_rx_crc_error += readl(ioaddr + MMC_RX_CRC_ERRROR);
        mmc->mmc_rx_align_error += readl(ioaddr + MMC_RX_ALIGN_ERROR);
        mmc->mmc_rx_run_error += readl(ioaddr + MMC_RX_RUN_ERROR);
        mmc->mmc_rx_jabber_error += readl(ioaddr + MMC_RX_JABBER_ERROR);
index 650a4be..5dd50c6 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "stmmac.h"
 
-static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
+static int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 {
        struct stmmac_priv *priv = (struct stmmac_priv *)p;
        unsigned int txsize = priv->dma_tx_size;
@@ -53,7 +53,10 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 
                desc->des2 = dma_map_single(priv->device, skb->data,
                                            bmax, DMA_TO_DEVICE);
-               priv->tx_skbuff_dma[entry] = desc->des2;
+               if (dma_mapping_error(priv->device, desc->des2))
+                       return -1;
+
+               priv->tx_skbuff_dma[entry].buf = desc->des2;
                desc->des3 = desc->des2 + BUF_SIZE_4KiB;
                priv->hw->desc->prepare_tx_desc(desc, 1, bmax, csum,
                                                STMMAC_RING_MODE);
@@ -68,7 +71,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
 
                desc->des2 = dma_map_single(priv->device, skb->data + bmax,
                                            len, DMA_TO_DEVICE);
-               priv->tx_skbuff_dma[entry] = desc->des2;
+               if (dma_mapping_error(priv->device, desc->des2))
+                       return -1;
+               priv->tx_skbuff_dma[entry].buf = desc->des2;
                desc->des3 = desc->des2 + BUF_SIZE_4KiB;
                priv->hw->desc->prepare_tx_desc(desc, 0, len, csum,
                                                STMMAC_RING_MODE);
@@ -77,7 +82,9 @@ static unsigned int stmmac_jumbo_frm(void *p, struct sk_buff *skb, int csum)
        } else {
                desc->des2 = dma_map_single(priv->device, skb->data,
                                            nopaged_len, DMA_TO_DEVICE);
-               priv->tx_skbuff_dma[entry] = desc->des2;
+               if (dma_mapping_error(priv->device, desc->des2))
+                       return -1;
+               priv->tx_skbuff_dma[entry].buf = desc->des2;
                desc->des3 = desc->des2 + BUF_SIZE_4KiB;
                priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len, csum,
                                                STMMAC_RING_MODE);
index ca01035..58097c0 100644 (file)
 #include <linux/ptp_clock_kernel.h>
 #include <linux/reset.h>
 
+struct stmmac_tx_info {
+       dma_addr_t buf;
+       bool map_as_page;
+};
+
 struct stmmac_priv {
        /* Frequently used values are kept adjacent for cache effect */
        struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp;
@@ -45,7 +50,7 @@ struct stmmac_priv {
        u32 tx_count_frames;
        u32 tx_coal_frames;
        u32 tx_coal_timer;
-       dma_addr_t *tx_skbuff_dma;
+       struct stmmac_tx_info *tx_skbuff_dma;
        dma_addr_t dma_tx_phy;
        int tx_coalesce;
        int hwts_tx_en;
@@ -105,6 +110,8 @@ struct stmmac_priv {
        struct ptp_clock *ptp_clock;
        struct ptp_clock_info ptp_clock_ops;
        unsigned int default_addend;
+       struct clk *clk_ptp_ref;
+       unsigned int clk_ptp_rate;
        u32 adv_ts;
        int use_riwt;
        int irq_wake;
index 9af50ba..cf4f38d 100644 (file)
@@ -175,7 +175,7 @@ static const struct stmmac_stats stmmac_mmc[] = {
        STMMAC_MMC_STAT(mmc_rx_octetcount_g),
        STMMAC_MMC_STAT(mmc_rx_broadcastframe_g),
        STMMAC_MMC_STAT(mmc_rx_multicastframe_g),
-       STMMAC_MMC_STAT(mmc_rx_crc_errror),
+       STMMAC_MMC_STAT(mmc_rx_crc_error),
        STMMAC_MMC_STAT(mmc_rx_align_error),
        STMMAC_MMC_STAT(mmc_rx_run_error),
        STMMAC_MMC_STAT(mmc_rx_jabber_error),
index 08addd6..6e6ee22 100644 (file)
@@ -275,6 +275,7 @@ static void stmmac_eee_ctrl_timer(unsigned long arg)
  */
 bool stmmac_eee_init(struct stmmac_priv *priv)
 {
+       char *phy_bus_name = priv->plat->phy_bus_name;
        bool ret = false;
 
        /* Using PCS we cannot dial with the phy registers at this stage
@@ -284,6 +285,10 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
            (priv->pcs == STMMAC_PCS_RTBI))
                goto out;
 
+       /* Never init EEE in case of a switch is attached */
+       if (phy_bus_name && (!strcmp(phy_bus_name, "fixed")))
+               goto out;
+
        /* MAC core supports the EEE feature. */
        if (priv->dma_cap.eee) {
                int tx_lpi_timer = priv->tx_lpi_timer;
@@ -316,10 +321,9 @@ bool stmmac_eee_init(struct stmmac_priv *priv)
                        priv->hw->mac->set_eee_timer(priv->hw,
                                                     STMMAC_DEFAULT_LIT_LS,
                                                     tx_lpi_timer);
-               } else
-                       /* Set HW EEE according to the speed */
-                       priv->hw->mac->set_eee_pls(priv->hw,
-                                                  priv->phydev->link);
+               }
+               /* Set HW EEE according to the speed */
+               priv->hw->mac->set_eee_pls(priv->hw, priv->phydev->link);
 
                pr_debug("stmmac: Energy-Efficient Ethernet initialized\n");
 
@@ -603,16 +607,16 @@ static int stmmac_hwtstamp_ioctl(struct net_device *dev, struct ifreq *ifr)
                /* calculate default added value:
                 * formula is :
                 * addend = (2^32)/freq_div_ratio;
-                * where, freq_div_ratio = STMMAC_SYSCLOCK/50MHz
-                * hence, addend = ((2^32) * 50MHz)/STMMAC_SYSCLOCK;
-                * NOTE: STMMAC_SYSCLOCK should be >= 50MHz to
+                * where, freq_div_ratio = clk_ptp_ref_i/50MHz
+                * hence, addend = ((2^32) * 50MHz)/clk_ptp_ref_i;
+                * NOTE: clk_ptp_ref_i should be >= 50MHz to
                 *       achive 20ns accuracy.
                 *
                 * 2^x * y == (y << x), hence
                 * 2^32 * 50000000 ==> (50000000 << 32)
                 */
                temp = (u64) (50000000ULL << 32);
-               priv->default_addend = div_u64(temp, STMMAC_SYSCLOCK);
+               priv->default_addend = div_u64(temp, priv->clk_ptp_rate);
                priv->hw->ptp->config_addend(priv->ioaddr,
                                             priv->default_addend);
 
@@ -638,6 +642,16 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
        if (!(priv->dma_cap.time_stamp || priv->dma_cap.atime_stamp))
                return -EOPNOTSUPP;
 
+       /* Fall-back to main clock in case of no PTP ref is passed */
+       priv->clk_ptp_ref = devm_clk_get(priv->device, "clk_ptp_ref");
+       if (IS_ERR(priv->clk_ptp_ref)) {
+               priv->clk_ptp_rate = clk_get_rate(priv->stmmac_clk);
+               priv->clk_ptp_ref = NULL;
+       } else {
+               clk_prepare_enable(priv->clk_ptp_ref);
+               priv->clk_ptp_rate = clk_get_rate(priv->clk_ptp_ref);
+       }
+
        priv->adv_ts = 0;
        if (priv->dma_cap.atime_stamp && priv->extend_desc)
                priv->adv_ts = 1;
@@ -657,6 +671,8 @@ static int stmmac_init_ptp(struct stmmac_priv *priv)
 
 static void stmmac_release_ptp(struct stmmac_priv *priv)
 {
+       if (priv->clk_ptp_ref)
+               clk_disable_unprepare(priv->clk_ptp_ref);
        stmmac_ptp_unregister(priv);
 }
 
@@ -1061,7 +1077,8 @@ static int init_dma_desc_rings(struct net_device *dev)
                else
                        p = priv->dma_tx + i;
                p->des2 = 0;
-               priv->tx_skbuff_dma[i] = 0;
+               priv->tx_skbuff_dma[i].buf = 0;
+               priv->tx_skbuff_dma[i].map_as_page = false;
                priv->tx_skbuff[i] = NULL;
        }
 
@@ -1100,17 +1117,24 @@ static void dma_free_tx_skbufs(struct stmmac_priv *priv)
                else
                        p = priv->dma_tx + i;
 
-               if (priv->tx_skbuff_dma[i]) {
-                       dma_unmap_single(priv->device,
-                                        priv->tx_skbuff_dma[i],
-                                        priv->hw->desc->get_tx_len(p),
-                                        DMA_TO_DEVICE);
-                       priv->tx_skbuff_dma[i] = 0;
+               if (priv->tx_skbuff_dma[i].buf) {
+                       if (priv->tx_skbuff_dma[i].map_as_page)
+                               dma_unmap_page(priv->device,
+                                              priv->tx_skbuff_dma[i].buf,
+                                              priv->hw->desc->get_tx_len(p),
+                                              DMA_TO_DEVICE);
+                       else
+                               dma_unmap_single(priv->device,
+                                                priv->tx_skbuff_dma[i].buf,
+                                                priv->hw->desc->get_tx_len(p),
+                                                DMA_TO_DEVICE);
                }
 
                if (priv->tx_skbuff[i] != NULL) {
                        dev_kfree_skb_any(priv->tx_skbuff[i]);
                        priv->tx_skbuff[i] = NULL;
+                       priv->tx_skbuff_dma[i].buf = 0;
+                       priv->tx_skbuff_dma[i].map_as_page = false;
                }
        }
 }
@@ -1131,7 +1155,8 @@ static int alloc_dma_desc_resources(struct stmmac_priv *priv)
        if (!priv->rx_skbuff)
                goto err_rx_skbuff;
 
-       priv->tx_skbuff_dma = kmalloc_array(txsize, sizeof(dma_addr_t),
+       priv->tx_skbuff_dma = kmalloc_array(txsize,
+                                           sizeof(*priv->tx_skbuff_dma),
                                            GFP_KERNEL);
        if (!priv->tx_skbuff_dma)
                goto err_tx_skbuff_dma;
@@ -1293,12 +1318,19 @@ static void stmmac_tx_clean(struct stmmac_priv *priv)
                        pr_debug("%s: curr %d, dirty %d\n", __func__,
                                 priv->cur_tx, priv->dirty_tx);
 
-               if (likely(priv->tx_skbuff_dma[entry])) {
-                       dma_unmap_single(priv->device,
-                                        priv->tx_skbuff_dma[entry],
-                                        priv->hw->desc->get_tx_len(p),
-                                        DMA_TO_DEVICE);
-                       priv->tx_skbuff_dma[entry] = 0;
+               if (likely(priv->tx_skbuff_dma[entry].buf)) {
+                       if (priv->tx_skbuff_dma[entry].map_as_page)
+                               dma_unmap_page(priv->device,
+                                              priv->tx_skbuff_dma[entry].buf,
+                                              priv->hw->desc->get_tx_len(p),
+                                              DMA_TO_DEVICE);
+                       else
+                               dma_unmap_single(priv->device,
+                                                priv->tx_skbuff_dma[entry].buf,
+                                                priv->hw->desc->get_tx_len(p),
+                                                DMA_TO_DEVICE);
+                       priv->tx_skbuff_dma[entry].buf = 0;
+                       priv->tx_skbuff_dma[entry].map_as_page = false;
                }
                priv->hw->mode->clean_desc3(priv, p);
 
@@ -1637,6 +1669,13 @@ static int stmmac_hw_setup(struct net_device *dev)
        /* Initialize the MAC Core */
        priv->hw->mac->core_init(priv->hw, dev->mtu);
 
+       ret = priv->hw->mac->rx_ipc(priv->hw);
+       if (!ret) {
+               pr_warn(" RX IPC Checksum Offload disabled\n");
+               priv->plat->rx_coe = STMMAC_RX_COE_NONE;
+               priv->hw->rx_csum = 0;
+       }
+
        /* Enable the MAC Rx/Tx */
        stmmac_set_mac(priv->ioaddr, true);
 
@@ -1887,12 +1926,16 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        if (likely(!is_jumbo)) {
                desc->des2 = dma_map_single(priv->device, skb->data,
                                            nopaged_len, DMA_TO_DEVICE);
-               priv->tx_skbuff_dma[entry] = desc->des2;
+               if (dma_mapping_error(priv->device, desc->des2))
+                       goto dma_map_err;
+               priv->tx_skbuff_dma[entry].buf = desc->des2;
                priv->hw->desc->prepare_tx_desc(desc, 1, nopaged_len,
                                                csum_insertion, priv->mode);
        } else {
                desc = first;
                entry = priv->hw->mode->jumbo_frm(priv, skb, csum_insertion);
+               if (unlikely(entry < 0))
+                       goto dma_map_err;
        }
 
        for (i = 0; i < nfrags; i++) {
@@ -1908,7 +1951,11 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
 
                desc->des2 = skb_frag_dma_map(priv->device, frag, 0, len,
                                              DMA_TO_DEVICE);
-               priv->tx_skbuff_dma[entry] = desc->des2;
+               if (dma_mapping_error(priv->device, desc->des2))
+                       goto dma_map_err; /* should reuse desc w/o issues */
+
+               priv->tx_skbuff_dma[entry].buf = desc->des2;
+               priv->tx_skbuff_dma[entry].map_as_page = true;
                priv->hw->desc->prepare_tx_desc(desc, 0, len, csum_insertion,
                                                priv->mode);
                wmb();
@@ -1975,7 +2022,12 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        priv->hw->dma->enable_dma_transmission(priv->ioaddr);
 
        spin_unlock(&priv->tx_lock);
+       return NETDEV_TX_OK;
 
+dma_map_err:
+       dev_err(priv->device, "Tx dma map failed\n");
+       dev_kfree_skb(skb);
+       priv->dev->stats.tx_dropped++;
        return NETDEV_TX_OK;
 }
 
@@ -2028,7 +2080,12 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv)
                        priv->rx_skbuff_dma[entry] =
                            dma_map_single(priv->device, skb->data, bfsize,
                                           DMA_FROM_DEVICE);
-
+                       if (dma_mapping_error(priv->device,
+                                             priv->rx_skbuff_dma[entry])) {
+                               dev_err(priv->device, "Rx dma map failed\n");
+                               dev_kfree_skb(skb);
+                               break;
+                       }
                        p->des2 = priv->rx_skbuff_dma[entry];
 
                        priv->hw->mode->refill_desc3(priv, p);
@@ -2055,7 +2112,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit)
        unsigned int entry = priv->cur_rx % rxsize;
        unsigned int next_entry;
        unsigned int count = 0;
-       int coe = priv->plat->rx_coe;
+       int coe = priv->hw->rx_csum;
 
        if (netif_msg_rx_status(priv)) {
                pr_debug("%s: descriptor ring:\n", __func__);
@@ -2276,8 +2333,7 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
 
        if (priv->plat->rx_coe == STMMAC_RX_COE_NONE)
                features &= ~NETIF_F_RXCSUM;
-       else if (priv->plat->rx_coe == STMMAC_RX_COE_TYPE1)
-               features &= ~NETIF_F_IPV6_CSUM;
+
        if (!priv->plat->tx_coe)
                features &= ~NETIF_F_ALL_CSUM;
 
@@ -2292,6 +2348,24 @@ static netdev_features_t stmmac_fix_features(struct net_device *dev,
        return features;
 }
 
+static int stmmac_set_features(struct net_device *netdev,
+                              netdev_features_t features)
+{
+       struct stmmac_priv *priv = netdev_priv(netdev);
+
+       /* Keep the COE Type in case of csum is supporting */
+       if (features & NETIF_F_RXCSUM)
+               priv->hw->rx_csum = priv->plat->rx_coe;
+       else
+               priv->hw->rx_csum = 0;
+       /* No check needed because rx_coe has been set before and it will be
+        * fixed in case of issue.
+        */
+       priv->hw->mac->rx_ipc(priv->hw);
+
+       return 0;
+}
+
 /**
  *  stmmac_interrupt - main ISR
  *  @irq: interrupt number.
@@ -2572,6 +2646,7 @@ static const struct net_device_ops stmmac_netdev_ops = {
        .ndo_stop = stmmac_release,
        .ndo_change_mtu = stmmac_change_mtu,
        .ndo_fix_features = stmmac_fix_features,
+       .ndo_set_features = stmmac_set_features,
        .ndo_set_rx_mode = stmmac_set_rx_mode,
        .ndo_tx_timeout = stmmac_tx_timeout,
        .ndo_do_ioctl = stmmac_ioctl,
@@ -2592,7 +2667,6 @@ static const struct net_device_ops stmmac_netdev_ops = {
  */
 static int stmmac_hw_init(struct stmmac_priv *priv)
 {
-       int ret;
        struct mac_device_info *mac;
 
        /* Identify the MAC HW device */
@@ -2649,15 +2723,11 @@ static int stmmac_hw_init(struct stmmac_priv *priv)
        /* To use alternate (extended) or normal descriptor structures */
        stmmac_selec_desc_mode(priv);
 
-       ret = priv->hw->mac->rx_ipc(priv->hw);
-       if (!ret) {
-               pr_warn(" RX IPC Checksum Offload not configured.\n");
-               priv->plat->rx_coe = STMMAC_RX_COE_NONE;
-       }
-
-       if (priv->plat->rx_coe)
+       if (priv->plat->rx_coe) {
+               priv->hw->rx_csum = priv->plat->rx_coe;
                pr_info(" RX Checksum Offload Engine supported (type %d)\n",
                        priv->plat->rx_coe);
+       }
        if (priv->plat->tx_coe)
                pr_info(" TX Checksum insertion supported\n");
 
index b7ad356..c5ee79d 100644 (file)
@@ -206,6 +206,7 @@ void stmmac_ptp_unregister(struct stmmac_priv *priv)
 {
        if (priv->ptp_clock) {
                ptp_clock_unregister(priv->ptp_clock);
+               priv->ptp_clock = NULL;
                pr_debug("Removed PTP HW clock successfully on %s\n",
                         priv->dev->name);
        }
index 3dbc047..4535df3 100644 (file)
@@ -25,8 +25,6 @@
 #ifndef __STMMAC_PTP_H__
 #define __STMMAC_PTP_H__
 
-#define STMMAC_SYSCLOCK 62500000
-
 /* IEEE 1588 PTP register offsets */
 #define PTP_TCR                0x0700  /* Timestamp Control Reg */
 #define PTP_SSIR       0x0704  /* Sub-Second Increment Reg */
index c1ba26c..3de2f0d 100644 (file)
 #define        PCI_MEM64BIT    (2<<1)       /* Base addr anywhere in 64 Bit range */
 #define        PCI_MEMSPACE    0x00000001L  /* Bit 0:  Memory Space Indic. */
 
-/*     PCI_BASE_2ND    32 bit  2nd Base address */
-#define        PCI_IOBASE      0xffffff00L  /* Bit 31..8:  I/O Base address */
-#define        PCI_IOSIZE      0x000000fcL  /* Bit 7..2:   I/O Size Requirements */
-#define        PCI_IOSPACE     0x00000001L  /* Bit 0:      I/O Space Indicator */
-
 /*     PCI_SUB_VID     16 bit  Subsystem Vendor ID */
 /*     PCI_SUB_ID      16 bit  Subsystem ID */
 
index c94e2a2..a854d38 100644 (file)
@@ -1036,31 +1036,31 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
                /* First check if the EEE ability is supported */
                eee_cap = phy_read_mmd_indirect(phydev, MDIO_PCS_EEE_ABLE,
                                                MDIO_MMD_PCS, phydev->addr);
-               if (eee_cap < 0)
-                       return eee_cap;
+               if (eee_cap <= 0)
+                       goto eee_exit_err;
 
                cap = mmd_eee_cap_to_ethtool_sup_t(eee_cap);
                if (!cap)
-                       return -EPROTONOSUPPORT;
+                       goto eee_exit_err;
 
                /* Check which link settings negotiated and verify it in
                 * the EEE advertising registers.
                 */
                eee_lp = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_LPABLE,
                                               MDIO_MMD_AN, phydev->addr);
-               if (eee_lp < 0)
-                       return eee_lp;
+               if (eee_lp <= 0)
+                       goto eee_exit_err;
 
                eee_adv = phy_read_mmd_indirect(phydev, MDIO_AN_EEE_ADV,
                                                MDIO_MMD_AN, phydev->addr);
-               if (eee_adv < 0)
-                       return eee_adv;
+               if (eee_adv <= 0)
+                       goto eee_exit_err;
 
                adv = mmd_eee_adv_to_ethtool_adv_t(eee_adv);
                lp = mmd_eee_adv_to_ethtool_adv_t(eee_lp);
                idx = phy_find_setting(phydev->speed, phydev->duplex);
                if (!(lp & adv & settings[idx].setting))
-                       return -EPROTONOSUPPORT;
+                       goto eee_exit_err;
 
                if (clk_stop_enable) {
                        /* Configure the PHY to stop receiving xMII
@@ -1080,7 +1080,7 @@ int phy_init_eee(struct phy_device *phydev, bool clk_stop_enable)
 
                return 0; /* EEE supported */
        }
-
+eee_exit_err:
        return -EPROTONOSUPPORT;
 }
 EXPORT_SYMBOL(phy_init_eee);
index d6e90c7..6dfcbf5 100644 (file)
@@ -2056,7 +2056,6 @@ vmxnet3_set_mc(struct net_device *netdev)
                if (!netdev_mc_empty(netdev)) {
                        new_table = vmxnet3_copy_mc(netdev);
                        if (new_table) {
-                               new_mode |= VMXNET3_RXM_MCAST;
                                rxConf->mfTableLen = cpu_to_le16(
                                        netdev_mc_count(netdev) * ETH_ALEN);
                                new_table_pa = dma_map_single(
@@ -2064,15 +2063,18 @@ vmxnet3_set_mc(struct net_device *netdev)
                                                        new_table,
                                                        rxConf->mfTableLen,
                                                        PCI_DMA_TODEVICE);
+                       }
+
+                       if (new_table_pa) {
+                               new_mode |= VMXNET3_RXM_MCAST;
                                rxConf->mfTablePA = cpu_to_le64(new_table_pa);
                        } else {
-                               netdev_info(netdev, "failed to copy mcast list"
-                                           ", setting ALL_MULTI\n");
+                               netdev_info(netdev,
+                                           "failed to copy mcast list, setting ALL_MULTI\n");
                                new_mode |= VMXNET3_RXM_ALL_MULTI;
                        }
                }
 
-
        if (!(new_mode & VMXNET3_RXM_MCAST)) {
                rxConf->mfTableLen = 0;
                rxConf->mfTablePA = 0;
@@ -2091,11 +2093,10 @@ vmxnet3_set_mc(struct net_device *netdev)
                               VMXNET3_CMD_UPDATE_MAC_FILTERS);
        spin_unlock_irqrestore(&adapter->cmd_lock, flags);
 
-       if (new_table) {
+       if (new_table_pa)
                dma_unmap_single(&adapter->pdev->dev, new_table_pa,
                                 rxConf->mfTableLen, PCI_DMA_TODEVICE);
-               kfree(new_table);
-       }
+       kfree(new_table);
 }
 
 void
index 29ee77f..3759479 100644 (file)
 /*
  * Version numbers
  */
-#define VMXNET3_DRIVER_VERSION_STRING   "1.2.0.0-k"
+#define VMXNET3_DRIVER_VERSION_STRING   "1.2.1.0-k"
 
 /* a 32-bit int, each byte encode a verion number in VMXNET3_DRIVER_VERSION */
-#define VMXNET3_DRIVER_VERSION_NUM      0x01020000
+#define VMXNET3_DRIVER_VERSION_NUM      0x01020100
 
 #if defined(CONFIG_PCI_MSI)
        /* RSS only makes sense if MSI-X is supported. */
index 1fb7b37..beb377b 100644 (file)
@@ -1327,7 +1327,7 @@ static int arp_reduce(struct net_device *dev, struct sk_buff *skb)
        } else if (vxlan->flags & VXLAN_F_L3MISS) {
                union vxlan_addr ipa = {
                        .sin.sin_addr.s_addr = tip,
-                       .sa.sa_family = AF_INET,
+                       .sin.sin_family = AF_INET,
                };
 
                vxlan_ip_miss(dev, &ipa);
@@ -1488,7 +1488,7 @@ static int neigh_reduce(struct net_device *dev, struct sk_buff *skb)
        } else if (vxlan->flags & VXLAN_F_L3MISS) {
                union vxlan_addr ipa = {
                        .sin6.sin6_addr = msg->target,
-                       .sa.sa_family = AF_INET6,
+                       .sin6.sin6_family = AF_INET6,
                };
 
                vxlan_ip_miss(dev, &ipa);
@@ -1521,7 +1521,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
                if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
                        union vxlan_addr ipa = {
                                .sin.sin_addr.s_addr = pip->daddr,
-                               .sa.sa_family = AF_INET,
+                               .sin.sin_family = AF_INET,
                        };
 
                        vxlan_ip_miss(dev, &ipa);
@@ -1542,7 +1542,7 @@ static bool route_shortcircuit(struct net_device *dev, struct sk_buff *skb)
                if (!n && (vxlan->flags & VXLAN_F_L3MISS)) {
                        union vxlan_addr ipa = {
                                .sin6.sin6_addr = pip6->daddr,
-                               .sa.sa_family = AF_INET6,
+                               .sin6.sin6_family = AF_INET6,
                        };
 
                        vxlan_ip_miss(dev, &ipa);
index 334c2ec..da92bfa 100644 (file)
@@ -2423,8 +2423,6 @@ static void at76_delete_device(struct at76_priv *priv)
 
        kfree_skb(priv->rx_skb);
 
-       usb_put_dev(priv->udev);
-
        at76_dbg(DBG_PROC_ENTRY, "%s: before freeing priv/ieee80211_hw",
                 __func__);
        ieee80211_free_hw(priv->hw);
@@ -2558,6 +2556,7 @@ static void at76_disconnect(struct usb_interface *interface)
 
        wiphy_info(priv->hw->wiphy, "disconnecting\n");
        at76_delete_device(priv);
+       usb_put_dev(priv->udev);
        dev_info(&interface->dev, "disconnected\n");
 }
 
index 5fe29b9..8f68426 100644 (file)
@@ -253,7 +253,7 @@ static ssize_t write_file_spec_scan_ctl(struct file *file,
 
        if (strncmp("trigger", buf, 7) == 0) {
                ath9k_spectral_scan_trigger(sc->hw);
-       } else if (strncmp("background", buf, 9) == 0) {
+       } else if (strncmp("background", buf, 10) == 0) {
                ath9k_spectral_scan_config(sc->hw, SPECTRAL_BACKGROUND);
                ath_dbg(common, CONFIG, "spectral scan: background mode enabled\n");
        } else if (strncmp("chanscan", buf, 8) == 0) {
index 6451d2b..824f5e2 100644 (file)
@@ -51,7 +51,6 @@ config IWLWIFI_LEDS
 
 config IWLDVM
        tristate "Intel Wireless WiFi DVM Firmware support"
-       depends on m
        default IWLWIFI
        help
          This is the driver that supports the DVM firmware which is
@@ -60,7 +59,6 @@ config IWLDVM
 
 config IWLMVM
        tristate "Intel Wireless WiFi MVM Firmware support"
-       depends on m
        help
          This is the driver that supports the MVM firmware which is
          currently only available for 7260 and 3160 devices.
index 6dc5dd3..ed50de6 100644 (file)
@@ -1068,6 +1068,13 @@ int iwlagn_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
        /* recalculate basic rates */
        iwl_calc_basic_rates(priv, ctx);
 
+       /*
+        * force CTS-to-self frames protection if RTS-CTS is not preferred
+        * one aggregation protection method
+        */
+       if (!priv->hw_params.use_rts_for_aggregation)
+               ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+
        if ((ctx->vif && ctx->vif->bss_conf.use_short_slot) ||
            !(ctx->staging.flags & RXON_FLG_BAND_24G_MSK))
                ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
@@ -1473,6 +1480,11 @@ void iwlagn_bss_info_changed(struct ieee80211_hw *hw,
        else
                ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
 
+       if (bss_conf->use_cts_prot)
+               ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
+       else
+               ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
+
        memcpy(ctx->staging.bssid_addr, bss_conf->bssid, ETH_ALEN);
 
        if (vif->type == NL80211_IFTYPE_AP ||
index 4873006..d67a37a 100644 (file)
@@ -67,8 +67,8 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL7260_UCODE_API_MAX  9
-#define IWL3160_UCODE_API_MAX  9
+#define IWL7260_UCODE_API_MAX  10
+#define IWL3160_UCODE_API_MAX  10
 
 /* Oldest version we won't warn about */
 #define IWL7260_UCODE_API_OK   9
index 44b19e0..e93c697 100644 (file)
@@ -67,7 +67,7 @@
 #include "iwl-agn-hw.h"
 
 /* Highest firmware API version supported */
-#define IWL8000_UCODE_API_MAX  9
+#define IWL8000_UCODE_API_MAX  10
 
 /* Oldest version we won't warn about */
 #define IWL8000_UCODE_API_OK   8
index 33da3df..d4bd550 100644 (file)
@@ -101,7 +101,7 @@ static bool halbtc_legacy(struct rtl_priv *adapter)
 
        bool is_legacy = false;
 
-       if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_B))
+       if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_G))
                is_legacy = true;
 
        return is_legacy;
index 361435f..1ac6383 100644 (file)
@@ -317,6 +317,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
        {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/
        {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
        {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
+       {RTL_USB_DEVICE(0x0df6, 0x0070, rtl92cu_hal_cfg)}, /*Sitecom - 150N */
        {RTL_USB_DEVICE(0x0df6, 0x0077, rtl92cu_hal_cfg)}, /*Sitecom-WLA2100V2*/
        {RTL_USB_DEVICE(0x0eb0, 0x9071, rtl92cu_hal_cfg)}, /*NO Brand - Etop*/
        {RTL_USB_DEVICE(0x4856, 0x0091, rtl92cu_hal_cfg)}, /*NetweeN - Feixun*/
index e29e15d..f379689 100644 (file)
@@ -576,6 +576,9 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref,
        init_waitqueue_head(&queue->dealloc_wq);
        atomic_set(&queue->inflight_packets, 0);
 
+       netif_napi_add(queue->vif->dev, &queue->napi, xenvif_poll,
+                       XENVIF_NAPI_WEIGHT);
+
        if (tx_evtchn == rx_evtchn) {
                /* feature-split-event-channels == 0 */
                err = bind_interdomain_evtchn_to_irqhandler(
@@ -629,9 +632,6 @@ int xenvif_connect(struct xenvif_queue *queue, unsigned long tx_ring_ref,
        wake_up_process(queue->task);
        wake_up_process(queue->dealloc_task);
 
-       netif_napi_add(queue->vif->dev, &queue->napi, xenvif_poll,
-                       XENVIF_NAPI_WEIGHT);
-
        return 0;
 
 err_rx_unbind:
index 9ca59a0..e12e5b0 100644 (file)
@@ -461,6 +461,7 @@ static struct irq_chip byt_irqchip = {
        .irq_mask = byt_irq_mask,
        .irq_unmask = byt_irq_unmask,
        .irq_set_type = byt_irq_type,
+       .flags = IRQCHIP_SKIP_SET_WAKE,
 };
 
 static void byt_gpio_irq_init_hw(struct byt_gpio *vg)
index 2ead7e7..14ba80b 100644 (file)
@@ -77,7 +77,7 @@ EXPORT_SYMBOL_GPL(dasd_nofcx);
  * strings when running as a module.
  */
 static char *dasd[256];
-module_param_array(dasd, charp, NULL, 0);
+module_param_array(dasd, charp, NULL, S_IRUGO);
 
 /*
  * Single spinlock to protect devmap and servermap structures and lists.
index 97ef37b..e7646ce 100644 (file)
@@ -889,6 +889,7 @@ extern const struct attribute_group *qeth_generic_attr_groups[];
 extern const struct attribute_group *qeth_osn_attr_groups[];
 extern struct workqueue_struct *qeth_wq;
 
+int qeth_card_hw_is_reachable(struct qeth_card *);
 const char *qeth_get_cardname_short(struct qeth_card *);
 int qeth_realloc_buffer_pool(struct qeth_card *, int);
 int qeth_core_load_discipline(struct qeth_card *, enum qeth_discipline_id);
index c0d6ba8..fd22c81 100644 (file)
@@ -73,6 +73,13 @@ static int qeth_init_qdio_out_buf(struct qeth_qdio_out_q *, int);
 struct workqueue_struct *qeth_wq;
 EXPORT_SYMBOL_GPL(qeth_wq);
 
+int qeth_card_hw_is_reachable(struct qeth_card *card)
+{
+       return (card->state == CARD_STATE_SOFTSETUP) ||
+               (card->state == CARD_STATE_UP);
+}
+EXPORT_SYMBOL_GPL(qeth_card_hw_is_reachable);
+
 static void qeth_close_dev_handler(struct work_struct *work)
 {
        struct qeth_card *card;
@@ -5790,6 +5797,7 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev,
        struct qeth_card *card = netdev->ml_priv;
        enum qeth_link_types link_type;
        struct carrier_info carrier_info;
+       int rc;
        u32 speed;
 
        if ((card->info.type == QETH_CARD_TYPE_IQD) || (card->info.guestlan))
@@ -5832,8 +5840,14 @@ int qeth_core_ethtool_get_settings(struct net_device *netdev,
        /* Check if we can obtain more accurate information.     */
        /* If QUERY_CARD_INFO command is not supported or fails, */
        /* just return the heuristics that was filled above.     */
-       if (qeth_query_card_info(card, &carrier_info) != 0)
+       if (!qeth_card_hw_is_reachable(card))
+               return -ENODEV;
+       rc = qeth_query_card_info(card, &carrier_info);
+       if (rc == -EOPNOTSUPP) /* for old hardware, return heuristic */
                return 0;
+       if (rc) /* report error from the hardware operation */
+               return rc;
+       /* on success, fill in the information got from the hardware */
 
        netdev_dbg(netdev,
        "card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n",
index ae1bc04..59e3aa5 100644 (file)
@@ -5,17 +5,12 @@
 
 #include <linux/slab.h>
 #include <asm/ebcdic.h>
+#include "qeth_core.h"
 #include "qeth_l2.h"
 
 #define QETH_DEVICE_ATTR(_id, _name, _mode, _show, _store) \
 struct device_attribute dev_attr_##_id = __ATTR(_name, _mode, _show, _store)
 
-static int qeth_card_hw_is_reachable(struct qeth_card *card)
-{
-       return (card->state == CARD_STATE_SOFTSETUP) ||
-               (card->state == CARD_STATE_UP);
-}
-
 static ssize_t qeth_bridge_port_role_state_show(struct device *dev,
                                struct device_attribute *attr, char *buf,
                                int show_state)
index 19396dc..bed2fed 100644 (file)
@@ -38,6 +38,7 @@ static const struct pci_device_id b43_pci_bridge_tbl[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432b) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x432c) },
        { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4350) },
+       { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4351) },
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, b43_pci_bridge_tbl);
index 603f18a..a2172f3 100644 (file)
@@ -22,6 +22,11 @@ config CIFS
          support for OS/2 and Windows ME and similar servers is provided as
          well.
 
+         The module also provides optional support for the followon
+         protocols for CIFS including SMB3, which enables
+         useful performance and security features (see the description
+         of CONFIG_CIFS_SMB2).
+
          The cifs module provides an advanced network file system
          client for mounting to CIFS compliant servers.  It includes
          support for DFS (hierarchical name space), secure per-user
@@ -121,7 +126,8 @@ config CIFS_ACL
          depends on CIFS_XATTR && KEYS
          help
            Allows fetching CIFS/NTFS ACL from the server.  The DACL blob
-           is handed over to the application/caller.
+           is handed over to the application/caller.  See the man
+           page for getcifsacl for more information.
 
 config CIFS_DEBUG
        bool "Enable CIFS debugging routines"
@@ -162,7 +168,7 @@ config CIFS_NFSD_EXPORT
           Allows NFS server to export a CIFS mounted share (nfsd over cifs)
 
 config CIFS_SMB2
-       bool "SMB2 network file system support"
+       bool "SMB2 and SMB3 network file system support"
        depends on CIFS && INET
        select NLS
        select KEYS
@@ -170,16 +176,21 @@ config CIFS_SMB2
        select DNS_RESOLVER
 
        help
-         This enables experimental support for the SMB2 (Server Message Block
-         version 2) protocol. The SMB2 protocol is the successor to the
-         popular CIFS and SMB network file sharing protocols. SMB2 is the
-         native file sharing mechanism for recent versions of Windows
-         operating systems (since Vista).  SMB2 enablement will eventually
-         allow users better performance, security and features, than would be
-         possible with cifs. Note that smb2 mount options also are simpler
-         (compared to cifs) due to protocol improvements.
-
-         Unless you are a developer or tester, say N.
+         This enables support for the Server Message Block version 2
+         family of protocols, including SMB3.  SMB3 support is
+         enabled on mount by specifying "vers=3.0" in the mount
+         options. These protocols are the successors to the popular
+         CIFS and SMB network file sharing protocols. SMB3 is the
+         native file sharing mechanism for the more recent
+         versions of Windows (Windows 8 and Windows 2012 and
+         later) and Samba server and many others support SMB3 well.
+         In general SMB3 enables better performance, security
+         and features, than would be possible with CIFS (Note that
+         when mounting to Samba, due to the CIFS POSIX extensions,
+         CIFS mounts can provide slightly better POSIX compatibility
+         than SMB3 mounts do though). Note that SMB2/SMB3 mount
+         options are also slightly simpler (compared to CIFS) due
+         to protocol improvements.
 
 config CIFS_FSCACHE
          bool "Provide CIFS client caching support"
index dfc731b..25b8392 100644 (file)
 #define SERVER_NAME_LENGTH 40
 #define SERVER_NAME_LEN_WITH_NULL     (SERVER_NAME_LENGTH + 1)
 
-/* used to define string lengths for reversing unicode strings */
-/*         (256+1)*2 = 514                                     */
-/*           (max path length + 1 for null) * 2 for unicode    */
-#define MAX_NAME 514
-
 /* SMB echo "timeout" -- FIXME: tunable? */
 #define SMB_ECHO_INTERVAL (60 * HZ)
 
index 03ed8a0..8a9fded 100644 (file)
@@ -837,7 +837,6 @@ cifs_demultiplex_thread(void *p)
        struct TCP_Server_Info *server = p;
        unsigned int pdu_length;
        char *buf = NULL;
-       struct task_struct *task_to_wake = NULL;
        struct mid_q_entry *mid_entry;
 
        current->flags |= PF_MEMALLOC;
@@ -928,19 +927,7 @@ cifs_demultiplex_thread(void *p)
        if (server->smallbuf) /* no sense logging a debug message if NULL */
                cifs_small_buf_release(server->smallbuf);
 
-       task_to_wake = xchg(&server->tsk, NULL);
        clean_demultiplex_info(server);
-
-       /* if server->tsk was NULL then wait for a signal before exiting */
-       if (!task_to_wake) {
-               set_current_state(TASK_INTERRUPTIBLE);
-               while (!signal_pending(current)) {
-                       schedule();
-                       set_current_state(TASK_INTERRUPTIBLE);
-               }
-               set_current_state(TASK_RUNNING);
-       }
-
        module_put_and_exit(0);
 }
 
@@ -1600,6 +1587,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                        tmp_end++;
                        if (!(tmp_end < end && tmp_end[1] == delim)) {
                                /* No it is not. Set the password to NULL */
+                               kfree(vol->password);
                                vol->password = NULL;
                                break;
                        }
@@ -1637,6 +1625,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
                                        options = end;
                        }
 
+                       kfree(vol->password);
                        /* Now build new password string */
                        temp_len = strlen(value);
                        vol->password = kzalloc(temp_len+1, GFP_KERNEL);
@@ -2061,8 +2050,6 @@ cifs_find_tcp_session(struct smb_vol *vol)
 static void
 cifs_put_tcp_session(struct TCP_Server_Info *server)
 {
-       struct task_struct *task;
-
        spin_lock(&cifs_tcp_ses_lock);
        if (--server->srv_count > 0) {
                spin_unlock(&cifs_tcp_ses_lock);
@@ -2086,10 +2073,6 @@ cifs_put_tcp_session(struct TCP_Server_Info *server)
        kfree(server->session_key.response);
        server->session_key.response = NULL;
        server->session_key.len = 0;
-
-       task = xchg(&server->tsk, NULL);
-       if (task)
-               force_sig(SIGKILL, task);
 }
 
 static struct TCP_Server_Info *
index 3db0c5f..6cbd9c6 100644 (file)
@@ -497,6 +497,14 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
                goto out;
        }
 
+       if (file->f_flags & O_DIRECT &&
+           CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
+               if (CIFS_SB(inode->i_sb)->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                       file->f_op = &cifs_file_direct_nobrl_ops;
+               else
+                       file->f_op = &cifs_file_direct_ops;
+               }
+
        file_info = cifs_new_fileinfo(&fid, file, tlink, oplock);
        if (file_info == NULL) {
                if (server->ops->close)
index d5fec92..7c018a1 100644 (file)
@@ -467,6 +467,14 @@ int cifs_open(struct inode *inode, struct file *file)
        cifs_dbg(FYI, "inode = 0x%p file flags are 0x%x for %s\n",
                 inode, file->f_flags, full_path);
 
+       if (file->f_flags & O_DIRECT &&
+           cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO) {
+               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
+                       file->f_op = &cifs_file_direct_nobrl_ops;
+               else
+                       file->f_op = &cifs_file_direct_ops;
+       }
+
        if (server->oplocks)
                oplock = REQ_OPLOCK;
        else
index 949ec90..7899a40 100644 (file)
@@ -1720,7 +1720,10 @@ cifs_rename2(struct inode *source_dir, struct dentry *source_dentry,
 unlink_target:
        /* Try unlinking the target dentry if it's not negative */
        if (target_dentry->d_inode && (rc == -EACCES || rc == -EEXIST)) {
-               tmprc = cifs_unlink(target_dir, target_dentry);
+               if (d_is_dir(target_dentry))
+                       tmprc = cifs_rmdir(target_dir, target_dentry);
+               else
+                       tmprc = cifs_unlink(target_dir, target_dentry);
                if (tmprc)
                        goto cifs_rename_exit;
                rc = cifs_do_rename(xid, source_dentry, from_name,
index 798c80a..b334a89 100644 (file)
@@ -596,8 +596,8 @@ find_cifs_entry(const unsigned int xid, struct cifs_tcon *tcon, loff_t pos,
                if (server->ops->dir_needs_close(cfile)) {
                        cfile->invalidHandle = true;
                        spin_unlock(&cifs_file_list_lock);
-                       if (server->ops->close)
-                               server->ops->close(xid, tcon, &cfile->fid);
+                       if (server->ops->close_dir)
+                               server->ops->close_dir(xid, tcon, &cfile->fid);
                } else
                        spin_unlock(&cifs_file_list_lock);
                if (cfile->srch_inf.ntwrk_buf_start) {
index 39ee326..3a5e833 100644 (file)
@@ -243,10 +243,11 @@ static void decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
        kfree(ses->serverOS);
 
        ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
-       if (ses->serverOS)
+       if (ses->serverOS) {
                strncpy(ses->serverOS, bcc_ptr, len);
-       if (strncmp(ses->serverOS, "OS/2", 4) == 0)
-               cifs_dbg(FYI, "OS/2 server\n");
+               if (strncmp(ses->serverOS, "OS/2", 4) == 0)
+                       cifs_dbg(FYI, "OS/2 server\n");
+       }
 
        bcc_ptr += len + 1;
        bleft -= len + 1;
index 3f17b45..4599294 100644 (file)
@@ -50,7 +50,7 @@ smb2_open_file(const unsigned int xid, struct cifs_open_parms *oparms,
                goto out;
        }
 
-       smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
+       smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
                            GFP_KERNEL);
        if (smb2_data == NULL) {
                rc = -ENOMEM;
index 0150182..899bbc8 100644 (file)
@@ -131,7 +131,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
        *adjust_tz = false;
        *symlink = false;
 
-       smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
+       smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
                            GFP_KERNEL);
        if (smb2_data == NULL)
                return -ENOMEM;
index 5a48aa2..f522193 100644 (file)
@@ -389,7 +389,7 @@ smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
        int rc;
        struct smb2_file_all_info *smb2_data;
 
-       smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
+       smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
                            GFP_KERNEL);
        if (smb2_data == NULL)
                return -ENOMEM;
@@ -1035,7 +1035,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
                if (keep_size == false)
                        return -EOPNOTSUPP;
 
-       /* 
+       /*
         * Must check if file sparse since fallocate -z (zero range) assumes
         * non-sparse allocation
         */
index fa0dd04..74b3a66 100644 (file)
@@ -530,7 +530,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses,
        struct smb2_sess_setup_rsp *rsp = NULL;
        struct kvec iov[2];
        int rc = 0;
-       int resp_buftype;
+       int resp_buftype = CIFS_NO_BUFFER;
        __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
        struct TCP_Server_Info *server = ses->server;
        u16 blob_length = 0;
@@ -1403,8 +1403,7 @@ SMB2_close(const unsigned int xid, struct cifs_tcon *tcon,
        rsp = (struct smb2_close_rsp *)iov[0].iov_base;
 
        if (rc != 0) {
-               if (tcon)
-                       cifs_stats_fail_inc(tcon, SMB2_CLOSE_HE);
+               cifs_stats_fail_inc(tcon, SMB2_CLOSE_HE);
                goto close_exit;
        }
 
@@ -1533,7 +1532,7 @@ SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon,
 {
        return query_info(xid, tcon, persistent_fid, volatile_fid,
                          FILE_ALL_INFORMATION,
-                         sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
+                         sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
                          sizeof(struct smb2_file_all_info), data);
 }
 
index b10b48c..7bcfff9 100644 (file)
@@ -1852,7 +1852,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
                goto error_tgt_fput;
 
        /* Check if EPOLLWAKEUP is allowed */
-       ep_take_care_of_epollwakeup(&epds);
+       if (ep_op_has_event(op))
+               ep_take_care_of_epollwakeup(&epds);
 
        /*
         * We have to check that the file structure underneath the file descriptor
index 90a3cdc..603e4eb 100644 (file)
@@ -3240,6 +3240,7 @@ static int ext4_rename(struct inode *old_dir, struct dentry *old_dentry,
                                 &new.de, &new.inlined);
        if (IS_ERR(new.bh)) {
                retval = PTR_ERR(new.bh);
+               new.bh = NULL;
                goto end_rename;
        }
        if (new.bh) {
@@ -3386,6 +3387,7 @@ static int ext4_cross_rename(struct inode *old_dir, struct dentry *old_dentry,
                                 &new.de, &new.inlined);
        if (IS_ERR(new.bh)) {
                retval = PTR_ERR(new.bh);
+               new.bh = NULL;
                goto end_rename;
        }
 
index bb0e80f..1e43b90 100644 (file)
@@ -575,6 +575,7 @@ handle_bb:
                bh = bclean(handle, sb, block);
                if (IS_ERR(bh)) {
                        err = PTR_ERR(bh);
+                       bh = NULL;
                        goto out;
                }
                overhead = ext4_group_overhead_blocks(sb, group);
@@ -603,6 +604,7 @@ handle_ib:
                bh = bclean(handle, sb, block);
                if (IS_ERR(bh)) {
                        err = PTR_ERR(bh);
+                       bh = NULL;
                        goto out;
                }
 
index 8f27c93..ec9e082 100644 (file)
@@ -253,13 +253,11 @@ static int lockd_up_net(struct svc_serv *serv, struct net *net)
 
        error = make_socks(serv, net);
        if (error < 0)
-               goto err_socks;
+               goto err_bind;
        set_grace_period(net);
        dprintk("lockd_up_net: per-net data created; net=%p\n", net);
        return 0;
 
-err_socks:
-       svc_rpcb_cleanup(serv, net);
 err_bind:
        ln->nlmsvc_users--;
        return error;
index f9821ce..e94457c 100644 (file)
@@ -2657,6 +2657,7 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
        struct xdr_stream *xdr = cd->xdr;
        int start_offset = xdr->buf->len;
        int cookie_offset;
+       u32 name_and_cookie;
        int entry_bytes;
        __be32 nfserr = nfserr_toosmall;
        __be64 wire_offset;
@@ -2718,7 +2719,14 @@ nfsd4_encode_dirent(void *ccdv, const char *name, int namlen,
        cd->rd_maxcount -= entry_bytes;
        if (!cd->rd_dircount)
                goto fail;
-       cd->rd_dircount--;
+       /*
+        * RFC 3530 14.2.24 describes rd_dircount as only a "hint", so
+        * let's always let through the first entry, at least:
+        */
+       name_and_cookie = 4 * XDR_QUADLEN(namlen) + 8;
+       if (name_and_cookie > cd->rd_dircount && cd->cookie_offset)
+               goto fail;
+       cd->rd_dircount -= min(cd->rd_dircount, name_and_cookie);
        cd->cookie_offset = cookie_offset;
 skip_entry:
        cd->common.err = nfs_ok;
@@ -3321,6 +3329,10 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
        }
        maxcount = min_t(int, maxcount-16, bytes_left);
 
+       /* RFC 3530 14.2.24 allows us to ignore dircount when it's 0: */
+       if (!readdir->rd_dircount)
+               readdir->rd_dircount = INT_MAX;
+
        readdir->xdr = xdr;
        readdir->rd_maxcount = maxcount;
        readdir->common.err = 0;
index 238a593..9d7e2b9 100644 (file)
@@ -42,7 +42,7 @@ static int show_mark_fhandle(struct seq_file *m, struct inode *inode)
 {
        struct {
                struct file_handle handle;
-               u8 pad[64];
+               u8 pad[MAX_HANDLE_SZ];
        } f;
        int size, ret, i;
 
@@ -50,7 +50,7 @@ static int show_mark_fhandle(struct seq_file *m, struct inode *inode)
        size = f.handle.handle_bytes >> 2;
 
        ret = exportfs_encode_inode_fh(inode, (struct fid *)f.handle.f_handle, &size, 0);
-       if ((ret == 255) || (ret == -ENOSPC)) {
+       if ((ret == FILEID_INVALID) || (ret < 0)) {
                WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret);
                return 0;
        }
index 6eaf5ed..e77db62 100644 (file)
@@ -45,7 +45,7 @@ void udf_free_inode(struct inode *inode)
        udf_free_blocks(sb, NULL, &UDF_I(inode)->i_location, 0, 1);
 }
 
-struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err)
+struct inode *udf_new_inode(struct inode *dir, umode_t mode)
 {
        struct super_block *sb = dir->i_sb;
        struct udf_sb_info *sbi = UDF_SB(sb);
@@ -55,14 +55,12 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err)
        struct udf_inode_info *iinfo;
        struct udf_inode_info *dinfo = UDF_I(dir);
        struct logicalVolIntegrityDescImpUse *lvidiu;
+       int err;
 
        inode = new_inode(sb);
 
-       if (!inode) {
-               *err = -ENOMEM;
-               return NULL;
-       }
-       *err = -ENOSPC;
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
 
        iinfo = UDF_I(inode);
        if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_EXTENDED_FE)) {
@@ -80,21 +78,22 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err)
        }
        if (!iinfo->i_ext.i_data) {
                iput(inode);
-               *err = -ENOMEM;
-               return NULL;
+               return ERR_PTR(-ENOMEM);
        }
 
+       err = -ENOSPC;
        block = udf_new_block(dir->i_sb, NULL,
                              dinfo->i_location.partitionReferenceNum,
-                             start, err);
-       if (*err) {
+                             start, &err);
+       if (err) {
                iput(inode);
-               return NULL;
+               return ERR_PTR(err);
        }
 
        lvidiu = udf_sb_lvidiu(sb);
        if (lvidiu) {
                iinfo->i_unique = lvid_get_unique_id(sb);
+               inode->i_generation = iinfo->i_unique;
                mutex_lock(&sbi->s_alloc_mutex);
                if (S_ISDIR(mode))
                        le32_add_cpu(&lvidiu->numDirs, 1);
@@ -123,9 +122,12 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err)
                iinfo->i_alloc_type = ICBTAG_FLAG_AD_LONG;
        inode->i_mtime = inode->i_atime = inode->i_ctime =
                iinfo->i_crtime = current_fs_time(inode->i_sb);
-       insert_inode_hash(inode);
+       if (unlikely(insert_inode_locked(inode) < 0)) {
+               make_bad_inode(inode);
+               iput(inode);
+               return ERR_PTR(-EIO);
+       }
        mark_inode_dirty(inode);
 
-       *err = 0;
        return inode;
 }
index 236cd48..0859884 100644 (file)
@@ -51,7 +51,6 @@ MODULE_LICENSE("GPL");
 
 static umode_t udf_convert_permissions(struct fileEntry *);
 static int udf_update_inode(struct inode *, int);
-static void udf_fill_inode(struct inode *, struct buffer_head *);
 static int udf_sync_inode(struct inode *inode);
 static int udf_alloc_i_data(struct inode *inode, size_t size);
 static sector_t inode_getblk(struct inode *, sector_t, int *, int *);
@@ -1271,12 +1270,33 @@ update_time:
        return 0;
 }
 
-static void __udf_read_inode(struct inode *inode)
+/*
+ * Maximum length of linked list formed by ICB hierarchy. The chosen number is
+ * arbitrary - just that we hopefully don't limit any real use of rewritten
+ * inode on write-once media but avoid looping for too long on corrupted media.
+ */
+#define UDF_MAX_ICB_NESTING 1024
+
+static int udf_read_inode(struct inode *inode)
 {
        struct buffer_head *bh = NULL;
        struct fileEntry *fe;
+       struct extendedFileEntry *efe;
        uint16_t ident;
        struct udf_inode_info *iinfo = UDF_I(inode);
+       struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
+       struct kernel_lb_addr *iloc = &iinfo->i_location;
+       unsigned int link_count;
+       unsigned int indirections = 0;
+       int ret = -EIO;
+
+reread:
+       if (iloc->logicalBlockNum >=
+           sbi->s_partmaps[iloc->partitionReferenceNum].s_partition_len) {
+               udf_debug("block=%d, partition=%d out of range\n",
+                         iloc->logicalBlockNum, iloc->partitionReferenceNum);
+               return -EIO;
+       }
 
        /*
         * Set defaults, but the inode is still incomplete!
@@ -1290,78 +1310,54 @@ static void __udf_read_inode(struct inode *inode)
         *      i_nlink = 1
         *      i_op = NULL;
         */
-       bh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 0, &ident);
+       bh = udf_read_ptagged(inode->i_sb, iloc, 0, &ident);
        if (!bh) {
                udf_err(inode->i_sb, "(ino %ld) failed !bh\n", inode->i_ino);
-               make_bad_inode(inode);
-               return;
+               return -EIO;
        }
 
        if (ident != TAG_IDENT_FE && ident != TAG_IDENT_EFE &&
            ident != TAG_IDENT_USE) {
                udf_err(inode->i_sb, "(ino %ld) failed ident=%d\n",
                        inode->i_ino, ident);
-               brelse(bh);
-               make_bad_inode(inode);
-               return;
+               goto out;
        }
 
        fe = (struct fileEntry *)bh->b_data;
+       efe = (struct extendedFileEntry *)bh->b_data;
 
        if (fe->icbTag.strategyType == cpu_to_le16(4096)) {
                struct buffer_head *ibh;
 
-               ibh = udf_read_ptagged(inode->i_sb, &iinfo->i_location, 1,
-                                       &ident);
+               ibh = udf_read_ptagged(inode->i_sb, iloc, 1, &ident);
                if (ident == TAG_IDENT_IE && ibh) {
-                       struct buffer_head *nbh = NULL;
                        struct kernel_lb_addr loc;
                        struct indirectEntry *ie;
 
                        ie = (struct indirectEntry *)ibh->b_data;
                        loc = lelb_to_cpu(ie->indirectICB.extLocation);
 
-                       if (ie->indirectICB.extLength &&
-                               (nbh = udf_read_ptagged(inode->i_sb, &loc, 0,
-                                                       &ident))) {
-                               if (ident == TAG_IDENT_FE ||
-                                       ident == TAG_IDENT_EFE) {
-                                       memcpy(&iinfo->i_location,
-                                               &loc,
-                                               sizeof(struct kernel_lb_addr));
-                                       brelse(bh);
-                                       brelse(ibh);
-                                       brelse(nbh);
-                                       __udf_read_inode(inode);
-                                       return;
+                       if (ie->indirectICB.extLength) {
+                               brelse(ibh);
+                               memcpy(&iinfo->i_location, &loc,
+                                      sizeof(struct kernel_lb_addr));
+                               if (++indirections > UDF_MAX_ICB_NESTING) {
+                                       udf_err(inode->i_sb,
+                                               "too many ICBs in ICB hierarchy"
+                                               " (max %d supported)\n",
+                                               UDF_MAX_ICB_NESTING);
+                                       goto out;
                                }
-                               brelse(nbh);
+                               brelse(bh);
+                               goto reread;
                        }
                }
                brelse(ibh);
        } else if (fe->icbTag.strategyType != cpu_to_le16(4)) {
                udf_err(inode->i_sb, "unsupported strategy type: %d\n",
                        le16_to_cpu(fe->icbTag.strategyType));
-               brelse(bh);
-               make_bad_inode(inode);
-               return;
+               goto out;
        }
-       udf_fill_inode(inode, bh);
-
-       brelse(bh);
-}
-
-static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
-{
-       struct fileEntry *fe;
-       struct extendedFileEntry *efe;
-       struct udf_sb_info *sbi = UDF_SB(inode->i_sb);
-       struct udf_inode_info *iinfo = UDF_I(inode);
-       unsigned int link_count;
-
-       fe = (struct fileEntry *)bh->b_data;
-       efe = (struct extendedFileEntry *)bh->b_data;
-
        if (fe->icbTag.strategyType == cpu_to_le16(4))
                iinfo->i_strat4096 = 0;
        else /* if (fe->icbTag.strategyType == cpu_to_le16(4096)) */
@@ -1378,11 +1374,10 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
        if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_EFE)) {
                iinfo->i_efe = 1;
                iinfo->i_use = 0;
-               if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
-                                       sizeof(struct extendedFileEntry))) {
-                       make_bad_inode(inode);
-                       return;
-               }
+               ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
+                                       sizeof(struct extendedFileEntry));
+               if (ret)
+                       goto out;
                memcpy(iinfo->i_ext.i_data,
                       bh->b_data + sizeof(struct extendedFileEntry),
                       inode->i_sb->s_blocksize -
@@ -1390,11 +1385,10 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
        } else if (fe->descTag.tagIdent == cpu_to_le16(TAG_IDENT_FE)) {
                iinfo->i_efe = 0;
                iinfo->i_use = 0;
-               if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
-                                               sizeof(struct fileEntry))) {
-                       make_bad_inode(inode);
-                       return;
-               }
+               ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
+                                               sizeof(struct fileEntry));
+               if (ret)
+                       goto out;
                memcpy(iinfo->i_ext.i_data,
                       bh->b_data + sizeof(struct fileEntry),
                       inode->i_sb->s_blocksize - sizeof(struct fileEntry));
@@ -1404,18 +1398,18 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                iinfo->i_lenAlloc = le32_to_cpu(
                                ((struct unallocSpaceEntry *)bh->b_data)->
                                 lengthAllocDescs);
-               if (udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
-                                       sizeof(struct unallocSpaceEntry))) {
-                       make_bad_inode(inode);
-                       return;
-               }
+               ret = udf_alloc_i_data(inode, inode->i_sb->s_blocksize -
+                                       sizeof(struct unallocSpaceEntry));
+               if (ret)
+                       goto out;
                memcpy(iinfo->i_ext.i_data,
                       bh->b_data + sizeof(struct unallocSpaceEntry),
                       inode->i_sb->s_blocksize -
                                        sizeof(struct unallocSpaceEntry));
-               return;
+               return 0;
        }
 
+       ret = -EIO;
        read_lock(&sbi->s_cred_lock);
        i_uid_write(inode, le32_to_cpu(fe->uid));
        if (!uid_valid(inode->i_uid) ||
@@ -1441,8 +1435,10 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
        read_unlock(&sbi->s_cred_lock);
 
        link_count = le16_to_cpu(fe->fileLinkCount);
-       if (!link_count)
-               link_count = 1;
+       if (!link_count) {
+               ret = -ESTALE;
+               goto out;
+       }
        set_nlink(inode, link_count);
 
        inode->i_size = le64_to_cpu(fe->informationLength);
@@ -1488,6 +1484,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs);
                iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint);
        }
+       inode->i_generation = iinfo->i_unique;
 
        switch (fe->icbTag.fileType) {
        case ICBTAG_FILE_TYPE_DIRECTORY:
@@ -1537,8 +1534,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
        default:
                udf_err(inode->i_sb, "(ino %ld) failed unknown file type=%d\n",
                        inode->i_ino, fe->icbTag.fileType);
-               make_bad_inode(inode);
-               return;
+               goto out;
        }
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
                struct deviceSpec *dsea =
@@ -1549,8 +1545,12 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh)
                                      le32_to_cpu(dsea->minorDeviceIdent)));
                        /* Developer ID ??? */
                } else
-                       make_bad_inode(inode);
+                       goto out;
        }
+       ret = 0;
+out:
+       brelse(bh);
+       return ret;
 }
 
 static int udf_alloc_i_data(struct inode *inode, size_t size)
@@ -1664,7 +1664,7 @@ static int udf_update_inode(struct inode *inode, int do_sync)
                     FE_PERM_U_DELETE | FE_PERM_U_CHATTR));
        fe->permissions = cpu_to_le32(udfperms);
 
-       if (S_ISDIR(inode->i_mode))
+       if (S_ISDIR(inode->i_mode) && inode->i_nlink > 0)
                fe->fileLinkCount = cpu_to_le16(inode->i_nlink - 1);
        else
                fe->fileLinkCount = cpu_to_le16(inode->i_nlink);
@@ -1830,32 +1830,23 @@ struct inode *udf_iget(struct super_block *sb, struct kernel_lb_addr *ino)
 {
        unsigned long block = udf_get_lb_pblock(sb, ino, 0);
        struct inode *inode = iget_locked(sb, block);
+       int err;
 
        if (!inode)
-               return NULL;
-
-       if (inode->i_state & I_NEW) {
-               memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
-               __udf_read_inode(inode);
-               unlock_new_inode(inode);
-       }
+               return ERR_PTR(-ENOMEM);
 
-       if (is_bad_inode(inode))
-               goto out_iput;
+       if (!(inode->i_state & I_NEW))
+               return inode;
 
-       if (ino->logicalBlockNum >= UDF_SB(sb)->
-                       s_partmaps[ino->partitionReferenceNum].s_partition_len) {
-               udf_debug("block=%d, partition=%d out of range\n",
-                         ino->logicalBlockNum, ino->partitionReferenceNum);
-               make_bad_inode(inode);
-               goto out_iput;
+       memcpy(&UDF_I(inode)->i_location, ino, sizeof(struct kernel_lb_addr));
+       err = udf_read_inode(inode);
+       if (err < 0) {
+               iget_failed(inode);
+               return ERR_PTR(err);
        }
+       unlock_new_inode(inode);
 
        return inode;
-
- out_iput:
-       iput(inode);
-       return NULL;
 }
 
 int udf_add_aext(struct inode *inode, struct extent_position *epos,
index 83a0600..c12e260 100644 (file)
@@ -270,9 +270,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
                                                NULL, 0),
                };
                inode = udf_iget(dir->i_sb, lb);
-               if (!inode) {
-                       return ERR_PTR(-EACCES);
-               }
+               if (IS_ERR(inode))
+                       return inode;
        } else
 #endif /* UDF_RECOVERY */
 
@@ -285,9 +284,8 @@ static struct dentry *udf_lookup(struct inode *dir, struct dentry *dentry,
 
                loc = lelb_to_cpu(cfi.icb.extLocation);
                inode = udf_iget(dir->i_sb, &loc);
-               if (!inode) {
-                       return ERR_PTR(-EACCES);
-               }
+               if (IS_ERR(inode))
+                       return ERR_CAST(inode);
        }
 
        return d_splice_alias(inode, dentry);
@@ -550,32 +548,18 @@ static int udf_delete_entry(struct inode *inode, struct fileIdentDesc *fi,
        return udf_write_fi(inode, cfi, fi, fibh, NULL, NULL);
 }
 
-static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode,
-                     bool excl)
+static int udf_add_nondir(struct dentry *dentry, struct inode *inode)
 {
+       struct udf_inode_info *iinfo = UDF_I(inode);
+       struct inode *dir = dentry->d_parent->d_inode;
        struct udf_fileident_bh fibh;
-       struct inode *inode;
        struct fileIdentDesc cfi, *fi;
        int err;
-       struct udf_inode_info *iinfo;
-
-       inode = udf_new_inode(dir, mode, &err);
-       if (!inode) {
-               return err;
-       }
-
-       iinfo = UDF_I(inode);
-       if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
-               inode->i_data.a_ops = &udf_adinicb_aops;
-       else
-               inode->i_data.a_ops = &udf_aops;
-       inode->i_op = &udf_file_inode_operations;
-       inode->i_fop = &udf_file_operations;
-       mark_inode_dirty(inode);
 
        fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
-       if (!fi) {
+       if (unlikely(!fi)) {
                inode_dec_link_count(inode);
+               unlock_new_inode(inode);
                iput(inode);
                return err;
        }
@@ -589,23 +573,21 @@ static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode,
        if (fibh.sbh != fibh.ebh)
                brelse(fibh.ebh);
        brelse(fibh.sbh);
+       unlock_new_inode(inode);
        d_instantiate(dentry, inode);
 
        return 0;
 }
 
-static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+static int udf_create(struct inode *dir, struct dentry *dentry, umode_t mode,
+                     bool excl)
 {
-       struct inode *inode;
-       struct udf_inode_info *iinfo;
-       int err;
+       struct inode *inode = udf_new_inode(dir, mode);
 
-       inode = udf_new_inode(dir, mode, &err);
-       if (!inode)
-               return err;
+       if (IS_ERR(inode))
+               return PTR_ERR(inode);
 
-       iinfo = UDF_I(inode);
-       if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
+       if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
                inode->i_data.a_ops = &udf_adinicb_aops;
        else
                inode->i_data.a_ops = &udf_aops;
@@ -613,7 +595,25 @@ static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
        inode->i_fop = &udf_file_operations;
        mark_inode_dirty(inode);
 
+       return udf_add_nondir(dentry, inode);
+}
+
+static int udf_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
+{
+       struct inode *inode = udf_new_inode(dir, mode);
+
+       if (IS_ERR(inode))
+               return PTR_ERR(inode);
+
+       if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
+               inode->i_data.a_ops = &udf_adinicb_aops;
+       else
+               inode->i_data.a_ops = &udf_aops;
+       inode->i_op = &udf_file_inode_operations;
+       inode->i_fop = &udf_file_operations;
+       mark_inode_dirty(inode);
        d_tmpfile(dentry, inode);
+       unlock_new_inode(inode);
        return 0;
 }
 
@@ -621,44 +621,16 @@ static int udf_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
                     dev_t rdev)
 {
        struct inode *inode;
-       struct udf_fileident_bh fibh;
-       struct fileIdentDesc cfi, *fi;
-       int err;
-       struct udf_inode_info *iinfo;
 
        if (!old_valid_dev(rdev))
                return -EINVAL;
 
-       err = -EIO;
-       inode = udf_new_inode(dir, mode, &err);
-       if (!inode)
-               goto out;
+       inode = udf_new_inode(dir, mode);
+       if (IS_ERR(inode))
+               return PTR_ERR(inode);
 
-       iinfo = UDF_I(inode);
        init_special_inode(inode, mode, rdev);
-       fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
-       if (!fi) {
-               inode_dec_link_count(inode);
-               iput(inode);
-               return err;
-       }
-       cfi.icb.extLength = cpu_to_le32(inode->i_sb->s_blocksize);
-       cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
-       *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
-               cpu_to_le32(iinfo->i_unique & 0x00000000FFFFFFFFUL);
-       udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
-       if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
-               mark_inode_dirty(dir);
-       mark_inode_dirty(inode);
-
-       if (fibh.sbh != fibh.ebh)
-               brelse(fibh.ebh);
-       brelse(fibh.sbh);
-       d_instantiate(dentry, inode);
-       err = 0;
-
-out:
-       return err;
+       return udf_add_nondir(dentry, inode);
 }
 
 static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
@@ -670,10 +642,9 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        struct udf_inode_info *dinfo = UDF_I(dir);
        struct udf_inode_info *iinfo;
 
-       err = -EIO;
-       inode = udf_new_inode(dir, S_IFDIR | mode, &err);
-       if (!inode)
-               goto out;
+       inode = udf_new_inode(dir, S_IFDIR | mode);
+       if (IS_ERR(inode))
+               return PTR_ERR(inode);
 
        iinfo = UDF_I(inode);
        inode->i_op = &udf_dir_inode_operations;
@@ -681,6 +652,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        fi = udf_add_entry(inode, NULL, &fibh, &cfi, &err);
        if (!fi) {
                inode_dec_link_count(inode);
+               unlock_new_inode(inode);
                iput(inode);
                goto out;
        }
@@ -699,6 +671,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        if (!fi) {
                clear_nlink(inode);
                mark_inode_dirty(inode);
+               unlock_new_inode(inode);
                iput(inode);
                goto out;
        }
@@ -710,6 +683,7 @@ static int udf_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
        udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
        inc_nlink(dir);
        mark_inode_dirty(dir);
+       unlock_new_inode(inode);
        d_instantiate(dentry, inode);
        if (fibh.sbh != fibh.ebh)
                brelse(fibh.ebh);
@@ -876,14 +850,11 @@ out:
 static int udf_symlink(struct inode *dir, struct dentry *dentry,
                       const char *symname)
 {
-       struct inode *inode;
+       struct inode *inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO);
        struct pathComponent *pc;
        const char *compstart;
-       struct udf_fileident_bh fibh;
        struct extent_position epos = {};
        int eoffset, elen = 0;
-       struct fileIdentDesc *fi;
-       struct fileIdentDesc cfi;
        uint8_t *ea;
        int err;
        int block;
@@ -892,9 +863,8 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
        struct udf_inode_info *iinfo;
        struct super_block *sb = dir->i_sb;
 
-       inode = udf_new_inode(dir, S_IFLNK | S_IRWXUGO, &err);
-       if (!inode)
-               goto out;
+       if (IS_ERR(inode))
+               return PTR_ERR(inode);
 
        iinfo = UDF_I(inode);
        down_write(&iinfo->i_data_sem);
@@ -1012,32 +982,15 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
        mark_inode_dirty(inode);
        up_write(&iinfo->i_data_sem);
 
-       fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
-       if (!fi)
-               goto out_fail;
-       cfi.icb.extLength = cpu_to_le32(sb->s_blocksize);
-       cfi.icb.extLocation = cpu_to_lelb(iinfo->i_location);
-       if (UDF_SB(inode->i_sb)->s_lvid_bh) {
-               *(__le32 *)((struct allocDescImpUse *)cfi.icb.impUse)->impUse =
-                       cpu_to_le32(lvid_get_unique_id(sb));
-       }
-       udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
-       if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
-               mark_inode_dirty(dir);
-       if (fibh.sbh != fibh.ebh)
-               brelse(fibh.ebh);
-       brelse(fibh.sbh);
-       d_instantiate(dentry, inode);
-       err = 0;
-
+       err = udf_add_nondir(dentry, inode);
 out:
        kfree(name);
        return err;
 
 out_no_entry:
        up_write(&iinfo->i_data_sem);
-out_fail:
        inode_dec_link_count(inode);
+       unlock_new_inode(inode);
        iput(inode);
        goto out;
 }
@@ -1222,7 +1175,7 @@ static struct dentry *udf_get_parent(struct dentry *child)
        struct udf_fileident_bh fibh;
 
        if (!udf_find_entry(child->d_inode, &dotdot, &fibh, &cfi))
-               goto out_unlock;
+               return ERR_PTR(-EACCES);
 
        if (fibh.sbh != fibh.ebh)
                brelse(fibh.ebh);
@@ -1230,12 +1183,10 @@ static struct dentry *udf_get_parent(struct dentry *child)
 
        tloc = lelb_to_cpu(cfi.icb.extLocation);
        inode = udf_iget(child->d_inode->i_sb, &tloc);
-       if (!inode)
-               goto out_unlock;
+       if (IS_ERR(inode))
+               return ERR_CAST(inode);
 
        return d_obtain_alias(inode);
-out_unlock:
-       return ERR_PTR(-EACCES);
 }
 
 
@@ -1252,8 +1203,8 @@ static struct dentry *udf_nfs_get_inode(struct super_block *sb, u32 block,
        loc.partitionReferenceNum = partref;
        inode = udf_iget(sb, &loc);
 
-       if (inode == NULL)
-               return ERR_PTR(-ENOMEM);
+       if (IS_ERR(inode))
+               return ERR_CAST(inode);
 
        if (generation && inode->i_generation != generation) {
                iput(inode);
index 813da94..5401fc3 100644 (file)
@@ -961,12 +961,14 @@ struct inode *udf_find_metadata_inode_efe(struct super_block *sb,
 
        metadata_fe = udf_iget(sb, &addr);
 
-       if (metadata_fe == NULL)
+       if (IS_ERR(metadata_fe)) {
                udf_warn(sb, "metadata inode efe not found\n");
-       else if (UDF_I(metadata_fe)->i_alloc_type != ICBTAG_FLAG_AD_SHORT) {
+               return metadata_fe;
+       }
+       if (UDF_I(metadata_fe)->i_alloc_type != ICBTAG_FLAG_AD_SHORT) {
                udf_warn(sb, "metadata inode efe does not have short allocation descriptors!\n");
                iput(metadata_fe);
-               metadata_fe = NULL;
+               return ERR_PTR(-EIO);
        }
 
        return metadata_fe;
@@ -978,6 +980,7 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
        struct udf_part_map *map;
        struct udf_meta_data *mdata;
        struct kernel_lb_addr addr;
+       struct inode *fe;
 
        map = &sbi->s_partmaps[partition];
        mdata = &map->s_type_specific.s_metadata;
@@ -986,22 +989,24 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
        udf_debug("Metadata file location: block = %d part = %d\n",
                  mdata->s_meta_file_loc, map->s_partition_num);
 
-       mdata->s_metadata_fe = udf_find_metadata_inode_efe(sb,
-               mdata->s_meta_file_loc, map->s_partition_num);
-
-       if (mdata->s_metadata_fe == NULL) {
+       fe = udf_find_metadata_inode_efe(sb, mdata->s_meta_file_loc,
+                                        map->s_partition_num);
+       if (IS_ERR(fe)) {
                /* mirror file entry */
                udf_debug("Mirror metadata file location: block = %d part = %d\n",
                          mdata->s_mirror_file_loc, map->s_partition_num);
 
-               mdata->s_mirror_fe = udf_find_metadata_inode_efe(sb,
-                       mdata->s_mirror_file_loc, map->s_partition_num);
+               fe = udf_find_metadata_inode_efe(sb, mdata->s_mirror_file_loc,
+                                                map->s_partition_num);
 
-               if (mdata->s_mirror_fe == NULL) {
+               if (IS_ERR(fe)) {
                        udf_err(sb, "Both metadata and mirror metadata inode efe can not found\n");
-                       return -EIO;
+                       return PTR_ERR(fe);
                }
-       }
+               mdata->s_mirror_fe = fe;
+       } else
+               mdata->s_metadata_fe = fe;
+
 
        /*
         * bitmap file entry
@@ -1015,15 +1020,16 @@ static int udf_load_metadata_files(struct super_block *sb, int partition)
                udf_debug("Bitmap file location: block = %d part = %d\n",
                          addr.logicalBlockNum, addr.partitionReferenceNum);
 
-               mdata->s_bitmap_fe = udf_iget(sb, &addr);
-               if (mdata->s_bitmap_fe == NULL) {
+               fe = udf_iget(sb, &addr);
+               if (IS_ERR(fe)) {
                        if (sb->s_flags & MS_RDONLY)
                                udf_warn(sb, "bitmap inode efe not found but it's ok since the disc is mounted read-only\n");
                        else {
                                udf_err(sb, "bitmap inode efe not found and attempted read-write mount\n");
-                               return -EIO;
+                               return PTR_ERR(fe);
                        }
-               }
+               } else
+                       mdata->s_bitmap_fe = fe;
        }
 
        udf_debug("udf_load_metadata_files Ok\n");
@@ -1111,13 +1117,15 @@ static int udf_fill_partdesc_info(struct super_block *sb,
                                phd->unallocSpaceTable.extPosition),
                        .partitionReferenceNum = p_index,
                };
+               struct inode *inode;
 
-               map->s_uspace.s_table = udf_iget(sb, &loc);
-               if (!map->s_uspace.s_table) {
+               inode = udf_iget(sb, &loc);
+               if (IS_ERR(inode)) {
                        udf_debug("cannot load unallocSpaceTable (part %d)\n",
                                  p_index);
-                       return -EIO;
+                       return PTR_ERR(inode);
                }
+               map->s_uspace.s_table = inode;
                map->s_partition_flags |= UDF_PART_FLAG_UNALLOC_TABLE;
                udf_debug("unallocSpaceTable (part %d) @ %ld\n",
                          p_index, map->s_uspace.s_table->i_ino);
@@ -1144,14 +1152,15 @@ static int udf_fill_partdesc_info(struct super_block *sb,
                                phd->freedSpaceTable.extPosition),
                        .partitionReferenceNum = p_index,
                };
+               struct inode *inode;
 
-               map->s_fspace.s_table = udf_iget(sb, &loc);
-               if (!map->s_fspace.s_table) {
+               inode = udf_iget(sb, &loc);
+               if (IS_ERR(inode)) {
                        udf_debug("cannot load freedSpaceTable (part %d)\n",
                                  p_index);
-                       return -EIO;
+                       return PTR_ERR(inode);
                }
-
+               map->s_fspace.s_table = inode;
                map->s_partition_flags |= UDF_PART_FLAG_FREED_TABLE;
                udf_debug("freedSpaceTable (part %d) @ %ld\n",
                          p_index, map->s_fspace.s_table->i_ino);
@@ -1178,6 +1187,7 @@ static void udf_find_vat_block(struct super_block *sb, int p_index,
        struct udf_part_map *map = &sbi->s_partmaps[p_index];
        sector_t vat_block;
        struct kernel_lb_addr ino;
+       struct inode *inode;
 
        /*
         * VAT file entry is in the last recorded block. Some broken disks have
@@ -1186,10 +1196,13 @@ static void udf_find_vat_block(struct super_block *sb, int p_index,
        ino.partitionReferenceNum = type1_index;
        for (vat_block = start_block;
             vat_block >= map->s_partition_root &&
-            vat_block >= start_block - 3 &&
-            !sbi->s_vat_inode; vat_block--) {
+            vat_block >= start_block - 3; vat_block--) {
                ino.logicalBlockNum = vat_block - map->s_partition_root;
-               sbi->s_vat_inode = udf_iget(sb, &ino);
+               inode = udf_iget(sb, &ino);
+               if (!IS_ERR(inode)) {
+                       sbi->s_vat_inode = inode;
+                       break;
+               }
        }
 }
 
@@ -2205,10 +2218,10 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
        /* assign inodes by physical block number */
        /* perhaps it's not extensible enough, but for now ... */
        inode = udf_iget(sb, &rootdir);
-       if (!inode) {
+       if (IS_ERR(inode)) {
                udf_err(sb, "Error in udf_iget, block=%d, partition=%d\n",
                       rootdir.logicalBlockNum, rootdir.partitionReferenceNum);
-               ret = -EIO;
+               ret = PTR_ERR(inode);
                goto error_out;
        }
 
index be7dabb..742557b 100644 (file)
@@ -143,7 +143,6 @@ extern int udf_expand_file_adinicb(struct inode *);
 extern struct buffer_head *udf_expand_dir_adinicb(struct inode *, int *, int *);
 extern struct buffer_head *udf_bread(struct inode *, int, int, int *);
 extern int udf_setsize(struct inode *, loff_t);
-extern void udf_read_inode(struct inode *);
 extern void udf_evict_inode(struct inode *);
 extern int udf_write_inode(struct inode *, struct writeback_control *wbc);
 extern long udf_block_map(struct inode *, sector_t);
@@ -209,7 +208,7 @@ extern int udf_CS0toUTF8(struct ustr *, const struct ustr *);
 
 /* ialloc.c */
 extern void udf_free_inode(struct inode *);
-extern struct inode *udf_new_inode(struct inode *, umode_t, int *);
+extern struct inode *udf_new_inode(struct inode *, umode_t);
 
 /* truncate.c */
 extern void udf_truncate_tail_extent(struct inode *);
index 071f6b2..511c6e0 100644 (file)
@@ -1196,6 +1196,9 @@ int mlx4_map_sw_to_hw_steering_id(struct mlx4_dev *dev,
                                  enum mlx4_net_trans_rule_id id);
 int mlx4_hw_rule_sz(struct mlx4_dev *dev, enum mlx4_net_trans_rule_id id);
 
+int mlx4_tunnel_steer_add(struct mlx4_dev *dev, unsigned char *addr,
+                         int port, int qpn, u16 prio, u64 *reg_id);
+
 void mlx4_sync_pkey_table(struct mlx4_dev *dev, int slave, int port,
                          int i, int val);
 
index 3837739..c8e388e 100644 (file)
@@ -3176,7 +3176,7 @@ static inline int __dev_uc_sync(struct net_device *dev,
 }
 
 /**
- *  __dev_uc_unsync - Remove synchonized addresses from device
+ *  __dev_uc_unsync - Remove synchronized addresses from device
  *  @dev:  device to sync
  *  @unsync: function to call if address should be removed
  *
@@ -3220,7 +3220,7 @@ static inline int __dev_mc_sync(struct net_device *dev,
 }
 
 /**
- *  __dev_mc_unsync - Remove synchonized addresses from device
+ *  __dev_mc_unsync - Remove synchronized addresses from device
  *  @dev:  device to sync
  *  @unsync: function to call if address should be removed
  *
index 2077489..2517ece 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/in6.h>
 #include <linux/wait.h>
 #include <linux/list.h>
+#include <linux/static_key.h>
 #include <uapi/linux/netfilter.h>
 #ifdef CONFIG_NETFILTER
 static inline int NF_DROP_GETERR(int verdict)
@@ -99,9 +100,9 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
 
 extern struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
 
-#if defined(CONFIG_JUMP_LABEL)
-#include <linux/static_key.h>
+#ifdef HAVE_JUMP_LABEL
 extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
+
 static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook)
 {
        if (__builtin_constant_p(pf) &&
index b5d5af3..6f884e6 100644 (file)
@@ -464,6 +464,8 @@ struct hci_conn_params {
                HCI_AUTO_CONN_ALWAYS,
                HCI_AUTO_CONN_LINK_LOSS,
        } auto_connect;
+
+       struct hci_conn *conn;
 };
 
 extern struct list_head hci_dev_list;
index e207096..8170f8d 100644 (file)
@@ -16,7 +16,6 @@ struct netns_sysctl_lowpan {
 struct netns_ieee802154_lowpan {
        struct netns_sysctl_lowpan sysctl;
        struct netns_frags      frags;
-       int                     max_dsize;
 };
 
 #endif
index 2599924..dad7ab2 100644 (file)
@@ -167,7 +167,7 @@ struct ieee80211_reg_rule {
 struct ieee80211_regdomain {
        struct rcu_head rcu_head;
        u32 n_reg_rules;
-       char alpha2[2];
+       char alpha2[3];
        enum nl80211_dfs_regions dfs_region;
        struct ieee80211_reg_rule reg_rules[];
 };
index f6e7397..9fbd856 100644 (file)
@@ -320,6 +320,19 @@ static inline sctp_assoc_t sctp_assoc2id(const struct sctp_association *asoc)
        return asoc ? asoc->assoc_id : 0;
 }
 
+static inline enum sctp_sstat_state
+sctp_assoc_to_state(const struct sctp_association *asoc)
+{
+       /* SCTP's uapi always had SCTP_EMPTY(=0) as a dummy state, but we
+        * got rid of it in kernel space. Therefore SCTP_CLOSED et al
+        * start at =1 in user space, but actually as =0 in kernel space.
+        * Now that we can not break user space and SCTP_EMPTY is exposed
+        * there, we need to fix it up with an ugly offset not to break
+        * applications. :(
+        */
+       return asoc->state + 1;
+}
+
 /* Look up the association by its id.  */
 struct sctp_association *sctp_id2assoc(struct sock *sk, sctp_assoc_t id);
 
index 7f2ab72..b9a5bd0 100644 (file)
@@ -2165,9 +2165,7 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)
         */
        if (sock_flag(sk, SOCK_RCVTSTAMP) ||
            (sk->sk_tsflags & SOF_TIMESTAMPING_RX_SOFTWARE) ||
-           (kt.tv64 &&
-            (sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE ||
-             skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP)) ||
+           (kt.tv64 && sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) ||
            (hwtstamps->hwtstamp.tv64 &&
             (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE)))
                __sock_recv_timestamp(msg, sk, skb);
index e52ef53..c52b685 100644 (file)
@@ -290,7 +290,7 @@ struct wimax_dev;
  *     This operation has to be synchronous, and return only when the
  *     reset is complete. In case of having had to resort to bus/cold
  *     reset implying a device disconnection, the call is allowed to
- *     return inmediately.
+ *     return immediately.
  *     NOTE: wimax_dev->mutex is NOT locked when this op is being
  *     called; however, wimax_dev->mutex_reset IS locked to ensure
  *     serialization of calls to wimax_reset().
index 1c09820..3608beb 100644 (file)
@@ -107,7 +107,7 @@ DECLARE_EVENT_CLASS(softirq,
  * @vec_nr:  softirq vector number
  *
  * When used in combination with the softirq_exit tracepoint
- * we can determine the softirq handler runtine.
+ * we can determine the softirq handler routine.
  */
 DEFINE_EVENT(softirq, softirq_entry,
 
@@ -121,7 +121,7 @@ DEFINE_EVENT(softirq, softirq_entry,
  * @vec_nr:  softirq vector number
  *
  * When used in combination with the softirq_entry tracepoint
- * we can determine the softirq handler runtine.
+ * we can determine the softirq handler routine.
  */
 DEFINE_EVENT(softirq, softirq_exit,
 
index 24e9033..939df69 100644 (file)
@@ -240,6 +240,7 @@ header-y += matroxfb.h
 header-y += mdio.h
 header-y += media.h
 header-y += mei.h
+header-y += memfd.h
 header-y += mempolicy.h
 header-y += meye.h
 header-y += mic_common.h
index 19df18c..1874ebe 100644 (file)
@@ -165,6 +165,7 @@ struct input_keymap_entry {
 #define INPUT_PROP_BUTTONPAD           0x02    /* has button(s) under pad */
 #define INPUT_PROP_SEMI_MT             0x03    /* touch rectangle only */
 #define INPUT_PROP_TOPBUTTONPAD                0x04    /* softbuttons at top of pad */
+#define INPUT_PROP_POINTING_STICK      0x05    /* is a pointing stick */
 
 #define INPUT_PROP_MAX                 0x1f
 #define INPUT_PROP_CNT                 (INPUT_PROP_MAX + 1)
index 7dc8788..940aced 100644 (file)
@@ -1035,6 +1035,11 @@ static void cgroup_get(struct cgroup *cgrp)
        css_get(&cgrp->self);
 }
 
+static bool cgroup_tryget(struct cgroup *cgrp)
+{
+       return css_tryget(&cgrp->self);
+}
+
 static void cgroup_put(struct cgroup *cgrp)
 {
        css_put(&cgrp->self);
@@ -1147,7 +1152,8 @@ static struct cgroup *cgroup_kn_lock_live(struct kernfs_node *kn)
         * protection against removal.  Ensure @cgrp stays accessible and
         * break the active_ref protection.
         */
-       cgroup_get(cgrp);
+       if (!cgroup_tryget(cgrp))
+               return NULL;
        kernfs_break_active_protection(kn);
 
        mutex_lock(&cgroup_mutex);
@@ -3271,8 +3277,17 @@ int cgroup_add_legacy_cftypes(struct cgroup_subsys *ss, struct cftype *cfts)
 {
        struct cftype *cft;
 
-       for (cft = cfts; cft && cft->name[0] != '\0'; cft++)
-               cft->flags |= __CFTYPE_NOT_ON_DFL;
+       /*
+        * If legacy_flies_on_dfl, we want to show the legacy files on the
+        * dfl hierarchy but iff the target subsystem hasn't been updated
+        * for the dfl hierarchy yet.
+        */
+       if (!cgroup_legacy_files_on_dfl ||
+           ss->dfl_cftypes != ss->legacy_cftypes) {
+               for (cft = cfts; cft && cft->name[0] != '\0'; cft++)
+                       cft->flags |= __CFTYPE_NOT_ON_DFL;
+       }
+
        return cgroup_add_cftypes(ss, cfts);
 }
 
@@ -4387,6 +4402,15 @@ static void css_release_work_fn(struct work_struct *work)
                /* cgroup release path */
                cgroup_idr_remove(&cgrp->root->cgroup_idr, cgrp->id);
                cgrp->id = -1;
+
+               /*
+                * There are two control paths which try to determine
+                * cgroup from dentry without going through kernfs -
+                * cgroupstats_build() and css_tryget_online_from_dir().
+                * Those are supported by RCU protecting clearing of
+                * cgrp->kn->priv backpointer.
+                */
+               RCU_INIT_POINTER(*(void __rcu __force **)&cgrp->kn->priv, NULL);
        }
 
        mutex_unlock(&cgroup_mutex);
@@ -4543,6 +4567,11 @@ static int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name,
        struct cftype *base_files;
        int ssid, ret;
 
+       /* Do not accept '\n' to prevent making /proc/<pid>/cgroup unparsable.
+        */
+       if (strchr(name, '\n'))
+               return -EINVAL;
+
        parent = cgroup_kn_lock_live(parent_kn);
        if (!parent)
                return -ENODEV;
@@ -4820,16 +4849,6 @@ static int cgroup_rmdir(struct kernfs_node *kn)
 
        cgroup_kn_unlock(kn);
 
-       /*
-        * There are two control paths which try to determine cgroup from
-        * dentry without going through kernfs - cgroupstats_build() and
-        * css_tryget_online_from_dir().  Those are supported by RCU
-        * protecting clearing of cgrp->kn->priv backpointer, which should
-        * happen after all files under it have been removed.
-        */
-       if (!ret)
-               RCU_INIT_POINTER(*(void __rcu __force **)&kn->priv, NULL);
-
        cgroup_put(cgrp);
        return ret;
 }
@@ -5416,7 +5435,7 @@ struct cgroup_subsys_state *css_tryget_online_from_dir(struct dentry *dentry,
        /*
         * This path doesn't originate from kernfs and @kn could already
         * have been or be removed at any point.  @kn->priv is RCU
-        * protected for this access.  See cgroup_rmdir() for details.
+        * protected for this access.  See css_release_work_fn() for details.
         */
        cgrp = rcu_dereference(kn->priv);
        if (cgrp)
index e30ac0f..0aa69ea 100644 (file)
@@ -44,11 +44,12 @@ static long kptr_obfuscate(long v, int type)
  */
 static int kcmp_ptr(void *v1, void *v2, enum kcmp_type type)
 {
-       long ret;
+       long t1, t2;
 
-       ret = kptr_obfuscate((long)v1, type) - kptr_obfuscate((long)v2, type);
+       t1 = kptr_obfuscate((long)v1, type);
+       t2 = kptr_obfuscate((long)v2, type);
 
-       return (ret < 0) | ((ret > 0) << 1);
+       return (t1 < t2) | ((t1 > t2) << 1);
 }
 
 /* The caller must have pinned the task */
index e04c455..1ce7706 100644 (file)
@@ -1665,15 +1665,15 @@ asmlinkage int vprintk_emit(int facility, int level,
        raw_spin_lock(&logbuf_lock);
        logbuf_cpu = this_cpu;
 
-       if (recursion_bug) {
+       if (unlikely(recursion_bug)) {
                static const char recursion_msg[] =
                        "BUG: recent printk recursion!";
 
                recursion_bug = 0;
-               text_len = strlen(recursion_msg);
                /* emit KERN_CRIT message */
                printed_len += log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0,
-                                        NULL, 0, recursion_msg, text_len);
+                                        NULL, 0, recursion_msg,
+                                        strlen(recursion_msg));
        }
 
        /*
index 70fad0c..6ecb0d9 100644 (file)
@@ -816,6 +816,10 @@ void __init_memblock __next_mem_range(u64 *idx, int nid,
                if (nid != NUMA_NO_NODE && nid != m_nid)
                        continue;
 
+               /* skip hotpluggable memory regions if needed */
+               if (movable_node_is_enabled() && memblock_is_hotpluggable(m))
+                       continue;
+
                if (!type_b) {
                        if (out_start)
                                *out_start = m_start;
index c1f2ea4..c0a3637 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -369,20 +369,20 @@ static int browse_rb(struct rb_root *root)
                struct vm_area_struct *vma;
                vma = rb_entry(nd, struct vm_area_struct, vm_rb);
                if (vma->vm_start < prev) {
-                       pr_info("vm_start %lx prev %lx\n", vma->vm_start, prev);
+                       pr_emerg("vm_start %lx prev %lx\n", vma->vm_start, prev);
                        bug = 1;
                }
                if (vma->vm_start < pend) {
-                       pr_info("vm_start %lx pend %lx\n", vma->vm_start, pend);
+                       pr_emerg("vm_start %lx pend %lx\n", vma->vm_start, pend);
                        bug = 1;
                }
                if (vma->vm_start > vma->vm_end) {
-                       pr_info("vm_end %lx < vm_start %lx\n",
+                       pr_emerg("vm_end %lx < vm_start %lx\n",
                                vma->vm_end, vma->vm_start);
                        bug = 1;
                }
                if (vma->rb_subtree_gap != vma_compute_subtree_gap(vma)) {
-                       pr_info("free gap %lx, correct %lx\n",
+                       pr_emerg("free gap %lx, correct %lx\n",
                               vma->rb_subtree_gap,
                               vma_compute_subtree_gap(vma));
                        bug = 1;
@@ -396,7 +396,7 @@ static int browse_rb(struct rb_root *root)
        for (nd = pn; nd; nd = rb_prev(nd))
                j++;
        if (i != j) {
-               pr_info("backwards %d, forwards %d\n", j, i);
+               pr_emerg("backwards %d, forwards %d\n", j, i);
                bug = 1;
        }
        return bug ? -1 : i;
@@ -431,17 +431,17 @@ static void validate_mm(struct mm_struct *mm)
                i++;
        }
        if (i != mm->map_count) {
-               pr_info("map_count %d vm_next %d\n", mm->map_count, i);
+               pr_emerg("map_count %d vm_next %d\n", mm->map_count, i);
                bug = 1;
        }
        if (highest_address != mm->highest_vm_end) {
-               pr_info("mm->highest_vm_end %lx, found %lx\n",
+               pr_emerg("mm->highest_vm_end %lx, found %lx\n",
                       mm->highest_vm_end, highest_address);
                bug = 1;
        }
        i = browse_rb(&mm->mm_rb);
        if (i != mm->map_count) {
-               pr_info("map_count %d rb %d\n", mm->map_count, i);
+               pr_emerg("map_count %d rb %d\n", mm->map_count, i);
                bug = 1;
        }
        BUG_ON(bug);
index 7ed5860..7c7ab32 100644 (file)
@@ -119,6 +119,8 @@ static unsigned long __init free_low_memory_core_early(void)
        phys_addr_t start, end;
        u64 i;
 
+       memblock_clear_hotplug(0, -1);
+
        for_each_free_mem_range(i, NUMA_NO_NODE, &start, &end, NULL)
                count += __free_memory_core(start, end);
 
index 3707c71..5110816 100644 (file)
@@ -108,7 +108,7 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk,
                            int page_start, int page_end)
 {
        const gfp_t gfp = GFP_KERNEL | __GFP_HIGHMEM | __GFP_COLD;
-       unsigned int cpu;
+       unsigned int cpu, tcpu;
        int i;
 
        for_each_possible_cpu(cpu) {
@@ -116,14 +116,23 @@ static int pcpu_alloc_pages(struct pcpu_chunk *chunk,
                        struct page **pagep = &pages[pcpu_page_idx(cpu, i)];
 
                        *pagep = alloc_pages_node(cpu_to_node(cpu), gfp, 0);
-                       if (!*pagep) {
-                               pcpu_free_pages(chunk, pages, populated,
-                                               page_start, page_end);
-                               return -ENOMEM;
-                       }
+                       if (!*pagep)
+                               goto err;
                }
        }
        return 0;
+
+err:
+       while (--i >= page_start)
+               __free_page(pages[pcpu_page_idx(cpu, i)]);
+
+       for_each_possible_cpu(tcpu) {
+               if (tcpu == cpu)
+                       break;
+               for (i = page_start; i < page_end; i++)
+                       __free_page(pages[pcpu_page_idx(tcpu, i)]);
+       }
+       return -ENOMEM;
 }
 
 /**
@@ -263,6 +272,7 @@ err:
                __pcpu_unmap_pages(pcpu_chunk_addr(chunk, tcpu, page_start),
                                   page_end - page_start);
        }
+       pcpu_post_unmap_tlb_flush(chunk, page_start, page_end);
        return err;
 }
 
index 2139e30..da997f9 100644 (file)
@@ -1932,6 +1932,8 @@ void __init setup_per_cpu_areas(void)
 
        if (pcpu_setup_first_chunk(ai, fc) < 0)
                panic("Failed to initialize percpu areas.");
+
+       pcpu_free_alloc_info(ai);
 }
 
 #endif /* CONFIG_SMP */
index b50dabb..faff624 100644 (file)
@@ -589,6 +589,14 @@ EXPORT_SYMBOL(hci_get_route);
 void hci_le_conn_failed(struct hci_conn *conn, u8 status)
 {
        struct hci_dev *hdev = conn->hdev;
+       struct hci_conn_params *params;
+
+       params = hci_pend_le_action_lookup(&hdev->pend_le_conns, &conn->dst,
+                                          conn->dst_type);
+       if (params && params->conn) {
+               hci_conn_drop(params->conn);
+               params->conn = NULL;
+       }
 
        conn->state = BT_CLOSED;
 
index c32d361..1d9c29a 100644 (file)
@@ -2536,8 +2536,13 @@ static void hci_pend_le_actions_clear(struct hci_dev *hdev)
 {
        struct hci_conn_params *p;
 
-       list_for_each_entry(p, &hdev->le_conn_params, list)
+       list_for_each_entry(p, &hdev->le_conn_params, list) {
+               if (p->conn) {
+                       hci_conn_drop(p->conn);
+                       p->conn = NULL;
+               }
                list_del_init(&p->action);
+       }
 
        BT_DBG("All LE pending actions cleared");
 }
@@ -2578,8 +2583,8 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 
        hci_dev_lock(hdev);
        hci_inquiry_cache_flush(hdev);
-       hci_conn_hash_flush(hdev);
        hci_pend_le_actions_clear(hdev);
+       hci_conn_hash_flush(hdev);
        hci_dev_unlock(hdev);
 
        hci_notify(hdev, HCI_DEV_DOWN);
@@ -3727,6 +3732,9 @@ void hci_conn_params_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
        if (!params)
                return;
 
+       if (params->conn)
+               hci_conn_drop(params->conn);
+
        list_del(&params->action);
        list_del(&params->list);
        kfree(params);
@@ -3757,6 +3765,8 @@ void hci_conn_params_clear_all(struct hci_dev *hdev)
        struct hci_conn_params *params, *tmp;
 
        list_for_each_entry_safe(params, tmp, &hdev->le_conn_params, list) {
+               if (params->conn)
+                       hci_conn_drop(params->conn);
                list_del(&params->action);
                list_del(&params->list);
                kfree(params);
index be35598..a600082 100644 (file)
@@ -4221,8 +4221,13 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
        hci_proto_connect_cfm(conn, ev->status);
 
        params = hci_conn_params_lookup(hdev, &conn->dst, conn->dst_type);
-       if (params)
+       if (params) {
                list_del_init(&params->action);
+               if (params->conn) {
+                       hci_conn_drop(params->conn);
+                       params->conn = NULL;
+               }
+       }
 
 unlock:
        hci_update_background_scan(hdev);
@@ -4304,8 +4309,16 @@ static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
 
        conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
                              HCI_LE_AUTOCONN_TIMEOUT, HCI_ROLE_MASTER);
-       if (!IS_ERR(conn))
+       if (!IS_ERR(conn)) {
+               /* Store the pointer since we don't really have any
+                * other owner of the object besides the params that
+                * triggered it. This way we can abort the connection if
+                * the parameters get removed and keep the reference
+                * count consistent once the connection is established.
+                */
+               params->conn = conn;
                return;
+       }
 
        switch (PTR_ERR(conn)) {
        case -EBUSY:
index 488dd1a..fdbc9a8 100644 (file)
@@ -775,7 +775,7 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb)
 EXPORT_SYMBOL(__skb_checksum_complete);
 
 /**
- *     skb_copy_and_csum_datagram_iovec - Copy and checkum skb to user iovec.
+ *     skb_copy_and_csum_datagram_iovec - Copy and checksum skb to user iovec.
  *     @skb: skbuff
  *     @hlen: hardware length
  *     @iov: io vector
index b65a505..ab9a165 100644 (file)
@@ -2587,13 +2587,19 @@ netdev_features_t netif_skb_features(struct sk_buff *skb)
                return harmonize_features(skb, features);
        }
 
-       features &= (skb->dev->vlan_features | NETIF_F_HW_VLAN_CTAG_TX |
-                                              NETIF_F_HW_VLAN_STAG_TX);
+       features = netdev_intersect_features(features,
+                                            skb->dev->vlan_features |
+                                            NETIF_F_HW_VLAN_CTAG_TX |
+                                            NETIF_F_HW_VLAN_STAG_TX);
 
        if (protocol == htons(ETH_P_8021Q) || protocol == htons(ETH_P_8021AD))
-               features &= NETIF_F_SG | NETIF_F_HIGHDMA | NETIF_F_FRAGLIST |
-                               NETIF_F_GEN_CSUM | NETIF_F_HW_VLAN_CTAG_TX |
-                               NETIF_F_HW_VLAN_STAG_TX;
+               features = netdev_intersect_features(features,
+                                                    NETIF_F_SG |
+                                                    NETIF_F_HIGHDMA |
+                                                    NETIF_F_FRAGLIST |
+                                                    NETIF_F_GEN_CSUM |
+                                                    NETIF_F_HW_VLAN_CTAG_TX |
+                                                    NETIF_F_HW_VLAN_STAG_TX);
 
        return harmonize_features(skb, features);
 }
@@ -4889,7 +4895,8 @@ static void __netdev_adjacent_dev_remove(struct net_device *dev,
        if (adj->master)
                sysfs_remove_link(&(dev->dev.kobj), "master");
 
-       if (netdev_adjacent_is_neigh_list(dev, dev_list))
+       if (netdev_adjacent_is_neigh_list(dev, dev_list) &&
+           net_eq(dev_net(dev),dev_net(adj_dev)))
                netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list);
 
        list_del_rcu(&adj->list);
@@ -5159,11 +5166,65 @@ void netdev_upper_dev_unlink(struct net_device *dev,
 }
 EXPORT_SYMBOL(netdev_upper_dev_unlink);
 
+void netdev_adjacent_add_links(struct net_device *dev)
+{
+       struct netdev_adjacent *iter;
+
+       struct net *net = dev_net(dev);
+
+       list_for_each_entry(iter, &dev->adj_list.upper, list) {
+               if (!net_eq(net,dev_net(iter->dev)))
+                       continue;
+               netdev_adjacent_sysfs_add(iter->dev, dev,
+                                         &iter->dev->adj_list.lower);
+               netdev_adjacent_sysfs_add(dev, iter->dev,
+                                         &dev->adj_list.upper);
+       }
+
+       list_for_each_entry(iter, &dev->adj_list.lower, list) {
+               if (!net_eq(net,dev_net(iter->dev)))
+                       continue;
+               netdev_adjacent_sysfs_add(iter->dev, dev,
+                                         &iter->dev->adj_list.upper);
+               netdev_adjacent_sysfs_add(dev, iter->dev,
+                                         &dev->adj_list.lower);
+       }
+}
+
+void netdev_adjacent_del_links(struct net_device *dev)
+{
+       struct netdev_adjacent *iter;
+
+       struct net *net = dev_net(dev);
+
+       list_for_each_entry(iter, &dev->adj_list.upper, list) {
+               if (!net_eq(net,dev_net(iter->dev)))
+                       continue;
+               netdev_adjacent_sysfs_del(iter->dev, dev->name,
+                                         &iter->dev->adj_list.lower);
+               netdev_adjacent_sysfs_del(dev, iter->dev->name,
+                                         &dev->adj_list.upper);
+       }
+
+       list_for_each_entry(iter, &dev->adj_list.lower, list) {
+               if (!net_eq(net,dev_net(iter->dev)))
+                       continue;
+               netdev_adjacent_sysfs_del(iter->dev, dev->name,
+                                         &iter->dev->adj_list.upper);
+               netdev_adjacent_sysfs_del(dev, iter->dev->name,
+                                         &dev->adj_list.lower);
+       }
+}
+
 void netdev_adjacent_rename_links(struct net_device *dev, char *oldname)
 {
        struct netdev_adjacent *iter;
 
+       struct net *net = dev_net(dev);
+
        list_for_each_entry(iter, &dev->adj_list.upper, list) {
+               if (!net_eq(net,dev_net(iter->dev)))
+                       continue;
                netdev_adjacent_sysfs_del(iter->dev, oldname,
                                          &iter->dev->adj_list.lower);
                netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -5171,6 +5232,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname)
        }
 
        list_for_each_entry(iter, &dev->adj_list.lower, list) {
+               if (!net_eq(net,dev_net(iter->dev)))
+                       continue;
                netdev_adjacent_sysfs_del(iter->dev, oldname,
                                          &iter->dev->adj_list.upper);
                netdev_adjacent_sysfs_add(iter->dev, dev,
@@ -6773,6 +6836,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
 
        /* Send a netdev-removed uevent to the old namespace */
        kobject_uevent(&dev->dev.kobj, KOBJ_REMOVE);
+       netdev_adjacent_del_links(dev);
 
        /* Actually switch the network namespace */
        dev_net_set(dev, net);
@@ -6787,6 +6851,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char
 
        /* Send a netdev-add uevent to the new namespace */
        kobject_uevent(&dev->dev.kobj, KOBJ_ADD);
+       netdev_adjacent_add_links(dev);
 
        /* Fixup kobjects */
        err = device_rename(&dev->dev, dev->name);
index 6b5b6e7..9d33dff 100644 (file)
@@ -197,7 +197,7 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats
  * as destination. A new timer with the interval specified in the
  * configuration TLV is created. Upon each interval, the latest statistics
  * will be read from &bstats and the estimated rate will be stored in
- * &rate_est with the statistics lock grabed during this period.
+ * &rate_est with the statistics lock grabbed during this period.
  *
  * Returns 0 on success or a negative error code.
  *
index 9d3d9e7..2ddbce4 100644 (file)
@@ -206,7 +206,7 @@ EXPORT_SYMBOL(gnet_stats_copy_queue);
  * @st: application specific statistics data
  * @len: length of data
  *
- * Appends the application sepecific statistics to the top level TLV created by
+ * Appends the application specific statistics to the top level TLV created by
  * gnet_stats_start_copy() and remembers the data for XSTATS if the dumping
  * handle is in backward compatibility mode.
  *
index 163b673..da1378a 100644 (file)
@@ -2647,7 +2647,7 @@ EXPORT_SYMBOL(skb_prepare_seq_read);
  * skb_seq_read() will return the remaining part of the block.
  *
  * Note 1: The size of each block of data returned can be arbitrary,
- *       this limitation is the cost for zerocopy seqeuental
+ *       this limitation is the cost for zerocopy sequential
  *       reads of potentially non linear data.
  *
  * Note 2: Fragment lists within fragments are not implemented
@@ -2781,7 +2781,7 @@ EXPORT_SYMBOL(skb_find_text);
 /**
  * skb_append_datato_frags - append the user data to a skb
  * @sk: sock  structure
- * @skb: skb structure to be appened with user data.
+ * @skb: skb structure to be appended with user data.
  * @getfrag: call back function to be used for getting the user data
  * @from: pointer to user message iov
  * @length: length of the iov message
index 2714811..d372b4b 100644 (file)
@@ -166,7 +166,7 @@ EXPORT_SYMBOL(sk_ns_capable);
 /**
  * sk_capable - Socket global capability test
  * @sk: Socket to use a capability on or through
- * @cap: The global capbility to use
+ * @cap: The global capability to use
  *
  * Test to see if the opener of the socket had when the socket was
  * created and the current process has the capability @cap in all user
@@ -183,7 +183,7 @@ EXPORT_SYMBOL(sk_capable);
  * @sk: Socket to use a capability on or through
  * @cap: The capability to use
  *
- * Test to see if the opener of the socket had when the socke was created
+ * Test to see if the opener of the socket had when the socket was created
  * and the current process has the capability @cap over the network namespace
  * the socket is a member of.
  */
@@ -1822,6 +1822,9 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len,
                                                           order);
                                        if (page)
                                                goto fill_page;
+                                       /* Do not retry other high order allocations */
+                                       order = 1;
+                                       max_page_order = 0;
                                }
                                order--;
                        }
@@ -1869,10 +1872,8 @@ EXPORT_SYMBOL(sock_alloc_send_skb);
  * no guarantee that allocations succeed. Therefore, @sz MUST be
  * less or equal than PAGE_SIZE.
  */
-bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio)
+bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t gfp)
 {
-       int order;
-
        if (pfrag->page) {
                if (atomic_read(&pfrag->page->_count) == 1) {
                        pfrag->offset = 0;
@@ -1883,20 +1884,21 @@ bool skb_page_frag_refill(unsigned int sz, struct page_frag *pfrag, gfp_t prio)
                put_page(pfrag->page);
        }
 
-       order = SKB_FRAG_PAGE_ORDER;
-       do {
-               gfp_t gfp = prio;
-
-               if (order)
-                       gfp |= __GFP_COMP | __GFP_NOWARN | __GFP_NORETRY;
-               pfrag->page = alloc_pages(gfp, order);
+       pfrag->offset = 0;
+       if (SKB_FRAG_PAGE_ORDER) {
+               pfrag->page = alloc_pages(gfp | __GFP_COMP |
+                                         __GFP_NOWARN | __GFP_NORETRY,
+                                         SKB_FRAG_PAGE_ORDER);
                if (likely(pfrag->page)) {
-                       pfrag->offset = 0;
-                       pfrag->size = PAGE_SIZE << order;
+                       pfrag->size = PAGE_SIZE << SKB_FRAG_PAGE_ORDER;
                        return true;
                }
-       } while (--order >= 0);
-
+       }
+       pfrag->page = alloc_page(gfp);
+       if (likely(pfrag->page)) {
+               pfrag->size = PAGE_SIZE;
+               return true;
+       }
        return false;
 }
 EXPORT_SYMBOL(skb_page_frag_refill);
index 016b77e..6591d27 100644 (file)
@@ -246,7 +246,7 @@ lowpan_alloc_frag(struct sk_buff *skb, int size,
                        return ERR_PTR(-rc);
                }
        } else {
-               frag = ERR_PTR(ENOMEM);
+               frag = ERR_PTR(-ENOMEM);
        }
 
        return frag;
@@ -437,7 +437,7 @@ static void lowpan_setup(struct net_device *dev)
        /* Frame Control + Sequence Number + Address fields + Security Header */
        dev->hard_header_len    = 2 + 1 + 20 + 14;
        dev->needed_tailroom    = 2; /* FCS */
-       dev->mtu                = 1281;
+       dev->mtu                = IPV6_MIN_MTU;
        dev->tx_queue_len       = 0;
        dev->flags              = IFF_BROADCAST | IFF_MULTICAST;
        dev->watchdog_timeo     = 0;
index ffec6ce..32755cb 100644 (file)
@@ -355,8 +355,6 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
        struct net *net = dev_net(skb->dev);
        struct lowpan_frag_info *frag_info = lowpan_cb(skb);
        struct ieee802154_addr source, dest;
-       struct netns_ieee802154_lowpan *ieee802154_lowpan =
-               net_ieee802154_lowpan(net);
        int err;
 
        source = mac_cb(skb)->source;
@@ -366,8 +364,10 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
        if (err < 0)
                goto err;
 
-       if (frag_info->d_size > ieee802154_lowpan->max_dsize)
+       if (frag_info->d_size > IPV6_MIN_MTU) {
+               net_warn_ratelimited("lowpan_frag_rcv: datagram size exceeds MTU\n");
                goto err;
+       }
 
        fq = fq_find(net, frag_info, &source, &dest);
        if (fq != NULL) {
@@ -415,13 +415,6 @@ static struct ctl_table lowpan_frags_ns_ctl_table[] = {
                .mode           = 0644,
                .proc_handler   = proc_dointvec_jiffies,
        },
-       {
-               .procname       = "6lowpanfrag_max_datagram_size",
-               .data           = &init_net.ieee802154_lowpan.max_dsize,
-               .maxlen         = sizeof(int),
-               .mode           = 0644,
-               .proc_handler   = proc_dointvec
-       },
        { }
 };
 
@@ -458,7 +451,6 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
                table[1].data = &ieee802154_lowpan->frags.low_thresh;
                table[1].extra2 = &ieee802154_lowpan->frags.high_thresh;
                table[2].data = &ieee802154_lowpan->frags.timeout;
-               table[3].data = &ieee802154_lowpan->max_dsize;
 
                /* Don't export sysctls to unprivileged users */
                if (net->user_ns != &init_user_ns)
@@ -533,7 +525,6 @@ static int __net_init lowpan_frags_init_net(struct net *net)
        ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
        ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
        ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
-       ieee802154_lowpan->max_dsize = 0xFFFF;
 
        inet_frags_init_net(&ieee802154_lowpan->frags);
 
index fb17312..7cbcaf4 100644 (file)
@@ -82,6 +82,52 @@ config NF_TABLES_ARP
        help
          This option enables the ARP support for nf_tables.
 
+config NF_NAT_IPV4
+       tristate "IPv4 NAT"
+       depends on NF_CONNTRACK_IPV4
+       default m if NETFILTER_ADVANCED=n
+       select NF_NAT
+       help
+         The IPv4 NAT option allows masquerading, port forwarding and other
+         forms of full Network Address Port Translation. This can be
+         controlled by iptables or nft.
+
+if NF_NAT_IPV4
+
+config NF_NAT_SNMP_BASIC
+       tristate "Basic SNMP-ALG support"
+       depends on NF_CONNTRACK_SNMP
+       depends on NETFILTER_ADVANCED
+       default NF_NAT && NF_CONNTRACK_SNMP
+       ---help---
+
+         This module implements an Application Layer Gateway (ALG) for
+         SNMP payloads.  In conjunction with NAT, it allows a network
+         management system to access multiple private networks with
+         conflicting addresses.  It works by modifying IP addresses
+         inside SNMP payloads to match IP-layer NAT mapping.
+
+         This is the "basic" form of SNMP-ALG, as described in RFC 2962
+
+         To compile it as a module, choose M here.  If unsure, say N.
+
+config NF_NAT_PROTO_GRE
+       tristate
+       depends on NF_CT_PROTO_GRE
+
+config NF_NAT_PPTP
+       tristate
+       depends on NF_CONNTRACK
+       default NF_CONNTRACK_PPTP
+       select NF_NAT_PROTO_GRE
+
+config NF_NAT_H323
+       tristate
+       depends on NF_CONNTRACK
+       default NF_CONNTRACK_H323
+
+endif # NF_NAT_IPV4
+
 config IP_NF_IPTABLES
        tristate "IP tables support (required for filtering/masq/NAT)"
        default m if NETFILTER_ADVANCED=n
@@ -170,19 +216,21 @@ config IP_NF_TARGET_SYNPROXY
          To compile it as a module, choose M here. If unsure, say N.
 
 # NAT + specific targets: nf_conntrack
-config NF_NAT_IPV4
-       tristate "IPv4 NAT"
+config IP_NF_NAT
+       tristate "iptables NAT support"
        depends on NF_CONNTRACK_IPV4
        default m if NETFILTER_ADVANCED=n
        select NF_NAT
+       select NF_NAT_IPV4
+       select NETFILTER_XT_NAT
        help
-         The IPv4 NAT option allows masquerading, port forwarding and other
-         forms of full Network Address Port Translation.  It is controlled by
-         the `nat' table in iptables: see the man page for iptables(8).
+         This enables the `nat' table in iptables. This allows masquerading,
+         port forwarding and other forms of full Network Address Port
+         Translation.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
-if NF_NAT_IPV4
+if IP_NF_NAT
 
 config IP_NF_TARGET_MASQUERADE
        tristate "MASQUERADE target support"
@@ -214,47 +262,7 @@ config IP_NF_TARGET_REDIRECT
        (e.g. when running oldconfig). It selects
        CONFIG_NETFILTER_XT_TARGET_REDIRECT.
 
-endif
-
-config NF_NAT_SNMP_BASIC
-       tristate "Basic SNMP-ALG support"
-       depends on NF_CONNTRACK_SNMP && NF_NAT_IPV4
-       depends on NETFILTER_ADVANCED
-       default NF_NAT && NF_CONNTRACK_SNMP
-       ---help---
-
-         This module implements an Application Layer Gateway (ALG) for
-         SNMP payloads.  In conjunction with NAT, it allows a network
-         management system to access multiple private networks with
-         conflicting addresses.  It works by modifying IP addresses
-         inside SNMP payloads to match IP-layer NAT mapping.
-
-         This is the "basic" form of SNMP-ALG, as described in RFC 2962
-
-         To compile it as a module, choose M here.  If unsure, say N.
-
-# If they want FTP, set to $CONFIG_IP_NF_NAT (m or y),
-# or $CONFIG_IP_NF_FTP (m or y), whichever is weaker.
-# From kconfig-language.txt:
-#
-#           <expr> '&&' <expr>                   (6)
-#
-# (6) Returns the result of min(/expr/, /expr/).
-
-config NF_NAT_PROTO_GRE
-       tristate
-       depends on NF_NAT_IPV4 && NF_CT_PROTO_GRE
-
-config NF_NAT_PPTP
-       tristate
-       depends on NF_CONNTRACK && NF_NAT_IPV4
-       default NF_NAT_IPV4 && NF_CONNTRACK_PPTP
-       select NF_NAT_PROTO_GRE
-
-config NF_NAT_H323
-       tristate
-       depends on NF_CONNTRACK && NF_NAT_IPV4
-       default NF_NAT_IPV4 && NF_CONNTRACK_H323
+endif # IP_NF_NAT
 
 # mangle + specific targets
 config IP_NF_MANGLE
index 3300162..edf4af3 100644 (file)
@@ -43,7 +43,7 @@ obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o
 # the three instances of ip_tables
 obj-$(CONFIG_IP_NF_FILTER) += iptable_filter.o
 obj-$(CONFIG_IP_NF_MANGLE) += iptable_mangle.o
-obj-$(CONFIG_NF_NAT_IPV4) += iptable_nat.o
+obj-$(CONFIG_IP_NF_NAT) += iptable_nat.o
 obj-$(CONFIG_IP_NF_RAW) += iptable_raw.o
 obj-$(CONFIG_IP_NF_SECURITY) += iptable_security.o
 
index 0b239fc..fc1fac2 100644 (file)
@@ -1690,14 +1690,12 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)
        addrconf_mod_dad_work(ifp, 0);
 }
 
-/* Join to solicited addr multicast group. */
-
+/* Join to solicited addr multicast group.
+ * caller must hold RTNL */
 void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
 {
        struct in6_addr maddr;
 
-       ASSERT_RTNL();
-
        if (dev->flags&(IFF_LOOPBACK|IFF_NOARP))
                return;
 
@@ -1705,12 +1703,11 @@ void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)
        ipv6_dev_mc_inc(dev, &maddr);
 }
 
+/* caller must hold RTNL */
 void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
 {
        struct in6_addr maddr;
 
-       ASSERT_RTNL();
-
        if (idev->dev->flags&(IFF_LOOPBACK|IFF_NOARP))
                return;
 
@@ -1718,12 +1715,11 @@ void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)
        __ipv6_dev_mc_dec(idev, &maddr);
 }
 
+/* caller must hold RTNL */
 static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
 {
        struct in6_addr addr;
 
-       ASSERT_RTNL();
-
        if (ifp->prefix_len >= 127) /* RFC 6164 */
                return;
        ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
@@ -1732,12 +1728,11 @@ static void addrconf_join_anycast(struct inet6_ifaddr *ifp)
        ipv6_dev_ac_inc(ifp->idev->dev, &addr);
 }
 
+/* caller must hold RTNL */
 static void addrconf_leave_anycast(struct inet6_ifaddr *ifp)
 {
        struct in6_addr addr;
 
-       ASSERT_RTNL();
-
        if (ifp->prefix_len >= 127) /* RFC 6164 */
                return;
        ipv6_addr_prefix(&addr, &ifp->addr, ifp->prefix_len);
@@ -4773,15 +4768,11 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp)
                addrconf_leave_solict(ifp->idev, &ifp->addr);
                if (!ipv6_addr_any(&ifp->peer_addr)) {
                        struct rt6_info *rt;
-                       struct net_device *dev = ifp->idev->dev;
-
-                       rt = rt6_lookup(dev_net(dev), &ifp->peer_addr, NULL,
-                                       dev->ifindex, 1);
-                       if (rt) {
-                               dst_hold(&rt->dst);
-                               if (ip6_del_rt(rt))
-                                       dst_free(&rt->dst);
-                       }
+
+                       rt = addrconf_get_prefix_route(&ifp->peer_addr, 128,
+                                                      ifp->idev->dev, 0, 0);
+                       if (rt && ip6_del_rt(rt))
+                               dst_free(&rt->dst);
                }
                dst_hold(&ifp->rt->dst);
 
index 2101832..ff2de7d 100644 (file)
@@ -77,6 +77,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
        pac->acl_next = NULL;
        pac->acl_addr = *addr;
 
+       rtnl_lock();
        rcu_read_lock();
        if (ifindex == 0) {
                struct rt6_info *rt;
@@ -137,6 +138,7 @@ int ipv6_sock_ac_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 
 error:
        rcu_read_unlock();
+       rtnl_unlock();
        if (pac)
                sock_kfree_s(sk, pac, sizeof(*pac));
        return err;
@@ -171,11 +173,13 @@ int ipv6_sock_ac_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
 
        spin_unlock_bh(&ipv6_sk_ac_lock);
 
+       rtnl_lock();
        rcu_read_lock();
        dev = dev_get_by_index_rcu(net, pac->acl_ifindex);
        if (dev)
                ipv6_dev_ac_dec(dev, &pac->acl_addr);
        rcu_read_unlock();
+       rtnl_unlock();
 
        sock_kfree_s(sk, pac, sizeof(*pac));
        return 0;
@@ -198,6 +202,7 @@ void ipv6_sock_ac_close(struct sock *sk)
        spin_unlock_bh(&ipv6_sk_ac_lock);
 
        prev_index = 0;
+       rtnl_lock();
        rcu_read_lock();
        while (pac) {
                struct ipv6_ac_socklist *next = pac->acl_next;
@@ -212,6 +217,7 @@ void ipv6_sock_ac_close(struct sock *sk)
                pac = next;
        }
        rcu_read_unlock();
+       rtnl_unlock();
 }
 
 static void aca_put(struct ifacaddr6 *ac)
@@ -233,6 +239,8 @@ int ipv6_dev_ac_inc(struct net_device *dev, const struct in6_addr *addr)
        struct rt6_info *rt;
        int err;
 
+       ASSERT_RTNL();
+
        idev = in6_dev_get(dev);
 
        if (idev == NULL)
@@ -302,6 +310,8 @@ int __ipv6_dev_ac_dec(struct inet6_dev *idev, const struct in6_addr *addr)
 {
        struct ifacaddr6 *aca, *prev_aca;
 
+       ASSERT_RTNL();
+
        write_lock_bh(&idev->lock);
        prev_aca = NULL;
        for (aca = idev->ac_list; aca; aca = aca->aca_next) {
index 617f095..a23b655 100644 (file)
@@ -172,6 +172,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
        mc_lst->next = NULL;
        mc_lst->addr = *addr;
 
+       rtnl_lock();
        rcu_read_lock();
        if (ifindex == 0) {
                struct rt6_info *rt;
@@ -185,6 +186,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 
        if (dev == NULL) {
                rcu_read_unlock();
+               rtnl_unlock();
                sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
                return -ENODEV;
        }
@@ -202,6 +204,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
 
        if (err) {
                rcu_read_unlock();
+               rtnl_unlock();
                sock_kfree_s(sk, mc_lst, sizeof(*mc_lst));
                return err;
        }
@@ -212,6 +215,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
        spin_unlock(&ipv6_sk_mc_lock);
 
        rcu_read_unlock();
+       rtnl_unlock();
 
        return 0;
 }
@@ -229,6 +233,7 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
        if (!ipv6_addr_is_multicast(addr))
                return -EINVAL;
 
+       rtnl_lock();
        spin_lock(&ipv6_sk_mc_lock);
        for (lnk = &np->ipv6_mc_list;
             (mc_lst = rcu_dereference_protected(*lnk,
@@ -252,12 +257,15 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
                        } else
                                (void) ip6_mc_leave_src(sk, mc_lst, NULL);
                        rcu_read_unlock();
+                       rtnl_unlock();
+
                        atomic_sub(sizeof(*mc_lst), &sk->sk_omem_alloc);
                        kfree_rcu(mc_lst, rcu);
                        return 0;
                }
        }
        spin_unlock(&ipv6_sk_mc_lock);
+       rtnl_unlock();
 
        return -EADDRNOTAVAIL;
 }
@@ -302,6 +310,7 @@ void ipv6_sock_mc_close(struct sock *sk)
        if (!rcu_access_pointer(np->ipv6_mc_list))
                return;
 
+       rtnl_lock();
        spin_lock(&ipv6_sk_mc_lock);
        while ((mc_lst = rcu_dereference_protected(np->ipv6_mc_list,
                                lockdep_is_held(&ipv6_sk_mc_lock))) != NULL) {
@@ -328,6 +337,7 @@ void ipv6_sock_mc_close(struct sock *sk)
                spin_lock(&ipv6_sk_mc_lock);
        }
        spin_unlock(&ipv6_sk_mc_lock);
+       rtnl_unlock();
 }
 
 int ip6_mc_source(int add, int omode, struct sock *sk,
@@ -845,6 +855,8 @@ int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr)
        struct ifmcaddr6 *mc;
        struct inet6_dev *idev;
 
+       ASSERT_RTNL();
+
        /* we need to take a reference on idev */
        idev = in6_dev_get(dev);
 
@@ -916,6 +928,8 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
 {
        struct ifmcaddr6 *ma, **map;
 
+       ASSERT_RTNL();
+
        write_lock_bh(&idev->lock);
        for (map = &idev->mc_list; (ma=*map) != NULL; map = &ma->next) {
                if (ipv6_addr_equal(&ma->mca_addr, addr)) {
index ac93df1..2812816 100644 (file)
@@ -57,9 +57,19 @@ config NFT_REJECT_IPV6
 
 config NF_LOG_IPV6
        tristate "IPv6 packet logging"
-       depends on NETFILTER_ADVANCED
+       default m if NETFILTER_ADVANCED=n
        select NF_LOG_COMMON
 
+config NF_NAT_IPV6
+       tristate "IPv6 NAT"
+       depends on NF_CONNTRACK_IPV6
+       depends on NETFILTER_ADVANCED
+       select NF_NAT
+       help
+         The IPv6 NAT option allows masquerading, port forwarding and other
+         forms of full Network Address Port Translation. This can be
+         controlled by iptables or nft.
+
 config IP6_NF_IPTABLES
        tristate "IP6 tables support (required for filtering)"
        depends on INET && IPV6
@@ -232,19 +242,21 @@ config IP6_NF_SECURITY
 
          If unsure, say N.
 
-config NF_NAT_IPV6
-       tristate "IPv6 NAT"
+config IP6_NF_NAT
+       tristate "ip6tables NAT support"
        depends on NF_CONNTRACK_IPV6
        depends on NETFILTER_ADVANCED
        select NF_NAT
+       select NF_NAT_IPV6
+       select NETFILTER_XT_NAT
        help
-         The IPv6 NAT option allows masquerading, port forwarding and other
-         forms of full Network Address Port Translation. It is controlled by
-         the `nat' table in ip6tables, see the man page for ip6tables(8).
+         This enables the `nat' table in ip6tables. This allows masquerading,
+         port forwarding and other forms of full Network Address Port
+         Translation.
 
          To compile it as a module, choose M here.  If unsure, say N.
 
-if NF_NAT_IPV6
+if IP6_NF_NAT
 
 config IP6_NF_TARGET_MASQUERADE
        tristate "MASQUERADE target support"
@@ -265,7 +277,7 @@ config IP6_NF_TARGET_NPT
 
          To compile it as a module, choose M here.  If unsure, say N.
 
-endif # NF_NAT_IPV6
+endif # IP6_NF_NAT
 
 endif # IP6_NF_IPTABLES
 
index c0b2631..c3d3286 100644 (file)
@@ -8,7 +8,7 @@ obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
 obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
 obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
 obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
-obj-$(CONFIG_NF_NAT_IPV6) += ip6table_nat.o
+obj-$(CONFIG_IP6_NF_NAT) += ip6table_nat.o
 
 # objects for l3 independent conntrack
 nf_conntrack_ipv6-y  :=  nf_conntrack_l3proto_ipv6.o nf_conntrack_proto_icmpv6.o
index 13752d9..b704a93 100644 (file)
@@ -755,7 +755,8 @@ static int pppol2tp_connect(struct socket *sock, struct sockaddr *uservaddr,
        /* If PMTU discovery was enabled, use the MTU that was discovered */
        dst = sk_dst_get(tunnel->sock);
        if (dst != NULL) {
-               u32 pmtu = dst_mtu(__sk_dst_get(tunnel->sock));
+               u32 pmtu = dst_mtu(dst);
+
                if (pmtu != 0)
                        session->mtu = session->mru = pmtu -
                                PPPOL2TP_HEADER_OVERHEAD;
index 0375009..399ad82 100644 (file)
@@ -541,6 +541,8 @@ static void ieee80211_recalc_chanctx_chantype(struct ieee80211_local *local,
                        continue;
                if (rcu_access_pointer(sdata->vif.chanctx_conf) != conf)
                        continue;
+               if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+                       continue;
 
                if (!compat)
                        compat = &sdata->vif.bss_conf.chandef;
index 3db9664..86173c0 100644 (file)
@@ -167,7 +167,7 @@ static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf,
        p += scnprintf(p, sizeof(buf) + buf - p, "next dialog_token: %#02x\n",
                        sta->ampdu_mlme.dialog_token_allocator + 1);
        p += scnprintf(p, sizeof(buf) + buf - p,
-                      "TID\t\tRX active\tDTKN\tSSN\t\tTX\tDTKN\tpending\n");
+                      "TID\t\tRX\tDTKN\tSSN\t\tTX\tDTKN\tpending\n");
 
        for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
                tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[i]);
index 01eede7..f75e5f1 100644 (file)
@@ -1175,8 +1175,8 @@ static void ieee80211_iface_work(struct work_struct *work)
                        if (sta) {
                                u16 last_seq;
 
-                               last_seq = le16_to_cpu(
-                                       sta->last_seq_ctrl[rx_agg->tid]);
+                               last_seq = IEEE80211_SEQ_TO_SN(le16_to_cpu(
+                                       sta->last_seq_ctrl[rx_agg->tid]));
 
                                __ieee80211_start_rx_ba_session(sta,
                                                0, 0,
index 63b8741..c47194d 100644 (file)
@@ -959,7 +959,8 @@ mesh_plink_get_event(struct ieee80211_sub_if_data *sdata,
                if (!matches_local)
                        event = CNF_RJCT;
                if (!mesh_plink_free_count(sdata) ||
-                   (sta->llid != llid || sta->plid != plid))
+                   sta->llid != llid ||
+                   (sta->plid && sta->plid != plid))
                        event = CNF_IGNR;
                else
                        event = CNF_ACPT;
@@ -1080,6 +1081,10 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
                goto unlock_rcu;
        }
 
+       /* 802.11-2012 13.3.7.2 - update plid on CNF if not set */
+       if (!sta->plid && event == CNF_ACPT)
+               sta->plid = plid;
+
        changed |= mesh_plink_fsm(sdata, sta, event);
 
 unlock_rcu:
index 31a8afa..b82a12a 100644 (file)
@@ -4376,8 +4376,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
        rcu_read_unlock();
 
        if (bss->wmm_used && bss->uapsd_supported &&
-           (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD) &&
-           sdata->wmm_acm != 0xff) {
+           (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
                assoc_data->uapsd = true;
                ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
        } else {
index c6ee213..441875f 100644 (file)
@@ -1094,8 +1094,11 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
        unsigned long flags;
        struct ps_data *ps;
 
-       if (sdata->vif.type == NL80211_IFTYPE_AP ||
-           sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+       if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
+               sdata = container_of(sdata->bss, struct ieee80211_sub_if_data,
+                                    u.ap);
+
+       if (sdata->vif.type == NL80211_IFTYPE_AP)
                ps = &sdata->bss->ps;
        else if (ieee80211_vif_is_mesh(&sdata->vif))
                ps = &sdata->u.mesh.ps;
index 3c3069f..5478388 100644 (file)
@@ -462,7 +462,10 @@ mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb,
                        skb->pkt_type = PACKET_OTHERHOST;
                break;
        default:
-               break;
+               spin_unlock_bh(&sdata->mib_lock);
+               pr_debug("invalid dest mode\n");
+               kfree_skb(skb);
+               return NET_RX_DROP;
        }
 
        spin_unlock_bh(&sdata->mib_lock);
@@ -573,6 +576,7 @@ void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)
        ret = mac802154_parse_frame_start(skb, &hdr);
        if (ret) {
                pr_debug("got invalid frame\n");
+               kfree_skb(skb);
                return;
        }
 
index ad751fe..b5c1d3a 100644 (file)
@@ -499,7 +499,7 @@ config NFT_LIMIT
 config NFT_NAT
        depends on NF_TABLES
        depends on NF_CONNTRACK
-       depends on NF_NAT
+       select NF_NAT
        tristate "Netfilter nf_tables nat module"
        help
          This option adds the "nat" expression that you can use to perform
@@ -747,7 +747,9 @@ config NETFILTER_XT_TARGET_LED
 
 config NETFILTER_XT_TARGET_LOG
        tristate "LOG target support"
-       depends on NF_LOG_IPV4 && NF_LOG_IPV6
+       select NF_LOG_COMMON
+       select NF_LOG_IPV4
+       select NF_LOG_IPV6 if IPV6
        default m if NETFILTER_ADVANCED=n
        help
          This option adds a `LOG' target, which allows you to create rules in
@@ -764,6 +766,14 @@ config NETFILTER_XT_TARGET_MARK
        (e.g. when running oldconfig). It selects
        CONFIG_NETFILTER_XT_MARK (combined mark/MARK module).
 
+config NETFILTER_XT_NAT
+       tristate '"SNAT and DNAT" targets support'
+       depends on NF_NAT
+       ---help---
+       This option enables the SNAT and DNAT targets.
+
+       To compile it as a module, choose M here. If unsure, say N.
+
 config NETFILTER_XT_TARGET_NETMAP
        tristate '"NETMAP" target support'
        depends on NF_NAT
index 8308624..fad5fdb 100644 (file)
@@ -95,7 +95,7 @@ obj-$(CONFIG_NETFILTER_XTABLES) += x_tables.o xt_tcpudp.o
 obj-$(CONFIG_NETFILTER_XT_MARK) += xt_mark.o
 obj-$(CONFIG_NETFILTER_XT_CONNMARK) += xt_connmark.o
 obj-$(CONFIG_NETFILTER_XT_SET) += xt_set.o
-obj-$(CONFIG_NF_NAT) += xt_nat.o
+obj-$(CONFIG_NETFILTER_XT_NAT) += xt_nat.o
 
 # targets
 obj-$(CONFIG_NETFILTER_XT_TARGET_AUDIT) += xt_AUDIT.o
index a93c97f..024a2e2 100644 (file)
@@ -54,7 +54,7 @@ EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
 struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly;
 EXPORT_SYMBOL(nf_hooks);
 
-#if defined(CONFIG_JUMP_LABEL)
+#ifdef HAVE_JUMP_LABEL
 struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
 EXPORT_SYMBOL(nf_hooks_needed);
 #endif
@@ -72,7 +72,7 @@ int nf_register_hook(struct nf_hook_ops *reg)
        }
        list_add_rcu(&reg->list, elem->list.prev);
        mutex_unlock(&nf_hook_mutex);
-#if defined(CONFIG_JUMP_LABEL)
+#ifdef HAVE_JUMP_LABEL
        static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
 #endif
        return 0;
@@ -84,7 +84,7 @@ void nf_unregister_hook(struct nf_hook_ops *reg)
        mutex_lock(&nf_hook_mutex);
        list_del_rcu(&reg->list);
        mutex_unlock(&nf_hook_mutex);
-#if defined(CONFIG_JUMP_LABEL)
+#ifdef HAVE_JUMP_LABEL
        static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]);
 #endif
        synchronize_net();
index e683675..5c34e8d 100644 (file)
@@ -1906,7 +1906,7 @@ static struct nf_hook_ops ip_vs_ops[] __read_mostly = {
        {
                .hook           = ip_vs_local_reply6,
                .owner          = THIS_MODULE,
-               .pf             = NFPROTO_IPV4,
+               .pf             = NFPROTO_IPV6,
                .hooknum        = NF_INET_LOCAL_OUT,
                .priority       = NF_IP6_PRI_NAT_DST + 1,
        },
index 6f70bdd..56896a4 100644 (file)
@@ -38,6 +38,7 @@
 #include <net/route.h>                  /* for ip_route_output */
 #include <net/ipv6.h>
 #include <net/ip6_route.h>
+#include <net/ip_tunnels.h>
 #include <net/addrconf.h>
 #include <linux/icmpv6.h>
 #include <linux/netfilter.h>
@@ -862,11 +863,15 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
                old_iph = ip_hdr(skb);
        }
 
-       skb->transport_header = skb->network_header;
-
        /* fix old IP header checksum */
        ip_send_check(old_iph);
 
+       skb = iptunnel_handle_offloads(skb, false, SKB_GSO_IPIP);
+       if (IS_ERR(skb))
+               goto tx_error;
+
+       skb->transport_header = skb->network_header;
+
        skb_push(skb, sizeof(struct iphdr));
        skb_reset_network_header(skb);
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
@@ -900,7 +905,8 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        return NF_STOLEN;
 
   tx_error:
-       kfree_skb(skb);
+       if (!IS_ERR(skb))
+               kfree_skb(skb);
        rcu_read_unlock();
        LeaveFunction(10);
        return NF_STOLEN;
@@ -953,6 +959,11 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
                old_iph = ipv6_hdr(skb);
        }
 
+       /* GSO: we need to provide proper SKB_GSO_ value for IPv6 */
+       skb = iptunnel_handle_offloads(skb, false, 0); /* SKB_GSO_SIT/IPV6 */
+       if (IS_ERR(skb))
+               goto tx_error;
+
        skb->transport_header = skb->network_header;
 
        skb_push(skb, sizeof(struct ipv6hdr));
@@ -988,7 +999,8 @@ ip_vs_tunnel_xmit_v6(struct sk_buff *skb, struct ip_vs_conn *cp,
        return NF_STOLEN;
 
 tx_error:
-       kfree_skb(skb);
+       if (!IS_ERR(skb))
+               kfree_skb(skb);
        rcu_read_unlock();
        LeaveFunction(10);
        return NF_STOLEN;
index f4e8330..7198d66 100644 (file)
@@ -31,7 +31,7 @@ static int cgroup_mt_check(const struct xt_mtchk_param *par)
        if (info->invert & ~1)
                return -EINVAL;
 
-       return info->id ? 0 : -EINVAL;
+       return 0;
 }
 
 static bool
index 7228ec3..91d66b7 100644 (file)
@@ -265,8 +265,11 @@ void ovs_dp_process_received_packet(struct vport *p, struct sk_buff *skb)
                upcall.key = &key;
                upcall.userdata = NULL;
                upcall.portid = ovs_vport_find_upcall_portid(p, skb);
-               ovs_dp_upcall(dp, skb, &upcall);
-               consume_skb(skb);
+               error = ovs_dp_upcall(dp, skb, &upcall);
+               if (unlikely(error))
+                       kfree_skb(skb);
+               else
+                       consume_skb(skb);
                stats_counter = &stats->n_missed;
                goto out;
        }
@@ -404,7 +407,7 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
 {
        struct ovs_header *upcall;
        struct sk_buff *nskb = NULL;
-       struct sk_buff *user_skb; /* to be queued to userspace */
+       struct sk_buff *user_skb = NULL; /* to be queued to userspace */
        struct nlattr *nla;
        struct genl_info info = {
                .dst_sk = ovs_dp_get_net(dp)->genl_sock,
@@ -494,9 +497,11 @@ static int queue_userspace_packet(struct datapath *dp, struct sk_buff *skb,
        ((struct nlmsghdr *) user_skb->data)->nlmsg_len = user_skb->len;
 
        err = genlmsg_unicast(ovs_dp_get_net(dp), user_skb, upcall_info->portid);
+       user_skb = NULL;
 out:
        if (err)
                skb_tx_error(skb);
+       kfree_skb(user_skb);
        kfree_skb(nskb);
        return err;
 }
index 14c98e4..02a86a2 100644 (file)
@@ -158,6 +158,7 @@ static const struct acpi_device_id rfkill_acpi_match[] = {
        { "BCM2E1A", RFKILL_TYPE_BLUETOOTH },
        { "BCM2E39", RFKILL_TYPE_BLUETOOTH },
        { "BCM2E3D", RFKILL_TYPE_BLUETOOTH },
+       { "BCM2E64", RFKILL_TYPE_BLUETOOTH },
        { "BCM4752", RFKILL_TYPE_GPS },
        { "LNV4752", RFKILL_TYPE_GPS },
        { },
index eb71d49..634a2ab 100644 (file)
@@ -4243,7 +4243,7 @@ static int sctp_getsockopt_sctp_status(struct sock *sk, int len,
        transport = asoc->peer.primary_path;
 
        status.sstat_assoc_id = sctp_assoc2id(asoc);
-       status.sstat_state = asoc->state;
+       status.sstat_state = sctp_assoc_to_state(asoc);
        status.sstat_rwnd =  asoc->peer.rwnd;
        status.sstat_unackdata = asoc->unack_data;
 
index 95ee7d8..2e2586e 100644 (file)
@@ -734,8 +734,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
        }
 
        memset(&tss, 0, sizeof(tss));
-       if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE ||
-            skb_shinfo(skb)->tx_flags & SKBTX_ANY_SW_TSTAMP) &&
+       if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) &&
            ktime_to_timespec_cond(skb->tstamp, tss.ts + 0))
                empty = 0;
        if (shhwtstamps &&
@@ -2602,7 +2601,7 @@ SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
  *
  *     This function is called by a protocol handler that wants to
  *     advertise its address family, and have it linked into the
- *     socket interface. The value ops->family coresponds to the
+ *     socket interface. The value ops->family corresponds to the
  *     socket system call protocol family.
  */
 int sock_register(const struct net_proto_family *ops)
index b385bcb..4d08b39 100755 (executable)
@@ -2133,7 +2133,10 @@ sub process {
 # Check for improperly formed commit descriptions
                if ($in_commit_log &&
                    $line =~ /\bcommit\s+[0-9a-f]{5,}/i &&
-                   $line !~ /\b[Cc]ommit [0-9a-f]{12,40} \("/) {
+                   !($line =~ /\b[Cc]ommit [0-9a-f]{12,40} \("/ ||
+                     ($line =~ /\b[Cc]ommit [0-9a-f]{12,40}\s*$/ &&
+                      defined $rawlines[$linenr] &&
+                      $rawlines[$linenr] =~ /^\s*\("/))) {
                        $line =~ /\b(c)ommit\s+([0-9a-f]{5,})/i;
                        my $init_char = $1;
                        my $orig_commit = lc($2);