Merge tag 'drm-fixes-2018-09-28' of git://anongit.freedesktop.org/drm/drm
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Sep 2018 16:55:17 +0000 (18:55 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 28 Sep 2018 16:55:17 +0000 (18:55 +0200)
Dave writes:
  "drm fixes for 4.19-rc6

   Looks like a pretty normal week for graphics,

   core: syncobj fix, panel link regression revert
   amd: suspend/resume fixes, EDID emulation fix
   mali-dp: NV12 writeback and vblank reset fixes
   etnaviv: DMA setup fix"

* tag 'drm-fixes-2018-09-28' of git://anongit.freedesktop.org/drm/drm:
  drm/amd/display: Fix Edid emulation for linux
  drm/amd/display: Fix Vega10 lightup on S3 resume
  drm/amdgpu: Fix vce work queue was not cancelled when suspend
  Revert "drm/panel: Add device_link from panel device to DRM device"
  drm/syncobj: Don't leak fences when WAIT_FOR_SUBMIT is set
  drm/malidp: Fix writeback in NV12
  drm: mali-dp: Call drm_crtc_vblank_reset on device init
  drm/etnaviv: add DMA configuration for etnaviv platform device

157 files changed:
Documentation/media/uapi/dvb/video_function_calls.rst
MAINTAINERS
arch/riscv/include/asm/asm-prototypes.h [new file with mode: 0644]
drivers/dax/device.c
drivers/hwtracing/intel_th/core.c
drivers/hwtracing/intel_th/pci.c
drivers/infiniband/core/cache.c
drivers/infiniband/core/ucma.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/uverbs_uapi.c
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/hfi1/chip.c
drivers/infiniband/hw/hfi1/pio.c
drivers/infiniband/hw/hfi1/pio.h
drivers/infiniband/hw/hfi1/user_sdma.c
drivers/infiniband/hw/hfi1/verbs.c
drivers/infiniband/hw/mlx5/devx.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/iommu/amd_iommu.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel-pasid.h
drivers/iommu/rockchip-iommu.c
drivers/media/i2c/mt9v111.c
drivers/media/platform/Kconfig
drivers/media/platform/qcom/camss/camss-csid.c
drivers/media/platform/qcom/camss/camss-csiphy-2ph-1-0.c
drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c
drivers/media/platform/qcom/camss/camss-csiphy.c
drivers/media/platform/qcom/camss/camss-ispif.c
drivers/media/platform/qcom/camss/camss-vfe-4-1.c
drivers/media/platform/qcom/camss/camss-vfe-4-7.c
drivers/media/platform/qcom/camss/camss.c
drivers/media/usb/dvb-usb-v2/af9035.c
drivers/net/bonding/bond_main.c
drivers/net/ethernet/apple/bmac.c
drivers/net/ethernet/apple/mace.c
drivers/net/ethernet/apple/macmace.c
drivers/net/ethernet/aquantia/atlantic/aq_ring.c
drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
drivers/net/ethernet/broadcom/bnxt/bnxt_tc.c
drivers/net/ethernet/chelsio/cxgb4/t4_msg.h
drivers/net/ethernet/cirrus/ep93xx_eth.c
drivers/net/ethernet/cirrus/mac89x0.c
drivers/net/ethernet/i825xx/ether1.c
drivers/net/ethernet/i825xx/lib82596.c
drivers/net/ethernet/i825xx/sun3_82586.c
drivers/net/ethernet/ibm/emac/core.c
drivers/net/ethernet/intel/fm10k/fm10k.h
drivers/net/ethernet/intel/fm10k/fm10k_netdev.c
drivers/net/ethernet/intel/fm10k/fm10k_pci.c
drivers/net/ethernet/intel/i40evf/i40evf_main.c
drivers/net/ethernet/intel/ice/ice_main.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/ixgb/ixgb_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/mellanox/mlx4/eq.c
drivers/net/ethernet/mellanox/mlx5/core/cmd.c
drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/transobj.c
drivers/net/ethernet/mellanox/mlxsw/spectrum.c
drivers/net/ethernet/mscc/ocelot_board.c
drivers/net/ethernet/netronome/nfp/nfp_net_common.c
drivers/net/ethernet/qlogic/qed/qed_dcbx.c
drivers/net/ethernet/qlogic/qed/qed_dcbx.h
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_hsi.h
drivers/net/ethernet/qlogic/qed/qed_mcp.c
drivers/net/ethernet/qlogic/qed/qed_reg_addr.h
drivers/net/ethernet/realtek/r8169.c
drivers/net/ethernet/renesas/ravb.h
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/ravb_ptp.c
drivers/net/ethernet/seeq/ether3.c
drivers/net/ethernet/seeq/sgiseeq.c
drivers/net/ethernet/sgi/ioc3-eth.c
drivers/net/ethernet/sgi/meth.c
drivers/net/ethernet/stmicro/stmmac/common.h
drivers/net/ethernet/stmicro/stmmac/stmmac.h
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/wiznet/w5100.c
drivers/net/ethernet/wiznet/w5300.c
drivers/net/phy/sfp-bus.c
drivers/net/tun.c
drivers/pci/controller/dwc/pcie-designware.c
drivers/pci/controller/dwc/pcie-designware.h
drivers/pci/controller/pci-hyperv.c
drivers/pci/hotplug/acpiphp_glue.c
drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c
drivers/scsi/ipr.c
drivers/scsi/ipr.h
drivers/scsi/lpfc/lpfc_attr.c
drivers/scsi/lpfc/lpfc_debugfs.c
drivers/scsi/lpfc/lpfc_nvme.c
drivers/scsi/sd.c
drivers/scsi/ufs/ufshcd.c
drivers/soundwire/stream.c
drivers/staging/media/mt9t031/Kconfig
drivers/target/iscsi/iscsi_target_auth.c
drivers/tty/serial/cpm_uart/cpm_uart_core.c
drivers/tty/serial/fsl_lpuart.c
drivers/tty/serial/imx.c
drivers/tty/serial/mvebu-uart.c
drivers/tty/tty_io.c
drivers/tty/vt/vt_ioctl.c
drivers/usb/class/cdc-wdm.c
drivers/usb/common/roles.c
drivers/usb/core/devio.c
drivers/usb/core/driver.c
drivers/usb/core/quirks.c
drivers/usb/core/usb.c
drivers/usb/musb/musb_dsps.c
drivers/usb/typec/mux.c
fs/dax.c
fs/ext2/inode.c
include/linux/netpoll.h
include/linux/stmmac.h
include/linux/uio.h
include/net/nfc/hci.h
include/uapi/linux/keyctl.h
kernel/bpf/sockmap.c
net/batman-adv/bat_v_elp.c
net/batman-adv/bridge_loop_avoidance.c
net/batman-adv/gateway_client.c
net/batman-adv/main.h
net/batman-adv/network-coding.c
net/batman-adv/soft-interface.c
net/batman-adv/sysfs.c
net/batman-adv/translation-table.c
net/batman-adv/tvlv.c
net/core/devlink.c
net/core/ethtool.c
net/core/netpoll.c
net/ipv4/ip_tunnel.c
net/ipv6/addrconf.c
net/ipv6/ip6_tunnel.c
net/ipv6/route.c
net/mpls/af_mpls.c
net/netlabel/netlabel_unlabeled.c
net/nfc/hci/core.c
net/rds/ib.h
net/sctp/transport.c
net/smc/af_smc.c
net/smc/smc_clc.c
net/smc/smc_close.c
net/smc/smc_pnet.c
security/keys/dh.c
tools/include/tools/libc_compat.h
tools/testing/selftests/bpf/test_maps.c
tools/testing/selftests/net/pmtu.sh

index 3f4f6c9..a4222b6 100644 (file)
@@ -33,4 +33,3 @@ Video Function Calls
     video-clear-buffer
     video-set-streamtype
     video-set-format
-    video-set-attributes
index 02a3961..a255240 100644 (file)
@@ -9716,13 +9716,6 @@ Q:       http://patchwork.linuxtv.org/project/linux-media/list/
 S:     Maintained
 F:     drivers/media/dvb-frontends/mn88473*
 
-PCI DRIVER FOR MOBIVEIL PCIE IP
-M:     Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
-L:     linux-pci@vger.kernel.org
-S:     Supported
-F:     Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
-F:     drivers/pci/controller/pcie-mobiveil.c
-
 MODULE SUPPORT
 M:     Jessica Yu <jeyu@kernel.org>
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux.git modules-next
@@ -11137,6 +11130,13 @@ F:     include/uapi/linux/switchtec_ioctl.h
 F:     include/linux/switchtec.h
 F:     drivers/ntb/hw/mscc/
 
+PCI DRIVER FOR MOBIVEIL PCIE IP
+M:     Subrahmanya Lingappa <l.subrahmanya@mobiveil.co.in>
+L:     linux-pci@vger.kernel.org
+S:     Supported
+F:     Documentation/devicetree/bindings/pci/mobiveil-pcie.txt
+F:     drivers/pci/controller/pcie-mobiveil.c
+
 PCI DRIVER FOR MVEBU (Marvell Armada 370 and Armada XP SOC support)
 M:     Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
 M:     Jason Cooper <jason@lakedaemon.net>
@@ -11203,8 +11203,14 @@ F:     tools/pci/
 
 PCI ENHANCED ERROR HANDLING (EEH) FOR POWERPC
 M:     Russell Currey <ruscur@russell.cc>
+M:     Sam Bobroff <sbobroff@linux.ibm.com>
+M:     Oliver O'Halloran <oohall@gmail.com>
 L:     linuxppc-dev@lists.ozlabs.org
 S:     Supported
+F:     Documentation/PCI/pci-error-recovery.txt
+F:     drivers/pci/pcie/aer.c
+F:     drivers/pci/pcie/dpc.c
+F:     drivers/pci/pcie/err.c
 F:     Documentation/powerpc/eeh-pci-error-recovery.txt
 F:     arch/powerpc/kernel/eeh*.c
 F:     arch/powerpc/platforms/*/eeh*.c
diff --git a/arch/riscv/include/asm/asm-prototypes.h b/arch/riscv/include/asm/asm-prototypes.h
new file mode 100644 (file)
index 0000000..c9fecd1
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _ASM_RISCV_PROTOTYPES_H
+
+#include <linux/ftrace.h>
+#include <asm-generic/asm-prototypes.h>
+
+#endif /* _ASM_RISCV_PROTOTYPES_H */
index bbe4d72..948806e 100644 (file)
@@ -535,6 +535,11 @@ static unsigned long dax_get_unmapped_area(struct file *filp,
        return current->mm->get_unmapped_area(filp, addr, len, pgoff, flags);
 }
 
+static const struct address_space_operations dev_dax_aops = {
+       .set_page_dirty         = noop_set_page_dirty,
+       .invalidatepage         = noop_invalidatepage,
+};
+
 static int dax_open(struct inode *inode, struct file *filp)
 {
        struct dax_device *dax_dev = inode_dax(inode);
@@ -544,6 +549,7 @@ static int dax_open(struct inode *inode, struct file *filp)
        dev_dbg(&dev_dax->dev, "trace\n");
        inode->i_mapping = __dax_inode->i_mapping;
        inode->i_mapping->host = __dax_inode;
+       inode->i_mapping->a_ops = &dev_dax_aops;
        filp->f_mapping = inode->i_mapping;
        filp->f_wb_err = filemap_sample_wb_err(filp->f_mapping);
        filp->private_data = dev_dax;
index da962aa..fc6b7f8 100644 (file)
@@ -139,7 +139,8 @@ static int intel_th_remove(struct device *dev)
                        th->thdev[i] = NULL;
                }
 
-               th->num_thdevs = lowest;
+               if (lowest >= 0)
+                       th->num_thdevs = lowest;
        }
 
        if (thdrv->attr_group)
@@ -487,7 +488,7 @@ static const struct intel_th_subdevice {
                                .flags  = IORESOURCE_MEM,
                        },
                        {
-                               .start  = TH_MMIO_SW,
+                               .start  = 1, /* use resource[1] */
                                .end    = 0,
                                .flags  = IORESOURCE_MEM,
                        },
@@ -580,6 +581,7 @@ intel_th_subdevice_alloc(struct intel_th *th,
        struct intel_th_device *thdev;
        struct resource res[3];
        unsigned int req = 0;
+       bool is64bit = false;
        int r, err;
 
        thdev = intel_th_device_alloc(th, subdev->type, subdev->name,
@@ -589,12 +591,18 @@ intel_th_subdevice_alloc(struct intel_th *th,
 
        thdev->drvdata = th->drvdata;
 
+       for (r = 0; r < th->num_resources; r++)
+               if (th->resource[r].flags & IORESOURCE_MEM_64) {
+                       is64bit = true;
+                       break;
+               }
+
        memcpy(res, subdev->res,
               sizeof(struct resource) * subdev->nres);
 
        for (r = 0; r < subdev->nres; r++) {
                struct resource *devres = th->resource;
-               int bar = TH_MMIO_CONFIG;
+               int bar = 0; /* cut subdevices' MMIO from resource[0] */
 
                /*
                 * Take .end == 0 to mean 'take the whole bar',
@@ -603,6 +611,8 @@ intel_th_subdevice_alloc(struct intel_th *th,
                 */
                if (!res[r].end && res[r].flags == IORESOURCE_MEM) {
                        bar = res[r].start;
+                       if (is64bit)
+                               bar *= 2;
                        res[r].start = 0;
                        res[r].end = resource_size(&devres[bar]) - 1;
                }
index c2e55e5..1cf6290 100644 (file)
@@ -160,6 +160,11 @@ static const struct pci_device_id intel_th_pci_id_table[] = {
                PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x18e1),
                .driver_data = (kernel_ulong_t)&intel_th_2x,
        },
+       {
+               /* Ice Lake PCH */
+               PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x34a6),
+               .driver_data = (kernel_ulong_t)&intel_th_2x,
+       },
        { 0 },
 };
 
index 0bee1f4..3208ad6 100644 (file)
@@ -337,6 +337,39 @@ static int add_roce_gid(struct ib_gid_table_entry *entry)
        return 0;
 }
 
+/**
+ * del_gid - Delete GID table entry
+ *
+ * @ib_dev:    IB device whose GID entry to be deleted
+ * @port:      Port number of the IB device
+ * @table:     GID table of the IB device for a port
+ * @ix:                GID entry index to delete
+ *
+ */
+static void del_gid(struct ib_device *ib_dev, u8 port,
+                   struct ib_gid_table *table, int ix)
+{
+       struct ib_gid_table_entry *entry;
+
+       lockdep_assert_held(&table->lock);
+
+       pr_debug("%s device=%s port=%d index=%d gid %pI6\n", __func__,
+                ib_dev->name, port, ix,
+                table->data_vec[ix]->attr.gid.raw);
+
+       write_lock_irq(&table->rwlock);
+       entry = table->data_vec[ix];
+       entry->state = GID_TABLE_ENTRY_PENDING_DEL;
+       /*
+        * For non RoCE protocol, GID entry slot is ready to use.
+        */
+       if (!rdma_protocol_roce(ib_dev, port))
+               table->data_vec[ix] = NULL;
+       write_unlock_irq(&table->rwlock);
+
+       put_gid_entry_locked(entry);
+}
+
 /**
  * add_modify_gid - Add or modify GID table entry
  *
@@ -358,7 +391,7 @@ static int add_modify_gid(struct ib_gid_table *table,
         * this index.
         */
        if (is_gid_entry_valid(table->data_vec[attr->index]))
-               put_gid_entry(table->data_vec[attr->index]);
+               del_gid(attr->device, attr->port_num, table, attr->index);
 
        /*
         * Some HCA's report multiple GID entries with only one valid GID, and
@@ -386,39 +419,6 @@ done:
        return ret;
 }
 
-/**
- * del_gid - Delete GID table entry
- *
- * @ib_dev:    IB device whose GID entry to be deleted
- * @port:      Port number of the IB device
- * @table:     GID table of the IB device for a port
- * @ix:                GID entry index to delete
- *
- */
-static void del_gid(struct ib_device *ib_dev, u8 port,
-                   struct ib_gid_table *table, int ix)
-{
-       struct ib_gid_table_entry *entry;
-
-       lockdep_assert_held(&table->lock);
-
-       pr_debug("%s device=%s port=%d index=%d gid %pI6\n", __func__,
-                ib_dev->name, port, ix,
-                table->data_vec[ix]->attr.gid.raw);
-
-       write_lock_irq(&table->rwlock);
-       entry = table->data_vec[ix];
-       entry->state = GID_TABLE_ENTRY_PENDING_DEL;
-       /*
-        * For non RoCE protocol, GID entry slot is ready to use.
-        */
-       if (!rdma_protocol_roce(ib_dev, port))
-               table->data_vec[ix] = NULL;
-       write_unlock_irq(&table->rwlock);
-
-       put_gid_entry_locked(entry);
-}
-
 /* rwlock should be read locked, or lock should be held */
 static int find_gid(struct ib_gid_table *table, const union ib_gid *gid,
                    const struct ib_gid_attr *val, bool default_gid,
index 5f437d1..21863dd 100644 (file)
@@ -1759,6 +1759,8 @@ static int ucma_close(struct inode *inode, struct file *filp)
                mutex_lock(&mut);
                if (!ctx->closing) {
                        mutex_unlock(&mut);
+                       ucma_put_ctx(ctx);
+                       wait_for_completion(&ctx->comp);
                        /* rdma_destroy_id ensures that no event handlers are
                         * inflight for that id before releasing it.
                         */
index a21d521..e012ca8 100644 (file)
@@ -2027,33 +2027,55 @@ static int modify_qp(struct ib_uverbs_file *file,
 
        if ((cmd->base.attr_mask & IB_QP_CUR_STATE &&
            cmd->base.cur_qp_state > IB_QPS_ERR) ||
-           cmd->base.qp_state > IB_QPS_ERR) {
+           (cmd->base.attr_mask & IB_QP_STATE &&
+           cmd->base.qp_state > IB_QPS_ERR)) {
                ret = -EINVAL;
                goto release_qp;
        }
 
-       attr->qp_state            = cmd->base.qp_state;
-       attr->cur_qp_state        = cmd->base.cur_qp_state;
-       attr->path_mtu            = cmd->base.path_mtu;
-       attr->path_mig_state      = cmd->base.path_mig_state;
-       attr->qkey                = cmd->base.qkey;
-       attr->rq_psn              = cmd->base.rq_psn;
-       attr->sq_psn              = cmd->base.sq_psn;
-       attr->dest_qp_num         = cmd->base.dest_qp_num;
-       attr->qp_access_flags     = cmd->base.qp_access_flags;
-       attr->pkey_index          = cmd->base.pkey_index;
-       attr->alt_pkey_index      = cmd->base.alt_pkey_index;
-       attr->en_sqd_async_notify = cmd->base.en_sqd_async_notify;
-       attr->max_rd_atomic       = cmd->base.max_rd_atomic;
-       attr->max_dest_rd_atomic  = cmd->base.max_dest_rd_atomic;
-       attr->min_rnr_timer       = cmd->base.min_rnr_timer;
-       attr->port_num            = cmd->base.port_num;
-       attr->timeout             = cmd->base.timeout;
-       attr->retry_cnt           = cmd->base.retry_cnt;
-       attr->rnr_retry           = cmd->base.rnr_retry;
-       attr->alt_port_num        = cmd->base.alt_port_num;
-       attr->alt_timeout         = cmd->base.alt_timeout;
-       attr->rate_limit          = cmd->rate_limit;
+       if (cmd->base.attr_mask & IB_QP_STATE)
+               attr->qp_state = cmd->base.qp_state;
+       if (cmd->base.attr_mask & IB_QP_CUR_STATE)
+               attr->cur_qp_state = cmd->base.cur_qp_state;
+       if (cmd->base.attr_mask & IB_QP_PATH_MTU)
+               attr->path_mtu = cmd->base.path_mtu;
+       if (cmd->base.attr_mask & IB_QP_PATH_MIG_STATE)
+               attr->path_mig_state = cmd->base.path_mig_state;
+       if (cmd->base.attr_mask & IB_QP_QKEY)
+               attr->qkey = cmd->base.qkey;
+       if (cmd->base.attr_mask & IB_QP_RQ_PSN)
+               attr->rq_psn = cmd->base.rq_psn;
+       if (cmd->base.attr_mask & IB_QP_SQ_PSN)
+               attr->sq_psn = cmd->base.sq_psn;
+       if (cmd->base.attr_mask & IB_QP_DEST_QPN)
+               attr->dest_qp_num = cmd->base.dest_qp_num;
+       if (cmd->base.attr_mask & IB_QP_ACCESS_FLAGS)
+               attr->qp_access_flags = cmd->base.qp_access_flags;
+       if (cmd->base.attr_mask & IB_QP_PKEY_INDEX)
+               attr->pkey_index = cmd->base.pkey_index;
+       if (cmd->base.attr_mask & IB_QP_EN_SQD_ASYNC_NOTIFY)
+               attr->en_sqd_async_notify = cmd->base.en_sqd_async_notify;
+       if (cmd->base.attr_mask & IB_QP_MAX_QP_RD_ATOMIC)
+               attr->max_rd_atomic = cmd->base.max_rd_atomic;
+       if (cmd->base.attr_mask & IB_QP_MAX_DEST_RD_ATOMIC)
+               attr->max_dest_rd_atomic = cmd->base.max_dest_rd_atomic;
+       if (cmd->base.attr_mask & IB_QP_MIN_RNR_TIMER)
+               attr->min_rnr_timer = cmd->base.min_rnr_timer;
+       if (cmd->base.attr_mask & IB_QP_PORT)
+               attr->port_num = cmd->base.port_num;
+       if (cmd->base.attr_mask & IB_QP_TIMEOUT)
+               attr->timeout = cmd->base.timeout;
+       if (cmd->base.attr_mask & IB_QP_RETRY_CNT)
+               attr->retry_cnt = cmd->base.retry_cnt;
+       if (cmd->base.attr_mask & IB_QP_RNR_RETRY)
+               attr->rnr_retry = cmd->base.rnr_retry;
+       if (cmd->base.attr_mask & IB_QP_ALT_PATH) {
+               attr->alt_port_num = cmd->base.alt_port_num;
+               attr->alt_timeout = cmd->base.alt_timeout;
+               attr->alt_pkey_index = cmd->base.alt_pkey_index;
+       }
+       if (cmd->base.attr_mask & IB_QP_RATE_LIMIT)
+               attr->rate_limit = cmd->rate_limit;
 
        if (cmd->base.attr_mask & IB_QP_AV)
                copy_ah_attr_from_uverbs(qp->device, &attr->ah_attr,
index 6d974e2..50152c1 100644 (file)
@@ -440,6 +440,7 @@ static int ib_uverbs_comp_event_close(struct inode *inode, struct file *filp)
                        list_del(&entry->obj_list);
                kfree(entry);
        }
+       file->ev_queue.is_closed = 1;
        spin_unlock_irq(&file->ev_queue.lock);
 
        uverbs_close_fd(filp);
index 73ea6f0..be85462 100644 (file)
@@ -248,6 +248,7 @@ void uverbs_destroy_api(struct uverbs_api *uapi)
                kfree(rcu_dereference_protected(*slot, true));
                radix_tree_iter_delete(&uapi->radix, &iter, slot);
        }
+       kfree(uapi);
 }
 
 struct uverbs_api *uverbs_alloc_api(
index 20b9f31..85cd1a3 100644 (file)
@@ -78,7 +78,7 @@ static struct list_head bnxt_re_dev_list = LIST_HEAD_INIT(bnxt_re_dev_list);
 /* Mutex to protect the list of bnxt_re devices added */
 static DEFINE_MUTEX(bnxt_re_dev_lock);
 static struct workqueue_struct *bnxt_re_wq;
-static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait);
+static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev);
 
 /* SR-IOV helper functions */
 
@@ -182,7 +182,7 @@ static void bnxt_re_shutdown(void *p)
        if (!rdev)
                return;
 
-       bnxt_re_ib_unreg(rdev, false);
+       bnxt_re_ib_unreg(rdev);
 }
 
 static void bnxt_re_stop_irq(void *handle)
@@ -251,7 +251,7 @@ static struct bnxt_ulp_ops bnxt_re_ulp_ops = {
 /* Driver registration routines used to let the networking driver (bnxt_en)
  * to know that the RoCE driver is now installed
  */
-static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev, bool lock_wait)
+static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev)
 {
        struct bnxt_en_dev *en_dev;
        int rc;
@@ -260,14 +260,9 @@ static int bnxt_re_unregister_netdev(struct bnxt_re_dev *rdev, bool lock_wait)
                return -EINVAL;
 
        en_dev = rdev->en_dev;
-       /* Acquire rtnl lock if it is not invokded from netdev event */
-       if (lock_wait)
-               rtnl_lock();
 
        rc = en_dev->en_ops->bnxt_unregister_device(rdev->en_dev,
                                                    BNXT_ROCE_ULP);
-       if (lock_wait)
-               rtnl_unlock();
        return rc;
 }
 
@@ -281,14 +276,12 @@ static int bnxt_re_register_netdev(struct bnxt_re_dev *rdev)
 
        en_dev = rdev->en_dev;
 
-       rtnl_lock();
        rc = en_dev->en_ops->bnxt_register_device(en_dev, BNXT_ROCE_ULP,
                                                  &bnxt_re_ulp_ops, rdev);
-       rtnl_unlock();
        return rc;
 }
 
-static int bnxt_re_free_msix(struct bnxt_re_dev *rdev, bool lock_wait)
+static int bnxt_re_free_msix(struct bnxt_re_dev *rdev)
 {
        struct bnxt_en_dev *en_dev;
        int rc;
@@ -298,13 +291,9 @@ static int bnxt_re_free_msix(struct bnxt_re_dev *rdev, bool lock_wait)
 
        en_dev = rdev->en_dev;
 
-       if (lock_wait)
-               rtnl_lock();
 
        rc = en_dev->en_ops->bnxt_free_msix(rdev->en_dev, BNXT_ROCE_ULP);
 
-       if (lock_wait)
-               rtnl_unlock();
        return rc;
 }
 
@@ -320,7 +309,6 @@ static int bnxt_re_request_msix(struct bnxt_re_dev *rdev)
 
        num_msix_want = min_t(u32, BNXT_RE_MAX_MSIX, num_online_cpus());
 
-       rtnl_lock();
        num_msix_got = en_dev->en_ops->bnxt_request_msix(en_dev, BNXT_ROCE_ULP,
                                                         rdev->msix_entries,
                                                         num_msix_want);
@@ -335,7 +323,6 @@ static int bnxt_re_request_msix(struct bnxt_re_dev *rdev)
        }
        rdev->num_msix = num_msix_got;
 done:
-       rtnl_unlock();
        return rc;
 }
 
@@ -358,24 +345,18 @@ static void bnxt_re_fill_fw_msg(struct bnxt_fw_msg *fw_msg, void *msg,
        fw_msg->timeout = timeout;
 }
 
-static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, u16 fw_ring_id,
-                                bool lock_wait)
+static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, u16 fw_ring_id)
 {
        struct bnxt_en_dev *en_dev = rdev->en_dev;
        struct hwrm_ring_free_input req = {0};
        struct hwrm_ring_free_output resp;
        struct bnxt_fw_msg fw_msg;
-       bool do_unlock = false;
        int rc = -EINVAL;
 
        if (!en_dev)
                return rc;
 
        memset(&fw_msg, 0, sizeof(fw_msg));
-       if (lock_wait) {
-               rtnl_lock();
-               do_unlock = true;
-       }
 
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_FREE, -1, -1);
        req.ring_type = RING_ALLOC_REQ_RING_TYPE_L2_CMPL;
@@ -386,8 +367,6 @@ static int bnxt_re_net_ring_free(struct bnxt_re_dev *rdev, u16 fw_ring_id,
        if (rc)
                dev_err(rdev_to_dev(rdev),
                        "Failed to free HW ring:%d :%#x", req.ring_id, rc);
-       if (do_unlock)
-               rtnl_unlock();
        return rc;
 }
 
@@ -405,7 +384,6 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
                return rc;
 
        memset(&fw_msg, 0, sizeof(fw_msg));
-       rtnl_lock();
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_RING_ALLOC, -1, -1);
        req.enables = 0;
        req.page_tbl_addr =  cpu_to_le64(dma_arr[0]);
@@ -426,27 +404,21 @@ static int bnxt_re_net_ring_alloc(struct bnxt_re_dev *rdev, dma_addr_t *dma_arr,
        if (!rc)
                *fw_ring_id = le16_to_cpu(resp.ring_id);
 
-       rtnl_unlock();
        return rc;
 }
 
 static int bnxt_re_net_stats_ctx_free(struct bnxt_re_dev *rdev,
-                                     u32 fw_stats_ctx_id, bool lock_wait)
+                                     u32 fw_stats_ctx_id)
 {
        struct bnxt_en_dev *en_dev = rdev->en_dev;
        struct hwrm_stat_ctx_free_input req = {0};
        struct bnxt_fw_msg fw_msg;
-       bool do_unlock = false;
        int rc = -EINVAL;
 
        if (!en_dev)
                return rc;
 
        memset(&fw_msg, 0, sizeof(fw_msg));
-       if (lock_wait) {
-               rtnl_lock();
-               do_unlock = true;
-       }
 
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_FREE, -1, -1);
        req.stat_ctx_id = cpu_to_le32(fw_stats_ctx_id);
@@ -457,8 +429,6 @@ static int bnxt_re_net_stats_ctx_free(struct bnxt_re_dev *rdev,
                dev_err(rdev_to_dev(rdev),
                        "Failed to free HW stats context %#x", rc);
 
-       if (do_unlock)
-               rtnl_unlock();
        return rc;
 }
 
@@ -478,7 +448,6 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev,
                return rc;
 
        memset(&fw_msg, 0, sizeof(fw_msg));
-       rtnl_lock();
 
        bnxt_re_init_hwrm_hdr(rdev, (void *)&req, HWRM_STAT_CTX_ALLOC, -1, -1);
        req.update_period_ms = cpu_to_le32(1000);
@@ -490,7 +459,6 @@ static int bnxt_re_net_stats_ctx_alloc(struct bnxt_re_dev *rdev,
        if (!rc)
                *fw_stats_ctx_id = le32_to_cpu(resp.stat_ctx_id);
 
-       rtnl_unlock();
        return rc;
 }
 
@@ -929,19 +897,19 @@ fail:
        return rc;
 }
 
-static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev, bool lock_wait)
+static void bnxt_re_free_nq_res(struct bnxt_re_dev *rdev)
 {
        int i;
 
        for (i = 0; i < rdev->num_msix - 1; i++) {
-               bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id, lock_wait);
+               bnxt_re_net_ring_free(rdev, rdev->nq[i].ring_id);
                bnxt_qplib_free_nq(&rdev->nq[i]);
        }
 }
 
-static void bnxt_re_free_res(struct bnxt_re_dev *rdev, bool lock_wait)
+static void bnxt_re_free_res(struct bnxt_re_dev *rdev)
 {
-       bnxt_re_free_nq_res(rdev, lock_wait);
+       bnxt_re_free_nq_res(rdev);
 
        if (rdev->qplib_res.dpi_tbl.max) {
                bnxt_qplib_dealloc_dpi(&rdev->qplib_res,
@@ -1219,7 +1187,7 @@ static int bnxt_re_setup_qos(struct bnxt_re_dev *rdev)
        return 0;
 }
 
-static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait)
+static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev)
 {
        int i, rc;
 
@@ -1234,28 +1202,27 @@ static void bnxt_re_ib_unreg(struct bnxt_re_dev *rdev, bool lock_wait)
                cancel_delayed_work(&rdev->worker);
 
        bnxt_re_cleanup_res(rdev);
-       bnxt_re_free_res(rdev, lock_wait);
+       bnxt_re_free_res(rdev);
 
        if (test_and_clear_bit(BNXT_RE_FLAG_RCFW_CHANNEL_EN, &rdev->flags)) {
                rc = bnxt_qplib_deinit_rcfw(&rdev->rcfw);
                if (rc)
                        dev_warn(rdev_to_dev(rdev),
                                 "Failed to deinitialize RCFW: %#x", rc);
-               bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id,
-                                          lock_wait);
+               bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
                bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx);
                bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
-               bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, lock_wait);
+               bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id);
                bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
        }
        if (test_and_clear_bit(BNXT_RE_FLAG_GOT_MSIX, &rdev->flags)) {
-               rc = bnxt_re_free_msix(rdev, lock_wait);
+               rc = bnxt_re_free_msix(rdev);
                if (rc)
                        dev_warn(rdev_to_dev(rdev),
                                 "Failed to free MSI-X vectors: %#x", rc);
        }
        if (test_and_clear_bit(BNXT_RE_FLAG_NETDEV_REGISTERED, &rdev->flags)) {
-               rc = bnxt_re_unregister_netdev(rdev, lock_wait);
+               rc = bnxt_re_unregister_netdev(rdev);
                if (rc)
                        dev_warn(rdev_to_dev(rdev),
                                 "Failed to unregister with netdev: %#x", rc);
@@ -1276,6 +1243,12 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 {
        int i, j, rc;
 
+       bool locked;
+
+       /* Acquire rtnl lock through out this function */
+       rtnl_lock();
+       locked = true;
+
        /* Registered a new RoCE device instance to netdev */
        rc = bnxt_re_register_netdev(rdev);
        if (rc) {
@@ -1374,12 +1347,16 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
                schedule_delayed_work(&rdev->worker, msecs_to_jiffies(30000));
        }
 
+       rtnl_unlock();
+       locked = false;
+
        /* Register ib dev */
        rc = bnxt_re_register_ib(rdev);
        if (rc) {
                pr_err("Failed to register with IB: %#x\n", rc);
                goto fail;
        }
+       set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags);
        dev_info(rdev_to_dev(rdev), "Device registered successfully");
        for (i = 0; i < ARRAY_SIZE(bnxt_re_attributes); i++) {
                rc = device_create_file(&rdev->ibdev.dev,
@@ -1395,7 +1372,6 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
                        goto fail;
                }
        }
-       set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags);
        ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed,
                         &rdev->active_width);
        set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);
@@ -1404,17 +1380,21 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
 
        return 0;
 free_sctx:
-       bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id, true);
+       bnxt_re_net_stats_ctx_free(rdev, rdev->qplib_ctx.stats.fw_id);
 free_ctx:
        bnxt_qplib_free_ctx(rdev->en_dev->pdev, &rdev->qplib_ctx);
 disable_rcfw:
        bnxt_qplib_disable_rcfw_channel(&rdev->rcfw);
 free_ring:
-       bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id, true);
+       bnxt_re_net_ring_free(rdev, rdev->rcfw.creq_ring_id);
 free_rcfw:
        bnxt_qplib_free_rcfw_channel(&rdev->rcfw);
 fail:
-       bnxt_re_ib_unreg(rdev, true);
+       if (!locked)
+               rtnl_lock();
+       bnxt_re_ib_unreg(rdev);
+       rtnl_unlock();
+
        return rc;
 }
 
@@ -1567,7 +1547,7 @@ static int bnxt_re_netdev_event(struct notifier_block *notifier,
                 */
                if (atomic_read(&rdev->sched_count) > 0)
                        goto exit;
-               bnxt_re_ib_unreg(rdev, false);
+               bnxt_re_ib_unreg(rdev);
                bnxt_re_remove_one(rdev);
                bnxt_re_dev_unreg(rdev);
                break;
@@ -1646,7 +1626,10 @@ static void __exit bnxt_re_mod_exit(void)
                 */
                flush_workqueue(bnxt_re_wq);
                bnxt_re_dev_stop(rdev);
-               bnxt_re_ib_unreg(rdev, true);
+               /* Acquire the rtnl_lock as the L2 resources are freed here */
+               rtnl_lock();
+               bnxt_re_ib_unreg(rdev);
+               rtnl_unlock();
                bnxt_re_remove_one(rdev);
                bnxt_re_dev_unreg(rdev);
        }
index 2c19bf7..e1668bc 100644 (file)
@@ -6733,6 +6733,7 @@ void start_freeze_handling(struct hfi1_pportdata *ppd, int flags)
        struct hfi1_devdata *dd = ppd->dd;
        struct send_context *sc;
        int i;
+       int sc_flags;
 
        if (flags & FREEZE_SELF)
                write_csr(dd, CCE_CTRL, CCE_CTRL_SPC_FREEZE_SMASK);
@@ -6743,11 +6744,13 @@ void start_freeze_handling(struct hfi1_pportdata *ppd, int flags)
        /* notify all SDMA engines that they are going into a freeze */
        sdma_freeze_notify(dd, !!(flags & FREEZE_LINK_DOWN));
 
+       sc_flags = SCF_FROZEN | SCF_HALTED | (flags & FREEZE_LINK_DOWN ?
+                                             SCF_LINK_DOWN : 0);
        /* do halt pre-handling on all enabled send contexts */
        for (i = 0; i < dd->num_send_contexts; i++) {
                sc = dd->send_contexts[i].sc;
                if (sc && (sc->flags & SCF_ENABLED))
-                       sc_stop(sc, SCF_FROZEN | SCF_HALTED);
+                       sc_stop(sc, sc_flags);
        }
 
        /* Send context are frozen. Notify user space */
@@ -10674,6 +10677,7 @@ int set_link_state(struct hfi1_pportdata *ppd, u32 state)
                add_rcvctrl(dd, RCV_CTRL_RCV_PORT_ENABLE_SMASK);
 
                handle_linkup_change(dd, 1);
+               pio_kernel_linkup(dd);
 
                /*
                 * After link up, a new link width will have been set.
index c2c1cba..7520576 100644 (file)
@@ -86,6 +86,7 @@ void pio_send_control(struct hfi1_devdata *dd, int op)
        unsigned long flags;
        int write = 1;  /* write sendctrl back */
        int flush = 0;  /* re-read sendctrl to make sure it is flushed */
+       int i;
 
        spin_lock_irqsave(&dd->sendctrl_lock, flags);
 
@@ -95,9 +96,13 @@ void pio_send_control(struct hfi1_devdata *dd, int op)
                reg |= SEND_CTRL_SEND_ENABLE_SMASK;
        /* Fall through */
        case PSC_DATA_VL_ENABLE:
+               mask = 0;
+               for (i = 0; i < ARRAY_SIZE(dd->vld); i++)
+                       if (!dd->vld[i].mtu)
+                               mask |= BIT_ULL(i);
                /* Disallow sending on VLs not enabled */
-               mask = (((~0ull) << num_vls) & SEND_CTRL_UNSUPPORTED_VL_MASK) <<
-                               SEND_CTRL_UNSUPPORTED_VL_SHIFT;
+               mask = (mask & SEND_CTRL_UNSUPPORTED_VL_MASK) <<
+                       SEND_CTRL_UNSUPPORTED_VL_SHIFT;
                reg = (reg & ~SEND_CTRL_UNSUPPORTED_VL_SMASK) | mask;
                break;
        case PSC_GLOBAL_DISABLE:
@@ -921,20 +926,18 @@ void sc_free(struct send_context *sc)
 void sc_disable(struct send_context *sc)
 {
        u64 reg;
-       unsigned long flags;
        struct pio_buf *pbuf;
 
        if (!sc)
                return;
 
        /* do all steps, even if already disabled */
-       spin_lock_irqsave(&sc->alloc_lock, flags);
+       spin_lock_irq(&sc->alloc_lock);
        reg = read_kctxt_csr(sc->dd, sc->hw_context, SC(CTRL));
        reg &= ~SC(CTRL_CTXT_ENABLE_SMASK);
        sc->flags &= ~SCF_ENABLED;
        sc_wait_for_packet_egress(sc, 1);
        write_kctxt_csr(sc->dd, sc->hw_context, SC(CTRL), reg);
-       spin_unlock_irqrestore(&sc->alloc_lock, flags);
 
        /*
         * Flush any waiters.  Once the context is disabled,
@@ -944,7 +947,7 @@ void sc_disable(struct send_context *sc)
         * proceed with the flush.
         */
        udelay(1);
-       spin_lock_irqsave(&sc->release_lock, flags);
+       spin_lock(&sc->release_lock);
        if (sc->sr) {   /* this context has a shadow ring */
                while (sc->sr_tail != sc->sr_head) {
                        pbuf = &sc->sr[sc->sr_tail].pbuf;
@@ -955,7 +958,8 @@ void sc_disable(struct send_context *sc)
                                sc->sr_tail = 0;
                }
        }
-       spin_unlock_irqrestore(&sc->release_lock, flags);
+       spin_unlock(&sc->release_lock);
+       spin_unlock_irq(&sc->alloc_lock);
 }
 
 /* return SendEgressCtxtStatus.PacketOccupancy */
@@ -1178,11 +1182,39 @@ void pio_kernel_unfreeze(struct hfi1_devdata *dd)
                sc = dd->send_contexts[i].sc;
                if (!sc || !(sc->flags & SCF_FROZEN) || sc->type == SC_USER)
                        continue;
+               if (sc->flags & SCF_LINK_DOWN)
+                       continue;
 
                sc_enable(sc);  /* will clear the sc frozen flag */
        }
 }
 
+/**
+ * pio_kernel_linkup() - Re-enable send contexts after linkup event
+ * @dd: valid devive data
+ *
+ * When the link goes down, the freeze path is taken.  However, a link down
+ * event is different from a freeze because if the send context is re-enabled
+ * whowever is sending data will start sending data again, which will hang
+ * any QP that is sending data.
+ *
+ * The freeze path now looks at the type of event that occurs and takes this
+ * path for link down event.
+ */
+void pio_kernel_linkup(struct hfi1_devdata *dd)
+{
+       struct send_context *sc;
+       int i;
+
+       for (i = 0; i < dd->num_send_contexts; i++) {
+               sc = dd->send_contexts[i].sc;
+               if (!sc || !(sc->flags & SCF_LINK_DOWN) || sc->type == SC_USER)
+                       continue;
+
+               sc_enable(sc);  /* will clear the sc link down flag */
+       }
+}
+
 /*
  * Wait for the SendPioInitCtxt.PioInitInProgress bit to clear.
  * Returns:
@@ -1382,11 +1414,10 @@ void sc_stop(struct send_context *sc, int flag)
 {
        unsigned long flags;
 
-       /* mark the context */
-       sc->flags |= flag;
-
        /* stop buffer allocations */
        spin_lock_irqsave(&sc->alloc_lock, flags);
+       /* mark the context */
+       sc->flags |= flag;
        sc->flags &= ~SCF_ENABLED;
        spin_unlock_irqrestore(&sc->alloc_lock, flags);
        wake_up(&sc->halt_wait);
index 058b08f..aaf372c 100644 (file)
@@ -139,6 +139,7 @@ struct send_context {
 #define SCF_IN_FREE 0x02
 #define SCF_HALTED  0x04
 #define SCF_FROZEN  0x08
+#define SCF_LINK_DOWN 0x10
 
 struct send_context_info {
        struct send_context *sc;        /* allocated working context */
@@ -306,6 +307,7 @@ void set_pio_integrity(struct send_context *sc);
 void pio_reset_all(struct hfi1_devdata *dd);
 void pio_freeze(struct hfi1_devdata *dd);
 void pio_kernel_unfreeze(struct hfi1_devdata *dd);
+void pio_kernel_linkup(struct hfi1_devdata *dd);
 
 /* global PIO send control operations */
 #define PSC_GLOBAL_ENABLE 0
index a3a7b33..5c88706 100644 (file)
@@ -828,7 +828,7 @@ static int user_sdma_send_pkts(struct user_sdma_request *req, unsigned maxpkts)
                        if (READ_ONCE(iovec->offset) == iovec->iov.iov_len) {
                                if (++req->iov_idx == req->data_iovs) {
                                        ret = -EFAULT;
-                                       goto free_txreq;
+                                       goto free_tx;
                                }
                                iovec = &req->iovs[req->iov_idx];
                                WARN_ON(iovec->offset);
index 13374c7..a7c586a 100644 (file)
@@ -1582,6 +1582,7 @@ static int hfi1_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr)
        struct hfi1_pportdata *ppd;
        struct hfi1_devdata *dd;
        u8 sc5;
+       u8 sl;
 
        if (hfi1_check_mcast(rdma_ah_get_dlid(ah_attr)) &&
            !(rdma_ah_get_ah_flags(ah_attr) & IB_AH_GRH))
@@ -1590,8 +1591,13 @@ static int hfi1_check_ah(struct ib_device *ibdev, struct rdma_ah_attr *ah_attr)
        /* test the mapping for validity */
        ibp = to_iport(ibdev, rdma_ah_get_port_num(ah_attr));
        ppd = ppd_from_ibp(ibp);
-       sc5 = ibp->sl_to_sc[rdma_ah_get_sl(ah_attr)];
        dd = dd_from_ppd(ppd);
+
+       sl = rdma_ah_get_sl(ah_attr);
+       if (sl >= ARRAY_SIZE(ibp->sl_to_sc))
+               return -EINVAL;
+
+       sc5 = ibp->sl_to_sc[sl];
        if (sc_to_vlt(dd, sc5) > num_vls && sc_to_vlt(dd, sc5) != 0xf)
                return -EINVAL;
        return 0;
index ac116d6..f2f11e6 100644 (file)
@@ -723,6 +723,7 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
                attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_HANDLE);
        struct mlx5_ib_ucontext *c = to_mucontext(uobj->context);
        struct mlx5_ib_dev *dev = to_mdev(c->ibucontext.device);
+       u32 out[MLX5_ST_SZ_DW(general_obj_out_cmd_hdr)];
        struct devx_obj *obj;
        int err;
 
@@ -754,10 +755,12 @@ static int UVERBS_HANDLER(MLX5_IB_METHOD_DEVX_OBJ_CREATE)(
 
        err = uverbs_copy_to(attrs, MLX5_IB_ATTR_DEVX_OBJ_CREATE_CMD_OUT, cmd_out, cmd_out_len);
        if (err)
-               goto obj_free;
+               goto obj_destroy;
 
        return 0;
 
+obj_destroy:
+       mlx5_cmd_exec(obj->mdev, obj->dinbox, obj->dinlen, out, sizeof(out));
 obj_free:
        kfree(obj);
        return err;
index 444d165..0b34e90 100644 (file)
@@ -2951,7 +2951,7 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
 {
        struct srp_target_port *target = host_to_target(scmnd->device->host);
        struct srp_rdma_ch *ch;
-       int i;
+       int i, j;
        u8 status;
 
        shost_printk(KERN_ERR, target->scsi_host, "SRP reset_device called\n");
@@ -2965,8 +2965,8 @@ static int srp_reset_device(struct scsi_cmnd *scmnd)
 
        for (i = 0; i < target->ch_count; i++) {
                ch = &target->ch[i];
-               for (i = 0; i < target->req_ring_size; ++i) {
-                       struct srp_request *req = &ch->req_ring[i];
+               for (j = 0; j < target->req_ring_size; ++j) {
+                       struct srp_request *req = &ch->req_ring[j];
 
                        srp_finish_req(ch, req, scmnd->device, DID_RESET << 16);
                }
index 4e04fff..73e47d9 100644 (file)
@@ -246,7 +246,13 @@ static u16 get_alias(struct device *dev)
 
        /* The callers make sure that get_device_id() does not fail here */
        devid = get_device_id(dev);
+
+       /* For ACPI HID devices, we simply return the devid as such */
+       if (!dev_is_pci(dev))
+               return devid;
+
        ivrs_alias = amd_iommu_alias_table[devid];
+
        pci_for_each_dma_alias(pdev, __last_alias, &pci_alias);
 
        if (ivrs_alias == pci_alias)
index 5f3f10c..bedc801 100644 (file)
@@ -2540,9 +2540,9 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
        if (dev && dev_is_pci(dev) && info->pasid_supported) {
                ret = intel_pasid_alloc_table(dev);
                if (ret) {
-                       __dmar_remove_one_dev_info(info);
-                       spin_unlock_irqrestore(&device_domain_lock, flags);
-                       return NULL;
+                       pr_warn("No pasid table for %s, pasid disabled\n",
+                               dev_name(dev));
+                       info->pasid_supported = 0;
                }
        }
        spin_unlock_irqrestore(&device_domain_lock, flags);
index 1c05ed6..1fb5e12 100644 (file)
@@ -11,7 +11,7 @@
 #define __INTEL_PASID_H
 
 #define PASID_MIN                      0x1
-#define PASID_MAX                      0x100000
+#define PASID_MAX                      0x20000
 
 struct pasid_entry {
        u64 val;
index 258115b..ad3e2b9 100644 (file)
@@ -1241,6 +1241,12 @@ err_unprepare_clocks:
 
 static void rk_iommu_shutdown(struct platform_device *pdev)
 {
+       struct rk_iommu *iommu = platform_get_drvdata(pdev);
+       int i = 0, irq;
+
+       while ((irq = platform_get_irq(pdev, i++)) != -ENXIO)
+               devm_free_irq(iommu->dev, irq, iommu);
+
        pm_runtime_force_suspend(&pdev->dev);
 }
 
index b5410ae..bb41bea 100644 (file)
@@ -1159,41 +1159,21 @@ static int mt9v111_probe(struct i2c_client *client)
                                              V4L2_CID_AUTO_WHITE_BALANCE,
                                              0, 1, 1,
                                              V4L2_WHITE_BALANCE_AUTO);
-       if (IS_ERR_OR_NULL(mt9v111->auto_awb)) {
-               ret = PTR_ERR(mt9v111->auto_awb);
-               goto error_free_ctrls;
-       }
-
        mt9v111->auto_exp = v4l2_ctrl_new_std_menu(&mt9v111->ctrls,
                                                   &mt9v111_ctrl_ops,
                                                   V4L2_CID_EXPOSURE_AUTO,
                                                   V4L2_EXPOSURE_MANUAL,
                                                   0, V4L2_EXPOSURE_AUTO);
-       if (IS_ERR_OR_NULL(mt9v111->auto_exp)) {
-               ret = PTR_ERR(mt9v111->auto_exp);
-               goto error_free_ctrls;
-       }
-
-       /* Initialize timings */
        mt9v111->hblank = v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops,
                                            V4L2_CID_HBLANK,
                                            MT9V111_CORE_R05_MIN_HBLANK,
                                            MT9V111_CORE_R05_MAX_HBLANK, 1,
                                            MT9V111_CORE_R05_DEF_HBLANK);
-       if (IS_ERR_OR_NULL(mt9v111->hblank)) {
-               ret = PTR_ERR(mt9v111->hblank);
-               goto error_free_ctrls;
-       }
-
        mt9v111->vblank = v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops,
                                            V4L2_CID_VBLANK,
                                            MT9V111_CORE_R06_MIN_VBLANK,
                                            MT9V111_CORE_R06_MAX_VBLANK, 1,
                                            MT9V111_CORE_R06_DEF_VBLANK);
-       if (IS_ERR_OR_NULL(mt9v111->vblank)) {
-               ret = PTR_ERR(mt9v111->vblank);
-               goto error_free_ctrls;
-       }
 
        /* PIXEL_RATE is fixed: just expose it to user space. */
        v4l2_ctrl_new_std(&mt9v111->ctrls, &mt9v111_ctrl_ops,
@@ -1201,6 +1181,10 @@ static int mt9v111_probe(struct i2c_client *client)
                          DIV_ROUND_CLOSEST(mt9v111->sysclk, 2), 1,
                          DIV_ROUND_CLOSEST(mt9v111->sysclk, 2));
 
+       if (mt9v111->ctrls.error) {
+               ret = mt9v111->ctrls.error;
+               goto error_free_ctrls;
+       }
        mt9v111->sd.ctrl_handler = &mt9v111->ctrls;
 
        /* Start with default configuration: 640x480 UYVY. */
@@ -1226,26 +1210,27 @@ static int mt9v111_probe(struct i2c_client *client)
        mt9v111->pad.flags      = MEDIA_PAD_FL_SOURCE;
        ret = media_entity_pads_init(&mt9v111->sd.entity, 1, &mt9v111->pad);
        if (ret)
-               goto error_free_ctrls;
+               goto error_free_entity;
 #endif
 
        ret = mt9v111_chip_probe(mt9v111);
        if (ret)
-               goto error_free_ctrls;
+               goto error_free_entity;
 
        ret = v4l2_async_register_subdev(&mt9v111->sd);
        if (ret)
-               goto error_free_ctrls;
+               goto error_free_entity;
 
        return 0;
 
-error_free_ctrls:
-       v4l2_ctrl_handler_free(&mt9v111->ctrls);
-
+error_free_entity:
 #if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
        media_entity_cleanup(&mt9v111->sd.entity);
 #endif
 
+error_free_ctrls:
+       v4l2_ctrl_handler_free(&mt9v111->ctrls);
+
        mutex_destroy(&mt9v111->pwr_mutex);
        mutex_destroy(&mt9v111->stream_mutex);
 
@@ -1259,12 +1244,12 @@ static int mt9v111_remove(struct i2c_client *client)
 
        v4l2_async_unregister_subdev(sd);
 
-       v4l2_ctrl_handler_free(&mt9v111->ctrls);
-
 #if IS_ENABLED(CONFIG_MEDIA_CONTROLLER)
        media_entity_cleanup(&sd->entity);
 #endif
 
+       v4l2_ctrl_handler_free(&mt9v111->ctrls);
+
        mutex_destroy(&mt9v111->pwr_mutex);
        mutex_destroy(&mt9v111->stream_mutex);
 
index 94c1fe0..54fe90a 100644 (file)
@@ -541,6 +541,8 @@ config VIDEO_CROS_EC_CEC
        depends on MFD_CROS_EC
        select CEC_CORE
        select CEC_NOTIFIER
+       select CHROME_PLATFORMS
+       select CROS_EC_PROTO
        ---help---
          If you say yes here you will get support for the
          ChromeOS Embedded Controller's CEC.
index 729b318..a5ae856 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
index c832539..12bce39 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #define CAMSS_CSI_PHY_LNn_CFG2(n)              (0x004 + 0x40 * (n))
 #define CAMSS_CSI_PHY_LNn_CFG3(n)              (0x008 + 0x40 * (n))
index bcd0dfd..2e65caf 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 
 #define CSIPHY_3PH_LNn_CFG1(n)                 (0x000 + 0x100 * (n))
 #define CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG    (BIT(7) | BIT(6))
index 4559f3b..008afb8 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
index 7f26902..1f33b4e 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/mutex.h>
@@ -1076,8 +1077,8 @@ int msm_ispif_subdev_init(struct ispif_device *ispif,
        else
                return -EINVAL;
 
-       ispif->line = kcalloc(ispif->line_num, sizeof(*ispif->line),
-                             GFP_KERNEL);
+       ispif->line = devm_kcalloc(dev, ispif->line_num, sizeof(*ispif->line),
+                                  GFP_KERNEL);
        if (!ispif->line)
                return -ENOMEM;
 
index da3a9fe..174a36b 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/iopoll.h>
 
 #include "camss-vfe.h"
index 4c584bf..0dca8bf 100644 (file)
@@ -9,6 +9,7 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/io.h>
 #include <linux/iopoll.h>
 
 #include "camss-vfe.h"
index dcc0c30..669615f 100644 (file)
@@ -848,17 +848,18 @@ static int camss_probe(struct platform_device *pdev)
                return -EINVAL;
        }
 
-       camss->csiphy = kcalloc(camss->csiphy_num, sizeof(*camss->csiphy),
-                               GFP_KERNEL);
+       camss->csiphy = devm_kcalloc(dev, camss->csiphy_num,
+                                    sizeof(*camss->csiphy), GFP_KERNEL);
        if (!camss->csiphy)
                return -ENOMEM;
 
-       camss->csid = kcalloc(camss->csid_num, sizeof(*camss->csid),
-                             GFP_KERNEL);
+       camss->csid = devm_kcalloc(dev, camss->csid_num, sizeof(*camss->csid),
+                                  GFP_KERNEL);
        if (!camss->csid)
                return -ENOMEM;
 
-       camss->vfe = kcalloc(camss->vfe_num, sizeof(*camss->vfe), GFP_KERNEL);
+       camss->vfe = devm_kcalloc(dev, camss->vfe_num, sizeof(*camss->vfe),
+                                 GFP_KERNEL);
        if (!camss->vfe)
                return -ENOMEM;
 
@@ -993,12 +994,12 @@ static const struct of_device_id camss_dt_match[] = {
 
 MODULE_DEVICE_TABLE(of, camss_dt_match);
 
-static int camss_runtime_suspend(struct device *dev)
+static int __maybe_unused camss_runtime_suspend(struct device *dev)
 {
        return 0;
 }
 
-static int camss_runtime_resume(struct device *dev)
+static int __maybe_unused camss_runtime_resume(struct device *dev)
 {
        return 0;
 }
index 666d319..1f6c1ee 100644 (file)
@@ -402,8 +402,10 @@ static int af9035_i2c_master_xfer(struct i2c_adapter *adap,
                        if (msg[0].addr == state->af9033_i2c_addr[1])
                                reg |= 0x100000;
 
-                       ret = af9035_wr_regs(d, reg, &msg[0].buf[3],
-                                       msg[0].len - 3);
+                       ret = (msg[0].len >= 3) ? af9035_wr_regs(d, reg,
+                                                                &msg[0].buf[3],
+                                                                msg[0].len - 3)
+                                               : -EOPNOTSUPP;
                } else {
                        /* I2C write */
                        u8 buf[MAX_XFER_SIZE];
index a764a83..0d87e11 100644 (file)
@@ -971,16 +971,13 @@ static void bond_poll_controller(struct net_device *bond_dev)
        struct slave *slave = NULL;
        struct list_head *iter;
        struct ad_info ad_info;
-       struct netpoll_info *ni;
-       const struct net_device_ops *ops;
 
        if (BOND_MODE(bond) == BOND_MODE_8023AD)
                if (bond_3ad_get_active_agg_info(bond, &ad_info))
                        return;
 
        bond_for_each_slave_rcu(bond, slave, iter) {
-               ops = slave->dev->netdev_ops;
-               if (!bond_slave_is_up(slave) || !ops->ndo_poll_controller)
+               if (!bond_slave_is_up(slave))
                        continue;
 
                if (BOND_MODE(bond) == BOND_MODE_8023AD) {
@@ -992,11 +989,7 @@ static void bond_poll_controller(struct net_device *bond_dev)
                                continue;
                }
 
-               ni = rcu_dereference_bh(slave->dev->npinfo);
-               if (down_trylock(&ni->dev_lock))
-                       continue;
-               ops->ndo_poll_controller(slave->dev);
-               up(&ni->dev_lock);
+               netpoll_poll_dev(slave->dev);
        }
 }
 
index 024998d..6a8e256 100644 (file)
@@ -154,7 +154,7 @@ static irqreturn_t bmac_txdma_intr(int irq, void *dev_id);
 static irqreturn_t bmac_rxdma_intr(int irq, void *dev_id);
 static void bmac_set_timeout(struct net_device *dev);
 static void bmac_tx_timeout(struct timer_list *t);
-static int bmac_output(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t bmac_output(struct sk_buff *skb, struct net_device *dev);
 static void bmac_start(struct net_device *dev);
 
 #define        DBDMA_SET(x)    ( ((x) | (x) << 16) )
@@ -1456,7 +1456,7 @@ bmac_start(struct net_device *dev)
        spin_unlock_irqrestore(&bp->lock, flags);
 }
 
-static int
+static netdev_tx_t
 bmac_output(struct sk_buff *skb, struct net_device *dev)
 {
        struct bmac_data *bp = netdev_priv(dev);
index 0b5429d..68b9ee4 100644 (file)
@@ -78,7 +78,7 @@ struct mace_data {
 
 static int mace_open(struct net_device *dev);
 static int mace_close(struct net_device *dev);
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
 static void mace_reset(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
@@ -525,7 +525,7 @@ static inline void mace_set_timeout(struct net_device *dev)
     mp->timeout_active = 1;
 }
 
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
     struct mace_data *mp = netdev_priv(dev);
     volatile struct dbdma_regs __iomem *td = mp->tx_dma;
index 137cbb4..376f2c2 100644 (file)
@@ -89,7 +89,7 @@ struct mace_frame {
 
 static int mace_open(struct net_device *dev);
 static int mace_close(struct net_device *dev);
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev);
 static void mace_set_multicast(struct net_device *dev);
 static int mace_set_address(struct net_device *dev, void *addr);
 static void mace_reset(struct net_device *dev);
@@ -444,7 +444,7 @@ static int mace_close(struct net_device *dev)
  * Transmit a frame
  */
 
-static int mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t mace_xmit_start(struct sk_buff *skb, struct net_device *dev)
 {
        struct mace_data *mp = netdev_priv(dev);
        unsigned long flags;
index b5f1f62..d1e1a0b 100644 (file)
@@ -225,9 +225,10 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
                }
 
                /* for single fragment packets use build_skb() */
-               if (buff->is_eop) {
+               if (buff->is_eop &&
+                   buff->len <= AQ_CFG_RX_FRAME_MAX - AQ_SKB_ALIGN) {
                        skb = build_skb(page_address(buff->page),
-                                       buff->len + AQ_SKB_ALIGN);
+                                       AQ_CFG_RX_FRAME_MAX);
                        if (unlikely(!skb)) {
                                err = -ENOMEM;
                                goto err_exit;
@@ -247,18 +248,21 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
                                        buff->len - ETH_HLEN,
                                        SKB_TRUESIZE(buff->len - ETH_HLEN));
 
-                       for (i = 1U, next_ = buff->next,
-                            buff_ = &self->buff_ring[next_]; true;
-                            next_ = buff_->next,
-                            buff_ = &self->buff_ring[next_], ++i) {
-                               skb_add_rx_frag(skb, i, buff_->page, 0,
-                                               buff_->len,
-                                               SKB_TRUESIZE(buff->len -
-                                               ETH_HLEN));
-                               buff_->is_cleaned = 1;
-
-                               if (buff_->is_eop)
-                                       break;
+                       if (!buff->is_eop) {
+                               for (i = 1U, next_ = buff->next,
+                                    buff_ = &self->buff_ring[next_];
+                                    true; next_ = buff_->next,
+                                    buff_ = &self->buff_ring[next_], ++i) {
+                                       skb_add_rx_frag(skb, i,
+                                                       buff_->page, 0,
+                                                       buff_->len,
+                                                       SKB_TRUESIZE(buff->len -
+                                                       ETH_HLEN));
+                                       buff_->is_cleaned = 1;
+
+                                       if (buff_->is_eop)
+                                               break;
+                               }
                        }
                }
 
index 71362b7..fcc2328 100644 (file)
@@ -12894,19 +12894,6 @@ static int bnx2x_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
        }
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void poll_bnx2x(struct net_device *dev)
-{
-       struct bnx2x *bp = netdev_priv(dev);
-       int i;
-
-       for_each_eth_queue(bp, i) {
-               struct bnx2x_fastpath *fp = &bp->fp[i];
-               napi_schedule(&bnx2x_fp(bp, fp->index, napi));
-       }
-}
-#endif
-
 static int bnx2x_validate_addr(struct net_device *dev)
 {
        struct bnx2x *bp = netdev_priv(dev);
@@ -13113,9 +13100,6 @@ static const struct net_device_ops bnx2x_netdev_ops = {
        .ndo_tx_timeout         = bnx2x_tx_timeout,
        .ndo_vlan_rx_add_vid    = bnx2x_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = bnx2x_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = poll_bnx2x,
-#endif
        .ndo_setup_tc           = __bnx2x_setup_tc,
 #ifdef CONFIG_BNX2X_SRIOV
        .ndo_set_vf_mac         = bnx2x_set_vf_mac,
index 177587f..61957b0 100644 (file)
@@ -7672,21 +7672,6 @@ static void bnxt_tx_timeout(struct net_device *dev)
        bnxt_queue_sp_work(bp);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void bnxt_poll_controller(struct net_device *dev)
-{
-       struct bnxt *bp = netdev_priv(dev);
-       int i;
-
-       /* Only process tx rings/combined rings in netpoll mode. */
-       for (i = 0; i < bp->tx_nr_rings; i++) {
-               struct bnxt_tx_ring_info *txr = &bp->tx_ring[i];
-
-               napi_schedule(&txr->bnapi->napi);
-       }
-}
-#endif
-
 static void bnxt_timer(struct timer_list *t)
 {
        struct bnxt *bp = from_timer(bp, t, timer);
@@ -8519,9 +8504,6 @@ static const struct net_device_ops bnxt_netdev_ops = {
        .ndo_set_vf_link_state  = bnxt_set_vf_link_state,
        .ndo_set_vf_spoofchk    = bnxt_set_vf_spoofchk,
        .ndo_set_vf_trust       = bnxt_set_vf_trust,
-#endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = bnxt_poll_controller,
 #endif
        .ndo_setup_tc           = bnxt_setup_tc,
 #ifdef CONFIG_RFS_ACCEL
index f3b9fbc..790c684 100644 (file)
@@ -46,6 +46,9 @@ static int bnxt_hwrm_nvm_req(struct bnxt *bp, u32 param_id, void *msg,
                }
        }
 
+       if (i == ARRAY_SIZE(nvm_params))
+               return -EOPNOTSUPP;
+
        if (nvm_param.dir_type == BNXT_NVM_PORT_CFG)
                idx = bp->pf.port_id;
        else if (nvm_param.dir_type == BNXT_NVM_FUNC_CFG)
index 092c817..e1594c9 100644 (file)
@@ -75,17 +75,23 @@ static int bnxt_tc_parse_redir(struct bnxt *bp,
        return 0;
 }
 
-static void bnxt_tc_parse_vlan(struct bnxt *bp,
-                              struct bnxt_tc_actions *actions,
-                              const struct tc_action *tc_act)
+static int bnxt_tc_parse_vlan(struct bnxt *bp,
+                             struct bnxt_tc_actions *actions,
+                             const struct tc_action *tc_act)
 {
-       if (tcf_vlan_action(tc_act) == TCA_VLAN_ACT_POP) {
+       switch (tcf_vlan_action(tc_act)) {
+       case TCA_VLAN_ACT_POP:
                actions->flags |= BNXT_TC_ACTION_FLAG_POP_VLAN;
-       } else if (tcf_vlan_action(tc_act) == TCA_VLAN_ACT_PUSH) {
+               break;
+       case TCA_VLAN_ACT_PUSH:
                actions->flags |= BNXT_TC_ACTION_FLAG_PUSH_VLAN;
                actions->push_vlan_tci = htons(tcf_vlan_push_vid(tc_act));
                actions->push_vlan_tpid = tcf_vlan_push_proto(tc_act);
+               break;
+       default:
+               return -EOPNOTSUPP;
        }
+       return 0;
 }
 
 static int bnxt_tc_parse_tunnel_set(struct bnxt *bp,
@@ -134,7 +140,9 @@ static int bnxt_tc_parse_actions(struct bnxt *bp,
 
                /* Push/pop VLAN */
                if (is_tcf_vlan(tc_act)) {
-                       bnxt_tc_parse_vlan(bp, actions, tc_act);
+                       rc = bnxt_tc_parse_vlan(bp, actions, tc_act);
+                       if (rc)
+                               return rc;
                        continue;
                }
 
index b8f75a2..f152da1 100644 (file)
@@ -753,7 +753,6 @@ struct cpl_abort_req_rss {
 };
 
 struct cpl_abort_req_rss6 {
-       WR_HDR;
        union opcode_tid ot;
        __be32 srqidx_status;
 };
index e2a7029..13dfdfc 100644 (file)
@@ -332,7 +332,7 @@ static int ep93xx_poll(struct napi_struct *napi, int budget)
        return rx;
 }
 
-static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ep93xx_priv *ep = netdev_priv(dev);
        struct ep93xx_tdesc *txd;
index 3f8fe8f..6324e80 100644 (file)
@@ -113,7 +113,7 @@ struct net_local {
 
 /* Index to functions, as function prototypes. */
 static int net_open(struct net_device *dev);
-static int net_send_packet(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t net_send_packet(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t net_interrupt(int irq, void *dev_id);
 static void set_multicast_list(struct net_device *dev);
 static void net_rx(struct net_device *dev);
@@ -324,7 +324,7 @@ net_open(struct net_device *dev)
        return 0;
 }
 
-static int
+static netdev_tx_t
 net_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
        struct net_local *lp = netdev_priv(dev);
index dc98345..35f6291 100644 (file)
@@ -64,7 +64,8 @@ static unsigned int net_debug = NET_DEBUG;
 #define RX_AREA_END    0x0fc00
 
 static int ether1_open(struct net_device *dev);
-static int ether1_sendpacket(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ether1_sendpacket(struct sk_buff *skb,
+                                    struct net_device *dev);
 static irqreturn_t ether1_interrupt(int irq, void *dev_id);
 static int ether1_close(struct net_device *dev);
 static void ether1_setmulticastlist(struct net_device *dev);
@@ -667,7 +668,7 @@ ether1_timeout(struct net_device *dev)
        netif_wake_queue(dev);
 }
 
-static int
+static netdev_tx_t
 ether1_sendpacket (struct sk_buff *skb, struct net_device *dev)
 {
        int tmp, tst, nopaddr, txaddr, tbdaddr, dataddr;
index f00a1dc..2f7ae11 100644 (file)
@@ -347,7 +347,7 @@ static const char init_setup[] =
        0x7f /*  *multi IA */ };
 
 static int i596_open(struct net_device *dev);
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t i596_interrupt(int irq, void *dev_id);
 static int i596_close(struct net_device *dev);
 static void i596_add_cmd(struct net_device *dev, struct i596_cmd *cmd);
@@ -966,7 +966,7 @@ static void i596_tx_timeout (struct net_device *dev)
 }
 
 
-static int i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t i596_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct i596_private *lp = netdev_priv(dev);
        struct tx_cmd *tx_cmd;
index 8bb15a8..1a86184 100644 (file)
@@ -121,7 +121,8 @@ static int     sun3_82586_probe1(struct net_device *dev,int ioaddr);
 static irqreturn_t sun3_82586_interrupt(int irq,void *dev_id);
 static int     sun3_82586_open(struct net_device *dev);
 static int     sun3_82586_close(struct net_device *dev);
-static int     sun3_82586_send_packet(struct sk_buff *,struct net_device *);
+static netdev_tx_t     sun3_82586_send_packet(struct sk_buff *,
+                                             struct net_device *);
 static struct  net_device_stats *sun3_82586_get_stats(struct net_device *dev);
 static void    set_multicast_list(struct net_device *dev);
 static void    sun3_82586_timeout(struct net_device *dev);
@@ -1002,7 +1003,8 @@ static void sun3_82586_timeout(struct net_device *dev)
  * send frame
  */
 
-static int sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev)
 {
        int len,i;
 #ifndef NO_NOPCOMMANDS
index 3726646..129f4e9 100644 (file)
@@ -2677,12 +2677,17 @@ static int emac_init_phy(struct emac_instance *dev)
                if (of_phy_is_fixed_link(np)) {
                        int res = emac_dt_mdio_probe(dev);
 
-                       if (!res) {
-                               res = of_phy_register_fixed_link(np);
-                               if (res)
-                                       mdiobus_unregister(dev->mii_bus);
+                       if (res)
+                               return res;
+
+                       res = of_phy_register_fixed_link(np);
+                       dev->phy_dev = of_phy_find_device(np);
+                       if (res || !dev->phy_dev) {
+                               mdiobus_unregister(dev->mii_bus);
+                               return res ? res : -EINVAL;
                        }
-                       return res;
+                       emac_adjust_link(dev->ndev);
+                       put_device(&dev->phy_dev->mdio.dev);
                }
                return 0;
        }
index a903a0b..7d42582 100644 (file)
@@ -504,9 +504,6 @@ void fm10k_update_stats(struct fm10k_intfc *interface);
 void fm10k_service_event_schedule(struct fm10k_intfc *interface);
 void fm10k_macvlan_schedule(struct fm10k_intfc *interface);
 void fm10k_update_rx_drop_en(struct fm10k_intfc *interface);
-#ifdef CONFIG_NET_POLL_CONTROLLER
-void fm10k_netpoll(struct net_device *netdev);
-#endif
 
 /* Netdev */
 struct net_device *fm10k_alloc_netdev(const struct fm10k_info *info);
index 929f538..538a846 100644 (file)
@@ -1648,9 +1648,6 @@ static const struct net_device_ops fm10k_netdev_ops = {
        .ndo_udp_tunnel_del     = fm10k_udp_tunnel_del,
        .ndo_dfwd_add_station   = fm10k_dfwd_add_station,
        .ndo_dfwd_del_station   = fm10k_dfwd_del_station,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = fm10k_netpoll,
-#endif
        .ndo_features_check     = fm10k_features_check,
 };
 
index 15071e4..c859aba 100644 (file)
@@ -1210,28 +1210,6 @@ static irqreturn_t fm10k_msix_mbx_vf(int __always_unused irq, void *data)
        return IRQ_HANDLED;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- *  fm10k_netpoll - A Polling 'interrupt' handler
- *  @netdev: network interface device structure
- *
- *  This is used by netconsole to send skbs without having to re-enable
- *  interrupts. It's not called while the normal interrupt routine is executing.
- **/
-void fm10k_netpoll(struct net_device *netdev)
-{
-       struct fm10k_intfc *interface = netdev_priv(netdev);
-       int i;
-
-       /* if interface is down do nothing */
-       if (test_bit(__FM10K_DOWN, interface->state))
-               return;
-
-       for (i = 0; i < interface->num_q_vectors; i++)
-               fm10k_msix_clean_rings(0, interface->q_vector[i]);
-}
-
-#endif
 #define FM10K_ERR_MSG(type) case (type): error = #type; break
 static void fm10k_handle_fault(struct fm10k_intfc *interface, int type,
                               struct fm10k_fault *fault)
index 5906c1c..fef6d89 100644 (file)
@@ -396,29 +396,6 @@ static void i40evf_map_rings_to_vectors(struct i40evf_adapter *adapter)
        adapter->aq_required |= I40EVF_FLAG_AQ_MAP_VECTORS;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- * i40evf_netpoll - A Polling 'interrupt' handler
- * @netdev: network interface device structure
- *
- * This is used by netconsole to send skbs without having to re-enable
- * interrupts.  It's not called while the normal interrupt routine is executing.
- **/
-static void i40evf_netpoll(struct net_device *netdev)
-{
-       struct i40evf_adapter *adapter = netdev_priv(netdev);
-       int q_vectors = adapter->num_msix_vectors - NONQ_VECS;
-       int i;
-
-       /* if interface is down do nothing */
-       if (test_bit(__I40E_VSI_DOWN, adapter->vsi.state))
-               return;
-
-       for (i = 0; i < q_vectors; i++)
-               i40evf_msix_clean_rings(0, &adapter->q_vectors[i]);
-}
-
-#endif
 /**
  * i40evf_irq_affinity_notify - Callback for affinity changes
  * @notify: context as to what irq was changed
@@ -3229,9 +3206,6 @@ static const struct net_device_ops i40evf_netdev_ops = {
        .ndo_features_check     = i40evf_features_check,
        .ndo_fix_features       = i40evf_fix_features,
        .ndo_set_features       = i40evf_set_features,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = i40evf_netpoll,
-#endif
        .ndo_setup_tc           = i40evf_setup_tc,
 };
 
index f1e80ee..3f047bb 100644 (file)
@@ -4806,30 +4806,6 @@ void ice_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
        stats->rx_length_errors = vsi_stats->rx_length_errors;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/**
- * ice_netpoll - polling "interrupt" handler
- * @netdev: network interface device structure
- *
- * Used by netconsole to send skbs without having to re-enable interrupts.
- * This is not called in the normal interrupt path.
- */
-static void ice_netpoll(struct net_device *netdev)
-{
-       struct ice_netdev_priv *np = netdev_priv(netdev);
-       struct ice_vsi *vsi = np->vsi;
-       struct ice_pf *pf = vsi->back;
-       int i;
-
-       if (test_bit(__ICE_DOWN, vsi->state) ||
-           !test_bit(ICE_FLAG_MSIX_ENA, pf->flags))
-               return;
-
-       for (i = 0; i < vsi->num_q_vectors; i++)
-               ice_msix_clean_rings(0, vsi->q_vectors[i]);
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
 /**
  * ice_napi_disable_all - Disable NAPI for all q_vectors in the VSI
  * @vsi: VSI having NAPI disabled
@@ -5497,9 +5473,6 @@ static const struct net_device_ops ice_netdev_ops = {
        .ndo_validate_addr = eth_validate_addr,
        .ndo_change_mtu = ice_change_mtu,
        .ndo_get_stats64 = ice_get_stats64,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller = ice_netpoll,
-#endif /* CONFIG_NET_POLL_CONTROLLER */
        .ndo_vlan_rx_add_vid = ice_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid = ice_vlan_rx_kill_vid,
        .ndo_set_features = ice_set_features,
index a32c576..0796cef 100644 (file)
@@ -205,10 +205,6 @@ static struct notifier_block dca_notifier = {
        .priority       = 0
 };
 #endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* for netdump / net console */
-static void igb_netpoll(struct net_device *);
-#endif
 #ifdef CONFIG_PCI_IOV
 static unsigned int max_vfs;
 module_param(max_vfs, uint, 0);
@@ -2881,9 +2877,6 @@ static const struct net_device_ops igb_netdev_ops = {
        .ndo_set_vf_spoofchk    = igb_ndo_set_vf_spoofchk,
        .ndo_set_vf_trust       = igb_ndo_set_vf_trust,
        .ndo_get_vf_config      = igb_ndo_get_vf_config,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = igb_netpoll,
-#endif
        .ndo_fix_features       = igb_fix_features,
        .ndo_set_features       = igb_set_features,
        .ndo_fdb_add            = igb_ndo_fdb_add,
@@ -9053,29 +9046,6 @@ static int igb_pci_sriov_configure(struct pci_dev *dev, int num_vfs)
        return 0;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void igb_netpoll(struct net_device *netdev)
-{
-       struct igb_adapter *adapter = netdev_priv(netdev);
-       struct e1000_hw *hw = &adapter->hw;
-       struct igb_q_vector *q_vector;
-       int i;
-
-       for (i = 0; i < adapter->num_q_vectors; i++) {
-               q_vector = adapter->q_vector[i];
-               if (adapter->flags & IGB_FLAG_HAS_MSIX)
-                       wr32(E1000_EIMC, q_vector->eims_value);
-               else
-                       igb_irq_disable(adapter);
-               napi_schedule(&q_vector->napi);
-       }
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
 /**
  *  igb_io_error_detected - called when PCI error is detected
  *  @pdev: Pointer to PCI device
index d3e72d0..7722153 100644 (file)
@@ -81,11 +81,6 @@ static int ixgb_vlan_rx_kill_vid(struct net_device *netdev,
                                 __be16 proto, u16 vid);
 static void ixgb_restore_vlan(struct ixgb_adapter *adapter);
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* for netdump / net console */
-static void ixgb_netpoll(struct net_device *dev);
-#endif
-
 static pci_ers_result_t ixgb_io_error_detected (struct pci_dev *pdev,
                              enum pci_channel_state state);
 static pci_ers_result_t ixgb_io_slot_reset (struct pci_dev *pdev);
@@ -348,9 +343,6 @@ static const struct net_device_ops ixgb_netdev_ops = {
        .ndo_tx_timeout         = ixgb_tx_timeout,
        .ndo_vlan_rx_add_vid    = ixgb_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = ixgb_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = ixgb_netpoll,
-#endif
        .ndo_fix_features       = ixgb_fix_features,
        .ndo_set_features       = ixgb_set_features,
 };
@@ -2195,23 +2187,6 @@ ixgb_restore_vlan(struct ixgb_adapter *adapter)
                ixgb_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-
-static void ixgb_netpoll(struct net_device *dev)
-{
-       struct ixgb_adapter *adapter = netdev_priv(dev);
-
-       disable_irq(adapter->pdev->irq);
-       ixgb_intr(adapter->pdev->irq, dev);
-       enable_irq(adapter->pdev->irq);
-}
-#endif
-
 /**
  * ixgb_io_error_detected - called when PCI error is detected
  * @pdev:    pointer to pci device with error
index 9a23d33..f27d73a 100644 (file)
@@ -8768,28 +8768,6 @@ static int ixgbe_del_sanmac_netdev(struct net_device *dev)
        return err;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void ixgbe_netpoll(struct net_device *netdev)
-{
-       struct ixgbe_adapter *adapter = netdev_priv(netdev);
-       int i;
-
-       /* if interface is down do nothing */
-       if (test_bit(__IXGBE_DOWN, &adapter->state))
-               return;
-
-       /* loop through and schedule all active queues */
-       for (i = 0; i < adapter->num_q_vectors; i++)
-               ixgbe_msix_clean_rings(0, adapter->q_vector[i]);
-}
-
-#endif
-
 static void ixgbe_get_ring_stats64(struct rtnl_link_stats64 *stats,
                                   struct ixgbe_ring *ring)
 {
@@ -10251,9 +10229,6 @@ static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_get_vf_config      = ixgbe_ndo_get_vf_config,
        .ndo_get_stats64        = ixgbe_get_stats64,
        .ndo_setup_tc           = __ixgbe_setup_tc,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = ixgbe_netpoll,
-#endif
 #ifdef IXGBE_FCOE
        .ndo_select_queue       = ixgbe_select_queue,
        .ndo_fcoe_ddp_setup = ixgbe_fcoe_ddp_get,
index d86446d..5a22858 100644 (file)
@@ -4233,24 +4233,6 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
        return 0;
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* Polling 'interrupt' - used by things like netconsole to send skbs
- * without having to re-enable interrupts. It's not called while
- * the interrupt routine is executing.
- */
-static void ixgbevf_netpoll(struct net_device *netdev)
-{
-       struct ixgbevf_adapter *adapter = netdev_priv(netdev);
-       int i;
-
-       /* if interface is down do nothing */
-       if (test_bit(__IXGBEVF_DOWN, &adapter->state))
-               return;
-       for (i = 0; i < adapter->num_rx_queues; i++)
-               ixgbevf_msix_clean_rings(0, adapter->q_vector[i]);
-}
-#endif /* CONFIG_NET_POLL_CONTROLLER */
-
 static int ixgbevf_suspend(struct pci_dev *pdev, pm_message_t state)
 {
        struct net_device *netdev = pci_get_drvdata(pdev);
@@ -4482,9 +4464,6 @@ static const struct net_device_ops ixgbevf_netdev_ops = {
        .ndo_tx_timeout         = ixgbevf_tx_timeout,
        .ndo_vlan_rx_add_vid    = ixgbevf_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = ixgbevf_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = ixgbevf_netpoll,
-#endif
        .ndo_features_check     = ixgbevf_features_check,
        .ndo_bpf                = ixgbevf_xdp,
 };
index bc80a67..b4ed7d3 100644 (file)
@@ -1890,8 +1890,8 @@ static void mvneta_rxq_drop_pkts(struct mvneta_port *pp,
                if (!data || !(rx_desc->buf_phys_addr))
                        continue;
 
-               dma_unmap_single(pp->dev->dev.parent, rx_desc->buf_phys_addr,
-                                MVNETA_RX_BUF_SIZE(pp->pkt_size), DMA_FROM_DEVICE);
+               dma_unmap_page(pp->dev->dev.parent, rx_desc->buf_phys_addr,
+                              PAGE_SIZE, DMA_FROM_DEVICE);
                __free_page(data);
        }
 }
@@ -2008,8 +2008,8 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
                                skb_add_rx_frag(rxq->skb, frag_num, page,
                                                frag_offset, frag_size,
                                                PAGE_SIZE);
-                               dma_unmap_single(dev->dev.parent, phys_addr,
-                                                PAGE_SIZE, DMA_FROM_DEVICE);
+                               dma_unmap_page(dev->dev.parent, phys_addr,
+                                              PAGE_SIZE, DMA_FROM_DEVICE);
                                rxq->left_size -= frag_size;
                        }
                } else {
@@ -2039,9 +2039,8 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
                                                frag_offset, frag_size,
                                                PAGE_SIZE);
 
-                               dma_unmap_single(dev->dev.parent, phys_addr,
-                                                PAGE_SIZE,
-                                                DMA_FROM_DEVICE);
+                               dma_unmap_page(dev->dev.parent, phys_addr,
+                                              PAGE_SIZE, DMA_FROM_DEVICE);
 
                                rxq->left_size -= frag_size;
                        }
index 702fec8..38cc01b 100644 (file)
@@ -3055,10 +3055,12 @@ static int mvpp2_poll(struct napi_struct *napi, int budget)
                                   cause_rx_tx & ~MVPP2_CAUSE_MISC_SUM_MASK);
        }
 
-       cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
-       if (cause_tx) {
-               cause_tx >>= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET;
-               mvpp2_tx_done(port, cause_tx, qv->sw_thread_id);
+       if (port->has_tx_irqs) {
+               cause_tx = cause_rx_tx & MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_MASK;
+               if (cause_tx) {
+                       cause_tx >>= MVPP2_CAUSE_TXQ_OCCUP_DESC_ALL_OFFSET;
+                       mvpp2_tx_done(port, cause_tx, qv->sw_thread_id);
+               }
        }
 
        /* Process RX packets */
index 6785661..fe49384 100644 (file)
@@ -1286,20 +1286,6 @@ out:
        mutex_unlock(&mdev->state_lock);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void mlx4_en_netpoll(struct net_device *dev)
-{
-       struct mlx4_en_priv *priv = netdev_priv(dev);
-       struct mlx4_en_cq *cq;
-       int i;
-
-       for (i = 0; i < priv->tx_ring_num[TX]; i++) {
-               cq = priv->tx_cq[TX][i];
-               napi_schedule(&cq->napi);
-       }
-}
-#endif
-
 static int mlx4_en_set_rss_steer_rules(struct mlx4_en_priv *priv)
 {
        u64 reg_id;
@@ -2946,9 +2932,6 @@ static const struct net_device_ops mlx4_netdev_ops = {
        .ndo_tx_timeout         = mlx4_en_tx_timeout,
        .ndo_vlan_rx_add_vid    = mlx4_en_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = mlx4_en_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = mlx4_en_netpoll,
-#endif
        .ndo_set_features       = mlx4_en_set_features,
        .ndo_fix_features       = mlx4_en_fix_features,
        .ndo_setup_tc           = __mlx4_en_setup_tc,
@@ -2983,9 +2966,6 @@ static const struct net_device_ops mlx4_netdev_ops_master = {
        .ndo_set_vf_link_state  = mlx4_en_set_vf_link_state,
        .ndo_get_vf_stats       = mlx4_en_get_vf_stats,
        .ndo_get_vf_config      = mlx4_en_get_vf_config,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = mlx4_en_netpoll,
-#endif
        .ndo_set_features       = mlx4_en_set_features,
        .ndo_fix_features       = mlx4_en_fix_features,
        .ndo_setup_tc           = __mlx4_en_setup_tc,
index 1f3372c..2df92db 100644 (file)
@@ -240,7 +240,8 @@ static void mlx4_set_eq_affinity_hint(struct mlx4_priv *priv, int vec)
        struct mlx4_dev *dev = &priv->dev;
        struct mlx4_eq *eq = &priv->eq_table.eq[vec];
 
-       if (!eq->affinity_mask || cpumask_empty(eq->affinity_mask))
+       if (!cpumask_available(eq->affinity_mask) ||
+           cpumask_empty(eq->affinity_mask))
                return;
 
        hint_err = irq_set_affinity_hint(eq->irq, eq->affinity_mask);
index 3ce14d4..a53736c 100644 (file)
@@ -206,7 +206,7 @@ static void poll_timeout(struct mlx5_cmd_work_ent *ent)
        u8 own;
 
        do {
-               own = ent->lay->status_own;
+               own = READ_ONCE(ent->lay->status_own);
                if (!(own & CMD_OWNER_HW)) {
                        ent->ret = 0;
                        return;
index eddd770..e88340e 100644 (file)
@@ -183,12 +183,13 @@ static const struct tlsdev_ops mlx5e_tls_ops = {
 
 void mlx5e_tls_build_netdev(struct mlx5e_priv *priv)
 {
-       u32 caps = mlx5_accel_tls_device_caps(priv->mdev);
        struct net_device *netdev = priv->netdev;
+       u32 caps;
 
        if (!mlx5_accel_is_tls_device(priv->mdev))
                return;
 
+       caps = mlx5_accel_tls_device_caps(priv->mdev);
        if (caps & MLX5_ACCEL_TLS_TX) {
                netdev->features          |= NETIF_F_HW_TLS_TX;
                netdev->hw_features       |= NETIF_F_HW_TLS_TX;
index 5a7939e..54118b7 100644 (file)
@@ -4315,22 +4315,6 @@ static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp)
        }
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-/* Fake "interrupt" called by netpoll (eg netconsole) to send skbs without
- * reenabling interrupts.
- */
-static void mlx5e_netpoll(struct net_device *dev)
-{
-       struct mlx5e_priv *priv = netdev_priv(dev);
-       struct mlx5e_channels *chs = &priv->channels;
-
-       int i;
-
-       for (i = 0; i < chs->num; i++)
-               napi_schedule(&chs->c[i]->napi);
-}
-#endif
-
 static const struct net_device_ops mlx5e_netdev_ops = {
        .ndo_open                = mlx5e_open,
        .ndo_stop                = mlx5e_close,
@@ -4356,9 +4340,6 @@ static const struct net_device_ops mlx5e_netdev_ops = {
 #ifdef CONFIG_MLX5_EN_ARFS
        .ndo_rx_flow_steer       = mlx5e_rx_flow_steer,
 #endif
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller     = mlx5e_netpoll,
-#endif
 #ifdef CONFIG_MLX5_ESWITCH
        /* SRIOV E-Switch NDOs */
        .ndo_set_vf_mac          = mlx5e_set_vf_mac,
index dae1c5c..d2f7607 100644 (file)
@@ -509,7 +509,7 @@ static int mlx5_hairpin_modify_sq(struct mlx5_core_dev *peer_mdev, u32 sqn,
 
        sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
 
-       if (next_state == MLX5_RQC_STATE_RDY) {
+       if (next_state == MLX5_SQC_STATE_RDY) {
                MLX5_SET(sqc, sqc, hairpin_peer_rq, peer_rq);
                MLX5_SET(sqc, sqc, hairpin_peer_vhca, peer_vhca);
        }
index 9307004..b492152 100644 (file)
@@ -44,8 +44,8 @@
 #define MLXSW_SP_FWREV_MINOR_TO_BRANCH(minor) ((minor) / 100)
 
 #define MLXSW_SP1_FWREV_MAJOR 13
-#define MLXSW_SP1_FWREV_MINOR 1702
-#define MLXSW_SP1_FWREV_SUBMINOR 6
+#define MLXSW_SP1_FWREV_MINOR 1703
+#define MLXSW_SP1_FWREV_SUBMINOR 4
 #define MLXSW_SP1_FWREV_CAN_RESET_MINOR 1702
 
 static const struct mlxsw_fw_rev mlxsw_sp1_fw_rev = {
index 26bb3b1..3cdf63e 100644 (file)
@@ -91,7 +91,7 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
                struct sk_buff *skb;
                struct net_device *dev;
                u32 *buf;
-               int sz, len;
+               int sz, len, buf_len;
                u32 ifh[4];
                u32 val;
                struct frame_info info;
@@ -116,14 +116,20 @@ static irqreturn_t ocelot_xtr_irq_handler(int irq, void *arg)
                        err = -ENOMEM;
                        break;
                }
-               buf = (u32 *)skb_put(skb, info.len);
+               buf_len = info.len - ETH_FCS_LEN;
+               buf = (u32 *)skb_put(skb, buf_len);
 
                len = 0;
                do {
                        sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
                        *buf++ = val;
                        len += sz;
-               } while ((sz == 4) && (len < info.len));
+               } while (len < buf_len);
+
+               /* Read the FCS and discard it */
+               sz = ocelot_rx_frame_word(ocelot, grp, false, &val);
+               /* Update the statistics if part of the FCS was read before */
+               len -= ETH_FCS_LEN - sz;
 
                if (sz < 0) {
                        err = sz;
index 253bdae..8ed38fd 100644 (file)
@@ -3146,21 +3146,6 @@ nfp_net_vlan_rx_kill_vid(struct net_device *netdev, __be16 proto, u16 vid)
        return nfp_net_reconfig_mbox(nn, NFP_NET_CFG_MBOX_CMD_CTAG_FILTER_KILL);
 }
 
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void nfp_net_netpoll(struct net_device *netdev)
-{
-       struct nfp_net *nn = netdev_priv(netdev);
-       int i;
-
-       /* nfp_net's NAPIs are statically allocated so even if there is a race
-        * with reconfig path this will simply try to schedule some disabled
-        * NAPI instances.
-        */
-       for (i = 0; i < nn->dp.num_stack_tx_rings; i++)
-               napi_schedule_irqoff(&nn->r_vecs[i].napi);
-}
-#endif
-
 static void nfp_net_stat64(struct net_device *netdev,
                           struct rtnl_link_stats64 *stats)
 {
@@ -3519,9 +3504,6 @@ const struct net_device_ops nfp_net_netdev_ops = {
        .ndo_get_stats64        = nfp_net_stat64,
        .ndo_vlan_rx_add_vid    = nfp_net_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = nfp_net_vlan_rx_kill_vid,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = nfp_net_netpoll,
-#endif
        .ndo_set_vf_mac         = nfp_app_set_vf_mac,
        .ndo_set_vf_vlan        = nfp_app_set_vf_vlan,
        .ndo_set_vf_spoofchk    = nfp_app_set_vf_spoofchk,
index 6bb76e6..f5459de 100644 (file)
@@ -190,10 +190,8 @@ qed_dcbx_dp_protocol(struct qed_hwfn *p_hwfn, struct qed_dcbx_results *p_data)
 
 static void
 qed_dcbx_set_params(struct qed_dcbx_results *p_data,
-                   struct qed_hw_info *p_info,
-                   bool enable,
-                   u8 prio,
-                   u8 tc,
+                   struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+                   bool enable, u8 prio, u8 tc,
                    enum dcbx_protocol_type type,
                    enum qed_pci_personality personality)
 {
@@ -206,19 +204,30 @@ qed_dcbx_set_params(struct qed_dcbx_results *p_data,
        else
                p_data->arr[type].update = DONT_UPDATE_DCB_DSCP;
 
+       /* Do not add vlan tag 0 when DCB is enabled and port in UFP/OV mode */
+       if ((test_bit(QED_MF_8021Q_TAGGING, &p_hwfn->cdev->mf_bits) ||
+            test_bit(QED_MF_8021AD_TAGGING, &p_hwfn->cdev->mf_bits)))
+               p_data->arr[type].dont_add_vlan0 = true;
+
        /* QM reconf data */
-       if (p_info->personality == personality)
-               qed_hw_info_set_offload_tc(p_info, tc);
+       if (p_hwfn->hw_info.personality == personality)
+               qed_hw_info_set_offload_tc(&p_hwfn->hw_info, tc);
+
+       /* Configure dcbx vlan priority in doorbell block for roce EDPM */
+       if (test_bit(QED_MF_UFP_SPECIFIC, &p_hwfn->cdev->mf_bits) &&
+           type == DCBX_PROTOCOL_ROCE) {
+               qed_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 1);
+               qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_PCP_BB_K2, prio << 1);
+       }
 }
 
 /* Update app protocol data and hw_info fields with the TLV info */
 static void
 qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
-                        struct qed_hwfn *p_hwfn,
-                        bool enable,
-                        u8 prio, u8 tc, enum dcbx_protocol_type type)
+                        struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
+                        bool enable, u8 prio, u8 tc,
+                        enum dcbx_protocol_type type)
 {
-       struct qed_hw_info *p_info = &p_hwfn->hw_info;
        enum qed_pci_personality personality;
        enum dcbx_protocol_type id;
        int i;
@@ -231,7 +240,7 @@ qed_dcbx_update_app_info(struct qed_dcbx_results *p_data,
 
                personality = qed_dcbx_app_update[i].personality;
 
-               qed_dcbx_set_params(p_data, p_info, enable,
+               qed_dcbx_set_params(p_data, p_hwfn, p_ptt, enable,
                                    prio, tc, type, personality);
        }
 }
@@ -265,7 +274,7 @@ qed_dcbx_get_app_protocol_type(struct qed_hwfn *p_hwfn,
  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
  */
 static int
-qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
+qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
                     struct qed_dcbx_results *p_data,
                     struct dcbx_app_priority_entry *p_tbl,
                     u32 pri_tc_tbl, int count, u8 dcbx_version)
@@ -309,7 +318,7 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
                                enable = true;
                        }
 
-                       qed_dcbx_update_app_info(p_data, p_hwfn, enable,
+                       qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable,
                                                 priority, tc, type);
                }
        }
@@ -331,7 +340,7 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
                        continue;
 
                enable = (type == DCBX_PROTOCOL_ETH) ? false : !!dcbx_version;
-               qed_dcbx_update_app_info(p_data, p_hwfn, enable,
+               qed_dcbx_update_app_info(p_data, p_hwfn, p_ptt, enable,
                                         priority, tc, type);
        }
 
@@ -341,7 +350,8 @@ qed_dcbx_process_tlv(struct qed_hwfn *p_hwfn,
 /* Parse app TLV's to update TC information in hw_info structure for
  * reconfiguring QM. Get protocol specific data for PF update ramrod command.
  */
-static int qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn)
+static int
+qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
 {
        struct dcbx_app_priority_feature *p_app;
        struct dcbx_app_priority_entry *p_tbl;
@@ -365,7 +375,7 @@ static int qed_dcbx_process_mib_info(struct qed_hwfn *p_hwfn)
        p_info = &p_hwfn->hw_info;
        num_entries = QED_MFW_GET_FIELD(p_app->flags, DCBX_APP_NUM_ENTRIES);
 
-       rc = qed_dcbx_process_tlv(p_hwfn, &data, p_tbl, pri_tc_tbl,
+       rc = qed_dcbx_process_tlv(p_hwfn, p_ptt, &data, p_tbl, pri_tc_tbl,
                                  num_entries, dcbx_version);
        if (rc)
                return rc;
@@ -891,7 +901,7 @@ qed_dcbx_mib_update_event(struct qed_hwfn *p_hwfn,
                return rc;
 
        if (type == QED_DCBX_OPERATIONAL_MIB) {
-               rc = qed_dcbx_process_mib_info(p_hwfn);
+               rc = qed_dcbx_process_mib_info(p_hwfn, p_ptt);
                if (!rc) {
                        /* reconfigure tcs of QM queues according
                         * to negotiation results
@@ -954,6 +964,7 @@ static void qed_dcbx_update_protocol_data(struct protocol_dcb_data *p_data,
        p_data->dcb_enable_flag = p_src->arr[type].enable;
        p_data->dcb_priority = p_src->arr[type].priority;
        p_data->dcb_tc = p_src->arr[type].tc;
+       p_data->dcb_dont_add_vlan0 = p_src->arr[type].dont_add_vlan0;
 }
 
 /* Set pf update ramrod command params */
index a4d688c..01f253e 100644 (file)
@@ -55,6 +55,7 @@ struct qed_dcbx_app_data {
        u8 update;              /* Update indication */
        u8 priority;            /* Priority */
        u8 tc;                  /* Traffic Class */
+       bool dont_add_vlan0;    /* Do not insert a vlan tag with id 0 */
 };
 
 #define QED_DCBX_VERSION_DISABLED       0
index 016ca8a..97f073f 100644 (file)
@@ -1706,7 +1706,7 @@ static int qed_vf_start(struct qed_hwfn *p_hwfn,
 int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
 {
        struct qed_load_req_params load_req_params;
-       u32 load_code, param, drv_mb_param;
+       u32 load_code, resp, param, drv_mb_param;
        bool b_default_mtu = true;
        struct qed_hwfn *p_hwfn;
        int rc = 0, mfw_rc, i;
@@ -1852,6 +1852,19 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
 
        if (IS_PF(cdev)) {
                p_hwfn = QED_LEADING_HWFN(cdev);
+
+               /* Get pre-negotiated values for stag, bandwidth etc. */
+               DP_VERBOSE(p_hwfn,
+                          QED_MSG_SPQ,
+                          "Sending GET_OEM_UPDATES command to trigger stag/bandwidth attention handling\n");
+               drv_mb_param = 1 << DRV_MB_PARAM_DUMMY_OEM_UPDATES_OFFSET;
+               rc = qed_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
+                                DRV_MSG_CODE_GET_OEM_UPDATES,
+                                drv_mb_param, &resp, &param);
+               if (rc)
+                       DP_NOTICE(p_hwfn,
+                                 "Failed to send GET_OEM_UPDATES attention request\n");
+
                drv_mb_param = STORM_FW_VERSION;
                rc = qed_mcp_cmd(p_hwfn, p_hwfn->p_main_ptt,
                                 DRV_MSG_CODE_OV_UPDATE_STORM_FW_VER,
index 8faceb6..9b3ef00 100644 (file)
@@ -12414,6 +12414,7 @@ struct public_drv_mb {
 #define DRV_MSG_SET_RESOURCE_VALUE_MSG         0x35000000
 #define DRV_MSG_CODE_OV_UPDATE_WOL              0x38000000
 #define DRV_MSG_CODE_OV_UPDATE_ESWITCH_MODE     0x39000000
+#define DRV_MSG_CODE_GET_OEM_UPDATES            0x41000000
 
 #define DRV_MSG_CODE_BW_UPDATE_ACK             0x32000000
 #define DRV_MSG_CODE_NIG_DRAIN                 0x30000000
@@ -12541,6 +12542,9 @@ struct public_drv_mb {
 #define DRV_MB_PARAM_ESWITCH_MODE_VEB  0x1
 #define DRV_MB_PARAM_ESWITCH_MODE_VEPA 0x2
 
+#define DRV_MB_PARAM_DUMMY_OEM_UPDATES_MASK    0x1
+#define DRV_MB_PARAM_DUMMY_OEM_UPDATES_OFFSET  0
+
 #define DRV_MB_PARAM_SET_LED_MODE_OPER         0x0
 #define DRV_MB_PARAM_SET_LED_MODE_ON           0x1
 #define DRV_MB_PARAM_SET_LED_MODE_OFF          0x2
index 5d37ec7..58c7eb9 100644 (file)
@@ -1581,13 +1581,29 @@ static void qed_mcp_update_stag(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
        p_hwfn->mcp_info->func_info.ovlan = (u16)shmem_info.ovlan_stag &
                                                 FUNC_MF_CFG_OV_STAG_MASK;
        p_hwfn->hw_info.ovlan = p_hwfn->mcp_info->func_info.ovlan;
-       if ((p_hwfn->hw_info.hw_mode & BIT(MODE_MF_SD)) &&
-           (p_hwfn->hw_info.ovlan != QED_MCP_VLAN_UNSET)) {
-               qed_wr(p_hwfn, p_ptt,
-                      NIG_REG_LLH_FUNC_TAG_VALUE, p_hwfn->hw_info.ovlan);
+       if (test_bit(QED_MF_OVLAN_CLSS, &p_hwfn->cdev->mf_bits)) {
+               if (p_hwfn->hw_info.ovlan != QED_MCP_VLAN_UNSET) {
+                       qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_VALUE,
+                              p_hwfn->hw_info.ovlan);
+                       qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_EN, 1);
+
+                       /* Configure DB to add external vlan to EDPM packets */
+                       qed_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 1);
+                       qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_EXT_VID_BB_K2,
+                              p_hwfn->hw_info.ovlan);
+               } else {
+                       qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_EN, 0);
+                       qed_wr(p_hwfn, p_ptt, NIG_REG_LLH_FUNC_TAG_VALUE, 0);
+                       qed_wr(p_hwfn, p_ptt, DORQ_REG_TAG1_OVRD_MODE, 0);
+                       qed_wr(p_hwfn, p_ptt, DORQ_REG_PF_EXT_VID_BB_K2, 0);
+               }
+
                qed_sp_pf_update_stag(p_hwfn);
        }
 
+       DP_VERBOSE(p_hwfn, QED_MSG_SP, "ovlan  = %d hw_mode = 0x%x\n",
+                  p_hwfn->mcp_info->func_info.ovlan, p_hwfn->hw_info.hw_mode);
+
        /* Acknowledge the MFW */
        qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_S_TAG_UPDATE_ACK, 0,
                    &resp, &param);
index f736f70..2440970 100644 (file)
        0x00c000UL
 #define  DORQ_REG_IFEN \
        0x100040UL
+#define DORQ_REG_TAG1_OVRD_MODE \
+       0x1008b4UL
+#define DORQ_REG_PF_PCP_BB_K2 \
+       0x1008c4UL
+#define DORQ_REG_PF_EXT_VID_BB_K2 \
+       0x1008c8UL
 #define DORQ_REG_DB_DROP_REASON \
        0x100a2cUL
 #define DORQ_REG_DB_DROP_DETAILS \
index bb529ff..ab30aae 100644 (file)
@@ -4071,6 +4071,15 @@ static void rtl8169_init_phy(struct net_device *dev, struct rtl8169_private *tp)
        phy_speed_up(dev->phydev);
 
        genphy_soft_reset(dev->phydev);
+
+       /* It was reported that chip version 33 ends up with 10MBit/Half on a
+        * 1GBit link after resuming from S3. For whatever reason the PHY on
+        * this chip doesn't properly start a renegotiation when soft-reset.
+        * Explicitly requesting a renegotiation fixes this.
+        */
+       if (tp->mac_version == RTL_GIGA_MAC_VER_33 &&
+           dev->phydev->autoneg == AUTONEG_ENABLE)
+               phy_restart_aneg(dev->phydev);
 }
 
 static void rtl_rar_set(struct rtl8169_private *tp, u8 *addr)
index 1470fc1..9b6bf55 100644 (file)
@@ -428,6 +428,7 @@ enum EIS_BIT {
        EIS_CULF1       = 0x00000080,
        EIS_TFFF        = 0x00000100,
        EIS_QFS         = 0x00010000,
+       EIS_RESERVED    = (GENMASK(31, 17) | GENMASK(15, 11)),
 };
 
 /* RIC0 */
@@ -472,6 +473,7 @@ enum RIS0_BIT {
        RIS0_FRF15      = 0x00008000,
        RIS0_FRF16      = 0x00010000,
        RIS0_FRF17      = 0x00020000,
+       RIS0_RESERVED   = GENMASK(31, 18),
 };
 
 /* RIC1 */
@@ -528,6 +530,7 @@ enum RIS2_BIT {
        RIS2_QFF16      = 0x00010000,
        RIS2_QFF17      = 0x00020000,
        RIS2_RFFF       = 0x80000000,
+       RIS2_RESERVED   = GENMASK(30, 18),
 };
 
 /* TIC */
@@ -544,6 +547,7 @@ enum TIS_BIT {
        TIS_FTF1        = 0x00000002,   /* Undocumented? */
        TIS_TFUF        = 0x00000100,
        TIS_TFWF        = 0x00000200,
+       TIS_RESERVED    = (GENMASK(31, 20) | GENMASK(15, 12) | GENMASK(7, 4))
 };
 
 /* ISS */
@@ -617,6 +621,7 @@ enum GIC_BIT {
 enum GIS_BIT {
        GIS_PTCF        = 0x00000001,   /* Undocumented? */
        GIS_PTMF        = 0x00000004,
+       GIS_RESERVED    = GENMASK(15, 10),
 };
 
 /* GIE (R-Car Gen3 only) */
index aff5516..d6f7539 100644 (file)
@@ -739,10 +739,11 @@ static void ravb_error_interrupt(struct net_device *ndev)
        u32 eis, ris2;
 
        eis = ravb_read(ndev, EIS);
-       ravb_write(ndev, ~EIS_QFS, EIS);
+       ravb_write(ndev, ~(EIS_QFS | EIS_RESERVED), EIS);
        if (eis & EIS_QFS) {
                ris2 = ravb_read(ndev, RIS2);
-               ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF), RIS2);
+               ravb_write(ndev, ~(RIS2_QFF0 | RIS2_RFFF | RIS2_RESERVED),
+                          RIS2);
 
                /* Receive Descriptor Empty int */
                if (ris2 & RIS2_QFF0)
@@ -795,7 +796,7 @@ static bool ravb_timestamp_interrupt(struct net_device *ndev)
        u32 tis = ravb_read(ndev, TIS);
 
        if (tis & TIS_TFUF) {
-               ravb_write(ndev, ~TIS_TFUF, TIS);
+               ravb_write(ndev, ~(TIS_TFUF | TIS_RESERVED), TIS);
                ravb_get_tx_tstamp(ndev);
                return true;
        }
@@ -930,7 +931,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
                /* Processing RX Descriptor Ring */
                if (ris0 & mask) {
                        /* Clear RX interrupt */
-                       ravb_write(ndev, ~mask, RIS0);
+                       ravb_write(ndev, ~(mask | RIS0_RESERVED), RIS0);
                        if (ravb_rx(ndev, &quota, q))
                                goto out;
                }
@@ -938,7 +939,7 @@ static int ravb_poll(struct napi_struct *napi, int budget)
                if (tis & mask) {
                        spin_lock_irqsave(&priv->lock, flags);
                        /* Clear TX interrupt */
-                       ravb_write(ndev, ~mask, TIS);
+                       ravb_write(ndev, ~(mask | TIS_RESERVED), TIS);
                        ravb_tx_free(ndev, q, true);
                        netif_wake_subqueue(ndev, q);
                        mmiowb();
index 0721b5c..dce2a40 100644 (file)
@@ -315,7 +315,7 @@ void ravb_ptp_interrupt(struct net_device *ndev)
                }
        }
 
-       ravb_write(ndev, ~gis, GIS);
+       ravb_write(ndev, ~(gis | GIS_RESERVED), GIS);
 }
 
 void ravb_ptp_init(struct net_device *ndev, struct platform_device *pdev)
index c5bc124..d1bb73b 100644 (file)
@@ -77,7 +77,8 @@ static void   ether3_setmulticastlist(struct net_device *dev);
 static int     ether3_rx(struct net_device *dev, unsigned int maxcnt);
 static void    ether3_tx(struct net_device *dev);
 static int     ether3_open (struct net_device *dev);
-static int     ether3_sendpacket (struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t     ether3_sendpacket(struct sk_buff *skb,
+                                         struct net_device *dev);
 static irqreturn_t ether3_interrupt (int irq, void *dev_id);
 static int     ether3_close (struct net_device *dev);
 static void    ether3_setmulticastlist (struct net_device *dev);
@@ -481,7 +482,7 @@ static void ether3_timeout(struct net_device *dev)
 /*
  * Transmit a packet
  */
-static int
+static netdev_tx_t
 ether3_sendpacket(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned long flags;
index 573691b..70cce63 100644 (file)
@@ -578,7 +578,8 @@ static inline int sgiseeq_reset(struct net_device *dev)
        return 0;
 }
 
-static int sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t
+sgiseeq_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct sgiseeq_private *sp = netdev_priv(dev);
        struct hpc3_ethregs *hregs = sp->hregs;
index 18d533f..3140999 100644 (file)
@@ -99,7 +99,7 @@ struct ioc3_private {
 
 static int ioc3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static void ioc3_set_multicast_list(struct net_device *dev);
-static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static void ioc3_timeout(struct net_device *dev);
 static inline unsigned int ioc3_hash(const unsigned char *addr);
 static inline void ioc3_stop(struct ioc3_private *ip);
@@ -1390,7 +1390,7 @@ static struct pci_driver ioc3_driver = {
        .remove         = ioc3_remove_one,
 };
 
-static int ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t ioc3_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        unsigned long data;
        struct ioc3_private *ip = netdev_priv(dev);
index ea55abd..703fbbe 100644 (file)
@@ -697,7 +697,7 @@ static void meth_add_to_tx_ring(struct meth_private *priv, struct sk_buff *skb)
 /*
  * Transmit a packet (called by the kernel)
  */
-static int meth_tx(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t meth_tx(struct sk_buff *skb, struct net_device *dev)
 {
        struct meth_private *priv = netdev_priv(dev);
        unsigned long flags;
index 1854f27..b1b305f 100644 (file)
@@ -258,10 +258,10 @@ struct stmmac_safety_stats {
 #define MAX_DMA_RIWT           0xff
 #define MIN_DMA_RIWT           0x20
 /* Tx coalesce parameters */
-#define STMMAC_COAL_TX_TIMER   40000
+#define STMMAC_COAL_TX_TIMER   1000
 #define STMMAC_MAX_COAL_TX_TICK        100000
 #define STMMAC_TX_MAX_FRAMES   256
-#define STMMAC_TX_FRAMES       64
+#define STMMAC_TX_FRAMES       25
 
 /* Packets types */
 enum packets_types {
index c0a855b..63e1064 100644 (file)
@@ -48,6 +48,8 @@ struct stmmac_tx_info {
 
 /* Frequently used values are kept adjacent for cache effect */
 struct stmmac_tx_queue {
+       u32 tx_count_frames;
+       struct timer_list txtimer;
        u32 queue_index;
        struct stmmac_priv *priv_data;
        struct dma_extended_desc *dma_etx ____cacheline_aligned_in_smp;
@@ -73,7 +75,14 @@ struct stmmac_rx_queue {
        u32 rx_zeroc_thresh;
        dma_addr_t dma_rx_phy;
        u32 rx_tail_addr;
+};
+
+struct stmmac_channel {
        struct napi_struct napi ____cacheline_aligned_in_smp;
+       struct stmmac_priv *priv_data;
+       u32 index;
+       int has_rx;
+       int has_tx;
 };
 
 struct stmmac_tc_entry {
@@ -109,14 +118,12 @@ struct stmmac_pps_cfg {
 
 struct stmmac_priv {
        /* Frequently used values are kept adjacent for cache effect */
-       u32 tx_count_frames;
        u32 tx_coal_frames;
        u32 tx_coal_timer;
 
        int tx_coalesce;
        int hwts_tx_en;
        bool tx_path_in_lpi_mode;
-       struct timer_list txtimer;
        bool tso;
 
        unsigned int dma_buf_sz;
@@ -137,6 +144,9 @@ struct stmmac_priv {
        /* TX Queue */
        struct stmmac_tx_queue tx_queue[MTL_MAX_TX_QUEUES];
 
+       /* Generic channel for NAPI */
+       struct stmmac_channel channel[STMMAC_CH_MAX];
+
        bool oldlink;
        int speed;
        int oldduplex;
index 9f458bb..75896d6 100644 (file)
@@ -148,12 +148,14 @@ static void stmmac_verify_args(void)
 static void stmmac_disable_all_queues(struct stmmac_priv *priv)
 {
        u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+       u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
+       u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
        u32 queue;
 
-       for (queue = 0; queue < rx_queues_cnt; queue++) {
-               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       for (queue = 0; queue < maxq; queue++) {
+               struct stmmac_channel *ch = &priv->channel[queue];
 
-               napi_disable(&rx_q->napi);
+               napi_disable(&ch->napi);
        }
 }
 
@@ -164,12 +166,14 @@ static void stmmac_disable_all_queues(struct stmmac_priv *priv)
 static void stmmac_enable_all_queues(struct stmmac_priv *priv)
 {
        u32 rx_queues_cnt = priv->plat->rx_queues_to_use;
+       u32 tx_queues_cnt = priv->plat->tx_queues_to_use;
+       u32 maxq = max(rx_queues_cnt, tx_queues_cnt);
        u32 queue;
 
-       for (queue = 0; queue < rx_queues_cnt; queue++) {
-               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       for (queue = 0; queue < maxq; queue++) {
+               struct stmmac_channel *ch = &priv->channel[queue];
 
-               napi_enable(&rx_q->napi);
+               napi_enable(&ch->napi);
        }
 }
 
@@ -1843,18 +1847,18 @@ static void stmmac_dma_operation_mode(struct stmmac_priv *priv)
  * @queue: TX queue index
  * Description: it reclaims the transmit resources after transmission completes.
  */
-static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
+static int stmmac_tx_clean(struct stmmac_priv *priv, int budget, u32 queue)
 {
        struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
        unsigned int bytes_compl = 0, pkts_compl = 0;
-       unsigned int entry;
+       unsigned int entry, count = 0;
 
-       netif_tx_lock(priv->dev);
+       __netif_tx_lock_bh(netdev_get_tx_queue(priv->dev, queue));
 
        priv->xstats.tx_clean++;
 
        entry = tx_q->dirty_tx;
-       while (entry != tx_q->cur_tx) {
+       while ((entry != tx_q->cur_tx) && (count < budget)) {
                struct sk_buff *skb = tx_q->tx_skbuff[entry];
                struct dma_desc *p;
                int status;
@@ -1870,6 +1874,8 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
                if (unlikely(status & tx_dma_own))
                        break;
 
+               count++;
+
                /* Make sure descriptor fields are read after reading
                 * the own bit.
                 */
@@ -1937,7 +1943,10 @@ static void stmmac_tx_clean(struct stmmac_priv *priv, u32 queue)
                stmmac_enable_eee_mode(priv);
                mod_timer(&priv->eee_ctrl_timer, STMMAC_LPI_T(eee_timer));
        }
-       netif_tx_unlock(priv->dev);
+
+       __netif_tx_unlock_bh(netdev_get_tx_queue(priv->dev, queue));
+
+       return count;
 }
 
 /**
@@ -2020,6 +2029,33 @@ static bool stmmac_safety_feat_interrupt(struct stmmac_priv *priv)
        return false;
 }
 
+static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan)
+{
+       int status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
+                                                &priv->xstats, chan);
+       struct stmmac_channel *ch = &priv->channel[chan];
+       bool needs_work = false;
+
+       if ((status & handle_rx) && ch->has_rx) {
+               needs_work = true;
+       } else {
+               status &= ~handle_rx;
+       }
+
+       if ((status & handle_tx) && ch->has_tx) {
+               needs_work = true;
+       } else {
+               status &= ~handle_tx;
+       }
+
+       if (needs_work && napi_schedule_prep(&ch->napi)) {
+               stmmac_disable_dma_irq(priv, priv->ioaddr, chan);
+               __napi_schedule(&ch->napi);
+       }
+
+       return status;
+}
+
 /**
  * stmmac_dma_interrupt - DMA ISR
  * @priv: driver private structure
@@ -2034,57 +2070,14 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
        u32 channels_to_check = tx_channel_count > rx_channel_count ?
                                tx_channel_count : rx_channel_count;
        u32 chan;
-       bool poll_scheduled = false;
        int status[max_t(u32, MTL_MAX_TX_QUEUES, MTL_MAX_RX_QUEUES)];
 
        /* Make sure we never check beyond our status buffer. */
        if (WARN_ON_ONCE(channels_to_check > ARRAY_SIZE(status)))
                channels_to_check = ARRAY_SIZE(status);
 
-       /* Each DMA channel can be used for rx and tx simultaneously, yet
-        * napi_struct is embedded in struct stmmac_rx_queue rather than in a
-        * stmmac_channel struct.
-        * Because of this, stmmac_poll currently checks (and possibly wakes)
-        * all tx queues rather than just a single tx queue.
-        */
        for (chan = 0; chan < channels_to_check; chan++)
-               status[chan] = stmmac_dma_interrupt_status(priv, priv->ioaddr,
-                               &priv->xstats, chan);
-
-       for (chan = 0; chan < rx_channel_count; chan++) {
-               if (likely(status[chan] & handle_rx)) {
-                       struct stmmac_rx_queue *rx_q = &priv->rx_queue[chan];
-
-                       if (likely(napi_schedule_prep(&rx_q->napi))) {
-                               stmmac_disable_dma_irq(priv, priv->ioaddr, chan);
-                               __napi_schedule(&rx_q->napi);
-                               poll_scheduled = true;
-                       }
-               }
-       }
-
-       /* If we scheduled poll, we already know that tx queues will be checked.
-        * If we didn't schedule poll, see if any DMA channel (used by tx) has a
-        * completed transmission, if so, call stmmac_poll (once).
-        */
-       if (!poll_scheduled) {
-               for (chan = 0; chan < tx_channel_count; chan++) {
-                       if (status[chan] & handle_tx) {
-                               /* It doesn't matter what rx queue we choose
-                                * here. We use 0 since it always exists.
-                                */
-                               struct stmmac_rx_queue *rx_q =
-                                       &priv->rx_queue[0];
-
-                               if (likely(napi_schedule_prep(&rx_q->napi))) {
-                                       stmmac_disable_dma_irq(priv,
-                                                       priv->ioaddr, chan);
-                                       __napi_schedule(&rx_q->napi);
-                               }
-                               break;
-                       }
-               }
-       }
+               status[chan] = stmmac_napi_check(priv, chan);
 
        for (chan = 0; chan < tx_channel_count; chan++) {
                if (unlikely(status[chan] & tx_hard_error_bump_tc)) {
@@ -2220,8 +2213,7 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
                stmmac_init_tx_chan(priv, priv->ioaddr, priv->plat->dma_cfg,
                                    tx_q->dma_tx_phy, chan);
 
-               tx_q->tx_tail_addr = tx_q->dma_tx_phy +
-                           (DMA_TX_SIZE * sizeof(struct dma_desc));
+               tx_q->tx_tail_addr = tx_q->dma_tx_phy;
                stmmac_set_tx_tail_ptr(priv, priv->ioaddr,
                                       tx_q->tx_tail_addr, chan);
        }
@@ -2233,6 +2225,13 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
        return ret;
 }
 
+static void stmmac_tx_timer_arm(struct stmmac_priv *priv, u32 queue)
+{
+       struct stmmac_tx_queue *tx_q = &priv->tx_queue[queue];
+
+       mod_timer(&tx_q->txtimer, STMMAC_COAL_TIMER(priv->tx_coal_timer));
+}
+
 /**
  * stmmac_tx_timer - mitigation sw timer for tx.
  * @data: data pointer
@@ -2241,13 +2240,14 @@ static int stmmac_init_dma_engine(struct stmmac_priv *priv)
  */
 static void stmmac_tx_timer(struct timer_list *t)
 {
-       struct stmmac_priv *priv = from_timer(priv, t, txtimer);
-       u32 tx_queues_count = priv->plat->tx_queues_to_use;
-       u32 queue;
+       struct stmmac_tx_queue *tx_q = from_timer(tx_q, t, txtimer);
+       struct stmmac_priv *priv = tx_q->priv_data;
+       struct stmmac_channel *ch;
+
+       ch = &priv->channel[tx_q->queue_index];
 
-       /* let's scan all the tx queues */
-       for (queue = 0; queue < tx_queues_count; queue++)
-               stmmac_tx_clean(priv, queue);
+       if (likely(napi_schedule_prep(&ch->napi)))
+               __napi_schedule(&ch->napi);
 }
 
 /**
@@ -2260,11 +2260,17 @@ static void stmmac_tx_timer(struct timer_list *t)
  */
 static void stmmac_init_tx_coalesce(struct stmmac_priv *priv)
 {
+       u32 tx_channel_count = priv->plat->tx_queues_to_use;
+       u32 chan;
+
        priv->tx_coal_frames = STMMAC_TX_FRAMES;
        priv->tx_coal_timer = STMMAC_COAL_TX_TIMER;
-       timer_setup(&priv->txtimer, stmmac_tx_timer, 0);
-       priv->txtimer.expires = STMMAC_COAL_TIMER(priv->tx_coal_timer);
-       add_timer(&priv->txtimer);
+
+       for (chan = 0; chan < tx_channel_count; chan++) {
+               struct stmmac_tx_queue *tx_q = &priv->tx_queue[chan];
+
+               timer_setup(&tx_q->txtimer, stmmac_tx_timer, 0);
+       }
 }
 
 static void stmmac_set_rings_length(struct stmmac_priv *priv)
@@ -2592,6 +2598,7 @@ static void stmmac_hw_teardown(struct net_device *dev)
 static int stmmac_open(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
+       u32 chan;
        int ret;
 
        stmmac_check_ether_addr(priv);
@@ -2688,7 +2695,9 @@ irq_error:
        if (dev->phydev)
                phy_stop(dev->phydev);
 
-       del_timer_sync(&priv->txtimer);
+       for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
+               del_timer_sync(&priv->tx_queue[chan].txtimer);
+
        stmmac_hw_teardown(dev);
 init_error:
        free_dma_desc_resources(priv);
@@ -2708,6 +2717,7 @@ dma_desc_error:
 static int stmmac_release(struct net_device *dev)
 {
        struct stmmac_priv *priv = netdev_priv(dev);
+       u32 chan;
 
        if (priv->eee_enabled)
                del_timer_sync(&priv->eee_ctrl_timer);
@@ -2722,7 +2732,8 @@ static int stmmac_release(struct net_device *dev)
 
        stmmac_disable_all_queues(priv);
 
-       del_timer_sync(&priv->txtimer);
+       for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
+               del_timer_sync(&priv->tx_queue[chan].txtimer);
 
        /* Free the IRQ lines */
        free_irq(dev->irq, dev);
@@ -2936,14 +2947,13 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
        priv->xstats.tx_tso_nfrags += nfrags;
 
        /* Manage tx mitigation */
-       priv->tx_count_frames += nfrags + 1;
-       if (likely(priv->tx_coal_frames > priv->tx_count_frames)) {
-               mod_timer(&priv->txtimer,
-                         STMMAC_COAL_TIMER(priv->tx_coal_timer));
-       } else {
-               priv->tx_count_frames = 0;
+       tx_q->tx_count_frames += nfrags + 1;
+       if (priv->tx_coal_frames <= tx_q->tx_count_frames) {
                stmmac_set_tx_ic(priv, desc);
                priv->xstats.tx_set_ic_bit++;
+               tx_q->tx_count_frames = 0;
+       } else {
+               stmmac_tx_timer_arm(priv, queue);
        }
 
        skb_tx_timestamp(skb);
@@ -2992,6 +3002,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 
        netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
 
+       tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
        stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
        return NETDEV_TX_OK;
@@ -3146,14 +3157,13 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
         * This approach takes care about the fragments: desc is the first
         * element in case of no SG.
         */
-       priv->tx_count_frames += nfrags + 1;
-       if (likely(priv->tx_coal_frames > priv->tx_count_frames)) {
-               mod_timer(&priv->txtimer,
-                         STMMAC_COAL_TIMER(priv->tx_coal_timer));
-       } else {
-               priv->tx_count_frames = 0;
+       tx_q->tx_count_frames += nfrags + 1;
+       if (priv->tx_coal_frames <= tx_q->tx_count_frames) {
                stmmac_set_tx_ic(priv, desc);
                priv->xstats.tx_set_ic_bit++;
+               tx_q->tx_count_frames = 0;
+       } else {
+               stmmac_tx_timer_arm(priv, queue);
        }
 
        skb_tx_timestamp(skb);
@@ -3199,6 +3209,8 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
        netdev_tx_sent_queue(netdev_get_tx_queue(dev, queue), skb->len);
 
        stmmac_enable_dma_transmission(priv, priv->ioaddr);
+
+       tx_q->tx_tail_addr = tx_q->dma_tx_phy + (tx_q->cur_tx * sizeof(*desc));
        stmmac_set_tx_tail_ptr(priv, priv->ioaddr, tx_q->tx_tail_addr, queue);
 
        return NETDEV_TX_OK;
@@ -3319,6 +3331,7 @@ static inline void stmmac_rx_refill(struct stmmac_priv *priv, u32 queue)
 static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
 {
        struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       struct stmmac_channel *ch = &priv->channel[queue];
        unsigned int entry = rx_q->cur_rx;
        int coe = priv->hw->rx_csum;
        unsigned int next_entry;
@@ -3491,7 +3504,7 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
                        else
                                skb->ip_summed = CHECKSUM_UNNECESSARY;
 
-                       napi_gro_receive(&rx_q->napi, skb);
+                       napi_gro_receive(&ch->napi, skb);
 
                        priv->dev->stats.rx_packets++;
                        priv->dev->stats.rx_bytes += frame_len;
@@ -3514,27 +3527,33 @@ static int stmmac_rx(struct stmmac_priv *priv, int limit, u32 queue)
  *  Description :
  *  To look at the incoming frames and clear the tx resources.
  */
-static int stmmac_poll(struct napi_struct *napi, int budget)
+static int stmmac_napi_poll(struct napi_struct *napi, int budget)
 {
-       struct stmmac_rx_queue *rx_q =
-               container_of(napi, struct stmmac_rx_queue, napi);
-       struct stmmac_priv *priv = rx_q->priv_data;
-       u32 tx_count = priv->plat->tx_queues_to_use;
-       u32 chan = rx_q->queue_index;
-       int work_done = 0;
-       u32 queue;
+       struct stmmac_channel *ch =
+               container_of(napi, struct stmmac_channel, napi);
+       struct stmmac_priv *priv = ch->priv_data;
+       int work_done = 0, work_rem = budget;
+       u32 chan = ch->index;
 
        priv->xstats.napi_poll++;
 
-       /* check all the queues */
-       for (queue = 0; queue < tx_count; queue++)
-               stmmac_tx_clean(priv, queue);
+       if (ch->has_tx) {
+               int done = stmmac_tx_clean(priv, work_rem, chan);
 
-       work_done = stmmac_rx(priv, budget, rx_q->queue_index);
-       if (work_done < budget) {
-               napi_complete_done(napi, work_done);
-               stmmac_enable_dma_irq(priv, priv->ioaddr, chan);
+               work_done += done;
+               work_rem -= done;
+       }
+
+       if (ch->has_rx) {
+               int done = stmmac_rx(priv, work_rem, chan);
+
+               work_done += done;
+               work_rem -= done;
        }
+
+       if (work_done < budget && napi_complete_done(napi, work_done))
+               stmmac_enable_dma_irq(priv, priv->ioaddr, chan);
+
        return work_done;
 }
 
@@ -4198,8 +4217,8 @@ int stmmac_dvr_probe(struct device *device,
 {
        struct net_device *ndev = NULL;
        struct stmmac_priv *priv;
+       u32 queue, maxq;
        int ret = 0;
-       u32 queue;
 
        ndev = alloc_etherdev_mqs(sizeof(struct stmmac_priv),
                                  MTL_MAX_TX_QUEUES,
@@ -4322,11 +4341,22 @@ int stmmac_dvr_probe(struct device *device,
                         "Enable RX Mitigation via HW Watchdog Timer\n");
        }
 
-       for (queue = 0; queue < priv->plat->rx_queues_to_use; queue++) {
-               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       /* Setup channels NAPI */
+       maxq = max(priv->plat->rx_queues_to_use, priv->plat->tx_queues_to_use);
 
-               netif_napi_add(ndev, &rx_q->napi, stmmac_poll,
-                              (8 * priv->plat->rx_queues_to_use));
+       for (queue = 0; queue < maxq; queue++) {
+               struct stmmac_channel *ch = &priv->channel[queue];
+
+               ch->priv_data = priv;
+               ch->index = queue;
+
+               if (queue < priv->plat->rx_queues_to_use)
+                       ch->has_rx = true;
+               if (queue < priv->plat->tx_queues_to_use)
+                       ch->has_tx = true;
+
+               netif_napi_add(ndev, &ch->napi, stmmac_napi_poll,
+                              NAPI_POLL_WEIGHT);
        }
 
        mutex_init(&priv->lock);
@@ -4372,10 +4402,10 @@ error_netdev_register:
            priv->hw->pcs != STMMAC_PCS_RTBI)
                stmmac_mdio_unregister(ndev);
 error_mdio_register:
-       for (queue = 0; queue < priv->plat->rx_queues_to_use; queue++) {
-               struct stmmac_rx_queue *rx_q = &priv->rx_queue[queue];
+       for (queue = 0; queue < maxq; queue++) {
+               struct stmmac_channel *ch = &priv->channel[queue];
 
-               netif_napi_del(&rx_q->napi);
+               netif_napi_del(&ch->napi);
        }
 error_hw_init:
        destroy_workqueue(priv->wq);
index 2bdfb39..d8ba512 100644 (file)
@@ -835,7 +835,7 @@ static void w5100_tx_work(struct work_struct *work)
        w5100_tx_skb(priv->ndev, skb);
 }
 
-static int w5100_start_tx(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t w5100_start_tx(struct sk_buff *skb, struct net_device *ndev)
 {
        struct w5100_priv *priv = netdev_priv(ndev);
 
index 56ae573..80fdbff 100644 (file)
@@ -365,7 +365,7 @@ static void w5300_tx_timeout(struct net_device *ndev)
        netif_wake_queue(ndev);
 }
 
-static int w5300_start_tx(struct sk_buff *skb, struct net_device *ndev)
+static netdev_tx_t w5300_start_tx(struct sk_buff *skb, struct net_device *ndev)
 {
        struct w5300_priv *priv = netdev_priv(ndev);
 
index 7406552..83060fb 100644 (file)
@@ -349,6 +349,7 @@ static int sfp_register_bus(struct sfp_bus *bus)
        }
        if (bus->started)
                bus->socket_ops->start(bus->sfp);
+       bus->netdev->sfp_bus = bus;
        bus->registered = true;
        return 0;
 }
@@ -357,6 +358,7 @@ static void sfp_unregister_bus(struct sfp_bus *bus)
 {
        const struct sfp_upstream_ops *ops = bus->upstream_ops;
 
+       bus->netdev->sfp_bus = NULL;
        if (bus->registered) {
                if (bus->started)
                        bus->socket_ops->stop(bus->sfp);
@@ -438,7 +440,6 @@ static void sfp_upstream_clear(struct sfp_bus *bus)
 {
        bus->upstream_ops = NULL;
        bus->upstream = NULL;
-       bus->netdev->sfp_bus = NULL;
        bus->netdev = NULL;
 }
 
@@ -467,7 +468,6 @@ struct sfp_bus *sfp_register_upstream(struct fwnode_handle *fwnode,
                bus->upstream_ops = ops;
                bus->upstream = upstream;
                bus->netdev = ndev;
-               ndev->sfp_bus = bus;
 
                if (bus->sfp) {
                        ret = sfp_register_bus(bus);
index ebd07ad..e2648b5 100644 (file)
@@ -1153,43 +1153,6 @@ static netdev_features_t tun_net_fix_features(struct net_device *dev,
 
        return (features & tun->set_features) | (features & ~TUN_USER_FEATURES);
 }
-#ifdef CONFIG_NET_POLL_CONTROLLER
-static void tun_poll_controller(struct net_device *dev)
-{
-       /*
-        * Tun only receives frames when:
-        * 1) the char device endpoint gets data from user space
-        * 2) the tun socket gets a sendmsg call from user space
-        * If NAPI is not enabled, since both of those are synchronous
-        * operations, we are guaranteed never to have pending data when we poll
-        * for it so there is nothing to do here but return.
-        * We need this though so netpoll recognizes us as an interface that
-        * supports polling, which enables bridge devices in virt setups to
-        * still use netconsole
-        * If NAPI is enabled, however, we need to schedule polling for all
-        * queues unless we are using napi_gro_frags(), which we call in
-        * process context and not in NAPI context.
-        */
-       struct tun_struct *tun = netdev_priv(dev);
-
-       if (tun->flags & IFF_NAPI) {
-               struct tun_file *tfile;
-               int i;
-
-               if (tun_napi_frags_enabled(tun))
-                       return;
-
-               rcu_read_lock();
-               for (i = 0; i < tun->numqueues; i++) {
-                       tfile = rcu_dereference(tun->tfiles[i]);
-                       if (tfile->napi_enabled)
-                               napi_schedule(&tfile->napi);
-               }
-               rcu_read_unlock();
-       }
-       return;
-}
-#endif
 
 static void tun_set_headroom(struct net_device *dev, int new_hr)
 {
@@ -1283,9 +1246,6 @@ static const struct net_device_ops tun_netdev_ops = {
        .ndo_start_xmit         = tun_net_xmit,
        .ndo_fix_features       = tun_net_fix_features,
        .ndo_select_queue       = tun_select_queue,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = tun_poll_controller,
-#endif
        .ndo_set_rx_headroom    = tun_set_headroom,
        .ndo_get_stats64        = tun_net_get_stats64,
 };
@@ -1365,9 +1325,6 @@ static const struct net_device_ops tap_netdev_ops = {
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_select_queue       = tun_select_queue,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = tun_poll_controller,
-#endif
        .ndo_features_check     = passthru_features_check,
        .ndo_set_rx_headroom    = tun_set_headroom,
        .ndo_get_stats64        = tun_net_get_stats64,
index 778c4f7..2153956 100644 (file)
@@ -135,7 +135,7 @@ static void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index,
                if (val & PCIE_ATU_ENABLE)
                        return;
 
-               usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+               mdelay(LINK_WAIT_IATU);
        }
        dev_err(pci->dev, "Outbound iATU is not being enabled\n");
 }
@@ -178,7 +178,7 @@ void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
                if (val & PCIE_ATU_ENABLE)
                        return;
 
-               usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+               mdelay(LINK_WAIT_IATU);
        }
        dev_err(pci->dev, "Outbound iATU is not being enabled\n");
 }
@@ -236,7 +236,7 @@ static int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index,
                if (val & PCIE_ATU_ENABLE)
                        return 0;
 
-               usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+               mdelay(LINK_WAIT_IATU);
        }
        dev_err(pci->dev, "Inbound iATU is not being enabled\n");
 
@@ -282,7 +282,7 @@ int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
                if (val & PCIE_ATU_ENABLE)
                        return 0;
 
-               usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
+               mdelay(LINK_WAIT_IATU);
        }
        dev_err(pci->dev, "Inbound iATU is not being enabled\n");
 
index 96126fd..9f1a5e3 100644 (file)
@@ -26,8 +26,7 @@
 
 /* Parameters for the waiting for iATU enabled routine */
 #define LINK_WAIT_MAX_IATU_RETRIES     5
-#define LINK_WAIT_IATU_MIN             9000
-#define LINK_WAIT_IATU_MAX             10000
+#define LINK_WAIT_IATU                 9
 
 /* Synopsys-specific PCIe configuration registers */
 #define PCIE_PORT_LINK_CONTROL         0x710
index ee80e79..9ba4d12 100644 (file)
@@ -1484,8 +1484,10 @@ static void hv_pci_assign_slots(struct hv_pcibus_device *hbus)
                snprintf(name, SLOT_NAME_SIZE, "%u", hpdev->desc.ser);
                hpdev->pci_slot = pci_create_slot(hbus->pci_bus, slot_nr,
                                          name, NULL);
-               if (!hpdev->pci_slot)
+               if (IS_ERR(hpdev->pci_slot)) {
                        pr_warn("pci_create slot %s failed\n", name);
+                       hpdev->pci_slot = NULL;
+               }
        }
 }
 
index ef0b1b6..12afa7f 100644 (file)
@@ -457,17 +457,18 @@ static void acpiphp_native_scan_bridge(struct pci_dev *bridge)
 /**
  * enable_slot - enable, configure a slot
  * @slot: slot to be enabled
+ * @bridge: true if enable is for the whole bridge (not a single slot)
  *
  * This function should be called per *physical slot*,
  * not per each slot object in ACPI namespace.
  */
-static void enable_slot(struct acpiphp_slot *slot)
+static void enable_slot(struct acpiphp_slot *slot, bool bridge)
 {
        struct pci_dev *dev;
        struct pci_bus *bus = slot->bus;
        struct acpiphp_func *func;
 
-       if (bus->self && hotplug_is_native(bus->self)) {
+       if (bridge && bus->self && hotplug_is_native(bus->self)) {
                /*
                 * If native hotplug is used, it will take care of hotplug
                 * slot management and resource allocation for hotplug
@@ -701,7 +702,7 @@ static void acpiphp_check_bridge(struct acpiphp_bridge *bridge)
                                        trim_stale_devices(dev);
 
                        /* configure all functions */
-                       enable_slot(slot);
+                       enable_slot(slot, true);
                } else {
                        disable_slot(slot);
                }
@@ -785,7 +786,7 @@ static void hotplug_event(u32 type, struct acpiphp_context *context)
                if (bridge)
                        acpiphp_check_bridge(bridge);
                else if (!(slot->flags & SLOT_IS_GOING_AWAY))
-                       enable_slot(slot);
+                       enable_slot(slot, false);
 
                break;
 
@@ -973,7 +974,7 @@ int acpiphp_enable_slot(struct acpiphp_slot *slot)
 
        /* configure all functions */
        if (!(slot->flags & SLOT_ENABLED))
-               enable_slot(slot);
+               enable_slot(slot, false);
 
        pci_unlock_rescan_remove();
        return 0;
index fac3773..f42a619 100644 (file)
@@ -3474,11 +3474,10 @@ static int ibmvscsis_probe(struct vio_dev *vdev,
                vscsi->dds.window[LOCAL].liobn,
                vscsi->dds.window[REMOTE].liobn);
 
-       strcpy(vscsi->eye, "VSCSI ");
-       strncat(vscsi->eye, vdev->name, MAX_EYE);
+       snprintf(vscsi->eye, sizeof(vscsi->eye), "VSCSI %s", vdev->name);
 
        vscsi->dds.unit_id = vdev->unit_address;
-       strncpy(vscsi->dds.partition_name, partition_name,
+       strscpy(vscsi->dds.partition_name, partition_name,
                sizeof(vscsi->dds.partition_name));
        vscsi->dds.partition_num = partition_number;
 
index f2ec80b..271990b 100644 (file)
@@ -3335,6 +3335,65 @@ static void ipr_release_dump(struct kref *kref)
        LEAVE;
 }
 
+static void ipr_add_remove_thread(struct work_struct *work)
+{
+       unsigned long lock_flags;
+       struct ipr_resource_entry *res;
+       struct scsi_device *sdev;
+       struct ipr_ioa_cfg *ioa_cfg =
+               container_of(work, struct ipr_ioa_cfg, scsi_add_work_q);
+       u8 bus, target, lun;
+       int did_work;
+
+       ENTER;
+       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+
+restart:
+       do {
+               did_work = 0;
+               if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
+                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                       return;
+               }
+
+               list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+                       if (res->del_from_ml && res->sdev) {
+                               did_work = 1;
+                               sdev = res->sdev;
+                               if (!scsi_device_get(sdev)) {
+                                       if (!res->add_to_ml)
+                                               list_move_tail(&res->queue, &ioa_cfg->free_res_q);
+                                       else
+                                               res->del_from_ml = 0;
+                                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                                       scsi_remove_device(sdev);
+                                       scsi_device_put(sdev);
+                                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+                               }
+                               break;
+                       }
+               }
+       } while (did_work);
+
+       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
+               if (res->add_to_ml) {
+                       bus = res->bus;
+                       target = res->target;
+                       lun = res->lun;
+                       res->add_to_ml = 0;
+                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+                       scsi_add_device(ioa_cfg->host, bus, target, lun);
+                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
+                       goto restart;
+               }
+       }
+
+       ioa_cfg->scan_done = 1;
+       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
+       kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
+       LEAVE;
+}
+
 /**
  * ipr_worker_thread - Worker thread
  * @work:              ioa config struct
@@ -3349,13 +3408,9 @@ static void ipr_release_dump(struct kref *kref)
 static void ipr_worker_thread(struct work_struct *work)
 {
        unsigned long lock_flags;
-       struct ipr_resource_entry *res;
-       struct scsi_device *sdev;
        struct ipr_dump *dump;
        struct ipr_ioa_cfg *ioa_cfg =
                container_of(work, struct ipr_ioa_cfg, work_q);
-       u8 bus, target, lun;
-       int did_work;
 
        ENTER;
        spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
@@ -3393,49 +3448,9 @@ static void ipr_worker_thread(struct work_struct *work)
                return;
        }
 
-restart:
-       do {
-               did_work = 0;
-               if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) {
-                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-                       return;
-               }
+       schedule_work(&ioa_cfg->scsi_add_work_q);
 
-               list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-                       if (res->del_from_ml && res->sdev) {
-                               did_work = 1;
-                               sdev = res->sdev;
-                               if (!scsi_device_get(sdev)) {
-                                       if (!res->add_to_ml)
-                                               list_move_tail(&res->queue, &ioa_cfg->free_res_q);
-                                       else
-                                               res->del_from_ml = 0;
-                                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-                                       scsi_remove_device(sdev);
-                                       scsi_device_put(sdev);
-                                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-                               }
-                               break;
-                       }
-               }
-       } while (did_work);
-
-       list_for_each_entry(res, &ioa_cfg->used_res_q, queue) {
-               if (res->add_to_ml) {
-                       bus = res->bus;
-                       target = res->target;
-                       lun = res->lun;
-                       res->add_to_ml = 0;
-                       spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-                       scsi_add_device(ioa_cfg->host, bus, target, lun);
-                       spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags);
-                       goto restart;
-               }
-       }
-
-       ioa_cfg->scan_done = 1;
        spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags);
-       kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE);
        LEAVE;
 }
 
@@ -9933,6 +9948,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg,
        INIT_LIST_HEAD(&ioa_cfg->free_res_q);
        INIT_LIST_HEAD(&ioa_cfg->used_res_q);
        INIT_WORK(&ioa_cfg->work_q, ipr_worker_thread);
+       INIT_WORK(&ioa_cfg->scsi_add_work_q, ipr_add_remove_thread);
        init_waitqueue_head(&ioa_cfg->reset_wait_q);
        init_waitqueue_head(&ioa_cfg->msi_wait_q);
        init_waitqueue_head(&ioa_cfg->eeh_wait_q);
index 68afbbd..f6baa23 100644 (file)
@@ -1575,6 +1575,7 @@ struct ipr_ioa_cfg {
        u8 saved_mode_page_len;
 
        struct work_struct work_q;
+       struct work_struct scsi_add_work_q;
        struct workqueue_struct *reset_work_q;
 
        wait_queue_head_t reset_wait_q;
index 057a60a..1a6ed9b 100644 (file)
@@ -360,12 +360,12 @@ lpfc_nvme_info_show(struct device *dev, struct device_attribute *attr,
                goto buffer_done;
 
        list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
+               nrport = NULL;
+               spin_lock(&vport->phba->hbalock);
                rport = lpfc_ndlp_get_nrport(ndlp);
-               if (!rport)
-                       continue;
-
-               /* local short-hand pointer. */
-               nrport = rport->remoteport;
+               if (rport)
+                       nrport = rport->remoteport;
+               spin_unlock(&vport->phba->hbalock);
                if (!nrport)
                        continue;
 
@@ -3386,6 +3386,7 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
        struct lpfc_nodelist  *ndlp;
 #if (IS_ENABLED(CONFIG_NVME_FC))
        struct lpfc_nvme_rport *rport;
+       struct nvme_fc_remote_port *remoteport = NULL;
 #endif
 
        shost = lpfc_shost_from_vport(vport);
@@ -3396,8 +3397,12 @@ lpfc_update_rport_devloss_tmo(struct lpfc_vport *vport)
                if (ndlp->rport)
                        ndlp->rport->dev_loss_tmo = vport->cfg_devloss_tmo;
 #if (IS_ENABLED(CONFIG_NVME_FC))
+               spin_lock(&vport->phba->hbalock);
                rport = lpfc_ndlp_get_nrport(ndlp);
                if (rport)
+                       remoteport = rport->remoteport;
+               spin_unlock(&vport->phba->hbalock);
+               if (remoteport)
                        nvme_fc_set_remoteport_devloss(rport->remoteport,
                                                       vport->cfg_devloss_tmo);
 #endif
index 9df0c05..aec5b10 100644 (file)
@@ -551,7 +551,7 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
        unsigned char *statep;
        struct nvme_fc_local_port *localport;
        struct lpfc_nvmet_tgtport *tgtp;
-       struct nvme_fc_remote_port *nrport;
+       struct nvme_fc_remote_port *nrport = NULL;
        struct lpfc_nvme_rport *rport;
 
        cnt = (LPFC_NODELIST_SIZE / LPFC_NODELIST_ENTRY_SIZE);
@@ -696,11 +696,11 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
        len += snprintf(buf + len, size - len, "\tRport List:\n");
        list_for_each_entry(ndlp, &vport->fc_nodes, nlp_listp) {
                /* local short-hand pointer. */
+               spin_lock(&phba->hbalock);
                rport = lpfc_ndlp_get_nrport(ndlp);
-               if (!rport)
-                       continue;
-
-               nrport = rport->remoteport;
+               if (rport)
+                       nrport = rport->remoteport;
+               spin_unlock(&phba->hbalock);
                if (!nrport)
                        continue;
 
index 028462e..918ae18 100644 (file)
@@ -2725,7 +2725,9 @@ lpfc_nvme_register_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        rpinfo.port_name = wwn_to_u64(ndlp->nlp_portname.u.wwn);
        rpinfo.node_name = wwn_to_u64(ndlp->nlp_nodename.u.wwn);
 
+       spin_lock_irq(&vport->phba->hbalock);
        oldrport = lpfc_ndlp_get_nrport(ndlp);
+       spin_unlock_irq(&vport->phba->hbalock);
        if (!oldrport)
                lpfc_nlp_get(ndlp);
 
@@ -2840,7 +2842,7 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        struct nvme_fc_local_port *localport;
        struct lpfc_nvme_lport *lport;
        struct lpfc_nvme_rport *rport;
-       struct nvme_fc_remote_port *remoteport;
+       struct nvme_fc_remote_port *remoteport = NULL;
 
        localport = vport->localport;
 
@@ -2854,11 +2856,14 @@ lpfc_nvme_unregister_port(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp)
        if (!lport)
                goto input_err;
 
+       spin_lock_irq(&vport->phba->hbalock);
        rport = lpfc_ndlp_get_nrport(ndlp);
-       if (!rport)
+       if (rport)
+               remoteport = rport->remoteport;
+       spin_unlock_irq(&vport->phba->hbalock);
+       if (!remoteport)
                goto input_err;
 
-       remoteport = rport->remoteport;
        lpfc_printf_vlog(vport, KERN_INFO, LOG_NVME_DISC,
                         "6033 Unreg nvme remoteport %p, portname x%llx, "
                         "port_id x%06x, portstate x%x port type x%x\n",
index b79b366..4a57ffe 100644 (file)
@@ -1276,7 +1276,8 @@ static int sd_init_command(struct scsi_cmnd *cmd)
        case REQ_OP_ZONE_RESET:
                return sd_zbc_setup_reset_cmnd(cmd);
        default:
-               BUG();
+               WARN_ON_ONCE(1);
+               return BLKPREP_KILL;
        }
 }
 
@@ -2959,6 +2960,9 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
        if (rot == 1) {
                blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
                blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, q);
+       } else {
+               blk_queue_flag_clear(QUEUE_FLAG_NONROT, q);
+               blk_queue_flag_set(QUEUE_FLAG_ADD_RANDOM, q);
        }
 
        if (sdkp->device->type == TYPE_ZBC) {
index 9d5d2ca..c55f38e 100644 (file)
@@ -7940,6 +7940,13 @@ int ufshcd_alloc_host(struct device *dev, struct ufs_hba **hba_handle)
                err = -ENOMEM;
                goto out_error;
        }
+
+       /*
+        * Do not use blk-mq at this time because blk-mq does not support
+        * runtime pm.
+        */
+       host->use_blk_mq = false;
+
        hba = shost_priv(host);
        hba->host = host;
        hba->dev = dev;
index 4b5e250..e5c7e1e 100644 (file)
@@ -899,9 +899,10 @@ static void sdw_release_master_stream(struct sdw_stream_runtime *stream)
        struct sdw_master_runtime *m_rt = stream->m_rt;
        struct sdw_slave_runtime *s_rt, *_s_rt;
 
-       list_for_each_entry_safe(s_rt, _s_rt,
-                       &m_rt->slave_rt_list, m_rt_node)
-               sdw_stream_remove_slave(s_rt->slave, stream);
+       list_for_each_entry_safe(s_rt, _s_rt, &m_rt->slave_rt_list, m_rt_node) {
+               sdw_slave_port_release(s_rt->slave->bus, s_rt->slave, stream);
+               sdw_release_slave_stream(s_rt->slave, stream);
+       }
 
        list_del(&m_rt->bus_node);
 }
@@ -1112,7 +1113,7 @@ int sdw_stream_add_master(struct sdw_bus *bus,
                                "Master runtime config failed for stream:%s",
                                stream->name);
                ret = -ENOMEM;
-               goto error;
+               goto unlock;
        }
 
        ret = sdw_config_stream(bus->dev, stream, stream_config, false);
@@ -1123,11 +1124,11 @@ int sdw_stream_add_master(struct sdw_bus *bus,
        if (ret)
                goto stream_error;
 
-       stream->state = SDW_STREAM_CONFIGURED;
+       goto unlock;
 
 stream_error:
        sdw_release_master_stream(stream);
-error:
+unlock:
        mutex_unlock(&bus->bus_lock);
        return ret;
 }
@@ -1141,6 +1142,10 @@ EXPORT_SYMBOL(sdw_stream_add_master);
  * @stream: SoundWire stream
  * @port_config: Port configuration for audio stream
  * @num_ports: Number of ports
+ *
+ * It is expected that Slave is added before adding Master
+ * to the Stream.
+ *
  */
 int sdw_stream_add_slave(struct sdw_slave *slave,
                struct sdw_stream_config *stream_config,
@@ -1186,6 +1191,12 @@ int sdw_stream_add_slave(struct sdw_slave *slave,
        if (ret)
                goto stream_error;
 
+       /*
+        * Change stream state to CONFIGURED on first Slave add.
+        * Bus is not aware of number of Slave(s) in a stream at this
+        * point so cannot depend on all Slave(s) to be added in order to
+        * change stream state to CONFIGURED.
+        */
        stream->state = SDW_STREAM_CONFIGURED;
        goto error;
 
index f48e06a..9a58aaf 100644 (file)
@@ -1,9 +1,3 @@
-config SOC_CAMERA_IMX074
-       tristate "imx074 support (DEPRECATED)"
-       depends on SOC_CAMERA && I2C
-       help
-         This driver supports IMX074 cameras from Sony
-
 config SOC_CAMERA_MT9T031
        tristate "mt9t031 support (DEPRECATED)"
        depends on SOC_CAMERA && I2C
index 9518ffd..4e680d7 100644 (file)
 #include "iscsi_target_nego.h"
 #include "iscsi_target_auth.h"
 
-static int chap_string_to_hex(unsigned char *dst, unsigned char *src, int len)
-{
-       int j = DIV_ROUND_UP(len, 2), rc;
-
-       rc = hex2bin(dst, src, j);
-       if (rc < 0)
-               pr_debug("CHAP string contains non hex digit symbols\n");
-
-       dst[j] = '\0';
-       return j;
-}
-
-static void chap_binaryhex_to_asciihex(char *dst, char *src, int src_len)
-{
-       int i;
-
-       for (i = 0; i < src_len; i++) {
-               sprintf(&dst[i*2], "%02x", (int) src[i] & 0xff);
-       }
-}
-
 static int chap_gen_challenge(
        struct iscsi_conn *conn,
        int caller,
@@ -62,7 +41,7 @@ static int chap_gen_challenge(
        ret = get_random_bytes_wait(chap->challenge, CHAP_CHALLENGE_LENGTH);
        if (unlikely(ret))
                return ret;
-       chap_binaryhex_to_asciihex(challenge_asciihex, chap->challenge,
+       bin2hex(challenge_asciihex, chap->challenge,
                                CHAP_CHALLENGE_LENGTH);
        /*
         * Set CHAP_C, and copy the generated challenge into c_str.
@@ -248,9 +227,16 @@ static int chap_server_compute_md5(
                pr_err("Could not find CHAP_R.\n");
                goto out;
        }
+       if (strlen(chap_r) != MD5_SIGNATURE_SIZE * 2) {
+               pr_err("Malformed CHAP_R\n");
+               goto out;
+       }
+       if (hex2bin(client_digest, chap_r, MD5_SIGNATURE_SIZE) < 0) {
+               pr_err("Malformed CHAP_R\n");
+               goto out;
+       }
 
        pr_debug("[server] Got CHAP_R=%s\n", chap_r);
-       chap_string_to_hex(client_digest, chap_r, strlen(chap_r));
 
        tfm = crypto_alloc_shash("md5", 0, 0);
        if (IS_ERR(tfm)) {
@@ -294,7 +280,7 @@ static int chap_server_compute_md5(
                goto out;
        }
 
-       chap_binaryhex_to_asciihex(response, server_digest, MD5_SIGNATURE_SIZE);
+       bin2hex(response, server_digest, MD5_SIGNATURE_SIZE);
        pr_debug("[server] MD5 Server Digest: %s\n", response);
 
        if (memcmp(server_digest, client_digest, MD5_SIGNATURE_SIZE) != 0) {
@@ -349,9 +335,7 @@ static int chap_server_compute_md5(
                pr_err("Could not find CHAP_C.\n");
                goto out;
        }
-       pr_debug("[server] Got CHAP_C=%s\n", challenge);
-       challenge_len = chap_string_to_hex(challenge_binhex, challenge,
-                               strlen(challenge));
+       challenge_len = DIV_ROUND_UP(strlen(challenge), 2);
        if (!challenge_len) {
                pr_err("Unable to convert incoming challenge\n");
                goto out;
@@ -360,6 +344,11 @@ static int chap_server_compute_md5(
                pr_err("CHAP_C exceeds maximum binary size of 1024 bytes\n");
                goto out;
        }
+       if (hex2bin(challenge_binhex, challenge, challenge_len) < 0) {
+               pr_err("Malformed CHAP_C\n");
+               goto out;
+       }
+       pr_debug("[server] Got CHAP_C=%s\n", challenge);
        /*
         * During mutual authentication, the CHAP_C generated by the
         * initiator must not match the original CHAP_C generated by
@@ -413,7 +402,7 @@ static int chap_server_compute_md5(
        /*
         * Convert response from binary hex to ascii hext.
         */
-       chap_binaryhex_to_asciihex(response, digest, MD5_SIGNATURE_SIZE);
+       bin2hex(response, digest, MD5_SIGNATURE_SIZE);
        *nr_out_len += sprintf(nr_out_ptr + *nr_out_len, "CHAP_R=0x%s",
                        response);
        *nr_out_len += 1;
index 24a5f05..e538959 100644 (file)
@@ -1054,8 +1054,8 @@ static int poll_wait_key(char *obuf, struct uart_cpm_port *pinfo)
        /* Get the address of the host memory buffer.
         */
        bdp = pinfo->rx_cur;
-       while (bdp->cbd_sc & BD_SC_EMPTY)
-               ;
+       if (bdp->cbd_sc & BD_SC_EMPTY)
+               return NO_POLL_CHAR;
 
        /* If the buffer address is in the CPM DPRAM, don't
         * convert it.
@@ -1090,7 +1090,11 @@ static int cpm_get_poll_char(struct uart_port *port)
                poll_chars = 0;
        }
        if (poll_chars <= 0) {
-               poll_chars = poll_wait_key(poll_buf, pinfo);
+               int ret = poll_wait_key(poll_buf, pinfo);
+
+               if (ret == NO_POLL_CHAR)
+                       return ret;
+               poll_chars = ret;
                pollp = poll_buf;
        }
        poll_chars--;
index 51e47a6..3f8d127 100644 (file)
@@ -979,7 +979,8 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
        struct circ_buf *ring = &sport->rx_ring;
        int ret, nent;
        int bits, baud;
-       struct tty_struct *tty = tty_port_tty_get(&sport->port.state->port);
+       struct tty_port *port = &sport->port.state->port;
+       struct tty_struct *tty = port->tty;
        struct ktermios *termios = &tty->termios;
 
        baud = tty_get_baud_rate(tty);
index 239c0fa..0f67197 100644 (file)
@@ -2351,6 +2351,14 @@ static int imx_uart_probe(struct platform_device *pdev)
                                ret);
                        return ret;
                }
+
+               ret = devm_request_irq(&pdev->dev, rtsirq, imx_uart_rtsint, 0,
+                                      dev_name(&pdev->dev), sport);
+               if (ret) {
+                       dev_err(&pdev->dev, "failed to request rts irq: %d\n",
+                               ret);
+                       return ret;
+               }
        } else {
                ret = devm_request_irq(&pdev->dev, rxirq, imx_uart_int, 0,
                                       dev_name(&pdev->dev), sport);
index d04b5ee..170e446 100644 (file)
@@ -511,6 +511,7 @@ static void mvebu_uart_set_termios(struct uart_port *port,
                termios->c_iflag |= old->c_iflag & ~(INPCK | IGNPAR);
                termios->c_cflag &= CREAD | CBAUD;
                termios->c_cflag |= old->c_cflag & ~(CREAD | CBAUD);
+               termios->c_cflag |= CS8;
        }
 
        spin_unlock_irqrestore(&port->lock, flags);
index 32bc3e3..5e5da9a 100644 (file)
@@ -1255,6 +1255,7 @@ static void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *
 static int tty_reopen(struct tty_struct *tty)
 {
        struct tty_driver *driver = tty->driver;
+       int retval;
 
        if (driver->type == TTY_DRIVER_TYPE_PTY &&
            driver->subtype == PTY_TYPE_MASTER)
@@ -1268,10 +1269,14 @@ static int tty_reopen(struct tty_struct *tty)
 
        tty->count++;
 
-       if (!tty->ldisc)
-               return tty_ldisc_reinit(tty, tty->termios.c_line);
+       if (tty->ldisc)
+               return 0;
 
-       return 0;
+       retval = tty_ldisc_reinit(tty, tty->termios.c_line);
+       if (retval)
+               tty->count--;
+
+       return retval;
 }
 
 /**
index a78ad10..73cdc0d 100644 (file)
@@ -32,6 +32,8 @@
 #include <asm/io.h>
 #include <linux/uaccess.h>
 
+#include <linux/nospec.h>
+
 #include <linux/kbd_kern.h>
 #include <linux/vt_kern.h>
 #include <linux/kbd_diacr.h>
@@ -700,6 +702,8 @@ int vt_ioctl(struct tty_struct *tty,
                if (vsa.console == 0 || vsa.console > MAX_NR_CONSOLES)
                        ret = -ENXIO;
                else {
+                       vsa.console = array_index_nospec(vsa.console,
+                                                        MAX_NR_CONSOLES + 1);
                        vsa.console--;
                        console_lock();
                        ret = vc_allocate(vsa.console);
index 656d247..bec581f 100644 (file)
@@ -460,7 +460,7 @@ static int service_outstanding_interrupt(struct wdm_device *desc)
 
        set_bit(WDM_RESPONDING, &desc->flags);
        spin_unlock_irq(&desc->iuspin);
-       rv = usb_submit_urb(desc->response, GFP_ATOMIC);
+       rv = usb_submit_urb(desc->response, GFP_KERNEL);
        spin_lock_irq(&desc->iuspin);
        if (rv) {
                dev_err(&desc->intf->dev,
index 15cc76e..99116af 100644 (file)
@@ -109,8 +109,15 @@ static void *usb_role_switch_match(struct device_connection *con, int ep,
  */
 struct usb_role_switch *usb_role_switch_get(struct device *dev)
 {
-       return device_connection_find_match(dev, "usb-role-switch", NULL,
-                                           usb_role_switch_match);
+       struct usb_role_switch *sw;
+
+       sw = device_connection_find_match(dev, "usb-role-switch", NULL,
+                                         usb_role_switch_match);
+
+       if (!IS_ERR_OR_NULL(sw))
+               WARN_ON(!try_module_get(sw->dev.parent->driver->owner));
+
+       return sw;
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_get);
 
@@ -122,8 +129,10 @@ EXPORT_SYMBOL_GPL(usb_role_switch_get);
  */
 void usb_role_switch_put(struct usb_role_switch *sw)
 {
-       if (!IS_ERR_OR_NULL(sw))
+       if (!IS_ERR_OR_NULL(sw)) {
                put_device(&sw->dev);
+               module_put(sw->dev.parent->driver->owner);
+       }
 }
 EXPORT_SYMBOL_GPL(usb_role_switch_put);
 
index 6ce77b3..244417d 100644 (file)
@@ -1434,10 +1434,13 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
        struct async *as = NULL;
        struct usb_ctrlrequest *dr = NULL;
        unsigned int u, totlen, isofrmlen;
-       int i, ret, is_in, num_sgs = 0, ifnum = -1;
+       int i, ret, num_sgs = 0, ifnum = -1;
        int number_of_packets = 0;
        unsigned int stream_id = 0;
        void *buf;
+       bool is_in;
+       bool allow_short = false;
+       bool allow_zero = false;
        unsigned long mask =    USBDEVFS_URB_SHORT_NOT_OK |
                                USBDEVFS_URB_BULK_CONTINUATION |
                                USBDEVFS_URB_NO_FSBR |
@@ -1471,6 +1474,8 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
        u = 0;
        switch (uurb->type) {
        case USBDEVFS_URB_TYPE_CONTROL:
+               if (is_in)
+                       allow_short = true;
                if (!usb_endpoint_xfer_control(&ep->desc))
                        return -EINVAL;
                /* min 8 byte setup packet */
@@ -1511,6 +1516,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
                break;
 
        case USBDEVFS_URB_TYPE_BULK:
+               if (!is_in)
+                       allow_zero = true;
+               else
+                       allow_short = true;
                switch (usb_endpoint_type(&ep->desc)) {
                case USB_ENDPOINT_XFER_CONTROL:
                case USB_ENDPOINT_XFER_ISOC:
@@ -1531,6 +1540,10 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
                if (!usb_endpoint_xfer_int(&ep->desc))
                        return -EINVAL;
  interrupt_urb:
+               if (!is_in)
+                       allow_zero = true;
+               else
+                       allow_short = true;
                break;
 
        case USBDEVFS_URB_TYPE_ISO:
@@ -1676,14 +1689,19 @@ static int proc_do_submiturb(struct usb_dev_state *ps, struct usbdevfs_urb *uurb
        u = (is_in ? URB_DIR_IN : URB_DIR_OUT);
        if (uurb->flags & USBDEVFS_URB_ISO_ASAP)
                u |= URB_ISO_ASAP;
-       if (uurb->flags & USBDEVFS_URB_SHORT_NOT_OK && is_in)
+       if (allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK)
                u |= URB_SHORT_NOT_OK;
-       if (uurb->flags & USBDEVFS_URB_ZERO_PACKET)
+       if (allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET)
                u |= URB_ZERO_PACKET;
        if (uurb->flags & USBDEVFS_URB_NO_INTERRUPT)
                u |= URB_NO_INTERRUPT;
        as->urb->transfer_flags = u;
 
+       if (!allow_short && uurb->flags & USBDEVFS_URB_SHORT_NOT_OK)
+               dev_warn(&ps->dev->dev, "Requested nonsensical USBDEVFS_URB_SHORT_NOT_OK.\n");
+       if (!allow_zero && uurb->flags & USBDEVFS_URB_ZERO_PACKET)
+               dev_warn(&ps->dev->dev, "Requested nonsensical USBDEVFS_URB_ZERO_PACKET.\n");
+
        as->urb->transfer_buffer_length = uurb->buffer_length;
        as->urb->setup_packet = (unsigned char *)dr;
        dr = NULL;
index e76e95f..a1f225f 100644 (file)
@@ -512,7 +512,6 @@ int usb_driver_claim_interface(struct usb_driver *driver,
        struct device *dev;
        struct usb_device *udev;
        int retval = 0;
-       int lpm_disable_error = -ENODEV;
 
        if (!iface)
                return -ENODEV;
@@ -533,16 +532,6 @@ int usb_driver_claim_interface(struct usb_driver *driver,
 
        iface->condition = USB_INTERFACE_BOUND;
 
-       /* See the comment about disabling LPM in usb_probe_interface(). */
-       if (driver->disable_hub_initiated_lpm) {
-               lpm_disable_error = usb_unlocked_disable_lpm(udev);
-               if (lpm_disable_error) {
-                       dev_err(&iface->dev, "%s Failed to disable LPM for driver %s\n",
-                               __func__, driver->name);
-                       return -ENOMEM;
-               }
-       }
-
        /* Claimed interfaces are initially inactive (suspended) and
         * runtime-PM-enabled, but only if the driver has autosuspend
         * support.  Otherwise they are marked active, to prevent the
@@ -561,9 +550,20 @@ int usb_driver_claim_interface(struct usb_driver *driver,
        if (device_is_registered(dev))
                retval = device_bind_driver(dev);
 
-       /* Attempt to re-enable USB3 LPM, if the disable was successful. */
-       if (!lpm_disable_error)
-               usb_unlocked_enable_lpm(udev);
+       if (retval) {
+               dev->driver = NULL;
+               usb_set_intfdata(iface, NULL);
+               iface->needs_remote_wakeup = 0;
+               iface->condition = USB_INTERFACE_UNBOUND;
+
+               /*
+                * Unbound interfaces are always runtime-PM-disabled
+                * and runtime-PM-suspended
+                */
+               if (driver->supports_autosuspend)
+                       pm_runtime_disable(dev);
+               pm_runtime_set_suspended(dev);
+       }
 
        return retval;
 }
index e77dfe5..178d6c6 100644 (file)
@@ -58,6 +58,7 @@ static int quirks_param_set(const char *val, const struct kernel_param *kp)
        quirk_list = kcalloc(quirk_count, sizeof(struct quirk_entry),
                             GFP_KERNEL);
        if (!quirk_list) {
+               quirk_count = 0;
                mutex_unlock(&quirk_mutex);
                return -ENOMEM;
        }
@@ -154,7 +155,7 @@ static struct kparam_string quirks_param_string = {
        .string = quirks_param,
 };
 
-module_param_cb(quirks, &quirks_param_ops, &quirks_param_string, 0644);
+device_param_cb(quirks, &quirks_param_ops, &quirks_param_string, 0644);
 MODULE_PARM_DESC(quirks, "Add/modify USB quirks by specifying quirks=vendorID:productID:quirks");
 
 /* Lists of quirky USB devices, split in device quirks and interface quirks.
index 623be31..79d8bd7 100644 (file)
@@ -228,6 +228,8 @@ struct usb_host_interface *usb_find_alt_setting(
        struct usb_interface_cache *intf_cache = NULL;
        int i;
 
+       if (!config)
+               return NULL;
        for (i = 0; i < config->desc.bNumInterfaces; i++) {
                if (config->intf_cache[i]->altsetting[0].desc.bInterfaceNumber
                                == iface_num) {
index df827ff..23a0df7 100644 (file)
@@ -658,16 +658,6 @@ dsps_dma_controller_create(struct musb *musb, void __iomem *base)
        return controller;
 }
 
-static void dsps_dma_controller_destroy(struct dma_controller *c)
-{
-       struct musb *musb = c->musb;
-       struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent);
-       void __iomem *usbss_base = glue->usbss_base;
-
-       musb_writel(usbss_base, USBSS_IRQ_CLEARR, USBSS_IRQ_PD_COMP);
-       cppi41_dma_controller_destroy(c);
-}
-
 #ifdef CONFIG_PM_SLEEP
 static void dsps_dma_controller_suspend(struct dsps_glue *glue)
 {
@@ -697,7 +687,7 @@ static struct musb_platform_ops dsps_ops = {
 
 #ifdef CONFIG_USB_TI_CPPI41_DMA
        .dma_init       = dsps_dma_controller_create,
-       .dma_exit       = dsps_dma_controller_destroy,
+       .dma_exit       = cppi41_dma_controller_destroy,
 #endif
        .enable         = dsps_musb_enable,
        .disable        = dsps_musb_disable,
index ddaac63..d990aa5 100644 (file)
@@ -9,6 +9,7 @@
 
 #include <linux/device.h>
 #include <linux/list.h>
+#include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/usb/typec_mux.h>
 
@@ -49,8 +50,10 @@ struct typec_switch *typec_switch_get(struct device *dev)
        mutex_lock(&switch_lock);
        sw = device_connection_find_match(dev, "typec-switch", NULL,
                                          typec_switch_match);
-       if (!IS_ERR_OR_NULL(sw))
+       if (!IS_ERR_OR_NULL(sw)) {
+               WARN_ON(!try_module_get(sw->dev->driver->owner));
                get_device(sw->dev);
+       }
        mutex_unlock(&switch_lock);
 
        return sw;
@@ -65,8 +68,10 @@ EXPORT_SYMBOL_GPL(typec_switch_get);
  */
 void typec_switch_put(struct typec_switch *sw)
 {
-       if (!IS_ERR_OR_NULL(sw))
+       if (!IS_ERR_OR_NULL(sw)) {
+               module_put(sw->dev->driver->owner);
                put_device(sw->dev);
+       }
 }
 EXPORT_SYMBOL_GPL(typec_switch_put);
 
@@ -136,8 +141,10 @@ struct typec_mux *typec_mux_get(struct device *dev, const char *name)
 
        mutex_lock(&mux_lock);
        mux = device_connection_find_match(dev, name, NULL, typec_mux_match);
-       if (!IS_ERR_OR_NULL(mux))
+       if (!IS_ERR_OR_NULL(mux)) {
+               WARN_ON(!try_module_get(mux->dev->driver->owner));
                get_device(mux->dev);
+       }
        mutex_unlock(&mux_lock);
 
        return mux;
@@ -152,8 +159,10 @@ EXPORT_SYMBOL_GPL(typec_mux_get);
  */
 void typec_mux_put(struct typec_mux *mux)
 {
-       if (!IS_ERR_OR_NULL(mux))
+       if (!IS_ERR_OR_NULL(mux)) {
+               module_put(mux->dev->driver->owner);
                put_device(mux->dev);
+       }
 }
 EXPORT_SYMBOL_GPL(typec_mux_put);
 
index f32d712..b68ce48 100644 (file)
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -1120,21 +1120,12 @@ static vm_fault_t dax_load_hole(struct address_space *mapping, void *entry,
 {
        struct inode *inode = mapping->host;
        unsigned long vaddr = vmf->address;
-       vm_fault_t ret = VM_FAULT_NOPAGE;
-       struct page *zero_page;
-       pfn_t pfn;
-
-       zero_page = ZERO_PAGE(0);
-       if (unlikely(!zero_page)) {
-               ret = VM_FAULT_OOM;
-               goto out;
-       }
+       pfn_t pfn = pfn_to_pfn_t(my_zero_pfn(vaddr));
+       vm_fault_t ret;
 
-       pfn = page_to_pfn_t(zero_page);
        dax_insert_mapping_entry(mapping, vmf, entry, pfn, RADIX_DAX_ZERO_PAGE,
                        false);
        ret = vmf_insert_mixed(vmf->vma, vaddr, pfn);
-out:
        trace_dax_load_hole(inode, vmf, ret);
        return ret;
 }
index 7f7ee18..e4bb938 100644 (file)
@@ -1448,6 +1448,7 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
        }
        inode->i_blocks = le32_to_cpu(raw_inode->i_blocks);
        ei->i_flags = le32_to_cpu(raw_inode->i_flags);
+       ext2_set_inode_flags(inode);
        ei->i_faddr = le32_to_cpu(raw_inode->i_faddr);
        ei->i_frag_no = raw_inode->i_frag;
        ei->i_frag_size = raw_inode->i_fsize;
@@ -1517,7 +1518,6 @@ struct inode *ext2_iget (struct super_block *sb, unsigned long ino)
                           new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
        }
        brelse (bh);
-       ext2_set_inode_flags(inode);
        unlock_new_inode(inode);
        return inode;
        
index 67662d0..3ef82d3 100644 (file)
@@ -49,8 +49,9 @@ struct netpoll_info {
 };
 
 #ifdef CONFIG_NETPOLL
-extern void netpoll_poll_disable(struct net_device *dev);
-extern void netpoll_poll_enable(struct net_device *dev);
+void netpoll_poll_dev(struct net_device *dev);
+void netpoll_poll_disable(struct net_device *dev);
+void netpoll_poll_enable(struct net_device *dev);
 #else
 static inline void netpoll_poll_disable(struct net_device *dev) { return; }
 static inline void netpoll_poll_enable(struct net_device *dev) { return; }
index c43e9a0..7ddfc65 100644 (file)
@@ -30,6 +30,7 @@
 
 #define MTL_MAX_RX_QUEUES      8
 #define MTL_MAX_TX_QUEUES      8
+#define STMMAC_CH_MAX          8
 
 #define STMMAC_RX_COE_NONE     0
 #define STMMAC_RX_COE_TYPE1    1
index 409c845..422b1c0 100644 (file)
@@ -172,7 +172,7 @@ size_t copy_from_iter_flushcache(void *addr, size_t bytes, struct iov_iter *i)
 static __always_inline __must_check
 size_t copy_to_iter_mcsafe(void *addr, size_t bytes, struct iov_iter *i)
 {
-       if (unlikely(!check_copy_size(addr, bytes, false)))
+       if (unlikely(!check_copy_size(addr, bytes, true)))
                return 0;
        else
                return _copy_to_iter_mcsafe(addr, bytes, i);
index 316694d..008f466 100644 (file)
@@ -87,7 +87,7 @@ struct nfc_hci_pipe {
  * According to specification 102 622 chapter 4.4 Pipes,
  * the pipe identifier is 7 bits long.
  */
-#define NFC_HCI_MAX_PIPES              127
+#define NFC_HCI_MAX_PIPES              128
 struct nfc_hci_init_data {
        u8 gate_count;
        struct nfc_hci_gate gates[NFC_HCI_MAX_CUSTOM_GATES];
index 910cc43..7b8c9e1 100644 (file)
@@ -65,7 +65,7 @@
 
 /* keyctl structures */
 struct keyctl_dh_params {
-       __s32 dh_private;
+       __s32 private;
        __s32 prime;
        __s32 base;
 };
index 488ef96..0a0f2ec 100644 (file)
@@ -132,6 +132,7 @@ struct smap_psock {
        struct work_struct gc_work;
 
        struct proto *sk_proto;
+       void (*save_unhash)(struct sock *sk);
        void (*save_close)(struct sock *sk, long timeout);
        void (*save_data_ready)(struct sock *sk);
        void (*save_write_space)(struct sock *sk);
@@ -143,6 +144,7 @@ static int bpf_tcp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 static int bpf_tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size);
 static int bpf_tcp_sendpage(struct sock *sk, struct page *page,
                            int offset, size_t size, int flags);
+static void bpf_tcp_unhash(struct sock *sk);
 static void bpf_tcp_close(struct sock *sk, long timeout);
 
 static inline struct smap_psock *smap_psock_sk(const struct sock *sk)
@@ -184,6 +186,7 @@ static void build_protos(struct proto prot[SOCKMAP_NUM_CONFIGS],
                         struct proto *base)
 {
        prot[SOCKMAP_BASE]                      = *base;
+       prot[SOCKMAP_BASE].unhash               = bpf_tcp_unhash;
        prot[SOCKMAP_BASE].close                = bpf_tcp_close;
        prot[SOCKMAP_BASE].recvmsg              = bpf_tcp_recvmsg;
        prot[SOCKMAP_BASE].stream_memory_read   = bpf_tcp_stream_read;
@@ -217,6 +220,7 @@ static int bpf_tcp_init(struct sock *sk)
                return -EBUSY;
        }
 
+       psock->save_unhash = sk->sk_prot->unhash;
        psock->save_close = sk->sk_prot->close;
        psock->sk_proto = sk->sk_prot;
 
@@ -305,30 +309,12 @@ static struct smap_psock_map_entry *psock_map_pop(struct sock *sk,
        return e;
 }
 
-static void bpf_tcp_close(struct sock *sk, long timeout)
+static void bpf_tcp_remove(struct sock *sk, struct smap_psock *psock)
 {
-       void (*close_fun)(struct sock *sk, long timeout);
        struct smap_psock_map_entry *e;
        struct sk_msg_buff *md, *mtmp;
-       struct smap_psock *psock;
        struct sock *osk;
 
-       lock_sock(sk);
-       rcu_read_lock();
-       psock = smap_psock_sk(sk);
-       if (unlikely(!psock)) {
-               rcu_read_unlock();
-               release_sock(sk);
-               return sk->sk_prot->close(sk, timeout);
-       }
-
-       /* The psock may be destroyed anytime after exiting the RCU critial
-        * section so by the time we use close_fun the psock may no longer
-        * be valid. However, bpf_tcp_close is called with the sock lock
-        * held so the close hook and sk are still valid.
-        */
-       close_fun = psock->save_close;
-
        if (psock->cork) {
                free_start_sg(psock->sock, psock->cork, true);
                kfree(psock->cork);
@@ -379,6 +365,42 @@ static void bpf_tcp_close(struct sock *sk, long timeout)
                kfree(e);
                e = psock_map_pop(sk, psock);
        }
+}
+
+static void bpf_tcp_unhash(struct sock *sk)
+{
+       void (*unhash_fun)(struct sock *sk);
+       struct smap_psock *psock;
+
+       rcu_read_lock();
+       psock = smap_psock_sk(sk);
+       if (unlikely(!psock)) {
+               rcu_read_unlock();
+               if (sk->sk_prot->unhash)
+                       sk->sk_prot->unhash(sk);
+               return;
+       }
+       unhash_fun = psock->save_unhash;
+       bpf_tcp_remove(sk, psock);
+       rcu_read_unlock();
+       unhash_fun(sk);
+}
+
+static void bpf_tcp_close(struct sock *sk, long timeout)
+{
+       void (*close_fun)(struct sock *sk, long timeout);
+       struct smap_psock *psock;
+
+       lock_sock(sk);
+       rcu_read_lock();
+       psock = smap_psock_sk(sk);
+       if (unlikely(!psock)) {
+               rcu_read_unlock();
+               release_sock(sk);
+               return sk->sk_prot->close(sk, timeout);
+       }
+       close_fun = psock->save_close;
+       bpf_tcp_remove(sk, psock);
        rcu_read_unlock();
        release_sock(sk);
        close_fun(sk, timeout);
@@ -2097,8 +2119,12 @@ static int sock_map_update_elem(struct bpf_map *map,
                return -EINVAL;
        }
 
+       /* ULPs are currently supported only for TCP sockets in ESTABLISHED
+        * state.
+        */
        if (skops.sk->sk_type != SOCK_STREAM ||
-           skops.sk->sk_protocol != IPPROTO_TCP) {
+           skops.sk->sk_protocol != IPPROTO_TCP ||
+           skops.sk->sk_state != TCP_ESTABLISHED) {
                fput(socket->file);
                return -EOPNOTSUPP;
        }
@@ -2453,6 +2479,16 @@ static int sock_hash_update_elem(struct bpf_map *map,
                return -EINVAL;
        }
 
+       /* ULPs are currently supported only for TCP sockets in ESTABLISHED
+        * state.
+        */
+       if (skops.sk->sk_type != SOCK_STREAM ||
+           skops.sk->sk_protocol != IPPROTO_TCP ||
+           skops.sk->sk_state != TCP_ESTABLISHED) {
+               fput(socket->file);
+               return -EOPNOTSUPP;
+       }
+
        lock_sock(skops.sk);
        preempt_disable();
        rcu_read_lock();
@@ -2543,10 +2579,22 @@ const struct bpf_map_ops sock_hash_ops = {
        .map_check_btf = map_check_no_btf,
 };
 
+static bool bpf_is_valid_sock_op(struct bpf_sock_ops_kern *ops)
+{
+       return ops->op == BPF_SOCK_OPS_PASSIVE_ESTABLISHED_CB ||
+              ops->op == BPF_SOCK_OPS_ACTIVE_ESTABLISHED_CB;
+}
 BPF_CALL_4(bpf_sock_map_update, struct bpf_sock_ops_kern *, bpf_sock,
           struct bpf_map *, map, void *, key, u64, flags)
 {
        WARN_ON_ONCE(!rcu_read_lock_held());
+
+       /* ULPs are currently supported only for TCP sockets in ESTABLISHED
+        * state. This checks that the sock ops triggering the update is
+        * one indicating we are (or will be soon) in an ESTABLISHED state.
+        */
+       if (!bpf_is_valid_sock_op(bpf_sock))
+               return -EOPNOTSUPP;
        return sock_map_ctx_update_elem(bpf_sock, map, key, flags);
 }
 
@@ -2565,6 +2613,9 @@ BPF_CALL_4(bpf_sock_hash_update, struct bpf_sock_ops_kern *, bpf_sock,
           struct bpf_map *, map, void *, key, u64, flags)
 {
        WARN_ON_ONCE(!rcu_read_lock_held());
+
+       if (!bpf_is_valid_sock_op(bpf_sock))
+               return -EOPNOTSUPP;
        return sock_hash_ctx_update_elem(bpf_sock, map, key, flags);
 }
 
index 71c20c1..9f481cf 100644 (file)
@@ -241,7 +241,7 @@ batadv_v_elp_wifi_neigh_probe(struct batadv_hardif_neigh_node *neigh)
                 * the packet to be exactly of that size to make the link
                 * throughput estimation effective.
                 */
-               skb_put(skb, probe_len - hard_iface->bat_v.elp_skb->len);
+               skb_put_zero(skb, probe_len - hard_iface->bat_v.elp_skb->len);
 
                batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                           "Sending unicast (probe) ELP packet on interface %s to %pM\n",
@@ -268,6 +268,7 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
        struct batadv_priv *bat_priv;
        struct sk_buff *skb;
        u32 elp_interval;
+       bool ret;
 
        bat_v = container_of(work, struct batadv_hard_iface_bat_v, elp_wq.work);
        hard_iface = container_of(bat_v, struct batadv_hard_iface, bat_v);
@@ -329,8 +330,11 @@ static void batadv_v_elp_periodic_work(struct work_struct *work)
                 * may sleep and that is not allowed in an rcu protected
                 * context. Therefore schedule a task for that.
                 */
-               queue_work(batadv_event_workqueue,
-                          &hardif_neigh->bat_v.metric_work);
+               ret = queue_work(batadv_event_workqueue,
+                                &hardif_neigh->bat_v.metric_work);
+
+               if (!ret)
+                       batadv_hardif_neigh_put(hardif_neigh);
        }
        rcu_read_unlock();
 
index ff9659a..5f1aeed 100644 (file)
@@ -1772,6 +1772,7 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
 {
        struct batadv_bla_backbone_gw *backbone_gw;
        struct ethhdr *ethhdr;
+       bool ret;
 
        ethhdr = eth_hdr(skb);
 
@@ -1795,8 +1796,13 @@ batadv_bla_loopdetect_check(struct batadv_priv *bat_priv, struct sk_buff *skb,
        if (unlikely(!backbone_gw))
                return true;
 
-       queue_work(batadv_event_workqueue, &backbone_gw->report_work);
-       /* backbone_gw is unreferenced in the report work function function */
+       ret = queue_work(batadv_event_workqueue, &backbone_gw->report_work);
+
+       /* backbone_gw is unreferenced in the report work function function
+        * if queue_work() call was successful
+        */
+       if (!ret)
+               batadv_backbone_gw_put(backbone_gw);
 
        return true;
 }
index 8b198ee..140c61a 100644 (file)
@@ -32,6 +32,7 @@
 #include <linux/kernel.h>
 #include <linux/kref.h>
 #include <linux/list.h>
+#include <linux/lockdep.h>
 #include <linux/netdevice.h>
 #include <linux/netlink.h>
 #include <linux/rculist.h>
@@ -348,6 +349,9 @@ out:
  * @bat_priv: the bat priv with all the soft interface information
  * @orig_node: originator announcing gateway capabilities
  * @gateway: announced bandwidth information
+ *
+ * Has to be called with the appropriate locks being acquired
+ * (gw.list_lock).
  */
 static void batadv_gw_node_add(struct batadv_priv *bat_priv,
                               struct batadv_orig_node *orig_node,
@@ -355,6 +359,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
 {
        struct batadv_gw_node *gw_node;
 
+       lockdep_assert_held(&bat_priv->gw.list_lock);
+
        if (gateway->bandwidth_down == 0)
                return;
 
@@ -369,10 +375,8 @@ static void batadv_gw_node_add(struct batadv_priv *bat_priv,
        gw_node->bandwidth_down = ntohl(gateway->bandwidth_down);
        gw_node->bandwidth_up = ntohl(gateway->bandwidth_up);
 
-       spin_lock_bh(&bat_priv->gw.list_lock);
        kref_get(&gw_node->refcount);
        hlist_add_head_rcu(&gw_node->list, &bat_priv->gw.gateway_list);
-       spin_unlock_bh(&bat_priv->gw.list_lock);
 
        batadv_dbg(BATADV_DBG_BATMAN, bat_priv,
                   "Found new gateway %pM -> gw bandwidth: %u.%u/%u.%u MBit\n",
@@ -428,11 +432,14 @@ void batadv_gw_node_update(struct batadv_priv *bat_priv,
 {
        struct batadv_gw_node *gw_node, *curr_gw = NULL;
 
+       spin_lock_bh(&bat_priv->gw.list_lock);
        gw_node = batadv_gw_node_get(bat_priv, orig_node);
        if (!gw_node) {
                batadv_gw_node_add(bat_priv, orig_node, gateway);
+               spin_unlock_bh(&bat_priv->gw.list_lock);
                goto out;
        }
+       spin_unlock_bh(&bat_priv->gw.list_lock);
 
        if (gw_node->bandwidth_down == ntohl(gateway->bandwidth_down) &&
            gw_node->bandwidth_up == ntohl(gateway->bandwidth_up))
index 8da3c93..3ccc75e 100644 (file)
@@ -25,7 +25,7 @@
 #define BATADV_DRIVER_DEVICE "batman-adv"
 
 #ifndef BATADV_SOURCE_VERSION
-#define BATADV_SOURCE_VERSION "2018.2"
+#define BATADV_SOURCE_VERSION "2018.3"
 #endif
 
 /* B.A.T.M.A.N. parameters */
index c357844..34caf12 100644 (file)
@@ -854,16 +854,27 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
        spinlock_t *lock; /* Used to lock list selected by "int in_coding" */
        struct list_head *list;
 
+       /* Select ingoing or outgoing coding node */
+       if (in_coding) {
+               lock = &orig_neigh_node->in_coding_list_lock;
+               list = &orig_neigh_node->in_coding_list;
+       } else {
+               lock = &orig_neigh_node->out_coding_list_lock;
+               list = &orig_neigh_node->out_coding_list;
+       }
+
+       spin_lock_bh(lock);
+
        /* Check if nc_node is already added */
        nc_node = batadv_nc_find_nc_node(orig_node, orig_neigh_node, in_coding);
 
        /* Node found */
        if (nc_node)
-               return nc_node;
+               goto unlock;
 
        nc_node = kzalloc(sizeof(*nc_node), GFP_ATOMIC);
        if (!nc_node)
-               return NULL;
+               goto unlock;
 
        /* Initialize nc_node */
        INIT_LIST_HEAD(&nc_node->list);
@@ -872,22 +883,14 @@ batadv_nc_get_nc_node(struct batadv_priv *bat_priv,
        kref_get(&orig_neigh_node->refcount);
        nc_node->orig_node = orig_neigh_node;
 
-       /* Select ingoing or outgoing coding node */
-       if (in_coding) {
-               lock = &orig_neigh_node->in_coding_list_lock;
-               list = &orig_neigh_node->in_coding_list;
-       } else {
-               lock = &orig_neigh_node->out_coding_list_lock;
-               list = &orig_neigh_node->out_coding_list;
-       }
-
        batadv_dbg(BATADV_DBG_NC, bat_priv, "Adding nc_node %pM -> %pM\n",
                   nc_node->addr, nc_node->orig_node->orig);
 
        /* Add nc_node to orig_node */
-       spin_lock_bh(lock);
        kref_get(&nc_node->refcount);
        list_add_tail_rcu(&nc_node->list, list);
+
+unlock:
        spin_unlock_bh(lock);
 
        return nc_node;
index 1485263..626ddca 100644 (file)
@@ -574,15 +574,20 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
        struct batadv_softif_vlan *vlan;
        int err;
 
+       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
+
        vlan = batadv_softif_vlan_get(bat_priv, vid);
        if (vlan) {
                batadv_softif_vlan_put(vlan);
+               spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
                return -EEXIST;
        }
 
        vlan = kzalloc(sizeof(*vlan), GFP_ATOMIC);
-       if (!vlan)
+       if (!vlan) {
+               spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
                return -ENOMEM;
+       }
 
        vlan->bat_priv = bat_priv;
        vlan->vid = vid;
@@ -590,17 +595,23 @@ int batadv_softif_create_vlan(struct batadv_priv *bat_priv, unsigned short vid)
 
        atomic_set(&vlan->ap_isolation, 0);
 
+       kref_get(&vlan->refcount);
+       hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
+       spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
+
+       /* batadv_sysfs_add_vlan cannot be in the spinlock section due to the
+        * sleeping behavior of the sysfs functions and the fs_reclaim lock
+        */
        err = batadv_sysfs_add_vlan(bat_priv->soft_iface, vlan);
        if (err) {
-               kfree(vlan);
+               /* ref for the function */
+               batadv_softif_vlan_put(vlan);
+
+               /* ref for the list */
+               batadv_softif_vlan_put(vlan);
                return err;
        }
 
-       spin_lock_bh(&bat_priv->softif_vlan_list_lock);
-       kref_get(&vlan->refcount);
-       hlist_add_head_rcu(&vlan->list, &bat_priv->softif_vlan_list);
-       spin_unlock_bh(&bat_priv->softif_vlan_list_lock);
-
        /* add a new TT local entry. This one will be marked with the NOPURGE
         * flag
         */
index f2eef43..09427fc 100644 (file)
@@ -188,7 +188,8 @@ ssize_t batadv_store_##_name(struct kobject *kobj,                  \
                                                                        \
        return __batadv_store_uint_attr(buff, count, _min, _max,        \
                                        _post_func, attr,               \
-                                       &bat_priv->_var, net_dev);      \
+                                       &bat_priv->_var, net_dev,       \
+                                       NULL);  \
 }
 
 #define BATADV_ATTR_SIF_SHOW_UINT(_name, _var)                         \
@@ -262,7 +263,9 @@ ssize_t batadv_store_##_name(struct kobject *kobj,                  \
                                                                        \
        length = __batadv_store_uint_attr(buff, count, _min, _max,      \
                                          _post_func, attr,             \
-                                         &hard_iface->_var, net_dev);  \
+                                         &hard_iface->_var,            \
+                                         hard_iface->soft_iface,       \
+                                         net_dev);                     \
                                                                        \
        batadv_hardif_put(hard_iface);                          \
        return length;                                                  \
@@ -356,10 +359,12 @@ __batadv_store_bool_attr(char *buff, size_t count,
 
 static int batadv_store_uint_attr(const char *buff, size_t count,
                                  struct net_device *net_dev,
+                                 struct net_device *slave_dev,
                                  const char *attr_name,
                                  unsigned int min, unsigned int max,
                                  atomic_t *attr)
 {
+       char ifname[IFNAMSIZ + 3] = "";
        unsigned long uint_val;
        int ret;
 
@@ -385,8 +390,11 @@ static int batadv_store_uint_attr(const char *buff, size_t count,
        if (atomic_read(attr) == uint_val)
                return count;
 
-       batadv_info(net_dev, "%s: Changing from: %i to: %lu\n",
-                   attr_name, atomic_read(attr), uint_val);
+       if (slave_dev)
+               snprintf(ifname, sizeof(ifname), "%s: ", slave_dev->name);
+
+       batadv_info(net_dev, "%s: %sChanging from: %i to: %lu\n",
+                   attr_name, ifname, atomic_read(attr), uint_val);
 
        atomic_set(attr, uint_val);
        return count;
@@ -397,12 +405,13 @@ static ssize_t __batadv_store_uint_attr(const char *buff, size_t count,
                                        void (*post_func)(struct net_device *),
                                        const struct attribute *attr,
                                        atomic_t *attr_store,
-                                       struct net_device *net_dev)
+                                       struct net_device *net_dev,
+                                       struct net_device *slave_dev)
 {
        int ret;
 
-       ret = batadv_store_uint_attr(buff, count, net_dev, attr->name, min, max,
-                                    attr_store);
+       ret = batadv_store_uint_attr(buff, count, net_dev, slave_dev,
+                                    attr->name, min, max, attr_store);
        if (post_func && ret)
                post_func(net_dev);
 
@@ -571,7 +580,7 @@ static ssize_t batadv_store_gw_sel_class(struct kobject *kobj,
        return __batadv_store_uint_attr(buff, count, 1, BATADV_TQ_MAX_VALUE,
                                        batadv_post_gw_reselect, attr,
                                        &bat_priv->gw.sel_class,
-                                       bat_priv->soft_iface);
+                                       bat_priv->soft_iface, NULL);
 }
 
 static ssize_t batadv_show_gw_bwidth(struct kobject *kobj,
@@ -1090,8 +1099,9 @@ static ssize_t batadv_store_throughput_override(struct kobject *kobj,
        if (old_tp_override == tp_override)
                goto out;
 
-       batadv_info(net_dev, "%s: Changing from: %u.%u MBit to: %u.%u MBit\n",
-                   "throughput_override",
+       batadv_info(hard_iface->soft_iface,
+                   "%s: %s: Changing from: %u.%u MBit to: %u.%u MBit\n",
+                   "throughput_override", net_dev->name,
                    old_tp_override / 10, old_tp_override % 10,
                    tp_override / 10, tp_override % 10);
 
index 12a2b7d..d21624c 100644 (file)
@@ -1613,6 +1613,8 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
 {
        struct batadv_tt_orig_list_entry *orig_entry;
 
+       spin_lock_bh(&tt_global->list_lock);
+
        orig_entry = batadv_tt_global_orig_entry_find(tt_global, orig_node);
        if (orig_entry) {
                /* refresh the ttvn: the current value could be a bogus one that
@@ -1635,11 +1637,9 @@ batadv_tt_global_orig_entry_add(struct batadv_tt_global_entry *tt_global,
        orig_entry->flags = flags;
        kref_init(&orig_entry->refcount);
 
-       spin_lock_bh(&tt_global->list_lock);
        kref_get(&orig_entry->refcount);
        hlist_add_head_rcu(&orig_entry->list,
                           &tt_global->orig_list);
-       spin_unlock_bh(&tt_global->list_lock);
        atomic_inc(&tt_global->orig_list_count);
 
 sync_flags:
@@ -1647,6 +1647,8 @@ sync_flags:
 out:
        if (orig_entry)
                batadv_tt_orig_list_entry_put(orig_entry);
+
+       spin_unlock_bh(&tt_global->list_lock);
 }
 
 /**
index a637458..40e69c9 100644 (file)
@@ -529,15 +529,20 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
 {
        struct batadv_tvlv_handler *tvlv_handler;
 
+       spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
+
        tvlv_handler = batadv_tvlv_handler_get(bat_priv, type, version);
        if (tvlv_handler) {
+               spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
                batadv_tvlv_handler_put(tvlv_handler);
                return;
        }
 
        tvlv_handler = kzalloc(sizeof(*tvlv_handler), GFP_ATOMIC);
-       if (!tvlv_handler)
+       if (!tvlv_handler) {
+               spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
                return;
+       }
 
        tvlv_handler->ogm_handler = optr;
        tvlv_handler->unicast_handler = uptr;
@@ -547,7 +552,6 @@ void batadv_tvlv_handler_register(struct batadv_priv *bat_priv,
        kref_init(&tvlv_handler->refcount);
        INIT_HLIST_NODE(&tvlv_handler->list);
 
-       spin_lock_bh(&bat_priv->tvlv.handler_list_lock);
        kref_get(&tvlv_handler->refcount);
        hlist_add_head_rcu(&tvlv_handler->list, &bat_priv->tvlv.handler_list);
        spin_unlock_bh(&bat_priv->tvlv.handler_list_lock);
index 65fc366..8c0ed22 100644 (file)
@@ -2592,7 +2592,7 @@ send_done:
        if (!nlh) {
                err = devlink_dpipe_send_and_alloc_skb(&skb, info);
                if (err)
-                       goto err_skb_send_alloc;
+                       return err;
                goto send_done;
        }
        return genlmsg_reply(skb, info);
@@ -2600,7 +2600,6 @@ send_done:
 nla_put_failure:
        err = -EMSGSIZE;
 err_resource_put:
-err_skb_send_alloc:
        nlmsg_free(skb);
        return err;
 }
index c9993c6..234a0ec 100644 (file)
@@ -2624,6 +2624,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
        case ETHTOOL_GPHYSTATS:
        case ETHTOOL_GTSO:
        case ETHTOOL_GPERMADDR:
+       case ETHTOOL_GUFO:
        case ETHTOOL_GGSO:
        case ETHTOOL_GGRO:
        case ETHTOOL_GFLAGS:
index 57557a6..3219a29 100644 (file)
@@ -187,16 +187,16 @@ static void poll_napi(struct net_device *dev)
        }
 }
 
-static void netpoll_poll_dev(struct net_device *dev)
+void netpoll_poll_dev(struct net_device *dev)
 {
-       const struct net_device_ops *ops;
        struct netpoll_info *ni = rcu_dereference_bh(dev->npinfo);
+       const struct net_device_ops *ops;
 
        /* Don't do any rx activity if the dev_lock mutex is held
         * the dev_open/close paths use this to block netpoll activity
         * while changing device state
         */
-       if (down_trylock(&ni->dev_lock))
+       if (!ni || down_trylock(&ni->dev_lock))
                return;
 
        if (!netif_running(dev)) {
@@ -205,13 +205,8 @@ static void netpoll_poll_dev(struct net_device *dev)
        }
 
        ops = dev->netdev_ops;
-       if (!ops->ndo_poll_controller) {
-               up(&ni->dev_lock);
-               return;
-       }
-
-       /* Process pending work on NIC */
-       ops->ndo_poll_controller(dev);
+       if (ops->ndo_poll_controller)
+               ops->ndo_poll_controller(dev);
 
        poll_napi(dev);
 
@@ -219,6 +214,7 @@ static void netpoll_poll_dev(struct net_device *dev)
 
        zap_completion_queue();
 }
+EXPORT_SYMBOL(netpoll_poll_dev);
 
 void netpoll_poll_disable(struct net_device *dev)
 {
@@ -613,8 +609,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev)
        strlcpy(np->dev_name, ndev->name, IFNAMSIZ);
        INIT_WORK(&np->cleanup_work, netpoll_async_cleanup);
 
-       if ((ndev->priv_flags & IFF_DISABLE_NETPOLL) ||
-           !ndev->netdev_ops->ndo_poll_controller) {
+       if (ndev->priv_flags & IFF_DISABLE_NETPOLL) {
                np_err(np, "%s doesn't support polling, aborting\n",
                       np->dev_name);
                err = -ENOTSUPP;
index c4f5602..284a221 100644 (file)
@@ -627,6 +627,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
                    const struct iphdr *tnl_params, u8 protocol)
 {
        struct ip_tunnel *tunnel = netdev_priv(dev);
+       unsigned int inner_nhdr_len = 0;
        const struct iphdr *inner_iph;
        struct flowi4 fl4;
        u8     tos, ttl;
@@ -636,6 +637,14 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
        __be32 dst;
        bool connected;
 
+       /* ensure we can access the inner net header, for several users below */
+       if (skb->protocol == htons(ETH_P_IP))
+               inner_nhdr_len = sizeof(struct iphdr);
+       else if (skb->protocol == htons(ETH_P_IPV6))
+               inner_nhdr_len = sizeof(struct ipv6hdr);
+       if (unlikely(!pskb_may_pull(skb, inner_nhdr_len)))
+               goto tx_error;
+
        inner_iph = (const struct iphdr *)skb_inner_network_header(skb);
        connected = (tunnel->parms.iph.daddr != 0);
 
index d51a8c0..c63ccce 100644 (file)
@@ -4201,7 +4201,6 @@ static struct inet6_ifaddr *if6_get_first(struct seq_file *seq, loff_t pos)
                                p++;
                                continue;
                        }
-                       state->offset++;
                        return ifa;
                }
 
@@ -4225,13 +4224,12 @@ static struct inet6_ifaddr *if6_get_next(struct seq_file *seq,
                return ifa;
        }
 
+       state->offset = 0;
        while (++state->bucket < IN6_ADDR_HSIZE) {
-               state->offset = 0;
                hlist_for_each_entry_rcu(ifa,
                                     &inet6_addr_lst[state->bucket], addr_lst) {
                        if (!net_eq(dev_net(ifa->idev->dev), net))
                                continue;
-                       state->offset++;
                        return ifa;
                }
        }
index 419960b..a0b6932 100644 (file)
@@ -1234,7 +1234,7 @@ static inline int
 ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       const struct iphdr  *iph = ip_hdr(skb);
+       const struct iphdr  *iph;
        int encap_limit = -1;
        struct flowi6 fl6;
        __u8 dsfield;
@@ -1242,6 +1242,11 @@ ip4ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
        u8 tproto;
        int err;
 
+       /* ensure we can access the full inner ip header */
+       if (!pskb_may_pull(skb, sizeof(struct iphdr)))
+               return -1;
+
+       iph = ip_hdr(skb);
        memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 
        tproto = READ_ONCE(t->parms.proto);
@@ -1306,7 +1311,7 @@ static inline int
 ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       struct ipv6hdr *ipv6h = ipv6_hdr(skb);
+       struct ipv6hdr *ipv6h;
        int encap_limit = -1;
        __u16 offset;
        struct flowi6 fl6;
@@ -1315,6 +1320,10 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
        u8 tproto;
        int err;
 
+       if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h))))
+               return -1;
+
+       ipv6h = ipv6_hdr(skb);
        tproto = READ_ONCE(t->parms.proto);
        if ((tproto != IPPROTO_IPV6 && tproto != 0) ||
            ip6_tnl_addr_conflict(t, ipv6h))
index 480a79f..826b14d 100644 (file)
@@ -364,11 +364,14 @@ EXPORT_SYMBOL(ip6_dst_alloc);
 
 static void ip6_dst_destroy(struct dst_entry *dst)
 {
+       struct dst_metrics *p = (struct dst_metrics *)DST_METRICS_PTR(dst);
        struct rt6_info *rt = (struct rt6_info *)dst;
        struct fib6_info *from;
        struct inet6_dev *idev;
 
-       dst_destroy_metrics_generic(dst);
+       if (p != &dst_default_metrics && refcount_dec_and_test(&p->refcnt))
+               kfree(p);
+
        rt6_uncached_list_del(rt);
 
        idev = rt->rt6i_idev;
@@ -976,6 +979,10 @@ static void rt6_set_from(struct rt6_info *rt, struct fib6_info *from)
        rt->rt6i_flags &= ~RTF_EXPIRES;
        rcu_assign_pointer(rt->from, from);
        dst_init_metrics(&rt->dst, from->fib6_metrics->metrics, true);
+       if (from->fib6_metrics != &dst_default_metrics) {
+               rt->dst._metrics |= DST_METRICS_REFCOUNTED;
+               refcount_inc(&from->fib6_metrics->refcnt);
+       }
 }
 
 /* Caller must already hold reference to @ort */
index 7a4de6d..8fbe6cd 100644 (file)
@@ -1533,10 +1533,14 @@ static int mpls_dev_notify(struct notifier_block *this, unsigned long event,
        unsigned int flags;
 
        if (event == NETDEV_REGISTER) {
-               /* For now just support Ethernet, IPGRE, SIT and IPIP devices */
+
+               /* For now just support Ethernet, IPGRE, IP6GRE, SIT and
+                * IPIP devices
+                */
                if (dev->type == ARPHRD_ETHER ||
                    dev->type == ARPHRD_LOOPBACK ||
                    dev->type == ARPHRD_IPGRE ||
+                   dev->type == ARPHRD_IP6GRE ||
                    dev->type == ARPHRD_SIT ||
                    dev->type == ARPHRD_TUNNEL) {
                        mdev = mpls_add_dev(dev);
index c070dfc..c92894c 100644 (file)
@@ -781,7 +781,8 @@ static int netlbl_unlabel_addrinfo_get(struct genl_info *info,
 {
        u32 addr_len;
 
-       if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR]) {
+       if (info->attrs[NLBL_UNLABEL_A_IPV4ADDR] &&
+           info->attrs[NLBL_UNLABEL_A_IPV4MASK]) {
                addr_len = nla_len(info->attrs[NLBL_UNLABEL_A_IPV4ADDR]);
                if (addr_len != sizeof(struct in_addr) &&
                    addr_len != nla_len(info->attrs[NLBL_UNLABEL_A_IPV4MASK]))
index ac8030c..19cb2e4 100644 (file)
@@ -209,6 +209,11 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
                }
                create_info = (struct hci_create_pipe_resp *)skb->data;
 
+               if (create_info->pipe >= NFC_HCI_MAX_PIPES) {
+                       status = NFC_HCI_ANY_E_NOK;
+                       goto exit;
+               }
+
                /* Save the new created pipe and bind with local gate,
                 * the description for skb->data[3] is destination gate id
                 * but since we received this cmd from host controller, we
@@ -232,6 +237,11 @@ void nfc_hci_cmd_received(struct nfc_hci_dev *hdev, u8 pipe, u8 cmd,
                }
                delete_info = (struct hci_delete_pipe_noti *)skb->data;
 
+               if (delete_info->pipe >= NFC_HCI_MAX_PIPES) {
+                       status = NFC_HCI_ANY_E_NOK;
+                       goto exit;
+               }
+
                hdev->pipes[delete_info->pipe].gate = NFC_HCI_INVALID_GATE;
                hdev->pipes[delete_info->pipe].dest_host = NFC_HCI_INVALID_HOST;
                break;
index 73427ff..71ff356 100644 (file)
@@ -443,7 +443,7 @@ int rds_ib_send_grab_credits(struct rds_ib_connection *ic, u32 wanted,
 int rds_ib_xmit_atomic(struct rds_connection *conn, struct rm_atomic_op *op);
 
 /* ib_stats.c */
-DECLARE_PER_CPU(struct rds_ib_statistics, rds_ib_stats);
+DECLARE_PER_CPU_SHARED_ALIGNED(struct rds_ib_statistics, rds_ib_stats);
 #define rds_ib_stats_inc(member) rds_stats_inc_which(rds_ib_stats, member)
 #define rds_ib_stats_add(member, count) \
                rds_stats_add_which(rds_ib_stats, member, count)
index 12cac85..033696e 100644 (file)
@@ -260,6 +260,7 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk)
 bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
 {
        struct dst_entry *dst = sctp_transport_dst_check(t);
+       struct sock *sk = t->asoc->base.sk;
        bool change = true;
 
        if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) {
@@ -271,12 +272,19 @@ bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu)
        pmtu = SCTP_TRUNC4(pmtu);
 
        if (dst) {
-               dst->ops->update_pmtu(dst, t->asoc->base.sk, NULL, pmtu);
+               struct sctp_pf *pf = sctp_get_pf_specific(dst->ops->family);
+               union sctp_addr addr;
+
+               pf->af->from_sk(&addr, sk);
+               pf->to_sk_daddr(&t->ipaddr, sk);
+               dst->ops->update_pmtu(dst, sk, NULL, pmtu);
+               pf->to_sk_daddr(&addr, sk);
+
                dst = sctp_transport_dst_check(t);
        }
 
        if (!dst) {
-               t->af_specific->get_dst(t, &t->saddr, &t->fl, t->asoc->base.sk);
+               t->af_specific->get_dst(t, &t->saddr, &t->fl, sk);
                dst = t->dst;
        }
 
index 2d8a1e1..0152317 100644 (file)
@@ -742,7 +742,10 @@ static void smc_connect_work(struct work_struct *work)
                smc->sk.sk_err = -rc;
 
 out:
-       smc->sk.sk_state_change(&smc->sk);
+       if (smc->sk.sk_err)
+               smc->sk.sk_state_change(&smc->sk);
+       else
+               smc->sk.sk_write_space(&smc->sk);
        kfree(smc->connect_info);
        smc->connect_info = NULL;
        release_sock(&smc->sk);
@@ -1150,9 +1153,9 @@ static int smc_listen_rdma_reg(struct smc_sock *new_smc, int local_contact)
 }
 
 /* listen worker: finish RDMA setup */
-static void smc_listen_rdma_finish(struct smc_sock *new_smc,
-                                  struct smc_clc_msg_accept_confirm *cclc,
-                                  int local_contact)
+static int smc_listen_rdma_finish(struct smc_sock *new_smc,
+                                 struct smc_clc_msg_accept_confirm *cclc,
+                                 int local_contact)
 {
        struct smc_link *link = &new_smc->conn.lgr->lnk[SMC_SINGLE_LINK];
        int reason_code = 0;
@@ -1175,11 +1178,12 @@ static void smc_listen_rdma_finish(struct smc_sock *new_smc,
                if (reason_code)
                        goto decline;
        }
-       return;
+       return 0;
 
 decline:
        mutex_unlock(&smc_create_lgr_pending);
        smc_listen_decline(new_smc, reason_code, local_contact);
+       return reason_code;
 }
 
 /* setup for RDMA connection of server */
@@ -1276,8 +1280,10 @@ static void smc_listen_work(struct work_struct *work)
        }
 
        /* finish worker */
-       if (!ism_supported)
-               smc_listen_rdma_finish(new_smc, &cclc, local_contact);
+       if (!ism_supported) {
+               if (smc_listen_rdma_finish(new_smc, &cclc, local_contact))
+                       return;
+       }
        smc_conn_save_peer_info(new_smc, &cclc);
        mutex_unlock(&smc_create_lgr_pending);
        smc_listen_out_connected(new_smc);
@@ -1529,7 +1535,7 @@ static __poll_t smc_poll(struct file *file, struct socket *sock,
                return EPOLLNVAL;
 
        smc = smc_sk(sock->sk);
-       if ((sk->sk_state == SMC_INIT) || smc->use_fallback) {
+       if (smc->use_fallback) {
                /* delegate to CLC child sock */
                mask = smc->clcsock->ops->poll(file, smc->clcsock, wait);
                sk->sk_err = smc->clcsock->sk->sk_err;
@@ -1560,9 +1566,9 @@ static __poll_t smc_poll(struct file *file, struct socket *sock,
                                mask |= EPOLLIN | EPOLLRDNORM | EPOLLRDHUP;
                        if (sk->sk_state == SMC_APPCLOSEWAIT1)
                                mask |= EPOLLIN;
+                       if (smc->conn.urg_state == SMC_URG_VALID)
+                               mask |= EPOLLPRI;
                }
-               if (smc->conn.urg_state == SMC_URG_VALID)
-                       mask |= EPOLLPRI;
        }
 
        return mask;
index 83aba9a..52241d6 100644 (file)
@@ -446,14 +446,12 @@ int smc_clc_send_proposal(struct smc_sock *smc, int smc_type,
        vec[i++].iov_len = sizeof(trl);
        /* due to the few bytes needed for clc-handshake this cannot block */
        len = kernel_sendmsg(smc->clcsock, &msg, vec, i, plen);
-       if (len < sizeof(pclc)) {
-               if (len >= 0) {
-                       reason_code = -ENETUNREACH;
-                       smc->sk.sk_err = -reason_code;
-               } else {
-                       smc->sk.sk_err = smc->clcsock->sk->sk_err;
-                       reason_code = -smc->sk.sk_err;
-               }
+       if (len < 0) {
+               smc->sk.sk_err = smc->clcsock->sk->sk_err;
+               reason_code = -smc->sk.sk_err;
+       } else if (len < (int)sizeof(pclc)) {
+               reason_code = -ENETUNREACH;
+               smc->sk.sk_err = -reason_code;
        }
 
        return reason_code;
index ac961df..ea2b87f 100644 (file)
@@ -100,15 +100,14 @@ static void smc_close_active_abort(struct smc_sock *smc)
        struct smc_cdc_conn_state_flags *txflags =
                &smc->conn.local_tx_ctrl.conn_state_flags;
 
-       sk->sk_err = ECONNABORTED;
-       if (smc->clcsock && smc->clcsock->sk) {
-               smc->clcsock->sk->sk_err = ECONNABORTED;
-               smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
+       if (sk->sk_state != SMC_INIT && smc->clcsock && smc->clcsock->sk) {
+               sk->sk_err = ECONNABORTED;
+               if (smc->clcsock && smc->clcsock->sk) {
+                       smc->clcsock->sk->sk_err = ECONNABORTED;
+                       smc->clcsock->sk->sk_state_change(smc->clcsock->sk);
+               }
        }
        switch (sk->sk_state) {
-       case SMC_INIT:
-               sk->sk_state = SMC_PEERABORTWAIT;
-               break;
        case SMC_ACTIVE:
                sk->sk_state = SMC_PEERABORTWAIT;
                release_sock(sk);
@@ -143,6 +142,7 @@ static void smc_close_active_abort(struct smc_sock *smc)
        case SMC_PEERFINCLOSEWAIT:
                sock_put(sk); /* passive closing */
                break;
+       case SMC_INIT:
        case SMC_PEERABORTWAIT:
        case SMC_CLOSED:
                break;
index 01c6ce0..7cb3e4f 100644 (file)
@@ -461,7 +461,7 @@ static const struct genl_ops smc_pnet_ops[] = {
 };
 
 /* SMC_PNETID family definition */
-static struct genl_family smc_pnet_nl_family = {
+static struct genl_family smc_pnet_nl_family __ro_after_init = {
        .hdrsize = 0,
        .name = SMCR_GENL_FAMILY_NAME,
        .version = SMCR_GENL_FAMILY_VERSION,
index 3b602a1..711e89d 100644 (file)
@@ -300,7 +300,7 @@ long __keyctl_dh_compute(struct keyctl_dh_params __user *params,
        }
        dh_inputs.g_size = dlen;
 
-       dlen = dh_data_from_key(pcopy.dh_private, &dh_inputs.key);
+       dlen = dh_data_from_key(pcopy.private, &dh_inputs.key);
        if (dlen < 0) {
                ret = dlen;
                goto out2;
index 664ced8..e907ba6 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: (LGPL-2.0+ OR BSD-2-Clause)
 /* Copyright (C) 2018 Netronome Systems, Inc. */
 
 #ifndef __TOOLS_LIBC_COMPAT_H
index 6f54f84..9b552c0 100644 (file)
@@ -580,7 +580,11 @@ static void test_sockmap(int tasks, void *data)
        /* Test update without programs */
        for (i = 0; i < 6; i++) {
                err = bpf_map_update_elem(fd, &i, &sfd[i], BPF_ANY);
-               if (err) {
+               if (i < 2 && !err) {
+                       printf("Allowed update sockmap '%i:%i' not in ESTABLISHED\n",
+                              i, sfd[i]);
+                       goto out_sockmap;
+               } else if (i >= 2 && err) {
                        printf("Failed noprog update sockmap '%i:%i'\n",
                               i, sfd[i]);
                        goto out_sockmap;
@@ -741,7 +745,7 @@ static void test_sockmap(int tasks, void *data)
        }
 
        /* Test map update elem afterwards fd lives in fd and map_fd */
-       for (i = 0; i < 6; i++) {
+       for (i = 2; i < 6; i++) {
                err = bpf_map_update_elem(map_fd_rx, &i, &sfd[i], BPF_ANY);
                if (err) {
                        printf("Failed map_fd_rx update sockmap %i '%i:%i'\n",
@@ -845,7 +849,7 @@ static void test_sockmap(int tasks, void *data)
        }
 
        /* Delete the elems without programs */
-       for (i = 0; i < 6; i++) {
+       for (i = 2; i < 6; i++) {
                err = bpf_map_delete_elem(fd, &i);
                if (err) {
                        printf("Failed delete sockmap %i '%i:%i'\n",
index 32a194e..0ab9423 100755 (executable)
@@ -178,8 +178,8 @@ setup() {
 
 cleanup() {
        [ ${cleanup_done} -eq 1 ] && return
-       ip netns del ${NS_A} 2 > /dev/null
-       ip netns del ${NS_B} 2 > /dev/null
+       ip netns del ${NS_A} 2> /dev/null
+       ip netns del ${NS_B} 2> /dev/null
        cleanup_done=1
 }