From 1c4415a679f9858f9de628b650cdef32a2abf9bb Mon Sep 17 00:00:00 2001 From: Mathew McBride Date: Tue, 24 Oct 2017 11:49:00 +1100 Subject: layerscape: reverse changes to ndo_get_stats64 The NXP LSDK kernel backported changes for interface ndo_get_stats64 functions from mainline, this causes a compile error with backports/mac80211, which expects the original 4.9 defintion. As reversing the ndo_get_stats64 change signifcantly reduces the size of patch 601, the patches that were aggregated into it have been disaggregated. Signed-off-by: Mathew McBride --- ...entralize-net_device-min-max-MTU-checking.patch | 78 + .../303-add-devm_alloc_percpu-support.patch | 125 ++ .../patches-4.9/601-net-readd-skb_recycle.patch | 66 + .../patches-4.9/601-net-support-layerscape.patch | 2365 -------------------- ...inux-core-export-copy_skb_header-function.patch | 47 + ...date-the-xmit-timestamp-to-avoid-watchdog.patch | 60 + .../706-fsl-dpaa-use-4-9-ndo-get-stats64.patch | 112 + .../patches-4.9/808-guts-support-layerscape.patch | 452 ---- ...-soc-Introduce-soc_device_match-interface.patch | 162 ++ .../patches-4.9/821-guts-support-layerscape.patch | 452 ++++ 10 files changed, 1102 insertions(+), 2817 deletions(-) create mode 100644 target/linux/layerscape/patches-4.9/001-net-centralize-net_device-min-max-MTU-checking.patch create mode 100644 target/linux/layerscape/patches-4.9/303-add-devm_alloc_percpu-support.patch create mode 100644 target/linux/layerscape/patches-4.9/601-net-readd-skb_recycle.patch delete mode 100644 target/linux/layerscape/patches-4.9/601-net-support-layerscape.patch create mode 100644 target/linux/layerscape/patches-4.9/602-linux-core-export-copy_skb_header-function.patch create mode 100644 target/linux/layerscape/patches-4.9/603-sdk_dpaa-update-the-xmit-timestamp-to-avoid-watchdog.patch create mode 100644 target/linux/layerscape/patches-4.9/706-fsl-dpaa-use-4-9-ndo-get-stats64.patch delete mode 100644 target/linux/layerscape/patches-4.9/808-guts-support-layerscape.patch create mode 100644 target/linux/layerscape/patches-4.9/820-base-soc-Introduce-soc_device_match-interface.patch create mode 100644 target/linux/layerscape/patches-4.9/821-guts-support-layerscape.patch (limited to 'target/linux/layerscape') diff --git a/target/linux/layerscape/patches-4.9/001-net-centralize-net_device-min-max-MTU-checking.patch b/target/linux/layerscape/patches-4.9/001-net-centralize-net_device-min-max-MTU-checking.patch new file mode 100644 index 0000000000..fcabb62f5e --- /dev/null +++ b/target/linux/layerscape/patches-4.9/001-net-centralize-net_device-min-max-MTU-checking.patch @@ -0,0 +1,78 @@ +From 95b8bbff6ecf0692747622af16d917a67313f8cc Mon Sep 17 00:00:00 2001 +From: Jarod Wilson +Date: Fri, 7 Oct 2016 22:04:33 -0400 +Subject: [PATCH] net: centralize net_device min/max MTU checking + +While looking into an MTU issue with sfc, I started noticing that almost +every NIC driver with an ndo_change_mtu function implemented almost +exactly the same range checks, and in many cases, that was the only +practical thing their ndo_change_mtu function was doing. Quite a few +drivers have either 68, 64, 60 or 46 as their minimum MTU value checked, +and then various sizes from 1500 to 65535 for their maximum MTU value. We +can remove a whole lot of redundant code here if we simple store min_mtu +and max_mtu in net_device, and check against those in net/core/dev.c's +dev_set_mtu(). + +In theory, there should be zero functional change with this patch, it just +puts the infrastructure in place. Subsequent patches will attempt to start +using said infrastructure, with theoretically zero change in +functionality. + +CC: netdev@vger.kernel.org +Signed-off-by: Jarod Wilson +Signed-off-by: David S. Miller +--- + include/linux/netdevice.h | 4 ++++ + net/core/dev.c | 13 +++++++++++-- + 2 files changed, 15 insertions(+), 2 deletions(-) + +diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h +index 780e7171f548..2082b7d02a77 100644 +--- a/include/linux/netdevice.h ++++ b/include/linux/netdevice.h +@@ -1507,6 +1507,8 @@ enum netdev_priv_flags { + * @if_port: Selectable AUI, TP, ... + * @dma: DMA channel + * @mtu: Interface MTU value ++ * @min_mtu: Interface Minimum MTU value ++ * @max_mtu: Interface Maximum MTU value + * @type: Interface hardware type + * @hard_header_len: Maximum hardware header length. + * @min_header_len: Minimum hardware header length +@@ -1728,6 +1730,8 @@ struct net_device { + unsigned char dma; + + unsigned int mtu; ++ unsigned int min_mtu; ++ unsigned int max_mtu; + unsigned short type; + unsigned short hard_header_len; + unsigned short min_header_len; +diff --git a/net/core/dev.c b/net/core/dev.c +index 2e04fd188081..c7ec56e8659a 100644 +--- a/net/core/dev.c ++++ b/net/core/dev.c +@@ -6524,9 +6524,18 @@ int dev_set_mtu(struct net_device *dev, int new_mtu) + if (new_mtu == dev->mtu) + return 0; + +- /* MTU must be positive. */ +- if (new_mtu < 0) ++ /* MTU must be positive, and in range */ ++ if (new_mtu < 0 || new_mtu < dev->min_mtu) { ++ net_err_ratelimited("%s: Invalid MTU %d requested, hw min %d\n", ++ dev->name, new_mtu, dev->min_mtu); + return -EINVAL; ++ } ++ ++ if (dev->max_mtu > 0 && new_mtu > dev->max_mtu) { ++ net_err_ratelimited("%s: Invalid MTU %d requested, hw max %d\n", ++ dev->name, new_mtu, dev->min_mtu); ++ return -EINVAL; ++ } + + if (!netif_device_present(dev)) + return -ENODEV; +-- +2.11.1 + diff --git a/target/linux/layerscape/patches-4.9/303-add-devm_alloc_percpu-support.patch b/target/linux/layerscape/patches-4.9/303-add-devm_alloc_percpu-support.patch new file mode 100644 index 0000000000..a8573cce00 --- /dev/null +++ b/target/linux/layerscape/patches-4.9/303-add-devm_alloc_percpu-support.patch @@ -0,0 +1,125 @@ +From d33bde3c487c722541ad359e1d22090a78df0c77 Mon Sep 17 00:00:00 2001 +From: Zhao Qiang +Date: Tue, 11 Jul 2017 16:47:18 +0800 +Subject: [PATCH] add devm_alloc_percpu support + +Signed-off-by: Zhao Qiang +--- + drivers/base/devres.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/device.h | 19 +++++++++++++++ + 2 files changed, 85 insertions(+) + +diff --git a/drivers/base/devres.c b/drivers/base/devres.c +index 8fc654f0807b..71d577025285 100644 +--- a/drivers/base/devres.c ++++ b/drivers/base/devres.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + #include "base.h" + +@@ -985,3 +986,68 @@ void devm_free_pages(struct device *dev, unsigned long addr) + &devres)); + } + EXPORT_SYMBOL_GPL(devm_free_pages); ++ ++static void devm_percpu_release(struct device *dev, void *pdata) ++{ ++ void __percpu *p; ++ ++ p = *(void __percpu **)pdata; ++ free_percpu(p); ++} ++ ++static int devm_percpu_match(struct device *dev, void *data, void *p) ++{ ++ struct devres *devr = container_of(data, struct devres, data); ++ ++ return *(void **)devr->data == p; ++} ++ ++/** ++ * __devm_alloc_percpu - Resource-managed alloc_percpu ++ * @dev: Device to allocate per-cpu memory for ++ * @size: Size of per-cpu memory to allocate ++ * @align: Alignment of per-cpu memory to allocate ++ * ++ * Managed alloc_percpu. Per-cpu memory allocated with this function is ++ * automatically freed on driver detach. ++ * ++ * RETURNS: ++ * Pointer to allocated memory on success, NULL on failure. ++ */ ++void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, ++ size_t align) ++{ ++ void *p; ++ void __percpu *pcpu; ++ ++ pcpu = __alloc_percpu(size, align); ++ if (!pcpu) ++ return NULL; ++ ++ p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL); ++ if (!p) { ++ free_percpu(pcpu); ++ return NULL; ++ } ++ ++ *(void __percpu **)p = pcpu; ++ ++ devres_add(dev, p); ++ ++ return pcpu; ++} ++EXPORT_SYMBOL_GPL(__devm_alloc_percpu); ++ ++/** ++ * devm_free_percpu - Resource-managed free_percpu ++ * @dev: Device this memory belongs to ++ * @pdata: Per-cpu memory to free ++ * ++ * Free memory allocated with devm_alloc_percpu(). ++ */ ++void devm_free_percpu(struct device *dev, void __percpu *pdata) ++{ ++ WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, ++ (void *)pdata)); ++} ++EXPORT_SYMBOL_GPL(devm_free_percpu); +diff --git a/include/linux/device.h b/include/linux/device.h +index bc41e87a969b..0a2135cbddc9 100644 +--- a/include/linux/device.h ++++ b/include/linux/device.h +@@ -686,6 +686,25 @@ void __iomem *devm_ioremap_resource(struct device *dev, struct resource *res); + int devm_add_action(struct device *dev, void (*action)(void *), void *data); + void devm_remove_action(struct device *dev, void (*action)(void *), void *data); + ++/** ++ * devm_alloc_percpu - Resource-managed alloc_percpu ++ * @dev: Device to allocate per-cpu memory for ++ * @type: Type to allocate per-cpu memory for ++ * ++ * Managed alloc_percpu. Per-cpu memory allocated with this function is ++ * automatically freed on driver detach. ++ * ++ * RETURNS: ++ * Pointer to allocated memory on success, NULL on failure. ++ */ ++#define devm_alloc_percpu(dev, type) \ ++ ((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \ ++ __alignof__(type))) ++ ++void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, ++ size_t align); ++void devm_free_percpu(struct device *dev, void __percpu *pdata); ++ + static inline int devm_add_action_or_reset(struct device *dev, + void (*action)(void *), void *data) + { +-- +2.11.1 + diff --git a/target/linux/layerscape/patches-4.9/601-net-readd-skb_recycle.patch b/target/linux/layerscape/patches-4.9/601-net-readd-skb_recycle.patch new file mode 100644 index 0000000000..08aa2a0944 --- /dev/null +++ b/target/linux/layerscape/patches-4.9/601-net-readd-skb_recycle.patch @@ -0,0 +1,66 @@ +From 9527ee5eb436ad773acc7320b372a5f4825a920d Mon Sep 17 00:00:00 2001 +From: Madalin Bucur +Date: Tue, 5 Jan 2016 12:12:07 +0200 +Subject: [PATCH] net: readd skb_recycle() + +Adding back skb_recycle() as it's used by the DPAA Ethernet driver. +This was removed from the upstream kernel because it was lacking users. + +Signed-off-by: Madalin Bucur +--- + include/linux/skbuff.h | 1 + + net/core/skbuff.c | 26 ++++++++++++++++++++++++++ + 2 files changed, 27 insertions(+) + +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index 32810f279f8e..a52a6fb0ac2e 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -902,6 +902,7 @@ void kfree_skb(struct sk_buff *skb); + void kfree_skb_list(struct sk_buff *segs); + void skb_tx_error(struct sk_buff *skb); + void consume_skb(struct sk_buff *skb); ++void skb_recycle(struct sk_buff *skb); + void __kfree_skb(struct sk_buff *skb); + extern struct kmem_cache *skbuff_head_cache; + +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index fe008f1bd930..ab1038083df2 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -825,6 +825,32 @@ void napi_consume_skb(struct sk_buff *skb, int budget) + } + EXPORT_SYMBOL(napi_consume_skb); + ++/** ++ * skb_recycle - clean up an skb for reuse ++ * @skb: buffer ++ * ++ * Recycles the skb to be reused as a receive buffer. This ++ * function does any necessary reference count dropping, and ++ * cleans up the skbuff as if it just came from __alloc_skb(). ++ */ ++void skb_recycle(struct sk_buff *skb) ++{ ++ struct skb_shared_info *shinfo; ++ u8 head_frag = skb->head_frag; ++ ++ skb_release_head_state(skb); ++ ++ shinfo = skb_shinfo(skb); ++ memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); ++ atomic_set(&shinfo->dataref, 1); ++ ++ memset(skb, 0, offsetof(struct sk_buff, tail)); ++ skb->data = skb->head + NET_SKB_PAD; ++ skb->head_frag = head_frag; ++ skb_reset_tail_pointer(skb); ++} ++EXPORT_SYMBOL(skb_recycle); ++ + /* Make sure a field is enclosed inside headers_start/headers_end section */ + #define CHECK_SKB_FIELD(field) \ + BUILD_BUG_ON(offsetof(struct sk_buff, field) < \ +-- +2.11.1 + diff --git a/target/linux/layerscape/patches-4.9/601-net-support-layerscape.patch b/target/linux/layerscape/patches-4.9/601-net-support-layerscape.patch deleted file mode 100644 index 9db40dc2ff..0000000000 --- a/target/linux/layerscape/patches-4.9/601-net-support-layerscape.patch +++ /dev/null @@ -1,2365 +0,0 @@ -From 2ed7bff3d1f2fa6c5f6eff0b2bd98deaa3dc18b0 Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Mon, 25 Sep 2017 10:57:14 +0800 -Subject: [PATCH] net: support layerscape - -This is a integrated patch for layerscape net support. - -Signed-off-by: Madalin Bucur -Signed-off-by: Zhao Qiang -Signed-off-by: Camelia Groza -Signed-off-by: Madalin Bucur -Signed-off-by: Zhang Ying-22455 -Signed-off-by: Ramneek Mehresh -Signed-off-by: Jarod Wilson -Signed-off-by: Nikhil Badola -Signed-off-by: stephen hemminger -Signed-off-by: Arnd Bergmann -Signed-off-by: Yangbo Lu ---- - drivers/base/devres.c | 66 +++++++++++++++ - drivers/base/soc.c | 66 +++++++++++++++ - drivers/net/bonding/bond_main.c | 10 +-- - drivers/net/dummy.c | 5 +- - drivers/net/ethernet/amazon/ena/ena_netdev.c | 10 +-- - drivers/net/ethernet/amd/xgbe/xgbe-drv.c | 6 +- - drivers/net/ethernet/apm/xgene/xgene_enet_main.c | 4 +- - drivers/net/ethernet/atheros/alx/main.c | 6 +- - drivers/net/ethernet/broadcom/b44.c | 5 +- - drivers/net/ethernet/broadcom/bnx2.c | 5 +- - drivers/net/ethernet/broadcom/bnxt/bnxt.c | 6 +- - drivers/net/ethernet/broadcom/tg3.c | 8 +- - drivers/net/ethernet/brocade/bna/bnad.c | 6 +- - drivers/net/ethernet/calxeda/xgmac.c | 5 +- - drivers/net/ethernet/cavium/thunder/nicvf_main.c | 5 +- - drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | 7 +- - drivers/net/ethernet/cisco/enic/enic_main.c | 8 +- - drivers/net/ethernet/ec_bhf.c | 4 +- - drivers/net/ethernet/emulex/benet/be_main.c | 5 +- - drivers/net/ethernet/hisilicon/hns/hns_enet.c | 6 +- - drivers/net/ethernet/ibm/ehea/ehea_main.c | 5 +- - drivers/net/ethernet/intel/e1000e/e1000.h | 4 +- - drivers/net/ethernet/intel/e1000e/netdev.c | 5 +- - drivers/net/ethernet/intel/fm10k/fm10k_netdev.c | 6 +- - drivers/net/ethernet/intel/i40e/i40e.h | 5 +- - drivers/net/ethernet/intel/i40e/i40e_main.c | 18 ++-- - drivers/net/ethernet/intel/igb/igb_main.c | 10 +-- - drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 7 +- - drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 6 +- - drivers/net/ethernet/marvell/mvneta.c | 4 +- - drivers/net/ethernet/marvell/mvpp2.c | 4 +- - drivers/net/ethernet/marvell/sky2.c | 6 +- - drivers/net/ethernet/mediatek/mtk_eth_soc.c | 6 +- - drivers/net/ethernet/mellanox/mlx4/en_netdev.c | 4 +- - drivers/net/ethernet/mellanox/mlx5/core/en_main.c | 3 +- - drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 4 +- - drivers/net/ethernet/mellanox/mlxsw/switchx2.c | 3 +- - drivers/net/ethernet/myricom/myri10ge/myri10ge.c | 9 +- - drivers/net/ethernet/neterion/vxge/vxge-main.c | 4 +- - .../net/ethernet/netronome/nfp/nfp_net_common.c | 6 +- - drivers/net/ethernet/nvidia/forcedeth.c | 4 +- - .../net/ethernet/qlogic/netxen/netxen_nic_main.c | 10 +-- - drivers/net/ethernet/qlogic/qede/qede_main.c | 7 +- - drivers/net/ethernet/qualcomm/emac/emac.c | 6 +- - drivers/net/ethernet/realtek/8139too.c | 9 +- - drivers/net/ethernet/realtek/r8169.c | 4 +- - drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | 8 +- - drivers/net/ethernet/sfc/efx.c | 6 +- - drivers/net/ethernet/sun/niu.c | 6 +- - drivers/net/ethernet/synopsys/dwc_eth_qos.c | 4 +- - drivers/net/ethernet/tile/tilepro.c | 4 +- - drivers/net/ethernet/via/via-rhine.c | 8 +- - drivers/net/fjes/fjes_main.c | 7 +- - drivers/net/hyperv/netvsc_drv.c | 6 +- - drivers/net/ifb.c | 6 +- - drivers/net/ipvlan/ipvlan_main.c | 5 +- - drivers/net/loopback.c | 5 +- - drivers/net/macsec.c | 8 +- - drivers/net/macvlan.c | 5 +- - drivers/net/nlmon.c | 4 +- - drivers/net/ppp/ppp_generic.c | 4 +- - drivers/net/slip/slip.c | 3 +- - drivers/net/team/team.c | 3 +- - drivers/net/tun.c | 3 +- - drivers/net/veth.c | 6 +- - drivers/net/virtio_net.c | 6 +- - drivers/net/vmxnet3/vmxnet3_ethtool.c | 4 +- - drivers/net/vmxnet3/vmxnet3_int.h | 4 +- - drivers/net/vrf.c | 5 +- - drivers/net/xen-netfront.c | 6 +- - drivers/staging/netlogic/xlr_net.c | 10 +-- - include/linux/device.h | 19 +++++ - include/linux/fsl/svr.h | 97 ++++++++++++++++++++++ - include/linux/fsl_devices.h | 3 + - include/linux/netdev_features.h | 2 + - include/linux/netdevice.h | 12 ++- - include/linux/skbuff.h | 2 + - include/linux/sys_soc.h | 3 + - include/net/ip_tunnels.h | 4 +- - include/uapi/linux/if_ether.h | 1 + - net/8021q/vlan_dev.c | 5 +- - net/bridge/br_device.c | 6 +- - net/core/dev.c | 13 ++- - net/core/skbuff.c | 29 ++++++- - net/ipv4/ip_tunnel_core.c | 6 +- - net/l2tp/l2tp_eth.c | 6 +- - net/mac80211/iface.c | 4 +- - net/openvswitch/vport-internal_dev.c | 4 +- - net/sched/sch_generic.c | 7 ++ - net/sched/sch_teql.c | 5 +- - 90 files changed, 468 insertions(+), 298 deletions(-) - create mode 100644 include/linux/fsl/svr.h - ---- a/drivers/base/devres.c -+++ b/drivers/base/devres.c -@@ -10,6 +10,7 @@ - #include - #include - #include -+#include - - #include "base.h" - -@@ -985,3 +986,68 @@ void devm_free_pages(struct device *dev, - &devres)); - } - EXPORT_SYMBOL_GPL(devm_free_pages); -+ -+static void devm_percpu_release(struct device *dev, void *pdata) -+{ -+ void __percpu *p; -+ -+ p = *(void __percpu **)pdata; -+ free_percpu(p); -+} -+ -+static int devm_percpu_match(struct device *dev, void *data, void *p) -+{ -+ struct devres *devr = container_of(data, struct devres, data); -+ -+ return *(void **)devr->data == p; -+} -+ -+/** -+ * __devm_alloc_percpu - Resource-managed alloc_percpu -+ * @dev: Device to allocate per-cpu memory for -+ * @size: Size of per-cpu memory to allocate -+ * @align: Alignment of per-cpu memory to allocate -+ * -+ * Managed alloc_percpu. Per-cpu memory allocated with this function is -+ * automatically freed on driver detach. -+ * -+ * RETURNS: -+ * Pointer to allocated memory on success, NULL on failure. -+ */ -+void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, -+ size_t align) -+{ -+ void *p; -+ void __percpu *pcpu; -+ -+ pcpu = __alloc_percpu(size, align); -+ if (!pcpu) -+ return NULL; -+ -+ p = devres_alloc(devm_percpu_release, sizeof(void *), GFP_KERNEL); -+ if (!p) { -+ free_percpu(pcpu); -+ return NULL; -+ } -+ -+ *(void __percpu **)p = pcpu; -+ -+ devres_add(dev, p); -+ -+ return pcpu; -+} -+EXPORT_SYMBOL_GPL(__devm_alloc_percpu); -+ -+/** -+ * devm_free_percpu - Resource-managed free_percpu -+ * @dev: Device this memory belongs to -+ * @pdata: Per-cpu memory to free -+ * -+ * Free memory allocated with devm_alloc_percpu(). -+ */ -+void devm_free_percpu(struct device *dev, void __percpu *pdata) -+{ -+ WARN_ON(devres_destroy(dev, devm_percpu_release, devm_percpu_match, -+ (void *)pdata)); -+} -+EXPORT_SYMBOL_GPL(devm_free_percpu); ---- a/drivers/base/soc.c -+++ b/drivers/base/soc.c -@@ -13,6 +13,7 @@ - #include - #include - #include -+#include - - static DEFINE_IDA(soc_ida); - -@@ -159,3 +160,68 @@ static int __init soc_bus_register(void) - return bus_register(&soc_bus_type); - } - core_initcall(soc_bus_register); -+ -+static int soc_device_match_one(struct device *dev, void *arg) -+{ -+ struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); -+ const struct soc_device_attribute *match = arg; -+ -+ if (match->machine && -+ !glob_match(match->machine, soc_dev->attr->machine)) -+ return 0; -+ -+ if (match->family && -+ !glob_match(match->family, soc_dev->attr->family)) -+ return 0; -+ -+ if (match->revision && -+ !glob_match(match->revision, soc_dev->attr->revision)) -+ return 0; -+ -+ if (match->soc_id && -+ !glob_match(match->soc_id, soc_dev->attr->soc_id)) -+ return 0; -+ -+ return 1; -+} -+ -+/* -+ * soc_device_match - identify the SoC in the machine -+ * @matches: zero-terminated array of possible matches -+ * -+ * returns the first matching entry of the argument array, or NULL -+ * if none of them match. -+ * -+ * This function is meant as a helper in place of of_match_node() -+ * in cases where either no device tree is available or the information -+ * in a device node is insufficient to identify a particular variant -+ * by its compatible strings or other properties. For new devices, -+ * the DT binding should always provide unique compatible strings -+ * that allow the use of of_match_node() instead. -+ * -+ * The calling function can use the .data entry of the -+ * soc_device_attribute to pass a structure or function pointer for -+ * each entry. -+ */ -+const struct soc_device_attribute *soc_device_match( -+ const struct soc_device_attribute *matches) -+{ -+ int ret = 0; -+ -+ if (!matches) -+ return NULL; -+ -+ while (!ret) { -+ if (!(matches->machine || matches->family || -+ matches->revision || matches->soc_id)) -+ break; -+ ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, -+ soc_device_match_one); -+ if (!ret) -+ matches++; -+ else -+ return matches; -+ } -+ return NULL; -+} -+EXPORT_SYMBOL_GPL(soc_device_match); ---- a/drivers/net/bonding/bond_main.c -+++ b/drivers/net/bonding/bond_main.c -@@ -211,8 +211,8 @@ static int lacp_fast; - - static int bond_init(struct net_device *bond_dev); - static void bond_uninit(struct net_device *bond_dev); --static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, -- struct rtnl_link_stats64 *stats); -+static void bond_get_stats(struct net_device *bond_dev, -+ struct rtnl_link_stats64 *stats); - static void bond_slave_arr_handler(struct work_struct *work); - static bool bond_time_in_interval(struct bonding *bond, unsigned long last_act, - int mod); -@@ -3336,8 +3336,8 @@ static void bond_fold_stats(struct rtnl_ - } - } - --static struct rtnl_link_stats64 *bond_get_stats(struct net_device *bond_dev, -- struct rtnl_link_stats64 *stats) -+static void bond_get_stats(struct net_device *bond_dev, -+ struct rtnl_link_stats64 *stats) - { - struct bonding *bond = netdev_priv(bond_dev); - struct rtnl_link_stats64 temp; -@@ -3361,8 +3361,6 @@ static struct rtnl_link_stats64 *bond_ge - - memcpy(&bond->bond_stats, stats, sizeof(*stats)); - spin_unlock(&bond->stats_lock); -- -- return stats; - } - - static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd) ---- a/drivers/net/dummy.c -+++ b/drivers/net/dummy.c -@@ -54,8 +54,8 @@ struct pcpu_dstats { - struct u64_stats_sync syncp; - }; - --static struct rtnl_link_stats64 *dummy_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void dummy_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - int i; - -@@ -73,7 +73,6 @@ static struct rtnl_link_stats64 *dummy_g - stats->tx_bytes += tbytes; - stats->tx_packets += tpackets; - } -- return stats; - } - - static netdev_tx_t dummy_xmit(struct sk_buff *skb, struct net_device *dev) ---- a/drivers/net/ethernet/amazon/ena/ena_netdev.c -+++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c -@@ -2172,19 +2172,19 @@ err: - ena_com_delete_debug_area(adapter->ena_dev); - } - --static struct rtnl_link_stats64 *ena_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void ena_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct ena_adapter *adapter = netdev_priv(netdev); - struct ena_admin_basic_stats ena_stats; - int rc; - - if (!test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) -- return NULL; -+ return; - - rc = ena_com_get_dev_basic_stats(adapter->ena_dev, &ena_stats); - if (rc) -- return NULL; -+ return; - - stats->tx_bytes = ((u64)ena_stats.tx_bytes_high << 32) | - ena_stats.tx_bytes_low; -@@ -2211,8 +2211,6 @@ static struct rtnl_link_stats64 *ena_get - - stats->rx_errors = 0; - stats->tx_errors = 0; -- -- return stats; - } - - static const struct net_device_ops ena_netdev_ops = { ---- a/drivers/net/ethernet/amd/xgbe/xgbe-drv.c -+++ b/drivers/net/ethernet/amd/xgbe/xgbe-drv.c -@@ -1542,8 +1542,8 @@ static void xgbe_tx_timeout(struct net_d - schedule_work(&pdata->restart_work); - } - --static struct rtnl_link_stats64 *xgbe_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *s) -+static void xgbe_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *s) - { - struct xgbe_prv_data *pdata = netdev_priv(netdev); - struct xgbe_mmc_stats *pstats = &pdata->mmc_stats; -@@ -1569,8 +1569,6 @@ static struct rtnl_link_stats64 *xgbe_ge - s->tx_dropped = netdev->stats.tx_dropped; - - DBGPR("<--%s\n", __func__); -- -- return s; - } - - static int xgbe_vlan_rx_add_vid(struct net_device *netdev, __be16 proto, ---- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c -+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c -@@ -1199,7 +1199,7 @@ err: - return ret; - } - --static struct rtnl_link_stats64 *xgene_enet_get_stats64( -+static void xgene_enet_get_stats64( - struct net_device *ndev, - struct rtnl_link_stats64 *storage) - { -@@ -1230,8 +1230,6 @@ static struct rtnl_link_stats64 *xgene_e - } - } - memcpy(storage, stats, sizeof(struct rtnl_link_stats64)); -- -- return storage; - } - - static int xgene_enet_set_mac_address(struct net_device *ndev, void *addr) ---- a/drivers/net/ethernet/atheros/alx/main.c -+++ b/drivers/net/ethernet/atheros/alx/main.c -@@ -1424,8 +1424,8 @@ static void alx_poll_controller(struct n - } - #endif - --static struct rtnl_link_stats64 *alx_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *net_stats) -+static void alx_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *net_stats) - { - struct alx_priv *alx = netdev_priv(dev); - struct alx_hw_stats *hw_stats = &alx->hw.stats; -@@ -1469,8 +1469,6 @@ static struct rtnl_link_stats64 *alx_get - net_stats->rx_packets = hw_stats->rx_ok + net_stats->rx_errors; - - spin_unlock(&alx->stats_lock); -- -- return net_stats; - } - - static const struct net_device_ops alx_netdev_ops = { ---- a/drivers/net/ethernet/broadcom/b44.c -+++ b/drivers/net/ethernet/broadcom/b44.c -@@ -1677,8 +1677,8 @@ static int b44_close(struct net_device * - return 0; - } - --static struct rtnl_link_stats64 *b44_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *nstat) -+static void b44_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *nstat) - { - struct b44 *bp = netdev_priv(dev); - struct b44_hw_stats *hwstat = &bp->hw_stats; -@@ -1721,7 +1721,6 @@ static struct rtnl_link_stats64 *b44_get - #endif - } while (u64_stats_fetch_retry_irq(&hwstat->syncp, start)); - -- return nstat; - } - - static int __b44_load_mcast(struct b44 *bp, struct net_device *dev) ---- a/drivers/net/ethernet/broadcom/bnx2.c -+++ b/drivers/net/ethernet/broadcom/bnx2.c -@@ -6828,13 +6828,13 @@ bnx2_save_stats(struct bnx2 *bp) - (unsigned long) (bp->stats_blk->ctr + \ - bp->temp_stats_blk->ctr) - --static struct rtnl_link_stats64 * -+static void - bnx2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) - { - struct bnx2 *bp = netdev_priv(dev); - - if (bp->stats_blk == NULL) -- return net_stats; -+ return; - - net_stats->rx_packets = - GET_64BIT_NET_STATS(stat_IfHCInUcastPkts) + -@@ -6898,7 +6898,6 @@ bnx2_get_stats64(struct net_device *dev, - GET_32BIT_NET_STATS(stat_IfInMBUFDiscards) + - GET_32BIT_NET_STATS(stat_FwRxDrop); - -- return net_stats; - } - - /* All ethtool functions called with rtnl_lock */ ---- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c -+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c -@@ -5664,7 +5664,7 @@ static int bnxt_ioctl(struct net_device - return -EOPNOTSUPP; - } - --static struct rtnl_link_stats64 * -+static void - bnxt_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - u32 i; -@@ -5673,7 +5673,7 @@ bnxt_get_stats64(struct net_device *dev, - memset(stats, 0, sizeof(struct rtnl_link_stats64)); - - if (!bp->bnapi) -- return stats; -+ return; - - /* TODO check if we need to synchronize with bnxt_close path */ - for (i = 0; i < bp->cp_nr_rings; i++) { -@@ -5720,8 +5720,6 @@ bnxt_get_stats64(struct net_device *dev, - stats->tx_fifo_errors = le64_to_cpu(tx->tx_fifo_underruns); - stats->tx_errors = le64_to_cpu(tx->tx_err); - } -- -- return stats; - } - - static bool bnxt_mc_list_updated(struct bnxt *bp, u32 *rx_mask) ---- a/drivers/net/ethernet/broadcom/tg3.c -+++ b/drivers/net/ethernet/broadcom/tg3.c -@@ -14145,8 +14145,8 @@ static const struct ethtool_ops tg3_etht - .set_link_ksettings = tg3_set_link_ksettings, - }; - --static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void tg3_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct tg3 *tp = netdev_priv(dev); - -@@ -14154,13 +14154,11 @@ static struct rtnl_link_stats64 *tg3_get - if (!tp->hw_stats) { - *stats = tp->net_stats_prev; - spin_unlock_bh(&tp->lock); -- return stats; -+ return; - } - - tg3_get_nstats(tp, stats); - spin_unlock_bh(&tp->lock); -- -- return stats; - } - - static void tg3_set_rx_mode(struct net_device *dev) ---- a/drivers/net/ethernet/brocade/bna/bnad.c -+++ b/drivers/net/ethernet/brocade/bna/bnad.c -@@ -3111,7 +3111,7 @@ bnad_start_xmit(struct sk_buff *skb, str - * Used spin_lock to synchronize reading of stats structures, which - * is written by BNA under the same lock. - */ --static struct rtnl_link_stats64 * -+static void - bnad_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) - { - struct bnad *bnad = netdev_priv(netdev); -@@ -3123,8 +3123,6 @@ bnad_get_stats64(struct net_device *netd - bnad_netdev_hwstats_fill(bnad, stats); - - spin_unlock_irqrestore(&bnad->bna_lock, flags); -- -- return stats; - } - - static void -@@ -3430,7 +3428,7 @@ static const struct net_device_ops bnad_ - .ndo_open = bnad_open, - .ndo_stop = bnad_stop, - .ndo_start_xmit = bnad_start_xmit, -- .ndo_get_stats64 = bnad_get_stats64, -+ .ndo_get_stats64 = bnad_get_stats64, - .ndo_set_rx_mode = bnad_set_rx_mode, - .ndo_validate_addr = eth_validate_addr, - .ndo_set_mac_address = bnad_set_mac_address, ---- a/drivers/net/ethernet/calxeda/xgmac.c -+++ b/drivers/net/ethernet/calxeda/xgmac.c -@@ -1460,9 +1460,9 @@ static void xgmac_poll_controller(struct - } - #endif - --static struct rtnl_link_stats64 * -+static void - xgmac_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *storage) -+ struct rtnl_link_stats64 *storage) - { - struct xgmac_priv *priv = netdev_priv(dev); - void __iomem *base = priv->base; -@@ -1490,7 +1490,6 @@ xgmac_get_stats64(struct net_device *dev - - writel(0, base + XGMAC_MMC_CTRL); - spin_unlock_bh(&priv->stats_lock); -- return storage; - } - - static int xgmac_set_mac_address(struct net_device *dev, void *p) ---- a/drivers/net/ethernet/cavium/thunder/nicvf_main.c -+++ b/drivers/net/ethernet/cavium/thunder/nicvf_main.c -@@ -1423,8 +1423,8 @@ void nicvf_update_stats(struct nicvf *ni - nicvf_update_sq_stats(nic, qidx); - } - --static struct rtnl_link_stats64 *nicvf_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void nicvf_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct nicvf *nic = netdev_priv(netdev); - struct nicvf_hw_stats *hw_stats = &nic->hw_stats; -@@ -1440,7 +1440,6 @@ static struct rtnl_link_stats64 *nicvf_g - stats->tx_packets = hw_stats->tx_frames; - stats->tx_dropped = hw_stats->tx_drops; - -- return stats; - } - - static void nicvf_tx_timeout(struct net_device *dev) ---- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c -+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c -@@ -2383,8 +2383,8 @@ int cxgb4_remove_server_filter(const str - } - EXPORT_SYMBOL(cxgb4_remove_server_filter); - --static struct rtnl_link_stats64 *cxgb_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *ns) -+static void cxgb_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *ns) - { - struct port_stats stats; - struct port_info *p = netdev_priv(dev); -@@ -2397,7 +2397,7 @@ static struct rtnl_link_stats64 *cxgb_ge - spin_lock(&adapter->stats_lock); - if (!netif_device_present(dev)) { - spin_unlock(&adapter->stats_lock); -- return ns; -+ return; - } - t4_get_port_stats_offset(adapter, p->tx_chan, &stats, - &p->stats_base); -@@ -2431,7 +2431,6 @@ static struct rtnl_link_stats64 *cxgb_ge - ns->tx_errors = stats.tx_error_frames; - ns->rx_errors = stats.rx_symbol_err + stats.rx_fcs_err + - ns->rx_length_errors + stats.rx_len_err + ns->rx_fifo_errors; -- return ns; - } - - static int cxgb_ioctl(struct net_device *dev, struct ifreq *req, int cmd) ---- a/drivers/net/ethernet/cisco/enic/enic_main.c -+++ b/drivers/net/ethernet/cisco/enic/enic_main.c -@@ -680,8 +680,8 @@ static netdev_tx_t enic_hard_start_xmit( - } - - /* dev_base_lock rwlock held, nominally process context */ --static struct rtnl_link_stats64 *enic_get_stats(struct net_device *netdev, -- struct rtnl_link_stats64 *net_stats) -+static void enic_get_stats(struct net_device *netdev, -+ struct rtnl_link_stats64 *net_stats) - { - struct enic *enic = netdev_priv(netdev); - struct vnic_stats *stats; -@@ -693,7 +693,7 @@ static struct rtnl_link_stats64 *enic_ge - * recorded stats. - */ - if (err == -ENOMEM) -- return net_stats; -+ return; - - net_stats->tx_packets = stats->tx.tx_frames_ok; - net_stats->tx_bytes = stats->tx.tx_bytes_ok; -@@ -707,8 +707,6 @@ static struct rtnl_link_stats64 *enic_ge - net_stats->rx_over_errors = enic->rq_truncated_pkts; - net_stats->rx_crc_errors = enic->rq_bad_fcs; - net_stats->rx_dropped = stats->rx.rx_no_bufs + stats->rx.rx_drop; -- -- return net_stats; - } - - static int enic_mc_sync(struct net_device *netdev, const u8 *mc_addr) ---- a/drivers/net/ethernet/ec_bhf.c -+++ b/drivers/net/ethernet/ec_bhf.c -@@ -458,7 +458,7 @@ static int ec_bhf_stop(struct net_device - return 0; - } - --static struct rtnl_link_stats64 * -+static void - ec_bhf_get_stats(struct net_device *net_dev, - struct rtnl_link_stats64 *stats) - { -@@ -473,8 +473,6 @@ ec_bhf_get_stats(struct net_device *net_ - - stats->tx_bytes = priv->stat_tx_bytes; - stats->rx_bytes = priv->stat_rx_bytes; -- -- return stats; - } - - static const struct net_device_ops ec_bhf_netdev_ops = { ---- a/drivers/net/ethernet/emulex/benet/be_main.c -+++ b/drivers/net/ethernet/emulex/benet/be_main.c -@@ -646,8 +646,8 @@ void be_parse_stats(struct be_adapter *a - } - } - --static struct rtnl_link_stats64 *be_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void be_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct be_adapter *adapter = netdev_priv(netdev); - struct be_drv_stats *drvs = &adapter->drv_stats; -@@ -711,7 +711,6 @@ static struct rtnl_link_stats64 *be_get_ - stats->rx_fifo_errors = drvs->rxpp_fifo_overflow_drop + - drvs->rx_input_fifo_overflow_drop + - drvs->rx_drops_no_pbuf; -- return stats; - } - - void be_link_status_update(struct be_adapter *adapter, u8 link_status) ---- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c -+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c -@@ -1536,8 +1536,8 @@ void hns_nic_set_rx_mode(struct net_devi - hns_set_multicast_list(ndev); - } - --struct rtnl_link_stats64 *hns_nic_get_stats64(struct net_device *ndev, -- struct rtnl_link_stats64 *stats) -+static void hns_nic_get_stats64(struct net_device *ndev, -+ struct rtnl_link_stats64 *stats) - { - int idx = 0; - u64 tx_bytes = 0; -@@ -1579,8 +1579,6 @@ struct rtnl_link_stats64 *hns_nic_get_st - stats->tx_window_errors = ndev->stats.tx_window_errors; - stats->rx_compressed = ndev->stats.rx_compressed; - stats->tx_compressed = ndev->stats.tx_compressed; -- -- return stats; - } - - static u16 ---- a/drivers/net/ethernet/ibm/ehea/ehea_main.c -+++ b/drivers/net/ethernet/ibm/ehea/ehea_main.c -@@ -328,8 +328,8 @@ out: - spin_unlock_irqrestore(&ehea_bcmc_regs.lock, flags); - } - --static struct rtnl_link_stats64 *ehea_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void ehea_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct ehea_port *port = netdev_priv(dev); - u64 rx_packets = 0, tx_packets = 0, rx_bytes = 0, tx_bytes = 0; -@@ -352,7 +352,6 @@ static struct rtnl_link_stats64 *ehea_ge - - stats->multicast = port->stats.multicast; - stats->rx_errors = port->stats.rx_errors; -- return stats; - } - - static void ehea_update_stats(struct work_struct *work) ---- a/drivers/net/ethernet/intel/e1000e/e1000.h -+++ b/drivers/net/ethernet/intel/e1000e/e1000.h -@@ -493,8 +493,8 @@ int e1000e_setup_rx_resources(struct e10 - int e1000e_setup_tx_resources(struct e1000_ring *ring); - void e1000e_free_rx_resources(struct e1000_ring *ring); - void e1000e_free_tx_resources(struct e1000_ring *ring); --struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats); -+void e1000e_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats); - void e1000e_set_interrupt_capability(struct e1000_adapter *adapter); - void e1000e_reset_interrupt_capability(struct e1000_adapter *adapter); - void e1000e_get_hw_control(struct e1000_adapter *adapter); ---- a/drivers/net/ethernet/intel/e1000e/netdev.c -+++ b/drivers/net/ethernet/intel/e1000e/netdev.c -@@ -5939,8 +5939,8 @@ static void e1000_reset_task(struct work - * - * Returns the address of the device statistics structure. - **/ --struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+void e1000e_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct e1000_adapter *adapter = netdev_priv(netdev); - -@@ -5977,7 +5977,6 @@ struct rtnl_link_stats64 *e1000e_get_sta - /* Tx Dropped needs to be maintained elsewhere */ - - spin_unlock(&adapter->stats64_lock); -- return stats; - } - - /** ---- a/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c -+++ b/drivers/net/ethernet/intel/fm10k/fm10k_netdev.c -@@ -1128,8 +1128,8 @@ void fm10k_reset_rx_state(struct fm10k_i - * Returns 64bit statistics, for use in the ndo_get_stats64 callback. This - * function replaces fm10k_get_stats for kernels which support it. - */ --static struct rtnl_link_stats64 *fm10k_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void fm10k_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct fm10k_intfc *interface = netdev_priv(netdev); - struct fm10k_ring *ring; -@@ -1174,8 +1174,6 @@ static struct rtnl_link_stats64 *fm10k_g - - /* following stats updated by fm10k_service_task() */ - stats->rx_missed_errors = netdev->stats.rx_missed_errors; -- -- return stats; - } - - int fm10k_setup_tc(struct net_device *dev, u8 tc) ---- a/drivers/net/ethernet/intel/i40e/i40e.h -+++ b/drivers/net/ethernet/intel/i40e/i40e.h -@@ -797,9 +797,8 @@ static inline void i40e_irq_dynamic_enab - void i40e_irq_dynamic_disable_icr0(struct i40e_pf *pf); - void i40e_irq_dynamic_enable_icr0(struct i40e_pf *pf, bool clearpba); - #ifdef I40E_FCOE --struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( -- struct net_device *netdev, -- struct rtnl_link_stats64 *storage); -+void i40e_get_netdev_stats_struct(struct net_device *netdev, -+ struct rtnl_link_stats64 *storage); - int i40e_set_mac(struct net_device *netdev, void *p); - void i40e_set_rx_mode(struct net_device *netdev); - #endif ---- a/drivers/net/ethernet/intel/i40e/i40e_main.c -+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c -@@ -408,15 +408,11 @@ struct rtnl_link_stats64 *i40e_get_vsi_s - * Returns the address of the device statistics structure. - * The statistics are actually updated from the service task. - **/ --#ifdef I40E_FCOE --struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( -- struct net_device *netdev, -- struct rtnl_link_stats64 *stats) --#else --static struct rtnl_link_stats64 *i40e_get_netdev_stats_struct( -- struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+#ifndef I40E_FCOE -+static - #endif -+void i40e_get_netdev_stats_struct(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct i40e_netdev_priv *np = netdev_priv(netdev); - struct i40e_ring *tx_ring, *rx_ring; -@@ -425,10 +421,10 @@ static struct rtnl_link_stats64 *i40e_ge - int i; - - if (test_bit(__I40E_DOWN, &vsi->state)) -- return stats; -+ return; - - if (!vsi->tx_rings) -- return stats; -+ return; - - rcu_read_lock(); - for (i = 0; i < vsi->num_queue_pairs; i++) { -@@ -468,8 +464,6 @@ static struct rtnl_link_stats64 *i40e_ge - stats->rx_dropped = vsi_stats->rx_dropped; - stats->rx_crc_errors = vsi_stats->rx_crc_errors; - stats->rx_length_errors = vsi_stats->rx_length_errors; -- -- return stats; - } - - /** ---- a/drivers/net/ethernet/intel/igb/igb_main.c -+++ b/drivers/net/ethernet/intel/igb/igb_main.c -@@ -137,8 +137,8 @@ static void igb_update_phy_info(unsigned - static void igb_watchdog(unsigned long); - static void igb_watchdog_task(struct work_struct *); - static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *); --static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats); -+static void igb_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - static int igb_change_mtu(struct net_device *, int); - static int igb_set_mac(struct net_device *, void *); - static void igb_set_uta(struct igb_adapter *adapter, bool set); -@@ -5386,8 +5386,8 @@ static void igb_reset_task(struct work_s - * @netdev: network interface device structure - * @stats: rtnl_link_stats64 pointer - **/ --static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void igb_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct igb_adapter *adapter = netdev_priv(netdev); - -@@ -5395,8 +5395,6 @@ static struct rtnl_link_stats64 *igb_get - igb_update_stats(adapter, &adapter->stats64); - memcpy(stats, &adapter->stats64, sizeof(*stats)); - spin_unlock(&adapter->stats64_lock); -- -- return stats; - } - - /** ---- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c -+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c -@@ -8085,8 +8085,9 @@ static void ixgbe_netpoll(struct net_dev - } - - #endif --static struct rtnl_link_stats64 *ixgbe_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+ -+static void ixgbe_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct ixgbe_adapter *adapter = netdev_priv(netdev); - int i; -@@ -8124,13 +8125,13 @@ static struct rtnl_link_stats64 *ixgbe_g - } - } - rcu_read_unlock(); -+ - /* following stats updated by ixgbe_watchdog_task() */ - stats->multicast = netdev->stats.multicast; - stats->rx_errors = netdev->stats.rx_errors; - stats->rx_length_errors = netdev->stats.rx_length_errors; - stats->rx_crc_errors = netdev->stats.rx_crc_errors; - stats->rx_missed_errors = netdev->stats.rx_missed_errors; -- return stats; - } - - #ifdef CONFIG_IXGBE_DCB ---- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c -+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c -@@ -3880,8 +3880,8 @@ static void ixgbevf_shutdown(struct pci_ - ixgbevf_suspend(pdev, PMSG_SUSPEND); - } - --static struct rtnl_link_stats64 *ixgbevf_get_stats(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void ixgbevf_get_stats(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct ixgbevf_adapter *adapter = netdev_priv(netdev); - unsigned int start; -@@ -3914,8 +3914,6 @@ static struct rtnl_link_stats64 *ixgbevf - stats->tx_bytes += bytes; - stats->tx_packets += packets; - } -- -- return stats; - } - - #define IXGBEVF_MAX_MAC_HDR_LEN 127 ---- a/drivers/net/ethernet/marvell/mvneta.c -+++ b/drivers/net/ethernet/marvell/mvneta.c -@@ -636,7 +636,7 @@ static void mvneta_mib_counters_clear(st - } - - /* Get System Network Statistics */ --static struct rtnl_link_stats64 * -+static void - mvneta_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { -@@ -670,8 +670,6 @@ mvneta_get_stats64(struct net_device *de - stats->rx_dropped = dev->stats.rx_dropped; - - stats->tx_dropped = dev->stats.tx_dropped; -- -- return stats; - } - - /* Rx descriptors helper methods */ ---- a/drivers/net/ethernet/marvell/mvpp2.c -+++ b/drivers/net/ethernet/marvell/mvpp2.c -@@ -5761,7 +5761,7 @@ error: - return err; - } - --static struct rtnl_link_stats64 * -+static void - mvpp2_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct mvpp2_port *port = netdev_priv(dev); -@@ -5793,8 +5793,6 @@ mvpp2_get_stats64(struct net_device *dev - stats->rx_errors = dev->stats.rx_errors; - stats->rx_dropped = dev->stats.rx_dropped; - stats->tx_dropped = dev->stats.tx_dropped; -- -- return stats; - } - - static int mvpp2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ---- a/drivers/net/ethernet/marvell/sky2.c -+++ b/drivers/net/ethernet/marvell/sky2.c -@@ -3898,8 +3898,8 @@ static void sky2_set_multicast(struct ne - gma_write16(hw, port, GM_RX_CTRL, reg); - } - --static struct rtnl_link_stats64 *sky2_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void sky2_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct sky2_port *sky2 = netdev_priv(dev); - struct sky2_hw *hw = sky2->hw; -@@ -3939,8 +3939,6 @@ static struct rtnl_link_stats64 *sky2_ge - stats->rx_dropped = dev->stats.rx_dropped; - stats->rx_fifo_errors = dev->stats.rx_fifo_errors; - stats->tx_fifo_errors = dev->stats.tx_fifo_errors; -- -- return stats; - } - - /* Can have one global because blinking is controlled by ---- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c -+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c -@@ -462,8 +462,8 @@ static void mtk_stats_update(struct mtk_ - } - } - --static struct rtnl_link_stats64 *mtk_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *storage) -+static void mtk_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *storage) - { - struct mtk_mac *mac = netdev_priv(dev); - struct mtk_hw_stats *hw_stats = mac->hw_stats; -@@ -494,8 +494,6 @@ static struct rtnl_link_stats64 *mtk_get - storage->tx_errors = dev->stats.tx_errors; - storage->rx_dropped = dev->stats.rx_dropped; - storage->tx_dropped = dev->stats.tx_dropped; -- -- return storage; - } - - static inline int mtk_max_frag_size(int mtu) ---- a/drivers/net/ethernet/mellanox/mlx4/en_netdev.c -+++ b/drivers/net/ethernet/mellanox/mlx4/en_netdev.c -@@ -1316,7 +1316,7 @@ static void mlx4_en_tx_timeout(struct ne - } - - --static struct rtnl_link_stats64 * -+static void - mlx4_en_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct mlx4_en_priv *priv = netdev_priv(dev); -@@ -1324,8 +1324,6 @@ mlx4_en_get_stats64(struct net_device *d - spin_lock_bh(&priv->stats_lock); - netdev_stats_to_stats64(stats, &dev->stats); - spin_unlock_bh(&priv->stats_lock); -- -- return stats; - } - - static void mlx4_en_set_default_moderation(struct mlx4_en_priv *priv) ---- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c -@@ -2647,7 +2647,7 @@ mqprio: - return mlx5e_setup_tc(dev, tc->tc); - } - --struct rtnl_link_stats64 * -+static void - mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct mlx5e_priv *priv = netdev_priv(dev); -@@ -2681,7 +2681,6 @@ mlx5e_get_stats(struct net_device *dev, - stats->multicast = - VPORT_COUNTER_GET(vstats, received_eth_multicast.packets); - -- return stats; - } - - static void mlx5e_set_rx_mode(struct net_device *dev) ---- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c -@@ -949,15 +949,13 @@ out: - /* Return the stats from a cache that is updated periodically, - * as this function might get called in an atomic context. - */ --static struct rtnl_link_stats64 * -+static void - mlxsw_sp_port_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { - struct mlxsw_sp_port *mlxsw_sp_port = netdev_priv(dev); - - memcpy(stats, mlxsw_sp_port->hw_stats.cache, sizeof(*stats)); -- -- return stats; - } - - int mlxsw_sp_port_vlan_set(struct mlxsw_sp_port *mlxsw_sp_port, u16 vid_begin, ---- a/drivers/net/ethernet/mellanox/mlxsw/switchx2.c -+++ b/drivers/net/ethernet/mellanox/mlxsw/switchx2.c -@@ -351,7 +351,7 @@ static int mlxsw_sx_port_change_mtu(stru - return 0; - } - --static struct rtnl_link_stats64 * -+static void - mlxsw_sx_port_get_stats64(struct net_device *dev, - struct rtnl_link_stats64 *stats) - { -@@ -380,7 +380,6 @@ mlxsw_sx_port_get_stats64(struct net_dev - tx_dropped += p->tx_dropped; - } - stats->tx_dropped = tx_dropped; -- return stats; - } - - static const struct net_device_ops mlxsw_sx_port_netdev_ops = { ---- a/drivers/net/ethernet/myricom/myri10ge/myri10ge.c -+++ b/drivers/net/ethernet/myricom/myri10ge/myri10ge.c -@@ -378,8 +378,8 @@ static inline void put_be32(__be32 val, - __raw_writel((__force __u32) val, (__force void __iomem *)p); - } - --static struct rtnl_link_stats64 *myri10ge_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats); -+static void myri10ge_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - - static void set_fw_name(struct myri10ge_priv *mgp, char *name, bool allocated) - { -@@ -3119,8 +3119,8 @@ drop: - return NETDEV_TX_OK; - } - --static struct rtnl_link_stats64 *myri10ge_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void myri10ge_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - const struct myri10ge_priv *mgp = netdev_priv(dev); - const struct myri10ge_slice_netstats *slice_stats; -@@ -3135,7 +3135,6 @@ static struct rtnl_link_stats64 *myri10g - stats->rx_dropped += slice_stats->rx_dropped; - stats->tx_dropped += slice_stats->tx_dropped; - } -- return stats; - } - - static void myri10ge_set_multicast_list(struct net_device *dev) ---- a/drivers/net/ethernet/neterion/vxge/vxge-main.c -+++ b/drivers/net/ethernet/neterion/vxge/vxge-main.c -@@ -3116,7 +3116,7 @@ static int vxge_change_mtu(struct net_de - * @stats: pointer to struct rtnl_link_stats64 - * - */ --static struct rtnl_link_stats64 * -+static void - vxge_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *net_stats) - { - struct vxgedev *vdev = netdev_priv(dev); -@@ -3155,8 +3155,6 @@ vxge_get_stats64(struct net_device *dev, - net_stats->tx_bytes += bytes; - net_stats->tx_errors += txstats->tx_errors; - } -- -- return net_stats; - } - - static enum vxge_hw_status vxge_timestamp_config(struct __vxge_hw_device *devh) ---- a/drivers/net/ethernet/netronome/nfp/nfp_net_common.c -+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_common.c -@@ -2400,8 +2400,8 @@ int nfp_net_set_ring_size(struct nfp_net - return err; - } - --static struct rtnl_link_stats64 *nfp_net_stat64(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void nfp_net_stat64(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct nfp_net *nn = netdev_priv(netdev); - int r; -@@ -2431,8 +2431,6 @@ static struct rtnl_link_stats64 *nfp_net - stats->tx_bytes += data[1]; - stats->tx_errors += data[2]; - } -- -- return stats; - } - - static bool nfp_net_ebpf_capable(struct nfp_net *nn) ---- a/drivers/net/ethernet/nvidia/forcedeth.c -+++ b/drivers/net/ethernet/nvidia/forcedeth.c -@@ -1733,7 +1733,7 @@ static void nv_update_stats(struct net_d - * Called with read_lock(&dev_base_lock) held for read - - * only synchronized against unregister_netdevice. - */ --static struct rtnl_link_stats64* -+static void - nv_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *storage) - __acquires(&netdev_priv(dev)->hwstats_lock) - __releases(&netdev_priv(dev)->hwstats_lock) -@@ -1793,8 +1793,6 @@ nv_get_stats64(struct net_device *dev, s - - spin_unlock_bh(&np->hwstats_lock); - } -- -- return storage; - } - - /* ---- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -+++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c -@@ -90,8 +90,8 @@ static irqreturn_t netxen_msix_intr(int - - static void netxen_free_ip_list(struct netxen_adapter *, bool); - static void netxen_restore_indev_addr(struct net_device *dev, unsigned long); --static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats); -+static void netxen_nic_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - static int netxen_nic_set_mac(struct net_device *netdev, void *p); - - /* PCI Device ID Table */ -@@ -2295,8 +2295,8 @@ request_reset: - clear_bit(__NX_RESETTING, &adapter->state); - } - --static struct rtnl_link_stats64 *netxen_nic_get_stats(struct net_device *netdev, -- struct rtnl_link_stats64 *stats) -+static void netxen_nic_get_stats(struct net_device *netdev, -+ struct rtnl_link_stats64 *stats) - { - struct netxen_adapter *adapter = netdev_priv(netdev); - -@@ -2306,8 +2306,6 @@ static struct rtnl_link_stats64 *netxen_ - stats->tx_bytes = adapter->stats.txbytes; - stats->rx_dropped = adapter->stats.rxdropped; - stats->tx_dropped = adapter->stats.txdropped; -- -- return stats; - } - - static irqreturn_t netxen_intr(int irq, void *data) ---- a/drivers/net/ethernet/qlogic/qede/qede_main.c -+++ b/drivers/net/ethernet/qlogic/qede/qede_main.c -@@ -1803,9 +1803,8 @@ void qede_fill_by_demand_stats(struct qe - edev->stats.tx_mac_ctrl_frames = stats.tx_mac_ctrl_frames; - } - --static --struct rtnl_link_stats64 *qede_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void qede_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct qede_dev *edev = netdev_priv(dev); - -@@ -1835,8 +1834,6 @@ struct rtnl_link_stats64 *qede_get_stats - stats->collisions = edev->stats.tx_total_collisions; - stats->rx_crc_errors = edev->stats.rx_crc_errors; - stats->rx_frame_errors = edev->stats.rx_align_errors; -- -- return stats; - } - - #ifdef CONFIG_QED_SRIOV ---- a/drivers/net/ethernet/qualcomm/emac/emac.c -+++ b/drivers/net/ethernet/qualcomm/emac/emac.c -@@ -319,8 +319,8 @@ static int emac_ioctl(struct net_device - } - - /* Provide network statistics info for the interface */ --static struct rtnl_link_stats64 *emac_get_stats64(struct net_device *netdev, -- struct rtnl_link_stats64 *net_stats) -+static void emac_get_stats64(struct net_device *netdev, -+ struct rtnl_link_stats64 *net_stats) - { - struct emac_adapter *adpt = netdev_priv(netdev); - unsigned int addr = REG_MAC_RX_STATUS_BIN; -@@ -384,8 +384,6 @@ static struct rtnl_link_stats64 *emac_ge - net_stats->tx_window_errors = stats->tx_late_col; - - spin_unlock(&stats->lock); -- -- return net_stats; - } - - static const struct net_device_ops emac_netdev_ops = { ---- a/drivers/net/ethernet/realtek/8139too.c -+++ b/drivers/net/ethernet/realtek/8139too.c -@@ -653,9 +653,8 @@ static int rtl8139_poll(struct napi_stru - static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance); - static int rtl8139_close (struct net_device *dev); - static int netdev_ioctl (struct net_device *dev, struct ifreq *rq, int cmd); --static struct rtnl_link_stats64 *rtl8139_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 -- *stats); -+static void rtl8139_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - static void rtl8139_set_rx_mode (struct net_device *dev); - static void __set_rx_mode (struct net_device *dev); - static void rtl8139_hw_start (struct net_device *dev); -@@ -2521,7 +2520,7 @@ static int netdev_ioctl(struct net_devic - } - - --static struct rtnl_link_stats64 * -+static void - rtl8139_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct rtl8139_private *tp = netdev_priv(dev); -@@ -2549,8 +2548,6 @@ rtl8139_get_stats64(struct net_device *d - stats->tx_packets = tp->tx_stats.packets; - stats->tx_bytes = tp->tx_stats.bytes; - } while (u64_stats_fetch_retry_irq(&tp->tx_stats.syncp, start)); -- -- return stats; - } - - /* Set or clear the multicast filter for this adaptor. ---- a/drivers/net/ethernet/realtek/r8169.c -+++ b/drivers/net/ethernet/realtek/r8169.c -@@ -7751,7 +7751,7 @@ err_pm_runtime_put: - goto out; - } - --static struct rtnl_link_stats64 * -+static void - rtl8169_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct rtl8169_private *tp = netdev_priv(dev); -@@ -7805,8 +7805,6 @@ rtl8169_get_stats64(struct net_device *d - le16_to_cpu(tp->tc_offset.tx_aborted); - - pm_runtime_put_noidle(&pdev->dev); -- -- return stats; - } - - static void rtl8169_net_suspend(struct net_device *dev) ---- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c -+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c -@@ -1721,11 +1721,9 @@ static inline u64 sxgbe_get_stat64(void - * This function is a driver entry point whenever ifconfig command gets - * executed to see device statistics. Statistics are number of - * bytes sent or received, errors occurred etc. -- * Return value: -- * This function returns various statistical information of device. - */ --static struct rtnl_link_stats64 *sxgbe_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void sxgbe_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct sxgbe_priv_data *priv = netdev_priv(dev); - void __iomem *ioaddr = priv->ioaddr; -@@ -1776,8 +1774,6 @@ static struct rtnl_link_stats64 *sxgbe_g - SXGBE_MMC_TXUFLWHI_GBCNT_REG); - writel(0, ioaddr + SXGBE_MMC_CTL_REG); - spin_unlock(&priv->stats_lock); -- -- return stats; - } - - /* sxgbe_set_features - entry point to set offload features of the device. ---- a/drivers/net/ethernet/sfc/efx.c -+++ b/drivers/net/ethernet/sfc/efx.c -@@ -2232,16 +2232,14 @@ int efx_net_stop(struct net_device *net_ - } - - /* Context: process, dev_base_lock or RTNL held, non-blocking. */ --static struct rtnl_link_stats64 *efx_net_stats(struct net_device *net_dev, -- struct rtnl_link_stats64 *stats) -+static void efx_net_stats(struct net_device *net_dev, -+ struct rtnl_link_stats64 *stats) - { - struct efx_nic *efx = netdev_priv(net_dev); - - spin_lock_bh(&efx->stats_lock); - efx->type->update_stats(efx, NULL, stats); - spin_unlock_bh(&efx->stats_lock); -- -- return stats; - } - - /* Context: netif_tx_lock held, BHs disabled. */ ---- a/drivers/net/ethernet/sun/niu.c -+++ b/drivers/net/ethernet/sun/niu.c -@@ -6294,8 +6294,8 @@ no_rings: - stats->tx_errors = errors; - } - --static struct rtnl_link_stats64 *niu_get_stats(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void niu_get_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct niu *np = netdev_priv(dev); - -@@ -6303,8 +6303,6 @@ static struct rtnl_link_stats64 *niu_get - niu_get_rx_stats(np, stats); - niu_get_tx_stats(np, stats); - } -- -- return stats; - } - - static void niu_load_hash_xmac(struct niu *np, u16 *hash) ---- a/drivers/net/ethernet/synopsys/dwc_eth_qos.c -+++ b/drivers/net/ethernet/synopsys/dwc_eth_qos.c -@@ -2490,7 +2490,7 @@ static void dwceqos_read_mmc_counters(st - dwceqos_read(lp, DWC_MMC_RXPACKETCOUNT_GB); - } - --static struct rtnl_link_stats64* -+static void - dwceqos_get_stats64(struct net_device *ndev, struct rtnl_link_stats64 *s) - { - unsigned long flags; -@@ -2522,8 +2522,6 @@ dwceqos_get_stats64(struct net_device *n - else - s->tx_errors = hwstats->txunderflowerror + - hwstats->txcarriererror; -- -- return s; - } - - static void ---- a/drivers/net/ethernet/tile/tilepro.c -+++ b/drivers/net/ethernet/tile/tilepro.c -@@ -2047,8 +2047,8 @@ static int tile_net_ioctl(struct net_dev - * - * Returns the address of the device statistics structure. - */ --static struct rtnl_link_stats64 *tile_net_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void tile_net_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct tile_net_priv *priv = netdev_priv(dev); - u64 rx_packets = 0, tx_packets = 0; ---- a/drivers/net/ethernet/via/via-rhine.c -+++ b/drivers/net/ethernet/via/via-rhine.c -@@ -513,8 +513,8 @@ static irqreturn_t rhine_interrupt(int i - static void rhine_tx(struct net_device *dev); - static int rhine_rx(struct net_device *dev, int limit); - static void rhine_set_rx_mode(struct net_device *dev); --static struct rtnl_link_stats64 *rhine_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats); -+static void rhine_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); - static const struct ethtool_ops netdev_ethtool_ops; - static int rhine_close(struct net_device *dev); -@@ -2222,7 +2222,7 @@ out_unlock: - mutex_unlock(&rp->task_lock); - } - --static struct rtnl_link_stats64 * -+static void - rhine_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct rhine_private *rp = netdev_priv(dev); -@@ -2245,8 +2245,6 @@ rhine_get_stats64(struct net_device *dev - stats->tx_packets = rp->tx_stats.packets; - stats->tx_bytes = rp->tx_stats.bytes; - } while (u64_stats_fetch_retry_irq(&rp->tx_stats.syncp, start)); -- -- return stats; - } - - static void rhine_set_rx_mode(struct net_device *dev) ---- a/drivers/net/fjes/fjes_main.c -+++ b/drivers/net/fjes/fjes_main.c -@@ -56,8 +56,7 @@ static void fjes_raise_intr_rxdata_task( - static void fjes_tx_stall_task(struct work_struct *); - static void fjes_force_close_task(struct work_struct *); - static irqreturn_t fjes_intr(int, void*); --static struct rtnl_link_stats64 * --fjes_get_stats64(struct net_device *, struct rtnl_link_stats64 *); -+static void fjes_get_stats64(struct net_device *, struct rtnl_link_stats64 *); - static int fjes_change_mtu(struct net_device *, int); - static int fjes_vlan_rx_add_vid(struct net_device *, __be16 proto, u16); - static int fjes_vlan_rx_kill_vid(struct net_device *, __be16 proto, u16); -@@ -762,14 +761,12 @@ static void fjes_tx_retry(struct net_dev - netif_tx_wake_queue(queue); - } - --static struct rtnl_link_stats64 * -+static void - fjes_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats) - { - struct fjes_adapter *adapter = netdev_priv(netdev); - - memcpy(stats, &adapter->stats64, sizeof(struct rtnl_link_stats64)); -- -- return stats; - } - - static int fjes_change_mtu(struct net_device *netdev, int new_mtu) ---- a/drivers/net/hyperv/netvsc_drv.c -+++ b/drivers/net/hyperv/netvsc_drv.c -@@ -918,8 +918,8 @@ out: - return ret; - } - --static struct rtnl_link_stats64 *netvsc_get_stats64(struct net_device *net, -- struct rtnl_link_stats64 *t) -+static void netvsc_get_stats64(struct net_device *net, -+ struct rtnl_link_stats64 *t) - { - struct net_device_context *ndev_ctx = netdev_priv(net); - int cpu; -@@ -957,8 +957,6 @@ static struct rtnl_link_stats64 *netvsc_ - - t->rx_dropped = net->stats.rx_dropped; - t->rx_errors = net->stats.rx_errors; -- -- return t; - } - - static int netvsc_set_mac_addr(struct net_device *ndev, void *p) ---- a/drivers/net/ifb.c -+++ b/drivers/net/ifb.c -@@ -129,8 +129,8 @@ resched: - - } - --static struct rtnl_link_stats64 *ifb_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void ifb_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct ifb_dev_private *dp = netdev_priv(dev); - struct ifb_q_private *txp = dp->tx_private; -@@ -157,8 +157,6 @@ static struct rtnl_link_stats64 *ifb_sta - } - stats->rx_dropped = dev->stats.rx_dropped; - stats->tx_dropped = dev->stats.tx_dropped; -- -- return stats; - } - - static int ifb_dev_init(struct net_device *dev) ---- a/drivers/net/ipvlan/ipvlan_main.c -+++ b/drivers/net/ipvlan/ipvlan_main.c -@@ -296,8 +296,8 @@ static void ipvlan_set_multicast_mac_fil - dev_mc_sync(ipvlan->phy_dev, dev); - } - --static struct rtnl_link_stats64 *ipvlan_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *s) -+static void ipvlan_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *s) - { - struct ipvl_dev *ipvlan = netdev_priv(dev); - -@@ -334,7 +334,6 @@ static struct rtnl_link_stats64 *ipvlan_ - s->rx_dropped = rx_errs; - s->tx_dropped = tx_drps; - } -- return s; - } - - static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) ---- a/drivers/net/loopback.c -+++ b/drivers/net/loopback.c -@@ -97,8 +97,8 @@ static netdev_tx_t loopback_xmit(struct - return NETDEV_TX_OK; - } - --static struct rtnl_link_stats64 *loopback_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void loopback_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - u64 bytes = 0; - u64 packets = 0; -@@ -122,7 +122,6 @@ static struct rtnl_link_stats64 *loopbac - stats->tx_packets = packets; - stats->rx_bytes = bytes; - stats->tx_bytes = bytes; -- return stats; - } - - static u32 always_on(struct net_device *dev) ---- a/drivers/net/macsec.c -+++ b/drivers/net/macsec.c -@@ -2899,13 +2899,13 @@ static int macsec_change_mtu(struct net_ - return 0; - } - --static struct rtnl_link_stats64 *macsec_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *s) -+static void macsec_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *s) - { - int cpu; - - if (!dev->tstats) -- return s; -+ return; - - for_each_possible_cpu(cpu) { - struct pcpu_sw_netstats *stats; -@@ -2929,8 +2929,6 @@ static struct rtnl_link_stats64 *macsec_ - - s->rx_dropped = dev->stats.rx_dropped; - s->tx_dropped = dev->stats.tx_dropped; -- -- return s; - } - - static int macsec_get_iflink(const struct net_device *dev) ---- a/drivers/net/macvlan.c -+++ b/drivers/net/macvlan.c -@@ -857,8 +857,8 @@ static void macvlan_uninit(struct net_de - macvlan_port_destroy(port->dev); - } - --static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void macvlan_dev_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct macvlan_dev *vlan = netdev_priv(dev); - -@@ -895,7 +895,6 @@ static struct rtnl_link_stats64 *macvlan - stats->rx_dropped = rx_errors; - stats->tx_dropped = tx_dropped; - } -- return stats; - } - - static int macvlan_vlan_rx_add_vid(struct net_device *dev, ---- a/drivers/net/nlmon.c -+++ b/drivers/net/nlmon.c -@@ -76,7 +76,7 @@ static int nlmon_close(struct net_device - return netlink_remove_tap(&nlmon->nt); - } - --static struct rtnl_link_stats64 * -+static void - nlmon_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - int i; -@@ -104,8 +104,6 @@ nlmon_get_stats64(struct net_device *dev - - stats->rx_bytes = bytes; - stats->tx_bytes = 0; -- -- return stats; - } - - static u32 always_on(struct net_device *dev) ---- a/drivers/net/ppp/ppp_generic.c -+++ b/drivers/net/ppp/ppp_generic.c -@@ -1312,7 +1312,7 @@ ppp_net_ioctl(struct net_device *dev, st - return err; - } - --static struct rtnl_link_stats64* -+static void - ppp_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats64) - { - struct ppp *ppp = netdev_priv(dev); -@@ -1332,8 +1332,6 @@ ppp_get_stats64(struct net_device *dev, - stats64->rx_dropped = dev->stats.rx_dropped; - stats64->tx_dropped = dev->stats.tx_dropped; - stats64->rx_length_errors = dev->stats.rx_length_errors; -- -- return stats64; - } - - static int ppp_dev_init(struct net_device *dev) ---- a/drivers/net/slip/slip.c -+++ b/drivers/net/slip/slip.c -@@ -571,7 +571,7 @@ static int sl_change_mtu(struct net_devi - - /* Netdevice get statistics request */ - --static struct rtnl_link_stats64 * -+static void - sl_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct net_device_stats *devstats = &dev->stats; -@@ -602,7 +602,6 @@ sl_get_stats64(struct net_device *dev, s - stats->collisions += comp->sls_o_misses; - } - #endif -- return stats; - } - - /* Netdevice register callback */ ---- a/drivers/net/team/team.c -+++ b/drivers/net/team/team.c -@@ -1798,7 +1798,7 @@ unwind: - return err; - } - --static struct rtnl_link_stats64 * -+static void - team_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - struct team *team = netdev_priv(dev); -@@ -1835,7 +1835,6 @@ team_get_stats64(struct net_device *dev, - stats->rx_dropped = rx_dropped; - stats->tx_dropped = tx_dropped; - stats->rx_nohandler = rx_nohandler; -- return stats; - } - - static int team_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid) ---- a/drivers/net/tun.c -+++ b/drivers/net/tun.c -@@ -983,7 +983,7 @@ static void tun_set_headroom(struct net_ - tun->align = new_hr; - } - --static struct rtnl_link_stats64 * -+static void - tun_net_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - u32 rx_dropped = 0, tx_dropped = 0, rx_frame_errors = 0; -@@ -1017,7 +1017,6 @@ tun_net_get_stats64(struct net_device *d - stats->rx_dropped = rx_dropped; - stats->rx_frame_errors = rx_frame_errors; - stats->tx_dropped = tx_dropped; -- return stats; - } - - static const struct net_device_ops tun_netdev_ops = { ---- a/drivers/net/veth.c -+++ b/drivers/net/veth.c -@@ -161,8 +161,8 @@ static u64 veth_stats_one(struct pcpu_vs - return atomic64_read(&priv->dropped); - } - --static struct rtnl_link_stats64 *veth_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *tot) -+static void veth_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *tot) - { - struct veth_priv *priv = netdev_priv(dev); - struct net_device *peer; -@@ -180,8 +180,6 @@ static struct rtnl_link_stats64 *veth_ge - tot->rx_packets = one.packets; - } - rcu_read_unlock(); -- -- return tot; - } - - /* fake multicast ability */ ---- a/drivers/net/virtio_net.c -+++ b/drivers/net/virtio_net.c -@@ -1017,8 +1017,8 @@ out: - return ret; - } - --static struct rtnl_link_stats64 *virtnet_stats(struct net_device *dev, -- struct rtnl_link_stats64 *tot) -+static void virtnet_stats(struct net_device *dev, -+ struct rtnl_link_stats64 *tot) - { - struct virtnet_info *vi = netdev_priv(dev); - int cpu; -@@ -1051,8 +1051,6 @@ static struct rtnl_link_stats64 *virtnet - tot->rx_dropped = dev->stats.rx_dropped; - tot->rx_length_errors = dev->stats.rx_length_errors; - tot->rx_frame_errors = dev->stats.rx_frame_errors; -- -- return tot; - } - - #ifdef CONFIG_NET_POLL_CONTROLLER ---- a/drivers/net/vmxnet3/vmxnet3_ethtool.c -+++ b/drivers/net/vmxnet3/vmxnet3_ethtool.c -@@ -113,7 +113,7 @@ vmxnet3_global_stats[] = { - }; - - --struct rtnl_link_stats64 * -+void - vmxnet3_get_stats64(struct net_device *netdev, - struct rtnl_link_stats64 *stats) - { -@@ -160,8 +160,6 @@ vmxnet3_get_stats64(struct net_device *n - stats->rx_dropped += drvRxStats->drop_total; - stats->multicast += devRxStats->mcastPktsRxOK; - } -- -- return stats; - } - - static int ---- a/drivers/net/vmxnet3/vmxnet3_int.h -+++ b/drivers/net/vmxnet3/vmxnet3_int.h -@@ -466,8 +466,8 @@ vmxnet3_create_queues(struct vmxnet3_ada - - void vmxnet3_set_ethtool_ops(struct net_device *netdev); - --struct rtnl_link_stats64 * --vmxnet3_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats); -+void vmxnet3_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats); - - extern char vmxnet3_driver_name[]; - #endif ---- a/drivers/net/vrf.c -+++ b/drivers/net/vrf.c -@@ -79,8 +79,8 @@ static void vrf_tx_error(struct net_devi - kfree_skb(skb); - } - --static struct rtnl_link_stats64 *vrf_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void vrf_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - int i; - -@@ -104,7 +104,6 @@ static struct rtnl_link_stats64 *vrf_get - stats->rx_bytes += rbytes; - stats->rx_packets += rpkts; - } -- return stats; - } - - /* Local traffic destined to local address. Reinsert the packet to rx ---- a/drivers/net/xen-netfront.c -+++ b/drivers/net/xen-netfront.c -@@ -1081,8 +1081,8 @@ static int xennet_change_mtu(struct net_ - return 0; - } - --static struct rtnl_link_stats64 *xennet_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *tot) -+static void xennet_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *tot) - { - struct netfront_info *np = netdev_priv(dev); - int cpu; -@@ -1113,8 +1113,6 @@ static struct rtnl_link_stats64 *xennet_ - - tot->rx_errors = dev->stats.rx_errors; - tot->tx_dropped = dev->stats.tx_dropped; -- -- return tot; - } - - static void xennet_release_tx_bufs(struct netfront_queue *queue) ---- a/drivers/staging/netlogic/xlr_net.c -+++ b/drivers/staging/netlogic/xlr_net.c -@@ -395,14 +395,6 @@ static void xlr_stats(struct net_device - TX_DROP_FRAME_COUNTER); - } - --static struct rtnl_link_stats64 *xlr_get_stats64(struct net_device *ndev, -- struct rtnl_link_stats64 *stats -- ) --{ -- xlr_stats(ndev, stats); -- return stats; --} -- - static const struct net_device_ops xlr_netdev_ops = { - .ndo_open = xlr_net_open, - .ndo_stop = xlr_net_stop, -@@ -410,7 +402,7 @@ static const struct net_device_ops xlr_n - .ndo_select_queue = xlr_net_select_queue, - .ndo_set_mac_address = xlr_net_set_mac_addr, - .ndo_set_rx_mode = xlr_set_rx_mode, -- .ndo_get_stats64 = xlr_get_stats64, -+ .ndo_get_stats64 = xlr_stats, - }; - - /* ---- a/include/linux/device.h -+++ b/include/linux/device.h -@@ -688,6 +688,25 @@ void __iomem *devm_ioremap_resource(stru - int devm_add_action(struct device *dev, void (*action)(void *), void *data); - void devm_remove_action(struct device *dev, void (*action)(void *), void *data); - -+/** -+ * devm_alloc_percpu - Resource-managed alloc_percpu -+ * @dev: Device to allocate per-cpu memory for -+ * @type: Type to allocate per-cpu memory for -+ * -+ * Managed alloc_percpu. Per-cpu memory allocated with this function is -+ * automatically freed on driver detach. -+ * -+ * RETURNS: -+ * Pointer to allocated memory on success, NULL on failure. -+ */ -+#define devm_alloc_percpu(dev, type) \ -+ ((typeof(type) __percpu *)__devm_alloc_percpu((dev), sizeof(type), \ -+ __alignof__(type))) -+ -+void __percpu *__devm_alloc_percpu(struct device *dev, size_t size, -+ size_t align); -+void devm_free_percpu(struct device *dev, void __percpu *pdata); -+ - static inline int devm_add_action_or_reset(struct device *dev, - void (*action)(void *), void *data) - { ---- /dev/null -+++ b/include/linux/fsl/svr.h -@@ -0,0 +1,97 @@ -+/* -+ * MPC85xx cpu type detection -+ * -+ * Copyright 2011-2012 Freescale Semiconductor, Inc. -+ * -+ * This is free software; you can redistribute it 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. -+ */ -+ -+#ifndef FSL_SVR_H -+#define FSL_SVR_H -+ -+#define SVR_REV(svr) ((svr) & 0xFF) /* SOC design resision */ -+#define SVR_MAJ(svr) (((svr) >> 4) & 0xF) /* Major revision field*/ -+#define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/ -+ -+/* Some parts define SVR[0:23] as the SOC version */ -+#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC Version fields */ -+ -+#define SVR_8533 0x803400 -+#define SVR_8535 0x803701 -+#define SVR_8536 0x803700 -+#define SVR_8540 0x803000 -+#define SVR_8541 0x807200 -+#define SVR_8543 0x803200 -+#define SVR_8544 0x803401 -+#define SVR_8545 0x803102 -+#define SVR_8547 0x803101 -+#define SVR_8548 0x803100 -+#define SVR_8555 0x807100 -+#define SVR_8560 0x807000 -+#define SVR_8567 0x807501 -+#define SVR_8568 0x807500 -+#define SVR_8569 0x808000 -+#define SVR_8572 0x80E000 -+#define SVR_P1010 0x80F100 -+#define SVR_P1011 0x80E500 -+#define SVR_P1012 0x80E501 -+#define SVR_P1013 0x80E700 -+#define SVR_P1014 0x80F101 -+#define SVR_P1017 0x80F700 -+#define SVR_P1020 0x80E400 -+#define SVR_P1021 0x80E401 -+#define SVR_P1022 0x80E600 -+#define SVR_P1023 0x80F600 -+#define SVR_P1024 0x80E402 -+#define SVR_P1025 0x80E403 -+#define SVR_P2010 0x80E300 -+#define SVR_P2020 0x80E200 -+#define SVR_P2040 0x821000 -+#define SVR_P2041 0x821001 -+#define SVR_P3041 0x821103 -+#define SVR_P4040 0x820100 -+#define SVR_P4080 0x820000 -+#define SVR_P5010 0x822100 -+#define SVR_P5020 0x822000 -+#define SVR_P5021 0X820500 -+#define SVR_P5040 0x820400 -+#define SVR_T4240 0x824000 -+#define SVR_T4120 0x824001 -+#define SVR_T4160 0x824100 -+#define SVR_T4080 0x824102 -+#define SVR_C291 0x850000 -+#define SVR_C292 0x850020 -+#define SVR_C293 0x850030 -+#define SVR_B4860 0X868000 -+#define SVR_G4860 0x868001 -+#define SVR_G4060 0x868003 -+#define SVR_B4440 0x868100 -+#define SVR_G4440 0x868101 -+#define SVR_B4420 0x868102 -+#define SVR_B4220 0x868103 -+#define SVR_T1040 0x852000 -+#define SVR_T1041 0x852001 -+#define SVR_T1042 0x852002 -+#define SVR_T1020 0x852100 -+#define SVR_T1021 0x852101 -+#define SVR_T1022 0x852102 -+#define SVR_T1023 0x854100 -+#define SVR_T1024 0x854000 -+#define SVR_T2080 0x853000 -+#define SVR_T2081 0x853100 -+ -+#define SVR_8610 0x80A000 -+#define SVR_8641 0x809000 -+#define SVR_8641D 0x809001 -+ -+#define SVR_9130 0x860001 -+#define SVR_9131 0x860000 -+#define SVR_9132 0x861000 -+#define SVR_9232 0x861400 -+ -+#define SVR_Unknown 0xFFFFFF -+ -+#endif ---- a/include/linux/fsl_devices.h -+++ b/include/linux/fsl_devices.h -@@ -99,7 +99,10 @@ struct fsl_usb2_platform_data { - unsigned suspended:1; - unsigned already_suspended:1; - unsigned has_fsl_erratum_a007792:1; -+ unsigned has_fsl_erratum_14:1; - unsigned has_fsl_erratum_a005275:1; -+ unsigned has_fsl_erratum_a006918:1; -+ unsigned has_fsl_erratum_a005697:1; - unsigned check_phy_clk_valid:1; - - /* register save area for suspend/resume */ ---- a/include/linux/netdev_features.h -+++ b/include/linux/netdev_features.h -@@ -74,6 +74,7 @@ enum { - NETIF_F_BUSY_POLL_BIT, /* Busy poll */ - - NETIF_F_HW_TC_BIT, /* Offload TC infrastructure */ -+ NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */ - - /* - * Add your fresh new feature above and remember to update -@@ -136,6 +137,7 @@ enum { - #define NETIF_F_HW_L2FW_DOFFLOAD __NETIF_F(HW_L2FW_DOFFLOAD) - #define NETIF_F_BUSY_POLL __NETIF_F(BUSY_POLL) - #define NETIF_F_HW_TC __NETIF_F(HW_TC) -+#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ) - - #define for_each_netdev_feature(mask_addr, bit) \ - for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT) ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -916,8 +916,8 @@ struct netdev_xdp { - * Callback used when the transmitter has not made any progress - * for dev->watchdog ticks. - * -- * struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev, -- * struct rtnl_link_stats64 *storage); -+ * void (*ndo_get_stats64)(struct net_device *dev, -+ * struct rtnl_link_stats64 *storage); - * struct net_device_stats* (*ndo_get_stats)(struct net_device *dev); - * Called when a user wants to get the network device usage - * statistics. Drivers must do one of the following: -@@ -1165,8 +1165,8 @@ struct net_device_ops { - struct neigh_parms *); - void (*ndo_tx_timeout) (struct net_device *dev); - -- struct rtnl_link_stats64* (*ndo_get_stats64)(struct net_device *dev, -- struct rtnl_link_stats64 *storage); -+ void (*ndo_get_stats64)(struct net_device *dev, -+ struct rtnl_link_stats64 *storage); - bool (*ndo_has_offload_stats)(int attr_id); - int (*ndo_get_offload_stats)(int attr_id, - const struct net_device *dev, -@@ -1509,6 +1509,8 @@ enum netdev_priv_flags { - * @if_port: Selectable AUI, TP, ... - * @dma: DMA channel - * @mtu: Interface MTU value -+ * @min_mtu: Interface Minimum MTU value -+ * @max_mtu: Interface Maximum MTU value - * @type: Interface hardware type - * @hard_header_len: Maximum hardware header length. - * @min_header_len: Minimum hardware header length -@@ -1735,6 +1737,8 @@ struct net_device { - unsigned char dma; - - unsigned int mtu; -+ unsigned int min_mtu; -+ unsigned int max_mtu; - unsigned short type; - unsigned short hard_header_len; - unsigned short min_header_len; ---- a/include/linux/skbuff.h -+++ b/include/linux/skbuff.h -@@ -903,6 +903,7 @@ void kfree_skb(struct sk_buff *skb); - void kfree_skb_list(struct sk_buff *segs); - void skb_tx_error(struct sk_buff *skb); - void consume_skb(struct sk_buff *skb); -+void skb_recycle(struct sk_buff *skb); - void __kfree_skb(struct sk_buff *skb); - extern struct kmem_cache *skbuff_head_cache; - -@@ -3057,6 +3058,7 @@ static inline void skb_free_datagram_loc - } - int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); - int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); -+void copy_skb_header(struct sk_buff *new, const struct sk_buff *old); - int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len); - __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, - int len, __wsum csum); ---- a/include/linux/sys_soc.h -+++ b/include/linux/sys_soc.h -@@ -13,6 +13,7 @@ struct soc_device_attribute { - const char *family; - const char *revision; - const char *soc_id; -+ const void *data; - }; - - /** -@@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_de - */ - struct device *soc_device_to_device(struct soc_device *soc); - -+const struct soc_device_attribute *soc_device_match( -+ const struct soc_device_attribute *matches); - #endif /* __SOC_BUS_H */ ---- a/include/net/ip_tunnels.h -+++ b/include/net/ip_tunnels.h -@@ -261,8 +261,8 @@ int ip_tunnel_ioctl(struct net_device *d - int __ip_tunnel_change_mtu(struct net_device *dev, int new_mtu, bool strict); - int ip_tunnel_change_mtu(struct net_device *dev, int new_mtu); - --struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *tot); -+void ip_tunnel_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *tot); - struct ip_tunnel *ip_tunnel_lookup(struct ip_tunnel_net *itn, - int link, __be16 flags, - __be32 remote, __be32 local, ---- a/include/uapi/linux/if_ether.h -+++ b/include/uapi/linux/if_ether.h -@@ -35,6 +35,7 @@ - #define ETH_DATA_LEN 1500 /* Max. octets in payload */ - #define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ - #define ETH_FCS_LEN 4 /* Octets in the FCS */ -+#define ETH_MIN_MTU 68 /* Min IPv4 MTU per RFC791 */ - - /* - * These are the defined Ethernet Protocol ID's. ---- a/net/8021q/vlan_dev.c -+++ b/net/8021q/vlan_dev.c -@@ -671,7 +671,8 @@ static int vlan_ethtool_get_ts_info(stru - return 0; - } - --static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) -+static void vlan_dev_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct vlan_pcpu_stats *p; - u32 rx_errors = 0, tx_dropped = 0; -@@ -702,8 +703,6 @@ static struct rtnl_link_stats64 *vlan_de - } - stats->rx_errors = rx_errors; - stats->tx_dropped = tx_dropped; -- -- return stats; - } - - #ifdef CONFIG_NET_POLL_CONTROLLER ---- a/net/bridge/br_device.c -+++ b/net/bridge/br_device.c -@@ -156,8 +156,8 @@ static int br_dev_stop(struct net_device - return 0; - } - --static struct rtnl_link_stats64 *br_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void br_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct net_bridge *br = netdev_priv(dev); - struct pcpu_sw_netstats tmp, sum = { 0 }; -@@ -181,8 +181,6 @@ static struct rtnl_link_stats64 *br_get_ - stats->tx_packets = sum.tx_packets; - stats->rx_bytes = sum.rx_bytes; - stats->rx_packets = sum.rx_packets; -- -- return stats; - } - - static int br_change_mtu(struct net_device *dev, int new_mtu) ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -6603,9 +6603,18 @@ int dev_set_mtu(struct net_device *dev, - if (new_mtu == dev->mtu) - return 0; - -- /* MTU must be positive. */ -- if (new_mtu < 0) -+ /* MTU must be positive, and in range */ -+ if (new_mtu < 0 || new_mtu < dev->min_mtu) { -+ net_err_ratelimited("%s: Invalid MTU %d requested, hw min %d\n", -+ dev->name, new_mtu, dev->min_mtu); - return -EINVAL; -+ } -+ -+ if (dev->max_mtu > 0 && new_mtu > dev->max_mtu) { -+ net_err_ratelimited("%s: Invalid MTU %d requested, hw max %d\n", -+ dev->name, new_mtu, dev->min_mtu); -+ return -EINVAL; -+ } - - if (!netif_device_present(dev)) - return -ENODEV; ---- a/net/core/skbuff.c -+++ b/net/core/skbuff.c -@@ -842,6 +842,32 @@ void napi_consume_skb(struct sk_buff *sk - } - EXPORT_SYMBOL(napi_consume_skb); - -+/** -+ * skb_recycle - clean up an skb for reuse -+ * @skb: buffer -+ * -+ * Recycles the skb to be reused as a receive buffer. This -+ * function does any necessary reference count dropping, and -+ * cleans up the skbuff as if it just came from __alloc_skb(). -+ */ -+void skb_recycle(struct sk_buff *skb) -+{ -+ struct skb_shared_info *shinfo; -+ u8 head_frag = skb->head_frag; -+ -+ skb_release_head_state(skb); -+ -+ shinfo = skb_shinfo(skb); -+ memset(shinfo, 0, offsetof(struct skb_shared_info, dataref)); -+ atomic_set(&shinfo->dataref, 1); -+ -+ memset(skb, 0, offsetof(struct sk_buff, tail)); -+ skb->data = skb->head + NET_SKB_PAD; -+ skb->head_frag = head_frag; -+ skb_reset_tail_pointer(skb); -+} -+EXPORT_SYMBOL(skb_recycle); -+ - /* Make sure a field is enclosed inside headers_start/headers_end section */ - #define CHECK_SKB_FIELD(field) \ - BUILD_BUG_ON(offsetof(struct sk_buff, field) < \ -@@ -1073,7 +1099,7 @@ static void skb_headers_offset_update(st - skb->inner_mac_header += off; - } - --static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) -+void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) - { - __copy_skb_header(new, old); - -@@ -1081,6 +1107,7 @@ static void copy_skb_header(struct sk_bu - skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; - skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; - } -+EXPORT_SYMBOL(copy_skb_header); - - static inline int skb_alloc_rx_flag(const struct sk_buff *skb) - { ---- a/net/ipv4/ip_tunnel_core.c -+++ b/net/ipv4/ip_tunnel_core.c -@@ -188,8 +188,8 @@ int iptunnel_handle_offloads(struct sk_b - EXPORT_SYMBOL_GPL(iptunnel_handle_offloads); - - /* Often modified stats are per cpu, other are shared (netdev->stats) */ --struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *tot) -+void ip_tunnel_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *tot) - { - int i; - -@@ -214,8 +214,6 @@ struct rtnl_link_stats64 *ip_tunnel_get_ - tot->rx_bytes += rx_bytes; - tot->tx_bytes += tx_bytes; - } -- -- return tot; - } - EXPORT_SYMBOL_GPL(ip_tunnel_get_stats64); - ---- a/net/l2tp/l2tp_eth.c -+++ b/net/l2tp/l2tp_eth.c -@@ -106,8 +106,8 @@ static int l2tp_eth_dev_xmit(struct sk_b - return NETDEV_TX_OK; - } - --static struct rtnl_link_stats64 *l2tp_eth_get_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void l2tp_eth_get_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct l2tp_eth *priv = netdev_priv(dev); - -@@ -117,10 +117,8 @@ static struct rtnl_link_stats64 *l2tp_et - stats->rx_bytes = atomic_long_read(&priv->rx_bytes); - stats->rx_packets = atomic_long_read(&priv->rx_packets); - stats->rx_errors = atomic_long_read(&priv->rx_errors); -- return stats; - } - -- - static const struct net_device_ops l2tp_eth_netdev_ops = { - .ndo_init = l2tp_eth_dev_init, - .ndo_uninit = l2tp_eth_dev_uninit, ---- a/net/mac80211/iface.c -+++ b/net/mac80211/iface.c -@@ -1146,7 +1146,7 @@ static u16 ieee80211_netdev_select_queue - return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb); - } - --static struct rtnl_link_stats64 * -+static void - ieee80211_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - int i; -@@ -1171,8 +1171,6 @@ ieee80211_get_stats64(struct net_device - stats->rx_bytes += rx_bytes; - stats->tx_bytes += tx_bytes; - } -- -- return stats; - } - - static const struct net_device_ops ieee80211_dataif_ops = { ---- a/net/openvswitch/vport-internal_dev.c -+++ b/net/openvswitch/vport-internal_dev.c -@@ -106,7 +106,7 @@ static void internal_dev_destructor(stru - free_netdev(dev); - } - --static struct rtnl_link_stats64 * -+static void - internal_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats) - { - int i; -@@ -134,8 +134,6 @@ internal_get_stats(struct net_device *de - stats->tx_bytes += local_stats.tx_bytes; - stats->tx_packets += local_stats.tx_packets; - } -- -- return stats; - } - - static void internal_set_rx_headroom(struct net_device *dev, int new_hr) ---- a/net/sched/sch_generic.c -+++ b/net/sched/sch_generic.c -@@ -309,6 +309,13 @@ static void dev_watchdog(unsigned long a - txq->trans_timeout++; - break; - } -+ -+ /* Devices with HW_ACCEL_MQ have multiple txqs -+ * but update only the first one's transmission -+ * timestamp so avoid checking the rest. -+ */ -+ if (dev->features & NETIF_F_HW_ACCEL_MQ) -+ break; - } - - if (some_queue_timedout) { ---- a/net/sched/sch_teql.c -+++ b/net/sched/sch_teql.c -@@ -401,8 +401,8 @@ static int teql_master_close(struct net_ - return 0; - } - --static struct rtnl_link_stats64 *teql_master_stats64(struct net_device *dev, -- struct rtnl_link_stats64 *stats) -+static void teql_master_stats64(struct net_device *dev, -+ struct rtnl_link_stats64 *stats) - { - struct teql_master *m = netdev_priv(dev); - -@@ -410,7 +410,6 @@ static struct rtnl_link_stats64 *teql_ma - stats->tx_bytes = m->tx_bytes; - stats->tx_errors = m->tx_errors; - stats->tx_dropped = m->tx_dropped; -- return stats; - } - - static int teql_master_mtu(struct net_device *dev, int new_mtu) diff --git a/target/linux/layerscape/patches-4.9/602-linux-core-export-copy_skb_header-function.patch b/target/linux/layerscape/patches-4.9/602-linux-core-export-copy_skb_header-function.patch new file mode 100644 index 0000000000..1244675a70 --- /dev/null +++ b/target/linux/layerscape/patches-4.9/602-linux-core-export-copy_skb_header-function.patch @@ -0,0 +1,47 @@ +From eae03a91605fd7dccb1de11053efee87db398df3 Mon Sep 17 00:00:00 2001 +From: Zhang Ying-22455 +Date: Fri, 1 Sep 2017 14:56:01 +0800 +Subject: [PATCH] linux/core: export copy_skb_header() function + +Signed-off-by: Camelia Groza camelia.groza@nxp.com +--- + include/linux/skbuff.h | 1 + + net/core/skbuff.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h +index a52a6fb0ac2e..a0385f9bdd4e 100644 +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -3063,6 +3063,7 @@ static inline void skb_free_datagram_locked(struct sock *sk, + } + int skb_kill_datagram(struct sock *sk, struct sk_buff *skb, unsigned int flags); + int skb_copy_bits(const struct sk_buff *skb, int offset, void *to, int len); ++void copy_skb_header(struct sk_buff *new, const struct sk_buff *old); + int skb_store_bits(struct sk_buff *skb, int offset, const void *from, int len); + __wsum skb_copy_and_csum_bits(const struct sk_buff *skb, int offset, u8 *to, + int len, __wsum csum); +diff --git a/net/core/skbuff.c b/net/core/skbuff.c +index ab1038083df2..2684c49b9805 100644 +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -1082,7 +1082,7 @@ static void skb_headers_offset_update(struct sk_buff *skb, int off) + skb->inner_mac_header += off; + } + +-static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) ++void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) + { + __copy_skb_header(new, old); + +@@ -1090,6 +1090,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old) + skb_shinfo(new)->gso_segs = skb_shinfo(old)->gso_segs; + skb_shinfo(new)->gso_type = skb_shinfo(old)->gso_type; + } ++EXPORT_SYMBOL(copy_skb_header); + + static inline int skb_alloc_rx_flag(const struct sk_buff *skb) + { +-- +2.11.1 + diff --git a/target/linux/layerscape/patches-4.9/603-sdk_dpaa-update-the-xmit-timestamp-to-avoid-watchdog.patch b/target/linux/layerscape/patches-4.9/603-sdk_dpaa-update-the-xmit-timestamp-to-avoid-watchdog.patch new file mode 100644 index 0000000000..a9a45962c5 --- /dev/null +++ b/target/linux/layerscape/patches-4.9/603-sdk_dpaa-update-the-xmit-timestamp-to-avoid-watchdog.patch @@ -0,0 +1,60 @@ +From 3d33284eb087deb7f62639a2d2c03b9d0a3eeb34 Mon Sep 17 00:00:00 2001 +From: Camelia Groza +Date: Mon, 11 Sep 2017 17:20:41 +0800 +Subject: [PATCH] sdk_dpaa: update the xmit timestamp to avoid watchdog + timeouts + +[core-linux part] + +Update txq0's trans_start in order to prevent the netdev watchdog from +triggering too quickly. Since we set the LLTX flag, the stack won't update +the jiffies for other tx queues. Prevent the watchdog from checking the +other tx queues by adding the NETIF_HW_ACCEL_MQ flag. + +Signed-off-by: Camelia Groza +--- + include/linux/netdev_features.h | 2 ++ + net/sched/sch_generic.c | 7 +++++++ + 2 files changed, 9 insertions(+) + +diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h +index 9c6c8ef2e9e7..90b4107ebeff 100644 +--- a/include/linux/netdev_features.h ++++ b/include/linux/netdev_features.h +@@ -74,6 +74,7 @@ enum { + NETIF_F_BUSY_POLL_BIT, /* Busy poll */ + + NETIF_F_HW_TC_BIT, /* Offload TC infrastructure */ ++ NETIF_F_HW_ACCEL_MQ_BIT, /* Hardware-accelerated multiqueue */ + + /* + * Add your fresh new feature above and remember to update +@@ -136,6 +137,7 @@ enum { + #define NETIF_F_HW_L2FW_DOFFLOAD __NETIF_F(HW_L2FW_DOFFLOAD) + #define NETIF_F_BUSY_POLL __NETIF_F(BUSY_POLL) + #define NETIF_F_HW_TC __NETIF_F(HW_TC) ++#define NETIF_F_HW_ACCEL_MQ __NETIF_F(HW_ACCEL_MQ) + + #define for_each_netdev_feature(mask_addr, bit) \ + for_each_set_bit(bit, (unsigned long *)mask_addr, NETDEV_FEATURE_COUNT) +diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c +index 6cfb6e9038c2..3fab16cb7c58 100644 +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -309,6 +309,13 @@ static void dev_watchdog(unsigned long arg) + txq->trans_timeout++; + break; + } ++ ++ /* Devices with HW_ACCEL_MQ have multiple txqs ++ * but update only the first one's transmission ++ * timestamp so avoid checking the rest. ++ */ ++ if (dev->features & NETIF_F_HW_ACCEL_MQ) ++ break; + } + + if (some_queue_timedout) { +-- +2.11.1 + diff --git a/target/linux/layerscape/patches-4.9/706-fsl-dpaa-use-4-9-ndo-get-stats64.patch b/target/linux/layerscape/patches-4.9/706-fsl-dpaa-use-4-9-ndo-get-stats64.patch new file mode 100644 index 0000000000..4fa29b2909 --- /dev/null +++ b/target/linux/layerscape/patches-4.9/706-fsl-dpaa-use-4-9-ndo-get-stats64.patch @@ -0,0 +1,112 @@ +From: Mathew McBride +Date: Tue, 24 Oct 2017 11:30:00 +1100 +Subject: [PATCH] dpaa: backport use of 4.9 ndo_get_stats64 + +This patch changes the declarations of ndo_get_stats64 handlers +to the previous struct rtnl_link_stats64 * return type instead of +the mainline void return. + +Suggested-by: Adrien Gallouët +Signed-off-by: Mathew McBride + +--- + drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 5 +++-- + drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h | 4 ++-- + drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 3 ++- + drivers/staging/fsl-dpaa2/ethsw/switch.c | 4 ++-- + drivers/staging/fsl-dpaa2/evb/evb.c | 4 ++-- + 5 files changed, 11 insertions(+), 9 deletions(-) + +--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c ++++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c +@@ -1296,7 +1296,7 @@ static int dpaa2_eth_set_addr(struct net + /** Fill in counters maintained by the GPP driver. These may be different from + * the hardware counters obtained by ethtool. + */ +-static void dpaa2_eth_get_stats(struct net_device *net_dev, ++static struct rtnl_link_stats64 *dpaa2_eth_get_stats(struct net_device *net_dev, + struct rtnl_link_stats64 *stats) + { + struct dpaa2_eth_priv *priv = netdev_priv(net_dev); +@@ -1312,6 +1312,7 @@ static void dpaa2_eth_get_stats(struct n + for (j = 0; j < num; j++) + netstats[j] += cpustats[j]; + } ++ return stats; + } + + static int dpaa2_eth_change_mtu(struct net_device *net_dev, int mtu) +--- a/drivers/staging/fsl-dpaa2/ethsw/switch.c ++++ b/drivers/staging/fsl-dpaa2/ethsw/switch.c +@@ -1094,7 +1094,7 @@ static int ethsw_port_fdb_del(struct ndm + return 0; + } + +-void ethsw_port_get_stats(struct net_device *netdev, ++struct rtnl_link_stats64 *ethsw_port_get_stats(struct net_device *netdev, + struct rtnl_link_stats64 *storage) + { + struct ethsw_port_priv *port_priv = netdev_priv(netdev); +@@ -1154,7 +1154,7 @@ void ethsw_port_get_stats(struct net_dev + if (err) + goto error; + +- return; ++ return storage; + + error: + netdev_err(netdev, "dpsw_if_get_counter err %d\n", err); +--- a/drivers/staging/fsl-dpaa2/evb/evb.c ++++ b/drivers/staging/fsl-dpaa2/evb/evb.c +@@ -765,7 +765,7 @@ static int evb_dellink(struct net_device + return 0; + } + +-void evb_port_get_stats(struct net_device *netdev, ++struct rtnl_link_stats64 *evb_port_get_stats(struct net_device *netdev, + struct rtnl_link_stats64 *storage) + { + struct evb_port_priv *port_priv = netdev_priv(netdev); +@@ -842,7 +842,7 @@ void evb_port_get_stats(struct net_devic + if (unlikely(err)) + goto error; + +- return; ++ return storage; + + error: + netdev_err(netdev, "dpdmux_if_get_counter err %d\n", err); +--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c ++++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c +@@ -239,8 +239,8 @@ EXPORT_SYMBOL(dpa_timeout); + * Calculates the statistics for the given device by adding the statistics + * collected by each CPU. + */ +-void __cold +-dpa_get_stats64(struct net_device *net_dev, ++struct rtnl_link_stats64 __cold ++*dpa_get_stats64(struct net_device *net_dev, + struct rtnl_link_stats64 *stats) + { + struct dpa_priv_s *priv = netdev_priv(net_dev); +@@ -258,6 +258,7 @@ dpa_get_stats64(struct net_device *net_d + for (j = 0; j < numstats; j++) + netstats[j] += cpustats[j]; + } ++ return stats; + } + EXPORT_SYMBOL(dpa_get_stats64); + +--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h ++++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.h +@@ -140,8 +140,8 @@ int dpa_netdev_init(struct net_device *n + int __cold dpa_start(struct net_device *net_dev); + int __cold dpa_stop(struct net_device *net_dev); + void __cold dpa_timeout(struct net_device *net_dev); +-void __cold +-dpa_get_stats64(struct net_device *net_dev, ++struct rtnl_link_stats64 __cold ++*dpa_get_stats64(struct net_device *net_dev, + struct rtnl_link_stats64 *stats); + int dpa_change_mtu(struct net_device *net_dev, int new_mtu); + int dpa_ndo_init(struct net_device *net_dev); diff --git a/target/linux/layerscape/patches-4.9/808-guts-support-layerscape.patch b/target/linux/layerscape/patches-4.9/808-guts-support-layerscape.patch deleted file mode 100644 index ffda8a6cf8..0000000000 --- a/target/linux/layerscape/patches-4.9/808-guts-support-layerscape.patch +++ /dev/null @@ -1,452 +0,0 @@ -From d51e307e4ecf51832c9e3bc30acb5dbd559d5f4d Mon Sep 17 00:00:00 2001 -From: Yangbo Lu -Date: Mon, 25 Sep 2017 12:19:34 +0800 -Subject: [PATCH] guts: support layerscape - -This is a integrated patch for layerscape guts support. - -Signed-off-by: Roy Pledge -Signed-off-by: Geert Uytterhoeven -Signed-off-by: Amrita Kumari -Signed-off-by: Yangbo Lu ---- - drivers/base/soc.c | 12 ++- - drivers/soc/fsl/guts.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/fsl/guts.h | 125 +++++++++++++++---------- - 3 files changed, 323 insertions(+), 52 deletions(-) - create mode 100644 drivers/soc/fsl/guts.c - ---- a/drivers/base/soc.c -+++ b/drivers/base/soc.c -@@ -167,19 +167,23 @@ static int soc_device_match_one(struct d - const struct soc_device_attribute *match = arg; - - if (match->machine && -- !glob_match(match->machine, soc_dev->attr->machine)) -+ (!soc_dev->attr->machine || -+ !glob_match(match->machine, soc_dev->attr->machine))) - return 0; - - if (match->family && -- !glob_match(match->family, soc_dev->attr->family)) -+ (!soc_dev->attr->family || -+ !glob_match(match->family, soc_dev->attr->family))) - return 0; - - if (match->revision && -- !glob_match(match->revision, soc_dev->attr->revision)) -+ (!soc_dev->attr->revision || -+ !glob_match(match->revision, soc_dev->attr->revision))) - return 0; - - if (match->soc_id && -- !glob_match(match->soc_id, soc_dev->attr->soc_id)) -+ (!soc_dev->attr->soc_id || -+ !glob_match(match->soc_id, soc_dev->attr->soc_id))) - return 0; - - return 1; ---- /dev/null -+++ b/drivers/soc/fsl/guts.c -@@ -0,0 +1,238 @@ -+/* -+ * Freescale QorIQ Platforms GUTS Driver -+ * -+ * Copyright (C) 2016 Freescale Semiconductor, Inc. -+ * -+ * This program is free software; you can redistribute it 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. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+struct guts { -+ struct ccsr_guts __iomem *regs; -+ bool little_endian; -+}; -+ -+struct fsl_soc_die_attr { -+ char *die; -+ u32 svr; -+ u32 mask; -+}; -+ -+static struct guts *guts; -+static struct soc_device_attribute soc_dev_attr; -+static struct soc_device *soc_dev; -+ -+ -+/* SoC die attribute definition for QorIQ platform */ -+static const struct fsl_soc_die_attr fsl_soc_die[] = { -+ /* -+ * Power Architecture-based SoCs T Series -+ */ -+ -+ /* Die: T4240, SoC: T4240/T4160/T4080 */ -+ { .die = "T4240", -+ .svr = 0x82400000, -+ .mask = 0xfff00000, -+ }, -+ /* Die: T1040, SoC: T1040/T1020/T1042/T1022 */ -+ { .die = "T1040", -+ .svr = 0x85200000, -+ .mask = 0xfff00000, -+ }, -+ /* Die: T2080, SoC: T2080/T2081 */ -+ { .die = "T2080", -+ .svr = 0x85300000, -+ .mask = 0xfff00000, -+ }, -+ /* Die: T1024, SoC: T1024/T1014/T1023/T1013 */ -+ { .die = "T1024", -+ .svr = 0x85400000, -+ .mask = 0xfff00000, -+ }, -+ -+ /* -+ * ARM-based SoCs LS Series -+ */ -+ -+ /* Die: LS1043A, SoC: LS1043A/LS1023A */ -+ { .die = "LS1043A", -+ .svr = 0x87920000, -+ .mask = 0xffff0000, -+ }, -+ /* Die: LS2080A, SoC: LS2080A/LS2040A/LS2085A */ -+ { .die = "LS2080A", -+ .svr = 0x87010000, -+ .mask = 0xff3f0000, -+ }, -+ /* Die: LS1088A, SoC: LS1088A/LS1048A/LS1084A/LS1044A */ -+ { .die = "LS1088A", -+ .svr = 0x87030000, -+ .mask = 0xff3f0000, -+ }, -+ /* Die: LS1012A, SoC: LS1012A */ -+ { .die = "LS1012A", -+ .svr = 0x87040000, -+ .mask = 0xffff0000, -+ }, -+ /* Die: LS1046A, SoC: LS1046A/LS1026A */ -+ { .die = "LS1046A", -+ .svr = 0x87070000, -+ .mask = 0xffff0000, -+ }, -+ /* Die: LS2088A, SoC: LS2088A/LS2048A/LS2084A/LS2044A */ -+ { .die = "LS2088A", -+ .svr = 0x87090000, -+ .mask = 0xff3f0000, -+ }, -+ /* Die: LS1021A, SoC: LS1021A/LS1020A/LS1022A */ -+ { .die = "LS1021A", -+ .svr = 0x87000000, -+ .mask = 0xfff70000, -+ }, -+ { }, -+}; -+ -+static const struct fsl_soc_die_attr *fsl_soc_die_match( -+ u32 svr, const struct fsl_soc_die_attr *matches) -+{ -+ while (matches->svr) { -+ if (matches->svr == (svr & matches->mask)) -+ return matches; -+ matches++; -+ }; -+ return NULL; -+} -+ -+u32 fsl_guts_get_svr(void) -+{ -+ u32 svr = 0; -+ -+ if (!guts || !guts->regs) -+ return svr; -+ -+ if (guts->little_endian) -+ svr = ioread32(&guts->regs->svr); -+ else -+ svr = ioread32be(&guts->regs->svr); -+ -+ return svr; -+} -+EXPORT_SYMBOL(fsl_guts_get_svr); -+ -+static int fsl_guts_probe(struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ struct device *dev = &pdev->dev; -+ struct resource *res; -+ const struct fsl_soc_die_attr *soc_die; -+ const char *machine; -+ u32 svr; -+ -+ /* Initialize guts */ -+ guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL); -+ if (!guts) -+ return -ENOMEM; -+ -+ guts->little_endian = of_property_read_bool(np, "little-endian"); -+ -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ guts->regs = devm_ioremap_resource(dev, res); -+ if (IS_ERR(guts->regs)) -+ return PTR_ERR(guts->regs); -+ -+ /* Register soc device */ -+ machine = of_flat_dt_get_machine_name(); -+ if (machine) -+ soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL); -+ -+ svr = fsl_guts_get_svr(); -+ soc_die = fsl_soc_die_match(svr, fsl_soc_die); -+ if (soc_die) { -+ soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, -+ "QorIQ %s", soc_die->die); -+ } else { -+ soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ"); -+ } -+ soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL, -+ "svr:0x%08x", svr); -+ soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d", -+ (svr >> 4) & 0xf, svr & 0xf); -+ -+ soc_dev = soc_device_register(&soc_dev_attr); -+ if (IS_ERR(soc_dev)) -+ return PTR_ERR(soc_dev); -+ -+ pr_info("Machine: %s\n", soc_dev_attr.machine); -+ pr_info("SoC family: %s\n", soc_dev_attr.family); -+ pr_info("SoC ID: %s, Revision: %s\n", -+ soc_dev_attr.soc_id, soc_dev_attr.revision); -+ return 0; -+} -+ -+static int fsl_guts_remove(struct platform_device *dev) -+{ -+ soc_device_unregister(soc_dev); -+ return 0; -+} -+ -+/* -+ * Table for matching compatible strings, for device tree -+ * guts node, for Freescale QorIQ SOCs. -+ */ -+static const struct of_device_id fsl_guts_of_match[] = { -+ { .compatible = "fsl,qoriq-device-config-1.0", }, -+ { .compatible = "fsl,qoriq-device-config-2.0", }, -+ { .compatible = "fsl,p1010-guts", }, -+ { .compatible = "fsl,p1020-guts", }, -+ { .compatible = "fsl,p1021-guts", }, -+ { .compatible = "fsl,p1022-guts", }, -+ { .compatible = "fsl,p1023-guts", }, -+ { .compatible = "fsl,p2020-guts", }, -+ { .compatible = "fsl,bsc9131-guts", }, -+ { .compatible = "fsl,bsc9132-guts", }, -+ { .compatible = "fsl,mpc8536-guts", }, -+ { .compatible = "fsl,mpc8544-guts", }, -+ { .compatible = "fsl,mpc8548-guts", }, -+ { .compatible = "fsl,mpc8568-guts", }, -+ { .compatible = "fsl,mpc8569-guts", }, -+ { .compatible = "fsl,mpc8572-guts", }, -+ { .compatible = "fsl,ls1021a-dcfg", }, -+ { .compatible = "fsl,ls1043a-dcfg", }, -+ { .compatible = "fsl,ls1046a-dcfg", }, -+ { .compatible = "fsl,ls2080a-dcfg", }, -+ { .compatible = "fsl,ls1088a-dcfg", }, -+ {} -+}; -+MODULE_DEVICE_TABLE(of, fsl_guts_of_match); -+ -+static struct platform_driver fsl_guts_driver = { -+ .driver = { -+ .name = "fsl-guts", -+ .of_match_table = fsl_guts_of_match, -+ }, -+ .probe = fsl_guts_probe, -+ .remove = fsl_guts_remove, -+}; -+ -+static int __init fsl_guts_init(void) -+{ -+ return platform_driver_register(&fsl_guts_driver); -+} -+core_initcall(fsl_guts_init); -+ -+static void __exit fsl_guts_exit(void) -+{ -+ platform_driver_unregister(&fsl_guts_driver); -+} -+module_exit(fsl_guts_exit); ---- a/include/linux/fsl/guts.h -+++ b/include/linux/fsl/guts.h -@@ -29,83 +29,112 @@ - * #ifdefs. - */ - struct ccsr_guts { -- __be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */ -- __be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */ -- __be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */ -- __be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */ -- __be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */ -- __be32 pordevsr2; /* 0x.0014 - POR device status register 2 */ -+ u32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */ -+ u32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */ -+ u32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and -+ * Control Register -+ */ -+ u32 pordevsr; /* 0x.000c - POR I/O Device Status Register */ -+ u32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */ -+ u32 pordevsr2; /* 0x.0014 - POR device status register 2 */ - u8 res018[0x20 - 0x18]; -- __be32 porcir; /* 0x.0020 - POR Configuration Information Register */ -+ u32 porcir; /* 0x.0020 - POR Configuration Information -+ * Register -+ */ - u8 res024[0x30 - 0x24]; -- __be32 gpiocr; /* 0x.0030 - GPIO Control Register */ -+ u32 gpiocr; /* 0x.0030 - GPIO Control Register */ - u8 res034[0x40 - 0x34]; -- __be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */ -+ u32 gpoutdr; /* 0x.0040 - General-Purpose Output Data -+ * Register -+ */ - u8 res044[0x50 - 0x44]; -- __be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */ -+ u32 gpindr; /* 0x.0050 - General-Purpose Input Data -+ * Register -+ */ - u8 res054[0x60 - 0x54]; -- __be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */ -- __be32 pmuxcr2; /* 0x.0064 - Alternate function signal multiplex control 2 */ -- __be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */ -+ u32 pmuxcr; /* 0x.0060 - Alternate Function Signal -+ * Multiplex Control -+ */ -+ u32 pmuxcr2; /* 0x.0064 - Alternate function signal -+ * multiplex control 2 -+ */ -+ u32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */ - u8 res06c[0x70 - 0x6c]; -- __be32 devdisr; /* 0x.0070 - Device Disable Control */ -+ u32 devdisr; /* 0x.0070 - Device Disable Control */ - #define CCSR_GUTS_DEVDISR_TB1 0x00001000 - #define CCSR_GUTS_DEVDISR_TB0 0x00004000 -- __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ -+ u32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ - u8 res078[0x7c - 0x78]; -- __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */ -- __be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */ -- __be32 pmrccr; /* 0x.0084 - Power Management Reset Counter Configuration Register */ -- __be32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter Configuration Register */ -- __be32 pmcdr; /* 0x.008c - 4Power management clock disable register */ -- __be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */ -- __be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */ -- __be32 ectrstcr; /* 0x.0098 - Exception reset control register */ -- __be32 autorstsr; /* 0x.009c - Automatic reset status register */ -- __be32 pvr; /* 0x.00a0 - Processor Version Register */ -- __be32 svr; /* 0x.00a4 - System Version Register */ -+ u32 pmjcr; /* 0x.007c - 4 Power Management Jog Control -+ * Register -+ */ -+ u32 powmgtcsr; /* 0x.0080 - Power Management Status and -+ * Control Register -+ */ -+ u32 pmrccr; /* 0x.0084 - Power Management Reset Counter -+ * Configuration Register -+ */ -+ u32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter -+ * Configuration Register -+ */ -+ u32 pmcdr; /* 0x.008c - 4Power management clock disable -+ * register -+ */ -+ u32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */ -+ u32 rstrscr; /* 0x.0094 - Reset Request Status and -+ * Control Register -+ */ -+ u32 ectrstcr; /* 0x.0098 - Exception reset control register */ -+ u32 autorstsr; /* 0x.009c - Automatic reset status register */ -+ u32 pvr; /* 0x.00a0 - Processor Version Register */ -+ u32 svr; /* 0x.00a4 - System Version Register */ - u8 res0a8[0xb0 - 0xa8]; -- __be32 rstcr; /* 0x.00b0 - Reset Control Register */ -+ u32 rstcr; /* 0x.00b0 - Reset Control Register */ - u8 res0b4[0xc0 - 0xb4]; -- __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register -+ u32 iovselsr; /* 0x.00c0 - I/O voltage select status register - Called 'elbcvselcr' on 86xx SOCs */ - u8 res0c4[0x100 - 0xc4]; -- __be32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers -+ u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers - There are 16 registers */ - u8 res140[0x224 - 0x140]; -- __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */ -- __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */ -+ u32 iodelay1; /* 0x.0224 - IO delay control register 1 */ -+ u32 iodelay2; /* 0x.0228 - IO delay control register 2 */ - u8 res22c[0x604 - 0x22c]; -- __be32 pamubypenr; /* 0x.604 - PAMU bypass enable register */ -+ u32 pamubypenr; /* 0x.604 - PAMU bypass enable register */ - u8 res608[0x800 - 0x608]; -- __be32 clkdvdr; /* 0x.0800 - Clock Divide Register */ -+ u32 clkdvdr; /* 0x.0800 - Clock Divide Register */ - u8 res804[0x900 - 0x804]; -- __be32 ircr; /* 0x.0900 - Infrared Control Register */ -+ u32 ircr; /* 0x.0900 - Infrared Control Register */ - u8 res904[0x908 - 0x904]; -- __be32 dmacr; /* 0x.0908 - DMA Control Register */ -+ u32 dmacr; /* 0x.0908 - DMA Control Register */ - u8 res90c[0x914 - 0x90c]; -- __be32 elbccr; /* 0x.0914 - eLBC Control Register */ -+ u32 elbccr; /* 0x.0914 - eLBC Control Register */ - u8 res918[0xb20 - 0x918]; -- __be32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */ -- __be32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */ -- __be32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */ -+ u32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */ -+ u32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */ -+ u32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */ - u8 resb2c[0xe00 - 0xb2c]; -- __be32 clkocr; /* 0x.0e00 - Clock Out Select Register */ -+ u32 clkocr; /* 0x.0e00 - Clock Out Select Register */ - u8 rese04[0xe10 - 0xe04]; -- __be32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */ -+ u32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */ - u8 rese14[0xe20 - 0xe14]; -- __be32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */ -- __be32 cpfor; /* 0x.0e24 - L2 charge pump fuse override register */ -+ u32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */ -+ u32 cpfor; /* 0x.0e24 - L2 charge pump fuse override -+ * register -+ */ - u8 rese28[0xf04 - 0xe28]; -- __be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */ -- __be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */ -+ u32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */ -+ u32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */ - u8 resf0c[0xf2c - 0xf0c]; -- __be32 itcr; /* 0x.0f2c - Internal transaction control register */ -+ u32 itcr; /* 0x.0f2c - Internal transaction control -+ * register -+ */ - u8 resf30[0xf40 - 0xf30]; -- __be32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */ -- __be32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */ -+ u32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */ -+ u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */ - } __attribute__ ((packed)); - -+u32 fsl_guts_get_svr(void); - - /* Alternate function signal multiplex control */ - #define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x)) diff --git a/target/linux/layerscape/patches-4.9/820-base-soc-Introduce-soc_device_match-interface.patch b/target/linux/layerscape/patches-4.9/820-base-soc-Introduce-soc_device_match-interface.patch new file mode 100644 index 0000000000..ec9e26191f --- /dev/null +++ b/target/linux/layerscape/patches-4.9/820-base-soc-Introduce-soc_device_match-interface.patch @@ -0,0 +1,162 @@ +From c97db7cc7778e34a53b42d58c766f0ec0e30d580 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 21 Sep 2016 14:57:19 +0800 +Subject: [PATCH] base: soc: Introduce soc_device_match() interface + +We keep running into cases where device drivers want to know the exact +version of the a SoC they are currently running on. In the past, this has +usually been done through a vendor specific API that can be called by a +driver, or by directly accessing some kind of version register that is +not part of the device itself but that belongs to a global register area +of the chip. + +Common reasons for doing this include: + +- A machine is not using devicetree or similar for passing data about + on-chip devices, but just announces their presence using boot-time + platform devices, and the machine code itself does not care about the + revision. + +- There is existing firmware or boot loaders with existing DT binaries + with generic compatible strings that do not identify the particular + revision of each device, but the driver knows which SoC revisions + include which part. + +- A prerelease version of a chip has some quirks and we are using the same + version of the bootloader and the DT blob on both the prerelease and the + final version. An update of the DT binding seems inappropriate because + that would involve maintaining multiple copies of the dts and/or + bootloader. + +This patch introduces the soc_device_match() interface that is meant to +work like of_match_node() but instead of identifying the version of a +device, it identifies the SoC itself using a vendor-agnostic interface. + +Unlike of_match_node(), we do not do an exact string compare but instead +use glob_match() to allow wildcards in strings. + +Signed-off-by: Arnd Bergmann +Signed-off-by: Yangbo Lu +Signed-off-by: Geert Uytterhoeven +Acked-by: Greg Kroah-Hartman +--- + drivers/base/Kconfig | 1 + + drivers/base/soc.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/sys_soc.h | 3 +++ + 3 files changed, 70 insertions(+) + +diff --git a/drivers/base/Kconfig b/drivers/base/Kconfig +index fdf44cac08e6..991b21e1f89b 100644 +--- a/drivers/base/Kconfig ++++ b/drivers/base/Kconfig +@@ -235,6 +235,7 @@ config GENERIC_CPU_AUTOPROBE + + config SOC_BUS + bool ++ select GLOB + + source "drivers/base/regmap/Kconfig" + +diff --git a/drivers/base/soc.c b/drivers/base/soc.c +index 028cef377fd4..04ee597fc3a3 100644 +--- a/drivers/base/soc.c ++++ b/drivers/base/soc.c +@@ -13,6 +13,7 @@ + #include + #include + #include ++#include + + static DEFINE_IDA(soc_ida); + +@@ -168,3 +169,68 @@ static int __init soc_bus_register(void) + return bus_register(&soc_bus_type); + } + core_initcall(soc_bus_register); ++ ++static int soc_device_match_one(struct device *dev, void *arg) ++{ ++ struct soc_device *soc_dev = container_of(dev, struct soc_device, dev); ++ const struct soc_device_attribute *match = arg; ++ ++ if (match->machine && ++ !glob_match(match->machine, soc_dev->attr->machine)) ++ return 0; ++ ++ if (match->family && ++ !glob_match(match->family, soc_dev->attr->family)) ++ return 0; ++ ++ if (match->revision && ++ !glob_match(match->revision, soc_dev->attr->revision)) ++ return 0; ++ ++ if (match->soc_id && ++ !glob_match(match->soc_id, soc_dev->attr->soc_id)) ++ return 0; ++ ++ return 1; ++} ++ ++/* ++ * soc_device_match - identify the SoC in the machine ++ * @matches: zero-terminated array of possible matches ++ * ++ * returns the first matching entry of the argument array, or NULL ++ * if none of them match. ++ * ++ * This function is meant as a helper in place of of_match_node() ++ * in cases where either no device tree is available or the information ++ * in a device node is insufficient to identify a particular variant ++ * by its compatible strings or other properties. For new devices, ++ * the DT binding should always provide unique compatible strings ++ * that allow the use of of_match_node() instead. ++ * ++ * The calling function can use the .data entry of the ++ * soc_device_attribute to pass a structure or function pointer for ++ * each entry. ++ */ ++const struct soc_device_attribute *soc_device_match( ++ const struct soc_device_attribute *matches) ++{ ++ int ret = 0; ++ ++ if (!matches) ++ return NULL; ++ ++ while (!ret) { ++ if (!(matches->machine || matches->family || ++ matches->revision || matches->soc_id)) ++ break; ++ ret = bus_for_each_dev(&soc_bus_type, NULL, (void *)matches, ++ soc_device_match_one); ++ if (!ret) ++ matches++; ++ else ++ return matches; ++ } ++ return NULL; ++} ++EXPORT_SYMBOL_GPL(soc_device_match); +diff --git a/include/linux/sys_soc.h b/include/linux/sys_soc.h +index 2739ccb69571..9f5eb06f9fd8 100644 +--- a/include/linux/sys_soc.h ++++ b/include/linux/sys_soc.h +@@ -13,6 +13,7 @@ struct soc_device_attribute { + const char *family; + const char *revision; + const char *soc_id; ++ const void *data; + }; + + /** +@@ -34,4 +35,6 @@ void soc_device_unregister(struct soc_device *soc_dev); + */ + struct device *soc_device_to_device(struct soc_device *soc); + ++const struct soc_device_attribute *soc_device_match( ++ const struct soc_device_attribute *matches); + #endif /* __SOC_BUS_H */ +-- +2.11.1 + diff --git a/target/linux/layerscape/patches-4.9/821-guts-support-layerscape.patch b/target/linux/layerscape/patches-4.9/821-guts-support-layerscape.patch new file mode 100644 index 0000000000..ffda8a6cf8 --- /dev/null +++ b/target/linux/layerscape/patches-4.9/821-guts-support-layerscape.patch @@ -0,0 +1,452 @@ +From d51e307e4ecf51832c9e3bc30acb5dbd559d5f4d Mon Sep 17 00:00:00 2001 +From: Yangbo Lu +Date: Mon, 25 Sep 2017 12:19:34 +0800 +Subject: [PATCH] guts: support layerscape + +This is a integrated patch for layerscape guts support. + +Signed-off-by: Roy Pledge +Signed-off-by: Geert Uytterhoeven +Signed-off-by: Amrita Kumari +Signed-off-by: Yangbo Lu +--- + drivers/base/soc.c | 12 ++- + drivers/soc/fsl/guts.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++ + include/linux/fsl/guts.h | 125 +++++++++++++++---------- + 3 files changed, 323 insertions(+), 52 deletions(-) + create mode 100644 drivers/soc/fsl/guts.c + +--- a/drivers/base/soc.c ++++ b/drivers/base/soc.c +@@ -167,19 +167,23 @@ static int soc_device_match_one(struct d + const struct soc_device_attribute *match = arg; + + if (match->machine && +- !glob_match(match->machine, soc_dev->attr->machine)) ++ (!soc_dev->attr->machine || ++ !glob_match(match->machine, soc_dev->attr->machine))) + return 0; + + if (match->family && +- !glob_match(match->family, soc_dev->attr->family)) ++ (!soc_dev->attr->family || ++ !glob_match(match->family, soc_dev->attr->family))) + return 0; + + if (match->revision && +- !glob_match(match->revision, soc_dev->attr->revision)) ++ (!soc_dev->attr->revision || ++ !glob_match(match->revision, soc_dev->attr->revision))) + return 0; + + if (match->soc_id && +- !glob_match(match->soc_id, soc_dev->attr->soc_id)) ++ (!soc_dev->attr->soc_id || ++ !glob_match(match->soc_id, soc_dev->attr->soc_id))) + return 0; + + return 1; +--- /dev/null ++++ b/drivers/soc/fsl/guts.c +@@ -0,0 +1,238 @@ ++/* ++ * Freescale QorIQ Platforms GUTS Driver ++ * ++ * Copyright (C) 2016 Freescale Semiconductor, Inc. ++ * ++ * This program is free software; you can redistribute it 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. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++struct guts { ++ struct ccsr_guts __iomem *regs; ++ bool little_endian; ++}; ++ ++struct fsl_soc_die_attr { ++ char *die; ++ u32 svr; ++ u32 mask; ++}; ++ ++static struct guts *guts; ++static struct soc_device_attribute soc_dev_attr; ++static struct soc_device *soc_dev; ++ ++ ++/* SoC die attribute definition for QorIQ platform */ ++static const struct fsl_soc_die_attr fsl_soc_die[] = { ++ /* ++ * Power Architecture-based SoCs T Series ++ */ ++ ++ /* Die: T4240, SoC: T4240/T4160/T4080 */ ++ { .die = "T4240", ++ .svr = 0x82400000, ++ .mask = 0xfff00000, ++ }, ++ /* Die: T1040, SoC: T1040/T1020/T1042/T1022 */ ++ { .die = "T1040", ++ .svr = 0x85200000, ++ .mask = 0xfff00000, ++ }, ++ /* Die: T2080, SoC: T2080/T2081 */ ++ { .die = "T2080", ++ .svr = 0x85300000, ++ .mask = 0xfff00000, ++ }, ++ /* Die: T1024, SoC: T1024/T1014/T1023/T1013 */ ++ { .die = "T1024", ++ .svr = 0x85400000, ++ .mask = 0xfff00000, ++ }, ++ ++ /* ++ * ARM-based SoCs LS Series ++ */ ++ ++ /* Die: LS1043A, SoC: LS1043A/LS1023A */ ++ { .die = "LS1043A", ++ .svr = 0x87920000, ++ .mask = 0xffff0000, ++ }, ++ /* Die: LS2080A, SoC: LS2080A/LS2040A/LS2085A */ ++ { .die = "LS2080A", ++ .svr = 0x87010000, ++ .mask = 0xff3f0000, ++ }, ++ /* Die: LS1088A, SoC: LS1088A/LS1048A/LS1084A/LS1044A */ ++ { .die = "LS1088A", ++ .svr = 0x87030000, ++ .mask = 0xff3f0000, ++ }, ++ /* Die: LS1012A, SoC: LS1012A */ ++ { .die = "LS1012A", ++ .svr = 0x87040000, ++ .mask = 0xffff0000, ++ }, ++ /* Die: LS1046A, SoC: LS1046A/LS1026A */ ++ { .die = "LS1046A", ++ .svr = 0x87070000, ++ .mask = 0xffff0000, ++ }, ++ /* Die: LS2088A, SoC: LS2088A/LS2048A/LS2084A/LS2044A */ ++ { .die = "LS2088A", ++ .svr = 0x87090000, ++ .mask = 0xff3f0000, ++ }, ++ /* Die: LS1021A, SoC: LS1021A/LS1020A/LS1022A */ ++ { .die = "LS1021A", ++ .svr = 0x87000000, ++ .mask = 0xfff70000, ++ }, ++ { }, ++}; ++ ++static const struct fsl_soc_die_attr *fsl_soc_die_match( ++ u32 svr, const struct fsl_soc_die_attr *matches) ++{ ++ while (matches->svr) { ++ if (matches->svr == (svr & matches->mask)) ++ return matches; ++ matches++; ++ }; ++ return NULL; ++} ++ ++u32 fsl_guts_get_svr(void) ++{ ++ u32 svr = 0; ++ ++ if (!guts || !guts->regs) ++ return svr; ++ ++ if (guts->little_endian) ++ svr = ioread32(&guts->regs->svr); ++ else ++ svr = ioread32be(&guts->regs->svr); ++ ++ return svr; ++} ++EXPORT_SYMBOL(fsl_guts_get_svr); ++ ++static int fsl_guts_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct device *dev = &pdev->dev; ++ struct resource *res; ++ const struct fsl_soc_die_attr *soc_die; ++ const char *machine; ++ u32 svr; ++ ++ /* Initialize guts */ ++ guts = devm_kzalloc(dev, sizeof(*guts), GFP_KERNEL); ++ if (!guts) ++ return -ENOMEM; ++ ++ guts->little_endian = of_property_read_bool(np, "little-endian"); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ guts->regs = devm_ioremap_resource(dev, res); ++ if (IS_ERR(guts->regs)) ++ return PTR_ERR(guts->regs); ++ ++ /* Register soc device */ ++ machine = of_flat_dt_get_machine_name(); ++ if (machine) ++ soc_dev_attr.machine = devm_kstrdup(dev, machine, GFP_KERNEL); ++ ++ svr = fsl_guts_get_svr(); ++ soc_die = fsl_soc_die_match(svr, fsl_soc_die); ++ if (soc_die) { ++ soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, ++ "QorIQ %s", soc_die->die); ++ } else { ++ soc_dev_attr.family = devm_kasprintf(dev, GFP_KERNEL, "QorIQ"); ++ } ++ soc_dev_attr.soc_id = devm_kasprintf(dev, GFP_KERNEL, ++ "svr:0x%08x", svr); ++ soc_dev_attr.revision = devm_kasprintf(dev, GFP_KERNEL, "%d.%d", ++ (svr >> 4) & 0xf, svr & 0xf); ++ ++ soc_dev = soc_device_register(&soc_dev_attr); ++ if (IS_ERR(soc_dev)) ++ return PTR_ERR(soc_dev); ++ ++ pr_info("Machine: %s\n", soc_dev_attr.machine); ++ pr_info("SoC family: %s\n", soc_dev_attr.family); ++ pr_info("SoC ID: %s, Revision: %s\n", ++ soc_dev_attr.soc_id, soc_dev_attr.revision); ++ return 0; ++} ++ ++static int fsl_guts_remove(struct platform_device *dev) ++{ ++ soc_device_unregister(soc_dev); ++ return 0; ++} ++ ++/* ++ * Table for matching compatible strings, for device tree ++ * guts node, for Freescale QorIQ SOCs. ++ */ ++static const struct of_device_id fsl_guts_of_match[] = { ++ { .compatible = "fsl,qoriq-device-config-1.0", }, ++ { .compatible = "fsl,qoriq-device-config-2.0", }, ++ { .compatible = "fsl,p1010-guts", }, ++ { .compatible = "fsl,p1020-guts", }, ++ { .compatible = "fsl,p1021-guts", }, ++ { .compatible = "fsl,p1022-guts", }, ++ { .compatible = "fsl,p1023-guts", }, ++ { .compatible = "fsl,p2020-guts", }, ++ { .compatible = "fsl,bsc9131-guts", }, ++ { .compatible = "fsl,bsc9132-guts", }, ++ { .compatible = "fsl,mpc8536-guts", }, ++ { .compatible = "fsl,mpc8544-guts", }, ++ { .compatible = "fsl,mpc8548-guts", }, ++ { .compatible = "fsl,mpc8568-guts", }, ++ { .compatible = "fsl,mpc8569-guts", }, ++ { .compatible = "fsl,mpc8572-guts", }, ++ { .compatible = "fsl,ls1021a-dcfg", }, ++ { .compatible = "fsl,ls1043a-dcfg", }, ++ { .compatible = "fsl,ls1046a-dcfg", }, ++ { .compatible = "fsl,ls2080a-dcfg", }, ++ { .compatible = "fsl,ls1088a-dcfg", }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, fsl_guts_of_match); ++ ++static struct platform_driver fsl_guts_driver = { ++ .driver = { ++ .name = "fsl-guts", ++ .of_match_table = fsl_guts_of_match, ++ }, ++ .probe = fsl_guts_probe, ++ .remove = fsl_guts_remove, ++}; ++ ++static int __init fsl_guts_init(void) ++{ ++ return platform_driver_register(&fsl_guts_driver); ++} ++core_initcall(fsl_guts_init); ++ ++static void __exit fsl_guts_exit(void) ++{ ++ platform_driver_unregister(&fsl_guts_driver); ++} ++module_exit(fsl_guts_exit); +--- a/include/linux/fsl/guts.h ++++ b/include/linux/fsl/guts.h +@@ -29,83 +29,112 @@ + * #ifdefs. + */ + struct ccsr_guts { +- __be32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */ +- __be32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */ +- __be32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and Control Register */ +- __be32 pordevsr; /* 0x.000c - POR I/O Device Status Register */ +- __be32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */ +- __be32 pordevsr2; /* 0x.0014 - POR device status register 2 */ ++ u32 porpllsr; /* 0x.0000 - POR PLL Ratio Status Register */ ++ u32 porbmsr; /* 0x.0004 - POR Boot Mode Status Register */ ++ u32 porimpscr; /* 0x.0008 - POR I/O Impedance Status and ++ * Control Register ++ */ ++ u32 pordevsr; /* 0x.000c - POR I/O Device Status Register */ ++ u32 pordbgmsr; /* 0x.0010 - POR Debug Mode Status Register */ ++ u32 pordevsr2; /* 0x.0014 - POR device status register 2 */ + u8 res018[0x20 - 0x18]; +- __be32 porcir; /* 0x.0020 - POR Configuration Information Register */ ++ u32 porcir; /* 0x.0020 - POR Configuration Information ++ * Register ++ */ + u8 res024[0x30 - 0x24]; +- __be32 gpiocr; /* 0x.0030 - GPIO Control Register */ ++ u32 gpiocr; /* 0x.0030 - GPIO Control Register */ + u8 res034[0x40 - 0x34]; +- __be32 gpoutdr; /* 0x.0040 - General-Purpose Output Data Register */ ++ u32 gpoutdr; /* 0x.0040 - General-Purpose Output Data ++ * Register ++ */ + u8 res044[0x50 - 0x44]; +- __be32 gpindr; /* 0x.0050 - General-Purpose Input Data Register */ ++ u32 gpindr; /* 0x.0050 - General-Purpose Input Data ++ * Register ++ */ + u8 res054[0x60 - 0x54]; +- __be32 pmuxcr; /* 0x.0060 - Alternate Function Signal Multiplex Control */ +- __be32 pmuxcr2; /* 0x.0064 - Alternate function signal multiplex control 2 */ +- __be32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */ ++ u32 pmuxcr; /* 0x.0060 - Alternate Function Signal ++ * Multiplex Control ++ */ ++ u32 pmuxcr2; /* 0x.0064 - Alternate function signal ++ * multiplex control 2 ++ */ ++ u32 dmuxcr; /* 0x.0068 - DMA Mux Control Register */ + u8 res06c[0x70 - 0x6c]; +- __be32 devdisr; /* 0x.0070 - Device Disable Control */ ++ u32 devdisr; /* 0x.0070 - Device Disable Control */ + #define CCSR_GUTS_DEVDISR_TB1 0x00001000 + #define CCSR_GUTS_DEVDISR_TB0 0x00004000 +- __be32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ ++ u32 devdisr2; /* 0x.0074 - Device Disable Control 2 */ + u8 res078[0x7c - 0x78]; +- __be32 pmjcr; /* 0x.007c - 4 Power Management Jog Control Register */ +- __be32 powmgtcsr; /* 0x.0080 - Power Management Status and Control Register */ +- __be32 pmrccr; /* 0x.0084 - Power Management Reset Counter Configuration Register */ +- __be32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter Configuration Register */ +- __be32 pmcdr; /* 0x.008c - 4Power management clock disable register */ +- __be32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */ +- __be32 rstrscr; /* 0x.0094 - Reset Request Status and Control Register */ +- __be32 ectrstcr; /* 0x.0098 - Exception reset control register */ +- __be32 autorstsr; /* 0x.009c - Automatic reset status register */ +- __be32 pvr; /* 0x.00a0 - Processor Version Register */ +- __be32 svr; /* 0x.00a4 - System Version Register */ ++ u32 pmjcr; /* 0x.007c - 4 Power Management Jog Control ++ * Register ++ */ ++ u32 powmgtcsr; /* 0x.0080 - Power Management Status and ++ * Control Register ++ */ ++ u32 pmrccr; /* 0x.0084 - Power Management Reset Counter ++ * Configuration Register ++ */ ++ u32 pmpdccr; /* 0x.0088 - Power Management Power Down Counter ++ * Configuration Register ++ */ ++ u32 pmcdr; /* 0x.008c - 4Power management clock disable ++ * register ++ */ ++ u32 mcpsumr; /* 0x.0090 - Machine Check Summary Register */ ++ u32 rstrscr; /* 0x.0094 - Reset Request Status and ++ * Control Register ++ */ ++ u32 ectrstcr; /* 0x.0098 - Exception reset control register */ ++ u32 autorstsr; /* 0x.009c - Automatic reset status register */ ++ u32 pvr; /* 0x.00a0 - Processor Version Register */ ++ u32 svr; /* 0x.00a4 - System Version Register */ + u8 res0a8[0xb0 - 0xa8]; +- __be32 rstcr; /* 0x.00b0 - Reset Control Register */ ++ u32 rstcr; /* 0x.00b0 - Reset Control Register */ + u8 res0b4[0xc0 - 0xb4]; +- __be32 iovselsr; /* 0x.00c0 - I/O voltage select status register ++ u32 iovselsr; /* 0x.00c0 - I/O voltage select status register + Called 'elbcvselcr' on 86xx SOCs */ + u8 res0c4[0x100 - 0xc4]; +- __be32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers ++ u32 rcwsr[16]; /* 0x.0100 - Reset Control Word Status registers + There are 16 registers */ + u8 res140[0x224 - 0x140]; +- __be32 iodelay1; /* 0x.0224 - IO delay control register 1 */ +- __be32 iodelay2; /* 0x.0228 - IO delay control register 2 */ ++ u32 iodelay1; /* 0x.0224 - IO delay control register 1 */ ++ u32 iodelay2; /* 0x.0228 - IO delay control register 2 */ + u8 res22c[0x604 - 0x22c]; +- __be32 pamubypenr; /* 0x.604 - PAMU bypass enable register */ ++ u32 pamubypenr; /* 0x.604 - PAMU bypass enable register */ + u8 res608[0x800 - 0x608]; +- __be32 clkdvdr; /* 0x.0800 - Clock Divide Register */ ++ u32 clkdvdr; /* 0x.0800 - Clock Divide Register */ + u8 res804[0x900 - 0x804]; +- __be32 ircr; /* 0x.0900 - Infrared Control Register */ ++ u32 ircr; /* 0x.0900 - Infrared Control Register */ + u8 res904[0x908 - 0x904]; +- __be32 dmacr; /* 0x.0908 - DMA Control Register */ ++ u32 dmacr; /* 0x.0908 - DMA Control Register */ + u8 res90c[0x914 - 0x90c]; +- __be32 elbccr; /* 0x.0914 - eLBC Control Register */ ++ u32 elbccr; /* 0x.0914 - eLBC Control Register */ + u8 res918[0xb20 - 0x918]; +- __be32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */ +- __be32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */ +- __be32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */ ++ u32 ddr1clkdr; /* 0x.0b20 - DDR1 Clock Disable Register */ ++ u32 ddr2clkdr; /* 0x.0b24 - DDR2 Clock Disable Register */ ++ u32 ddrclkdr; /* 0x.0b28 - DDR Clock Disable Register */ + u8 resb2c[0xe00 - 0xb2c]; +- __be32 clkocr; /* 0x.0e00 - Clock Out Select Register */ ++ u32 clkocr; /* 0x.0e00 - Clock Out Select Register */ + u8 rese04[0xe10 - 0xe04]; +- __be32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */ ++ u32 ddrdllcr; /* 0x.0e10 - DDR DLL Control Register */ + u8 rese14[0xe20 - 0xe14]; +- __be32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */ +- __be32 cpfor; /* 0x.0e24 - L2 charge pump fuse override register */ ++ u32 lbcdllcr; /* 0x.0e20 - LBC DLL Control Register */ ++ u32 cpfor; /* 0x.0e24 - L2 charge pump fuse override ++ * register ++ */ + u8 rese28[0xf04 - 0xe28]; +- __be32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */ +- __be32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */ ++ u32 srds1cr0; /* 0x.0f04 - SerDes1 Control Register 0 */ ++ u32 srds1cr1; /* 0x.0f08 - SerDes1 Control Register 0 */ + u8 resf0c[0xf2c - 0xf0c]; +- __be32 itcr; /* 0x.0f2c - Internal transaction control register */ ++ u32 itcr; /* 0x.0f2c - Internal transaction control ++ * register ++ */ + u8 resf30[0xf40 - 0xf30]; +- __be32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */ +- __be32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */ ++ u32 srds2cr0; /* 0x.0f40 - SerDes2 Control Register 0 */ ++ u32 srds2cr1; /* 0x.0f44 - SerDes2 Control Register 0 */ + } __attribute__ ((packed)); + ++u32 fsl_guts_get_svr(void); + + /* Alternate function signal multiplex control */ + #define MPC85xx_PMUXCR_QE(x) (0x8000 >> (x)) -- cgit v1.2.3