]> git.proxmox.com Git - mirror_ubuntu-eoan-kernel.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorDavid S. Miller <davem@davemloft.net>
Sat, 3 Dec 2016 16:46:54 +0000 (11:46 -0500)
committerDavid S. Miller <davem@davemloft.net>
Sat, 3 Dec 2016 17:29:53 +0000 (12:29 -0500)
Couple conflicts resolved here:

1) In the MACB driver, a bug fix to properly initialize the
   RX tail pointer properly overlapped with some changes
   to support variable sized rings.

2) In XGBE we had a "CONFIG_PM" --> "CONFIG_PM_SLEEP" fix
   overlapping with a reorganization of the driver to support
   ACPI, OF, as well as PCI variants of the chip.

3) In 'net' we had several probe error path bug fixes to the
   stmmac driver, meanwhile a lot of this code was cleaned up
   and reorganized in 'net-next'.

4) The cls_flower classifier obtained a helper function in
   'net-next' called __fl_delete() and this overlapped with
   Daniel Borkamann's bug fix to use RCU for object destruction
   in 'net'.  It also overlapped with Jiri's change to guard
   the rhashtable_remove_fast() call with a check against
   tc_skip_sw().

5) In mlx4, a revert bug fix in 'net' overlapped with some
   unrelated changes in 'net-next'.

6) In geneve, a stale header pointer after pskb_expand_head()
   bug fix in 'net' overlapped with a large reorganization of
   the same code in 'net-next'.  Since the 'net-next' code no
   longer had the bug in question, there was nothing to do
   other than to simply take the 'net-next' hunks.

Signed-off-by: David S. Miller <davem@davemloft.net>
62 files changed:
1  2 
MAINTAINERS
drivers/net/ethernet/altera/altera_tse_main.c
drivers/net/ethernet/amd/xgbe/xgbe-platform.c
drivers/net/ethernet/aurora/nb8800.c
drivers/net/ethernet/broadcom/genet/bcmgenet.c
drivers/net/ethernet/cadence/macb.c
drivers/net/ethernet/freescale/fec_main.c
drivers/net/ethernet/freescale/fman/mac.c
drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
drivers/net/ethernet/freescale/gianfar.c
drivers/net/ethernet/freescale/ucc_geth.c
drivers/net/ethernet/intel/igb/igb_main.c
drivers/net/ethernet/intel/igbvf/netdev.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/mediatek/mtk_eth_soc.c
drivers/net/ethernet/mellanox/mlx4/en_netdev.c
drivers/net/ethernet/qualcomm/emac/emac.c
drivers/net/ethernet/renesas/ravb_main.c
drivers/net/ethernet/renesas/sh_eth.c
drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
drivers/net/ethernet/stmicro/stmmac/dwmac-sti.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
drivers/net/ethernet/synopsys/dwc_eth_qos.c
drivers/net/ethernet/ti/cpsw.c
drivers/net/ipvlan/ipvlan_main.c
drivers/net/macvtap.c
drivers/net/tun.c
drivers/net/usb/asix_devices.c
drivers/net/usb/cdc_ether.c
drivers/net/vxlan.c
drivers/net/wireless/marvell/mwifiex/cfg80211.c
include/net/ipv6.h
include/net/netfilter/nf_tables.h
init/Kconfig
kernel/bpf/verifier.c
net/core/rtnetlink.c
net/core/sock.c
net/dccp/ipv4.c
net/dsa/slave.c
net/ipv4/Kconfig
net/ipv4/af_inet.c
net/ipv4/ip_output.c
net/ipv4/netfilter/arp_tables.c
net/ipv6/datagram.c
net/ipv6/esp6.c
net/ipv6/icmp.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
net/l2tp/l2tp_ip6.c
net/netfilter/nft_hash.c
net/netfilter/nft_range.c
net/openvswitch/conntrack.c
net/packet/af_packet.c
net/rds/tcp.c
net/sched/act_pedit.c
net/sched/cls_bpf.c
net/sched/cls_flower.c
samples/bpf/bpf_helpers.h

diff --cc MAINTAINERS
Simple merge
index 8c530dccb4470a31a58cab1a82fe17973a6d9df7,0000000000000000000000000000000000000000..84d4c51cab8c352bcff37647b46649a131fd38ca
mode 100644,000000..100644
--- /dev/null
@@@ -1,642 -1,0 +1,642 @@@
- #ifdef CONFIG_PM
 +/*
 + * AMD 10Gb Ethernet driver
 + *
 + * This file is available to you under your choice of the following two
 + * licenses:
 + *
 + * License 1: GPLv2
 + *
 + * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
 + *
 + * This file is free software; you may copy, redistribute and/or modify
 + * it under the terms of the GNU General Public License as published by
 + * the Free Software Foundation, either version 2 of the License, or (at
 + * your option) any later version.
 + *
 + * This file is distributed in the hope that it will be useful, but
 + * WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 + * General Public License for more details.
 + *
 + * You should have received a copy of the GNU General Public License
 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 + *
 + * This file incorporates work covered by the following copyright and
 + * permission notice:
 + *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
 + *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
 + *     Inc. unless otherwise expressly agreed to in writing between Synopsys
 + *     and you.
 + *
 + *     The Software IS NOT an item of Licensed Software or Licensed Product
 + *     under any End User Software License Agreement or Agreement for Licensed
 + *     Product with Synopsys or any supplement thereto.  Permission is hereby
 + *     granted, free of charge, to any person obtaining a copy of this software
 + *     annotated with this license and the Software, to deal in the Software
 + *     without restriction, including without limitation the rights to use,
 + *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 + *     of the Software, and to permit persons to whom the Software is furnished
 + *     to do so, subject to the following conditions:
 + *
 + *     The above copyright notice and this permission notice shall be included
 + *     in all copies or substantial portions of the Software.
 + *
 + *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
 + *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 + *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
 + *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 + *     THE POSSIBILITY OF SUCH DAMAGE.
 + *
 + *
 + * License 2: Modified BSD
 + *
 + * Copyright (c) 2014-2016 Advanced Micro Devices, Inc.
 + * All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions are met:
 + *     * Redistributions of source code must retain the above copyright
 + *       notice, this list of conditions and the following disclaimer.
 + *     * Redistributions in binary form must reproduce the above copyright
 + *       notice, this list of conditions and the following disclaimer in the
 + *       documentation and/or other materials provided with the distribution.
 + *     * Neither the name of Advanced Micro Devices, Inc. nor the
 + *       names of its contributors may be used to endorse or promote products
 + *       derived from this software without specific prior written permission.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 + * ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 + *
 + * This file incorporates work covered by the following copyright and
 + * permission notice:
 + *     The Synopsys DWC ETHER XGMAC Software Driver and documentation
 + *     (hereinafter "Software") is an unsupported proprietary work of Synopsys,
 + *     Inc. unless otherwise expressly agreed to in writing between Synopsys
 + *     and you.
 + *
 + *     The Software IS NOT an item of Licensed Software or Licensed Product
 + *     under any End User Software License Agreement or Agreement for Licensed
 + *     Product with Synopsys or any supplement thereto.  Permission is hereby
 + *     granted, free of charge, to any person obtaining a copy of this software
 + *     annotated with this license and the Software, to deal in the Software
 + *     without restriction, including without limitation the rights to use,
 + *     copy, modify, merge, publish, distribute, sublicense, and/or sell copies
 + *     of the Software, and to permit persons to whom the Software is furnished
 + *     to do so, subject to the following conditions:
 + *
 + *     The above copyright notice and this permission notice shall be included
 + *     in all copies or substantial portions of the Software.
 + *
 + *     THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS"
 + *     BASIS AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 + *     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 + *     PARTICULAR PURPOSE ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS
 + *     BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 + *     CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 + *     SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 + *     INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 + *     CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 + *     ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 + *     THE POSSIBILITY OF SUCH DAMAGE.
 + */
 +
 +#include <linux/module.h>
 +#include <linux/device.h>
 +#include <linux/platform_device.h>
 +#include <linux/spinlock.h>
 +#include <linux/netdevice.h>
 +#include <linux/etherdevice.h>
 +#include <linux/io.h>
 +#include <linux/of.h>
 +#include <linux/of_net.h>
 +#include <linux/of_address.h>
 +#include <linux/of_platform.h>
 +#include <linux/of_device.h>
 +#include <linux/clk.h>
 +#include <linux/property.h>
 +#include <linux/acpi.h>
 +#include <linux/mdio.h>
 +
 +#include "xgbe.h"
 +#include "xgbe-common.h"
 +
 +#ifdef CONFIG_ACPI
 +static const struct acpi_device_id xgbe_acpi_match[];
 +
 +static struct xgbe_version_data *xgbe_acpi_vdata(struct xgbe_prv_data *pdata)
 +{
 +      const struct acpi_device_id *id;
 +
 +      id = acpi_match_device(xgbe_acpi_match, pdata->dev);
 +
 +      return id ? (struct xgbe_version_data *)id->driver_data : NULL;
 +}
 +
 +static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
 +{
 +      struct device *dev = pdata->dev;
 +      u32 property;
 +      int ret;
 +
 +      /* Obtain the system clock setting */
 +      ret = device_property_read_u32(dev, XGBE_ACPI_DMA_FREQ, &property);
 +      if (ret) {
 +              dev_err(dev, "unable to obtain %s property\n",
 +                      XGBE_ACPI_DMA_FREQ);
 +              return ret;
 +      }
 +      pdata->sysclk_rate = property;
 +
 +      /* Obtain the PTP clock setting */
 +      ret = device_property_read_u32(dev, XGBE_ACPI_PTP_FREQ, &property);
 +      if (ret) {
 +              dev_err(dev, "unable to obtain %s property\n",
 +                      XGBE_ACPI_PTP_FREQ);
 +              return ret;
 +      }
 +      pdata->ptpclk_rate = property;
 +
 +      return 0;
 +}
 +#else   /* CONFIG_ACPI */
 +static struct xgbe_version_data *xgbe_acpi_vdata(struct xgbe_prv_data *pdata)
 +{
 +      return NULL;
 +}
 +
 +static int xgbe_acpi_support(struct xgbe_prv_data *pdata)
 +{
 +      return -EINVAL;
 +}
 +#endif  /* CONFIG_ACPI */
 +
 +#ifdef CONFIG_OF
 +static const struct of_device_id xgbe_of_match[];
 +
 +static struct xgbe_version_data *xgbe_of_vdata(struct xgbe_prv_data *pdata)
 +{
 +      const struct of_device_id *id;
 +
 +      id = of_match_device(xgbe_of_match, pdata->dev);
 +
 +      return id ? (struct xgbe_version_data *)id->data : NULL;
 +}
 +
 +static int xgbe_of_support(struct xgbe_prv_data *pdata)
 +{
 +      struct device *dev = pdata->dev;
 +
 +      /* Obtain the system clock setting */
 +      pdata->sysclk = devm_clk_get(dev, XGBE_DMA_CLOCK);
 +      if (IS_ERR(pdata->sysclk)) {
 +              dev_err(dev, "dma devm_clk_get failed\n");
 +              return PTR_ERR(pdata->sysclk);
 +      }
 +      pdata->sysclk_rate = clk_get_rate(pdata->sysclk);
 +
 +      /* Obtain the PTP clock setting */
 +      pdata->ptpclk = devm_clk_get(dev, XGBE_PTP_CLOCK);
 +      if (IS_ERR(pdata->ptpclk)) {
 +              dev_err(dev, "ptp devm_clk_get failed\n");
 +              return PTR_ERR(pdata->ptpclk);
 +      }
 +      pdata->ptpclk_rate = clk_get_rate(pdata->ptpclk);
 +
 +      return 0;
 +}
 +
 +static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata)
 +{
 +      struct device *dev = pdata->dev;
 +      struct device_node *phy_node;
 +      struct platform_device *phy_pdev;
 +
 +      phy_node = of_parse_phandle(dev->of_node, "phy-handle", 0);
 +      if (phy_node) {
 +              /* Old style device tree:
 +               *   The XGBE and PHY resources are separate
 +               */
 +              phy_pdev = of_find_device_by_node(phy_node);
 +              of_node_put(phy_node);
 +      } else {
 +              /* New style device tree:
 +               *   The XGBE and PHY resources are grouped together with
 +               *   the PHY resources listed last
 +               */
 +              get_device(dev);
 +              phy_pdev = pdata->platdev;
 +      }
 +
 +      return phy_pdev;
 +}
 +#else   /* CONFIG_OF */
 +static struct xgbe_version_data *xgbe_of_vdata(struct xgbe_prv_data *pdata)
 +{
 +      return NULL;
 +}
 +
 +static int xgbe_of_support(struct xgbe_prv_data *pdata)
 +{
 +      return -EINVAL;
 +}
 +
 +static struct platform_device *xgbe_of_get_phy_pdev(struct xgbe_prv_data *pdata)
 +{
 +      return NULL;
 +}
 +#endif  /* CONFIG_OF */
 +
 +static unsigned int xgbe_resource_count(struct platform_device *pdev,
 +                                      unsigned int type)
 +{
 +      unsigned int count;
 +      int i;
 +
 +      for (i = 0, count = 0; i < pdev->num_resources; i++) {
 +              struct resource *res = &pdev->resource[i];
 +
 +              if (type == resource_type(res))
 +                      count++;
 +      }
 +
 +      return count;
 +}
 +
 +static struct platform_device *xgbe_get_phy_pdev(struct xgbe_prv_data *pdata)
 +{
 +      struct platform_device *phy_pdev;
 +
 +      if (pdata->use_acpi) {
 +              get_device(pdata->dev);
 +              phy_pdev = pdata->platdev;
 +      } else {
 +              phy_pdev = xgbe_of_get_phy_pdev(pdata);
 +      }
 +
 +      return phy_pdev;
 +}
 +
 +static struct xgbe_version_data *xgbe_get_vdata(struct xgbe_prv_data *pdata)
 +{
 +      return pdata->use_acpi ? xgbe_acpi_vdata(pdata)
 +                             : xgbe_of_vdata(pdata);
 +}
 +
 +static int xgbe_platform_probe(struct platform_device *pdev)
 +{
 +      struct xgbe_prv_data *pdata;
 +      struct device *dev = &pdev->dev;
 +      struct platform_device *phy_pdev;
 +      struct resource *res;
 +      const char *phy_mode;
 +      unsigned int phy_memnum, phy_irqnum;
 +      unsigned int dma_irqnum, dma_irqend;
 +      enum dev_dma_attr attr;
 +      int ret;
 +
 +      pdata = xgbe_alloc_pdata(dev);
 +      if (IS_ERR(pdata)) {
 +              ret = PTR_ERR(pdata);
 +              goto err_alloc;
 +      }
 +
 +      pdata->platdev = pdev;
 +      pdata->adev = ACPI_COMPANION(dev);
 +      platform_set_drvdata(pdev, pdata);
 +
 +      /* Check if we should use ACPI or DT */
 +      pdata->use_acpi = dev->of_node ? 0 : 1;
 +
 +      /* Get the version data */
 +      pdata->vdata = xgbe_get_vdata(pdata);
 +
 +      phy_pdev = xgbe_get_phy_pdev(pdata);
 +      if (!phy_pdev) {
 +              dev_err(dev, "unable to obtain phy device\n");
 +              ret = -EINVAL;
 +              goto err_phydev;
 +      }
 +      pdata->phy_platdev = phy_pdev;
 +      pdata->phy_dev = &phy_pdev->dev;
 +
 +      if (pdev == phy_pdev) {
 +              /* New style device tree or ACPI:
 +               *   The XGBE and PHY resources are grouped together with
 +               *   the PHY resources listed last
 +               */
 +              phy_memnum = xgbe_resource_count(pdev, IORESOURCE_MEM) - 3;
 +              phy_irqnum = xgbe_resource_count(pdev, IORESOURCE_IRQ) - 1;
 +              dma_irqnum = 1;
 +              dma_irqend = phy_irqnum;
 +      } else {
 +              /* Old style device tree:
 +               *   The XGBE and PHY resources are separate
 +               */
 +              phy_memnum = 0;
 +              phy_irqnum = 0;
 +              dma_irqnum = 1;
 +              dma_irqend = xgbe_resource_count(pdev, IORESOURCE_IRQ);
 +      }
 +
 +      /* Obtain the mmio areas for the device */
 +      res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 +      pdata->xgmac_regs = devm_ioremap_resource(dev, res);
 +      if (IS_ERR(pdata->xgmac_regs)) {
 +              dev_err(dev, "xgmac ioremap failed\n");
 +              ret = PTR_ERR(pdata->xgmac_regs);
 +              goto err_io;
 +      }
 +      if (netif_msg_probe(pdata))
 +              dev_dbg(dev, "xgmac_regs = %p\n", pdata->xgmac_regs);
 +
 +      res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 +      pdata->xpcs_regs = devm_ioremap_resource(dev, res);
 +      if (IS_ERR(pdata->xpcs_regs)) {
 +              dev_err(dev, "xpcs ioremap failed\n");
 +              ret = PTR_ERR(pdata->xpcs_regs);
 +              goto err_io;
 +      }
 +      if (netif_msg_probe(pdata))
 +              dev_dbg(dev, "xpcs_regs  = %p\n", pdata->xpcs_regs);
 +
 +      res = platform_get_resource(phy_pdev, IORESOURCE_MEM, phy_memnum++);
 +      pdata->rxtx_regs = devm_ioremap_resource(dev, res);
 +      if (IS_ERR(pdata->rxtx_regs)) {
 +              dev_err(dev, "rxtx ioremap failed\n");
 +              ret = PTR_ERR(pdata->rxtx_regs);
 +              goto err_io;
 +      }
 +      if (netif_msg_probe(pdata))
 +              dev_dbg(dev, "rxtx_regs  = %p\n", pdata->rxtx_regs);
 +
 +      res = platform_get_resource(phy_pdev, IORESOURCE_MEM, phy_memnum++);
 +      pdata->sir0_regs = devm_ioremap_resource(dev, res);
 +      if (IS_ERR(pdata->sir0_regs)) {
 +              dev_err(dev, "sir0 ioremap failed\n");
 +              ret = PTR_ERR(pdata->sir0_regs);
 +              goto err_io;
 +      }
 +      if (netif_msg_probe(pdata))
 +              dev_dbg(dev, "sir0_regs  = %p\n", pdata->sir0_regs);
 +
 +      res = platform_get_resource(phy_pdev, IORESOURCE_MEM, phy_memnum++);
 +      pdata->sir1_regs = devm_ioremap_resource(dev, res);
 +      if (IS_ERR(pdata->sir1_regs)) {
 +              dev_err(dev, "sir1 ioremap failed\n");
 +              ret = PTR_ERR(pdata->sir1_regs);
 +              goto err_io;
 +      }
 +      if (netif_msg_probe(pdata))
 +              dev_dbg(dev, "sir1_regs  = %p\n", pdata->sir1_regs);
 +
 +      /* Retrieve the MAC address */
 +      ret = device_property_read_u8_array(dev, XGBE_MAC_ADDR_PROPERTY,
 +                                          pdata->mac_addr,
 +                                          sizeof(pdata->mac_addr));
 +      if (ret || !is_valid_ether_addr(pdata->mac_addr)) {
 +              dev_err(dev, "invalid %s property\n", XGBE_MAC_ADDR_PROPERTY);
 +              if (!ret)
 +                      ret = -EINVAL;
 +              goto err_io;
 +      }
 +
 +      /* Retrieve the PHY mode - it must be "xgmii" */
 +      ret = device_property_read_string(dev, XGBE_PHY_MODE_PROPERTY,
 +                                        &phy_mode);
 +      if (ret || strcmp(phy_mode, phy_modes(PHY_INTERFACE_MODE_XGMII))) {
 +              dev_err(dev, "invalid %s property\n", XGBE_PHY_MODE_PROPERTY);
 +              if (!ret)
 +                      ret = -EINVAL;
 +              goto err_io;
 +      }
 +      pdata->phy_mode = PHY_INTERFACE_MODE_XGMII;
 +
 +      /* Check for per channel interrupt support */
 +      if (device_property_present(dev, XGBE_DMA_IRQS_PROPERTY)) {
 +              pdata->per_channel_irq = 1;
 +              pdata->channel_irq_mode = XGBE_IRQ_MODE_EDGE;
 +      }
 +
 +      /* Obtain device settings unique to ACPI/OF */
 +      if (pdata->use_acpi)
 +              ret = xgbe_acpi_support(pdata);
 +      else
 +              ret = xgbe_of_support(pdata);
 +      if (ret)
 +              goto err_io;
 +
 +      /* Set the DMA coherency values */
 +      attr = device_get_dma_attr(dev);
 +      if (attr == DEV_DMA_NOT_SUPPORTED) {
 +              dev_err(dev, "DMA is not supported");
 +              ret = -ENODEV;
 +              goto err_io;
 +      }
 +      pdata->coherent = (attr == DEV_DMA_COHERENT);
 +      if (pdata->coherent) {
 +              pdata->axdomain = XGBE_DMA_OS_AXDOMAIN;
 +              pdata->arcache = XGBE_DMA_OS_ARCACHE;
 +              pdata->awcache = XGBE_DMA_OS_AWCACHE;
 +      } else {
 +              pdata->axdomain = XGBE_DMA_SYS_AXDOMAIN;
 +              pdata->arcache = XGBE_DMA_SYS_ARCACHE;
 +              pdata->awcache = XGBE_DMA_SYS_AWCACHE;
 +      }
 +
 +      /* Set the maximum fifo amounts */
 +      pdata->tx_max_fifo_size = pdata->vdata->tx_max_fifo_size;
 +      pdata->rx_max_fifo_size = pdata->vdata->rx_max_fifo_size;
 +
 +      /* Set the hardware channel and queue counts */
 +      xgbe_set_counts(pdata);
 +
 +      /* Always have XGMAC and XPCS (auto-negotiation) interrupts */
 +      pdata->irq_count = 2;
 +
 +      /* Get the device interrupt */
 +      ret = platform_get_irq(pdev, 0);
 +      if (ret < 0) {
 +              dev_err(dev, "platform_get_irq 0 failed\n");
 +              goto err_io;
 +      }
 +      pdata->dev_irq = ret;
 +
 +      /* Get the per channel DMA interrupts */
 +      if (pdata->per_channel_irq) {
 +              unsigned int i, max = ARRAY_SIZE(pdata->channel_irq);
 +
 +              for (i = 0; (i < max) && (dma_irqnum < dma_irqend); i++) {
 +                      ret = platform_get_irq(pdata->platdev, dma_irqnum++);
 +                      if (ret < 0) {
 +                              netdev_err(pdata->netdev,
 +                                         "platform_get_irq %u failed\n",
 +                                         dma_irqnum - 1);
 +                              goto err_io;
 +                      }
 +
 +                      pdata->channel_irq[i] = ret;
 +              }
 +
 +              pdata->channel_irq_count = max;
 +
 +              pdata->irq_count += max;
 +      }
 +
 +      /* Get the auto-negotiation interrupt */
 +      ret = platform_get_irq(phy_pdev, phy_irqnum++);
 +      if (ret < 0) {
 +              dev_err(dev, "platform_get_irq phy 0 failed\n");
 +              goto err_io;
 +      }
 +      pdata->an_irq = ret;
 +
 +      /* Configure the netdev resource */
 +      ret = xgbe_config_netdev(pdata);
 +      if (ret)
 +              goto err_io;
 +
 +      netdev_notice(pdata->netdev, "net device enabled\n");
 +
 +      return 0;
 +
 +err_io:
 +      platform_device_put(phy_pdev);
 +
 +err_phydev:
 +      xgbe_free_pdata(pdata);
 +
 +err_alloc:
 +      dev_notice(dev, "net device not enabled\n");
 +
 +      return ret;
 +}
 +
 +static int xgbe_platform_remove(struct platform_device *pdev)
 +{
 +      struct xgbe_prv_data *pdata = platform_get_drvdata(pdev);
 +
 +      xgbe_deconfig_netdev(pdata);
 +
 +      platform_device_put(pdata->phy_platdev);
 +
 +      xgbe_free_pdata(pdata);
 +
 +      return 0;
 +}
 +
- #endif /* CONFIG_PM */
++#ifdef CONFIG_PM_SLEEP
 +static int xgbe_platform_suspend(struct device *dev)
 +{
 +      struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
 +      struct net_device *netdev = pdata->netdev;
 +      int ret = 0;
 +
 +      DBGPR("-->xgbe_suspend\n");
 +
 +      if (netif_running(netdev))
 +              ret = xgbe_powerdown(netdev, XGMAC_DRIVER_CONTEXT);
 +
 +      pdata->lpm_ctrl = XMDIO_READ(pdata, MDIO_MMD_PCS, MDIO_CTRL1);
 +      pdata->lpm_ctrl |= MDIO_CTRL1_LPOWER;
 +      XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
 +
 +      DBGPR("<--xgbe_suspend\n");
 +
 +      return ret;
 +}
 +
 +static int xgbe_platform_resume(struct device *dev)
 +{
 +      struct xgbe_prv_data *pdata = dev_get_drvdata(dev);
 +      struct net_device *netdev = pdata->netdev;
 +      int ret = 0;
 +
 +      DBGPR("-->xgbe_resume\n");
 +
 +      pdata->lpm_ctrl &= ~MDIO_CTRL1_LPOWER;
 +      XMDIO_WRITE(pdata, MDIO_MMD_PCS, MDIO_CTRL1, pdata->lpm_ctrl);
 +
 +      if (netif_running(netdev)) {
 +              ret = xgbe_powerup(netdev, XGMAC_DRIVER_CONTEXT);
 +
 +              /* Schedule a restart in case the link or phy state changed
 +               * while we were powered down.
 +               */
 +              schedule_work(&pdata->restart_work);
 +      }
 +
 +      DBGPR("<--xgbe_resume\n");
 +
 +      return ret;
 +}
++#endif /* CONFIG_PM_SLEEP */
 +
 +static const struct xgbe_version_data xgbe_v1 = {
 +      .init_function_ptrs_phy_impl    = xgbe_init_function_ptrs_phy_v1,
 +      .xpcs_access                    = XGBE_XPCS_ACCESS_V1,
 +      .tx_max_fifo_size               = 81920,
 +      .rx_max_fifo_size               = 81920,
 +      .tx_tstamp_workaround           = 1,
 +};
 +
 +#ifdef CONFIG_ACPI
 +static const struct acpi_device_id xgbe_acpi_match[] = {
 +      { .id = "AMDI8001",
 +        .driver_data = (kernel_ulong_t)&xgbe_v1 },
 +      {},
 +};
 +
 +MODULE_DEVICE_TABLE(acpi, xgbe_acpi_match);
 +#endif
 +
 +#ifdef CONFIG_OF
 +static const struct of_device_id xgbe_of_match[] = {
 +      { .compatible = "amd,xgbe-seattle-v1a",
 +        .data = &xgbe_v1 },
 +      {},
 +};
 +
 +MODULE_DEVICE_TABLE(of, xgbe_of_match);
 +#endif
 +
 +static SIMPLE_DEV_PM_OPS(xgbe_platform_pm_ops,
 +                       xgbe_platform_suspend, xgbe_platform_resume);
 +
 +static struct platform_driver xgbe_driver = {
 +      .driver = {
 +              .name = XGBE_DRV_NAME,
 +#ifdef CONFIG_ACPI
 +              .acpi_match_table = xgbe_acpi_match,
 +#endif
 +#ifdef CONFIG_OF
 +              .of_match_table = xgbe_of_match,
 +#endif
 +              .pm = &xgbe_platform_pm_ops,
 +      },
 +      .probe = xgbe_platform_probe,
 +      .remove = xgbe_platform_remove,
 +};
 +
 +int xgbe_platform_init(void)
 +{
 +      return platform_driver_register(&xgbe_driver);
 +}
 +
 +void xgbe_platform_exit(void)
 +{
 +      platform_driver_unregister(&xgbe_driver);
 +}
Simple merge
index 0e489bb82456adc5018694495cb52955c04d79fd,ec09fcece711dc326dca2c63db8440e193eb2b31..538544a7c642f6cf1ca19c0d9222ec1c928077dd
@@@ -990,7 -974,8 +990,8 @@@ static inline void macb_init_rx_ring(st
                bp->rx_ring[i].ctrl = 0;
                addr += bp->rx_buffer_size;
        }
 -      bp->rx_ring[RX_RING_SIZE - 1].addr |= MACB_BIT(RX_WRAP);
 +      bp->rx_ring[bp->rx_ring_size - 1].addr |= MACB_BIT(RX_WRAP);
+       bp->rx_tail = 0;
  }
  
  static int macb_rx(struct macb *bp, int budget)
@@@ -1735,9 -1617,7 +1737,7 @@@ static void macb_init_rings(struct mac
        }
        bp->queues[0].tx_head = 0;
        bp->queues[0].tx_tail = 0;
 -      bp->queues[0].tx_ring[TX_RING_SIZE - 1].ctrl |= MACB_BIT(TX_WRAP);
 +      bp->queues[0].tx_ring[bp->tx_ring_size - 1].ctrl |= MACB_BIT(TX_WRAP);
-       bp->rx_tail = 0;
  }
  
  static void macb_reset_hw(struct macb *bp)
Simple merge
index 091b904262bc7932d3edf99cf850affb23b9ce6e,fb8bb027b69c3332ef23d4b59f9288103a5b12ba..49a81f1fc1d60082671e4ad462577f7beb01abe9
@@@ -2214,9 -2155,6 +2207,7 @@@ void mlx4_en_destroy_netdev(struct net_
  {
        struct mlx4_en_priv *priv = netdev_priv(dev);
        struct mlx4_en_dev *mdev = priv->mdev;
-       bool shutdown = mdev->dev->persist->interface_state &
-                                           MLX4_INTERFACE_STATE_SHUTDOWN;
 +      int t;
  
        en_dbg(DRV, priv, "Destroying netdev on port:%d\n", priv->port);
  
        mlx4_en_free_resources(priv);
        mutex_unlock(&mdev->state_lock);
  
 -      kfree(priv->tx_ring);
 -      kfree(priv->tx_cq);
 +      for (t = 0; t < MLX4_EN_NUM_TX_TYPES; t++) {
 +              kfree(priv->tx_ring[t]);
 +              kfree(priv->tx_cq[t]);
 +      }
  
-       if (!shutdown)
-               free_netdev(dev);
+       free_netdev(dev);
  }
  
  static int mlx4_en_change_mtu(struct net_device *dev, int new_mtu)
Simple merge
index 6b787d73b32ab94c84fb967a824577c06cc873a6,d80c88bd2bba812123484f9d6b14a373bc33102f..77ab0a85f0673d4b2f5748403ecc249d520a5f00
@@@ -936,60 -974,36 +936,73 @@@ static int rk_gmac_probe(struct platfor
                return PTR_ERR(plat_dat);
  
        plat_dat->has_gmac = true;
 -      plat_dat->init = rk_gmac_init;
 -      plat_dat->exit = rk_gmac_exit;
        plat_dat->fix_mac_speed = rk_fix_speed;
 -      plat_dat->suspend = rk_gmac_suspend;
 -      plat_dat->resume = rk_gmac_resume;
  
        plat_dat->bsp_priv = rk_gmac_setup(pdev, data);
-       if (IS_ERR(plat_dat->bsp_priv))
-               return PTR_ERR(plat_dat->bsp_priv);
+       if (IS_ERR(plat_dat->bsp_priv)) {
+               ret = PTR_ERR(plat_dat->bsp_priv);
+               goto err_remove_config_dt;
+       }
  
 -      ret = rk_gmac_init(pdev, plat_dat->bsp_priv);
 +      ret = rk_gmac_powerup(plat_dat->bsp_priv);
        if (ret)
-               return ret;
+               goto err_remove_config_dt;
+       ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       if (ret)
 -              goto err_gmac_exit;
++              goto err_gmac_powerdown;
  
-       return stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
+       return 0;
 -err_gmac_exit:
 -      rk_gmac_exit(pdev, plat_dat->bsp_priv);
++err_gmac_powerdown:
++      rk_gmac_powerdown(plat_dat->bsp_priv);
+ err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
+       return ret;
  }
  
 +static int rk_gmac_remove(struct platform_device *pdev)
 +{
 +      struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(&pdev->dev);
 +      int ret = stmmac_dvr_remove(&pdev->dev);
 +
 +      rk_gmac_powerdown(bsp_priv);
 +
 +      return ret;
 +}
 +
 +#ifdef CONFIG_PM_SLEEP
 +static int rk_gmac_suspend(struct device *dev)
 +{
 +      struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
 +      int ret = stmmac_suspend(dev);
 +
 +      /* Keep the PHY up if we use Wake-on-Lan. */
 +      if (!device_may_wakeup(dev)) {
 +              rk_gmac_powerdown(bsp_priv);
 +              bsp_priv->suspended = true;
 +      }
 +
 +      return ret;
 +}
 +
 +static int rk_gmac_resume(struct device *dev)
 +{
 +      struct rk_priv_data *bsp_priv = get_stmmac_bsp_priv(dev);
 +
 +      /* The PHY was up for Wake-on-Lan. */
 +      if (bsp_priv->suspended) {
 +              rk_gmac_powerup(bsp_priv);
 +              bsp_priv->suspended = false;
 +      }
 +
 +      return stmmac_resume(dev);
 +}
 +#endif /* CONFIG_PM_SLEEP */
 +
 +static SIMPLE_DEV_PM_OPS(rk_gmac_pm_ops, rk_gmac_suspend, rk_gmac_resume);
 +
  static const struct of_device_id rk_gmac_dwmac_match[] = {
        { .compatible = "rockchip,rk3228-gmac", .data = &rk3228_ops },
        { .compatible = "rockchip,rk3288-gmac", .data = &rk3288_ops },
index c9006ab083d5a08a799d4493a677221abc5d41a4,060b98c37a851834f1f1293d67795b9e31ec5a85..86e0e053804c75decc2e434791c2562fd6763b1d
@@@ -341,24 -359,25 +343,27 @@@ static int sti_dwmac_probe(struct platf
        dwmac->fix_retime_src = data->fix_retime_src;
  
        plat_dat->bsp_priv = dwmac;
 -      plat_dat->init = sti_dwmac_init;
 -      plat_dat->exit = sti_dwmac_exit;
        plat_dat->fix_mac_speed = data->fix_retime_src;
  
 -      ret = sti_dwmac_init(pdev, plat_dat->bsp_priv);
 +      ret = clk_prepare_enable(dwmac->clk);
        if (ret)
-               return ret;
+               goto err_remove_config_dt;
  
 +      ret = sti_dwmac_set_mode(dwmac);
 +      if (ret)
 +              goto disable_clk;
 +
        ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
        if (ret)
 -              goto err_dwmac_exit;
 +              goto disable_clk;
  
        return 0;
  
 -err_dwmac_exit:
 -      sti_dwmac_exit(pdev, plat_dat->bsp_priv);
 +disable_clk:
 +      clk_disable_unprepare(dwmac->clk);
+ err_remove_config_dt:
+       stmmac_remove_config_dt(pdev, plat_dat);
        return ret;
  }
  
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc init/Kconfig
Simple merge
Simple merge
Simple merge
diff --cc net/core/sock.c
Simple merge
diff --cc net/dccp/ipv4.c
Simple merge
diff --cc net/dsa/slave.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc net/ipv6/esp6.c
Simple merge
diff --cc net/ipv6/icmp.c
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
diff --cc net/rds/tcp.c
Simple merge
Simple merge
Simple merge
index 1cacfa5c95f3246e8038f112c1fd4ed6b86a97bc,904442421db3afae405548a9f5c316ce65e22de3..c5cea78491dc782e01430d7ab4acb4cea4186c0b
@@@ -271,21 -267,30 +275,39 @@@ static void fl_hw_update_stats(struct t
        offload.cookie = (unsigned long)f;
        offload.exts = &f->exts;
  
 -      tc.type = TC_SETUP_CLSFLOWER;
 -      tc.cls_flower = &offload;
 +      tc->type = TC_SETUP_CLSFLOWER;
 +      tc->cls_flower = &offload;
  
 -      dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, &tc);
 +      dev->netdev_ops->ndo_setup_tc(dev, tp->q->handle, tp->protocol, tc);
 +}
 +
 +static void __fl_delete(struct tcf_proto *tp, struct cls_fl_filter *f)
 +{
 +      list_del_rcu(&f->list);
 +      if (!tc_skip_hw(f->flags))
 +              fl_hw_destroy_filter(tp, f);
 +      tcf_unbind_filter(tp, &f->res);
 +      call_rcu(&f->rcu, fl_destroy_filter);
  }
  
+ static void fl_destroy_sleepable(struct work_struct *work)
+ {
+       struct cls_fl_head *head = container_of(work, struct cls_fl_head,
+                                               work);
+       if (head->mask_assigned)
+               rhashtable_destroy(&head->ht);
+       kfree(head);
+       module_put(THIS_MODULE);
+ }
+ static void fl_destroy_rcu(struct rcu_head *rcu)
+ {
+       struct cls_fl_head *head = container_of(rcu, struct cls_fl_head, rcu);
+       INIT_WORK(&head->work, fl_destroy_sleepable);
+       schedule_work(&head->work);
+ }
  static bool fl_destroy(struct tcf_proto *tp, bool force)
  {
        struct cls_fl_head *head = rtnl_dereference(tp->root);
        if (!force && !list_empty(&head->filters))
                return false;
  
 -      list_for_each_entry_safe(f, next, &head->filters, list) {
 -              fl_hw_destroy_filter(tp, (unsigned long)f);
 -              list_del_rcu(&f->list);
 -              call_rcu(&f->rcu, fl_destroy_filter);
 -      }
 +      list_for_each_entry_safe(f, next, &head->filters, list)
 +              __fl_delete(tp, f);
-       RCU_INIT_POINTER(tp->root, NULL);
-       if (head->mask_assigned)
-               rhashtable_destroy(&head->ht);
-       kfree_rcu(head, rcu);
+       __module_get(THIS_MODULE);
+       call_rcu(&head->rcu, fl_destroy_rcu);
++
        return true;
  }
  
@@@ -749,20 -721,21 +771,21 @@@ static int fl_change(struct net *net, s
                        goto errout;
        }
  
 -      err = fl_hw_replace_filter(tp,
 -                                 &head->dissector,
 -                                 &mask.key,
 -                                 &fnew->key,
 -                                 &fnew->exts,
 -                                 (unsigned long)fnew,
 -                                 fnew->flags);
 -      if (err)
 -              goto errout;
 +      if (!tc_skip_hw(fnew->flags)) {
 +              err = fl_hw_replace_filter(tp,
 +                                         &head->dissector,
 +                                         &mask.key,
 +                                         fnew);
 +              if (err)
 +                      goto errout;
 +      }
  
        if (fold) {
-               rhashtable_remove_fast(&head->ht, &fold->ht_node,
-                                      head->ht_params);
+               if (!tc_skip_sw(fold->flags))
+                       rhashtable_remove_fast(&head->ht, &fold->ht_node,
+                                              head->ht_params);
 -              fl_hw_destroy_filter(tp, (unsigned long)fold);
 +              if (!tc_skip_hw(fold->flags))
 +                      fl_hw_destroy_filter(tp, fold);
        }
  
        *arg = (unsigned long) fnew;
@@@ -788,9 -761,13 +811,10 @@@ static int fl_delete(struct tcf_proto *
        struct cls_fl_head *head = rtnl_dereference(tp->root);
        struct cls_fl_filter *f = (struct cls_fl_filter *) arg;
  
-       rhashtable_remove_fast(&head->ht, &f->ht_node,
-                              head->ht_params);
+       if (!tc_skip_sw(f->flags))
+               rhashtable_remove_fast(&head->ht, &f->ht_node,
+                                      head->ht_params);
 -      list_del_rcu(&f->list);
 -      fl_hw_destroy_filter(tp, (unsigned long)f);
 -      tcf_unbind_filter(tp, &f->res);
 -      call_rcu(&f->rcu, fl_destroy_filter);
 +      __fl_delete(tp, f);
        return 0;
  }
  
Simple merge